From 6d744374db5ac64fc538f89412eb91f4798187b0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 12 May 2020 11:22:25 +0200 Subject: [PATCH 01/37] [tracking] Use enum-conveniences --- src/modules/tracking/TrackingType.h | 12 +++++++++--- src/modules/tracking/TrackingViewStep.cpp | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/modules/tracking/TrackingType.h b/src/modules/tracking/TrackingType.h index 02dbd934e..04e8d2ebe 100644 --- a/src/modules/tracking/TrackingType.h +++ b/src/modules/tracking/TrackingType.h @@ -19,11 +19,17 @@ #ifndef TRACKINGTYPE_H #define TRACKINGTYPE_H +#include "utils/NamedEnum.h" + enum class TrackingType { - InstallTracking, - MachineTracking, - UserTracking + NoTracking, // Do not enable tracking at all + InstallTracking, // Track that *this* install has happened + MachineTracking, // Track the machine, ongoing + UserTracking // Track the user, ongoing }; +// Implemented in TrackingViewStep.cpp +const NamedEnumTable< TrackingType >& trackingNames(); + #endif //TRACKINGTYPE_H diff --git a/src/modules/tracking/TrackingViewStep.cpp b/src/modules/tracking/TrackingViewStep.cpp index a51864ea9..2cb97f079 100644 --- a/src/modules/tracking/TrackingViewStep.cpp +++ b/src/modules/tracking/TrackingViewStep.cpp @@ -189,3 +189,20 @@ TrackingViewStep::setConfigurationMap( const QVariantMap& configurationMap ) m_widget->setGeneralPolicy( CalamaresUtils::getString( configurationMap, "policy" ) ); m_widget->setTrackingLevel( CalamaresUtils::getString( configurationMap, "default" ) ); } + +const NamedEnumTable< TrackingType >& +trackingNames() +{ + // *INDENT-OFF* + // clang-format off + static const NamedEnumTable< TrackingType > names { + { QStringLiteral( "none" ), TrackingType::NoTracking }, + { QStringLiteral( "install" ), TrackingType::InstallTracking }, + { QStringLiteral( "machine" ), TrackingType::MachineTracking }, + { QStringLiteral( "user" ), TrackingType::UserTracking } + }; + // clang-format on + // *INDENT-ON* + + return names; +} From fd2853b2cfa49d6af5add66ceaa75c60b0f97391 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 12 May 2020 11:41:02 +0200 Subject: [PATCH 02/37] [tracking] Switch setTrackingLevel() to use enum --- src/modules/tracking/TrackingPage.cpp | 34 ++++++++++------------- src/modules/tracking/TrackingPage.h | 14 ++++++---- src/modules/tracking/TrackingViewStep.cpp | 7 ++++- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index ba1d5efd0..359fac4b4 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -172,34 +172,28 @@ TrackingPage::setGeneralPolicy( QString url ) } void -TrackingPage::setTrackingLevel( const QString& l ) +TrackingPage::setTrackingLevel( TrackingType t ) { - QString level = l.toLower(); QRadioButton* button = nullptr; - if ( level.isEmpty() || level == "none" ) + switch( t ) { - button = ui->noneRadio; - } - else if ( level == "install" ) - { - button = ui->installRadio; - } - else if ( level == "machine" ) - { - button = ui->machineRadio; - } - else if ( level == "user" ) - { - button = ui->userRadio; + case TrackingType::NoTracking: + button = ui->noneRadio; + break; + case TrackingType::InstallTracking: + button = ui->installRadio; + break; + case TrackingType::MachineTracking: + button = ui->machineRadio; + break; + case TrackingType::UserTracking: + button = ui->userRadio; + break; } if ( button != nullptr ) { button->setChecked( true ); } - else - { - cWarning() << "unknown default tracking level" << l; - } } diff --git a/src/modules/tracking/TrackingPage.h b/src/modules/tracking/TrackingPage.h index 560115b92..52cfca493 100644 --- a/src/modules/tracking/TrackingPage.h +++ b/src/modules/tracking/TrackingPage.h @@ -35,7 +35,8 @@ class TrackingPage : public QWidget public: explicit TrackingPage( QWidget* parent = nullptr ); - /** + /** @brief Set initial state for each option + * * Enables or disables the tracking-option block for the given * tracking option @p t, and sets the initial state of the * checkbox to the @p user default. @@ -43,19 +44,20 @@ public: * Call this in ascending order of tracking type. */ void enableTrackingOption( TrackingType t, bool enabled ); - /** + /** @brief Is the given tracking type enabled? + * * Returns whether tracking type @p is selected by the user * (i.e. is the radio button for that level, or for a higher * tracking level, enabled). */ bool getTrackingOption( TrackingType t ); - /* URL for given level @p t */ + ///@brief Set URL for given level @p t void setTrackingPolicy( TrackingType t, QString url ); - /* URL for the global link */ + ///@brief Set URL for the global link void setGeneralPolicy( QString url ); - /* Select one of the four levels by name */ - void setTrackingLevel( const QString& level ); + ///@brief Select one of the four levels by name + void setTrackingLevel( TrackingType t ); private: Ui::TrackingPage* ui; diff --git a/src/modules/tracking/TrackingViewStep.cpp b/src/modules/tracking/TrackingViewStep.cpp index 2cb97f079..f934301bd 100644 --- a/src/modules/tracking/TrackingViewStep.cpp +++ b/src/modules/tracking/TrackingViewStep.cpp @@ -187,7 +187,12 @@ TrackingViewStep::setConfigurationMap( const QVariantMap& configurationMap ) setTrackingOption( configurationMap, "user", TrackingType::UserTracking ); m_widget->setGeneralPolicy( CalamaresUtils::getString( configurationMap, "policy" ) ); - m_widget->setTrackingLevel( CalamaresUtils::getString( configurationMap, "default" ) ); + bool ok; + m_widget->setTrackingLevel( trackingNames().find(CalamaresUtils::getString( configurationMap, "default" ), ok ) ); + if ( !ok ) + { + cWarning() << "Default tracking level unknown:" << CalamaresUtils::getString( configurationMap, "default" ); + } } const NamedEnumTable< TrackingType >& From 8ed8b5dfa3e00274eb98dd4fa40274a1bbbfb82e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 12 May 2020 12:11:11 +0200 Subject: [PATCH 03/37] [tracking] Reduce compiler warnings - Newly added enum value NoTracking needs explicit handling in some switch()es, although it will never be passed in. --- src/modules/tracking/TrackingPage.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index 359fac4b4..0ac466673 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -70,6 +70,9 @@ TrackingPage::enableTrackingOption( TrackingType t, bool enabled ) switch ( t ) { + case TrackingType::NoTracking: + // Nothing to do, this **has** no widget + return; case TrackingType::InstallTracking: group = ui->installGroup; break; @@ -108,6 +111,8 @@ TrackingPage::getTrackingOption( TrackingType t ) #define ch( x ) ui->x->isChecked() switch ( t ) { + case TrackingType::NoTracking: + return false; case TrackingType::InstallTracking: enabled = ch( installRadio ) || ch( machineRadio ) || ch( userRadio ); break; @@ -128,6 +133,9 @@ TrackingPage::setTrackingPolicy( TrackingType t, QString url ) QToolButton* button = nullptr; switch ( t ) { + case TrackingType::NoTracking: + cWarning() << "Cannot configure NoTracking widget"; + return; case TrackingType::InstallTracking: button = ui->installPolicyButton; break; From a69d47c115bcd32e9d4b8628b9ac939efb26d3fa Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 12 May 2020 14:24:33 +0200 Subject: [PATCH 04/37] [tracking] Add a Config object --- src/modules/tracking/CMakeLists.txt | 1 + src/modules/tracking/Config.cpp | 40 +++++++++++++++++++++++++ src/modules/tracking/Config.h | 45 +++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 src/modules/tracking/Config.cpp create mode 100644 src/modules/tracking/Config.h diff --git a/src/modules/tracking/CMakeLists.txt b/src/modules/tracking/CMakeLists.txt index 24e020af4..11ccdb00b 100644 --- a/src/modules/tracking/CMakeLists.txt +++ b/src/modules/tracking/CMakeLists.txt @@ -2,6 +2,7 @@ calamares_add_plugin( tracking TYPE viewmodule EXPORT_MACRO PLUGINDLLEXPORT_PRO SOURCES + Config.cpp TrackingJobs.cpp TrackingPage.cpp TrackingViewStep.cpp diff --git a/src/modules/tracking/Config.cpp b/src/modules/tracking/Config.cpp new file mode 100644 index 000000000..d920074fa --- /dev/null +++ b/src/modules/tracking/Config.cpp @@ -0,0 +1,40 @@ +/* === This file is part of Calamares - === + * + * Copyright 2020, Adriaan de Groot + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#include "Config.h" + +#include "utils/Logger.h" +#include "utils/Variant.h" + +Config::Config( QObject* parent ) + : QObject( parent ) +{ +} + +void +Config::setConfigurationMap( const QVariantMap& m ) +{ + m_generalPolicy = CalamaresUtils::getString( m, "policy" ); + emit generalPolicyChanged( m_generalPolicy ); +} + +QString +Config::generalPolicy() const +{ + return m_generalPolicy; +} diff --git a/src/modules/tracking/Config.h b/src/modules/tracking/Config.h new file mode 100644 index 000000000..d0d6f6e0c --- /dev/null +++ b/src/modules/tracking/Config.h @@ -0,0 +1,45 @@ +/* === This file is part of Calamares - === + * + * Copyright 2020, Adriaan de Groot + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#ifndef TRACKING_CONFIG_H +#define TRACKING_CONFIG_H + +#include +#include +#include + +class Config : public QObject +{ + Q_OBJECT + Q_PROPERTY( QString generalPolicy READ generalPolicy NOTIFY generalPolicyChanged FINAL ) + +public: + Config( QObject* parent = nullptr ); + void setConfigurationMap( const QVariantMap& ); + +public Q_SLOTS: + QString generalPolicy() const; + +signals: + void generalPolicyChanged( QString ); + +private: + QString m_generalPolicy; +}; + +#endif From 044f5ce2b56f97600d604353f4eef94bfdf7ac78 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 12 May 2020 14:39:42 +0200 Subject: [PATCH 05/37] [tracking] Use the config object - right now only holds the global policy URL (as a string) --- src/modules/tracking/TrackingPage.cpp | 75 +++++++++++++---------- src/modules/tracking/TrackingPage.h | 12 +++- src/modules/tracking/TrackingViewStep.cpp | 9 ++- src/modules/tracking/TrackingViewStep.h | 2 + 4 files changed, 60 insertions(+), 38 deletions(-) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index 0ac466673..ae9a04843 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -18,6 +18,7 @@ #include "TrackingPage.h" +#include "Config.h" #include "ui_page_trackingstep.h" #include "Branding.h" @@ -32,27 +33,12 @@ #include #include -TrackingPage::TrackingPage( QWidget* parent ) +TrackingPage::TrackingPage( Config* config, QWidget* parent ) : QWidget( parent ) , ui( new Ui::TrackingPage ) { ui->setupUi( this ); - CALAMARES_RETRANSLATE( - QString product = Calamares::Branding::instance()->shortProductName(); ui->retranslateUi( this ); - ui->generalExplanation->setText( - tr( "Install tracking helps %1 to see how many users they have, what hardware they install %1 to and (with " - "the last two options below), get continuous information about preferred applications. To see what " - "will be sent, please click the help icon next to each area." ) - .arg( product ) ); - ui->installExplanation->setText( - tr( "By selecting this you will send information about your installation and hardware. This information " - "will only be sent once after the installation finishes." ) ); - ui->machineExplanation->setText( tr( "By selecting this you will periodically send information about " - "your installation, hardware and applications, to %1." ) - .arg( product ) ); - ui->userExplanation->setText( tr( "By selecting this you will regularly send information about your " - "installation, hardware, applications and usage patterns, to %1." ) - .arg( product ) ); ) + CALAMARES_RETRANSLATE_SLOT( &TrackingPage::retranslate ); QButtonGroup* group = new QButtonGroup( this ); group->setExclusive( true ); @@ -61,8 +47,33 @@ TrackingPage::TrackingPage( QWidget* parent ) group->addButton( ui->machineRadio ); group->addButton( ui->userRadio ); ui->noneRadio->setChecked( true ); + + connect( config, &Config::generalPolicyChanged, this, &TrackingPage::setGeneralPolicy ); + retranslate(); } +void +TrackingPage::retranslate() +{ + QString product = Calamares::Branding::instance()->shortProductName(); + ui->retranslateUi( this ); + ui->generalExplanation->setText( + tr( "Install tracking helps %1 to see how many users they have, what hardware they install %1 to and (with " + "the last two options below), get continuous information about preferred applications. To see what " + "will be sent, please click the help icon next to each area." ) + .arg( product ) ); + ui->installExplanation->setText( + tr( "By selecting this you will send information about your installation and hardware. This information " + "will only be sent once after the installation finishes." ) ); + ui->machineExplanation->setText( tr( "By selecting this you will periodically send information about " + "your installation, hardware and applications, to %1." ) + .arg( product ) ); + ui->userExplanation->setText( tr( "By selecting this you will regularly send information about your " + "installation, hardware, applications and usage patterns, to %1." ) + .arg( product ) ); +} + + void TrackingPage::enableTrackingOption( TrackingType t, bool enabled ) { @@ -154,7 +165,7 @@ TrackingPage::setTrackingPolicy( TrackingType t, QString url ) } else { - connect( button, &QToolButton::clicked, [ url ] { QDesktopServices::openUrl( url ); } ); + connect( button, &QToolButton::clicked, [url] { QDesktopServices::openUrl( url ); } ); cDebug() << "Tracking policy" << int( t ) << "set to" << url; } else @@ -175,7 +186,7 @@ TrackingPage::setGeneralPolicy( QString url ) ui->generalPolicyLabel->show(); ui->generalPolicyLabel->setTextInteractionFlags( Qt::TextBrowserInteraction ); ui->generalPolicyLabel->show(); - connect( ui->generalPolicyLabel, &QLabel::linkActivated, [ url ] { QDesktopServices::openUrl( url ); } ); + connect( ui->generalPolicyLabel, &QLabel::linkActivated, [url] { QDesktopServices::openUrl( url ); } ); } } @@ -184,20 +195,20 @@ TrackingPage::setTrackingLevel( TrackingType t ) { QRadioButton* button = nullptr; - switch( t ) + switch ( t ) { - case TrackingType::NoTracking: - button = ui->noneRadio; - break; - case TrackingType::InstallTracking: - button = ui->installRadio; - break; - case TrackingType::MachineTracking: - button = ui->machineRadio; - break; - case TrackingType::UserTracking: - button = ui->userRadio; - break; + case TrackingType::NoTracking: + button = ui->noneRadio; + break; + case TrackingType::InstallTracking: + button = ui->installRadio; + break; + case TrackingType::MachineTracking: + button = ui->machineRadio; + break; + case TrackingType::UserTracking: + button = ui->userRadio; + break; } if ( button != nullptr ) diff --git a/src/modules/tracking/TrackingPage.h b/src/modules/tracking/TrackingPage.h index 52cfca493..dbc9cc20c 100644 --- a/src/modules/tracking/TrackingPage.h +++ b/src/modules/tracking/TrackingPage.h @@ -29,11 +29,13 @@ namespace Ui class TrackingPage; } +class Config; + class TrackingPage : public QWidget { Q_OBJECT public: - explicit TrackingPage( QWidget* parent = nullptr ); + explicit TrackingPage( Config* config, QWidget* parent = nullptr ); /** @brief Set initial state for each option * @@ -54,11 +56,15 @@ public: ///@brief Set URL for given level @p t void setTrackingPolicy( TrackingType t, QString url ); - ///@brief Set URL for the global link - void setGeneralPolicy( QString url ); ///@brief Select one of the four levels by name void setTrackingLevel( TrackingType t ); +public Q_SLOTS: + ///@brief Set URL for the global link + void setGeneralPolicy( QString url ); + + void retranslate(); + private: Ui::TrackingPage* ui; }; diff --git a/src/modules/tracking/TrackingViewStep.cpp b/src/modules/tracking/TrackingViewStep.cpp index f934301bd..6da292242 100644 --- a/src/modules/tracking/TrackingViewStep.cpp +++ b/src/modules/tracking/TrackingViewStep.cpp @@ -18,6 +18,7 @@ #include "TrackingViewStep.h" +#include "Config.h" #include "TrackingJobs.h" #include "TrackingPage.h" @@ -43,7 +44,8 @@ isValidStyle( const QString& s ) TrackingViewStep::TrackingViewStep( QObject* parent ) : Calamares::ViewStep( parent ) - , m_widget( new TrackingPage ) + , m_config( new Config( this ) ) + , m_widget( new TrackingPage( m_config ) ) { emit nextStatusChanged( false ); } @@ -186,9 +188,10 @@ TrackingViewStep::setConfigurationMap( const QVariantMap& configurationMap ) setTrackingOption( configurationMap, "user", TrackingType::UserTracking ); - m_widget->setGeneralPolicy( CalamaresUtils::getString( configurationMap, "policy" ) ); + m_config->setConfigurationMap( configurationMap ); + bool ok; - m_widget->setTrackingLevel( trackingNames().find(CalamaresUtils::getString( configurationMap, "default" ), ok ) ); + m_widget->setTrackingLevel( trackingNames().find( CalamaresUtils::getString( configurationMap, "default" ), ok ) ); if ( !ok ) { cWarning() << "Default tracking level unknown:" << CalamaresUtils::getString( configurationMap, "default" ); diff --git a/src/modules/tracking/TrackingViewStep.h b/src/modules/tracking/TrackingViewStep.h index bb40d292a..a342dc498 100644 --- a/src/modules/tracking/TrackingViewStep.h +++ b/src/modules/tracking/TrackingViewStep.h @@ -29,6 +29,7 @@ #include #include +class Config; class TrackingPage; class PLUGINDLLEXPORT TrackingViewStep : public Calamares::ViewStep @@ -58,6 +59,7 @@ public: private: QVariantMap setTrackingOption( const QVariantMap& configurationMap, const QString& key, TrackingType t ); + Config* m_config; TrackingPage* m_widget; QString m_installTrackingUrl; QString m_machineTrackingStyle; From ed71b2fbf530af59dff51782dc7e37e6d25e0954 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 12 May 2020 14:42:04 +0200 Subject: [PATCH 06/37] [tracking] Only accept valid policy URLs --- src/modules/tracking/Config.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/modules/tracking/Config.cpp b/src/modules/tracking/Config.cpp index d920074fa..67da7025d 100644 --- a/src/modules/tracking/Config.cpp +++ b/src/modules/tracking/Config.cpp @@ -21,6 +21,8 @@ #include "utils/Logger.h" #include "utils/Variant.h" +#include + Config::Config( QObject* parent ) : QObject( parent ) { @@ -30,6 +32,12 @@ void Config::setConfigurationMap( const QVariantMap& m ) { m_generalPolicy = CalamaresUtils::getString( m, "policy" ); + + if ( !QUrl( m_generalPolicy ).isValid() ) + { + m_generalPolicy = QString(); + } + emit generalPolicyChanged( m_generalPolicy ); } From d9fb9c19a80efd4f149b5952e868b2639a8e5034 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 18 May 2020 16:41:25 +0200 Subject: [PATCH 07/37] [tracking] Refactor the information for one tracking type - a single tracking type can be enabled for configuration in the config file; each must have a policy URL. Class TrackingStyleConfig is a base class for that kind of configuration. --- src/modules/tracking/Config.cpp | 58 +++++++++++++++++++++++++-- src/modules/tracking/Config.h | 70 +++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 4 deletions(-) diff --git a/src/modules/tracking/Config.cpp b/src/modules/tracking/Config.cpp index 67da7025d..217babba4 100644 --- a/src/modules/tracking/Config.cpp +++ b/src/modules/tracking/Config.cpp @@ -23,22 +23,72 @@ #include -Config::Config( QObject* parent ) +TrackingStyleConfig::TrackingStyleConfig( QObject* parent ) : QObject( parent ) { } +TrackingStyleConfig::~TrackingStyleConfig() { } + void -Config::setConfigurationMap( const QVariantMap& m ) +TrackingStyleConfig::setTracking( bool enabled ) { - m_generalPolicy = CalamaresUtils::getString( m, "policy" ); + setTracking( enabled ? EnabledByUser : DisabledByUser ); +} + +void +TrackingStyleConfig::setTracking( TrackingStyleConfig::TrackingState state ) +{ + if ( m_state != TrackingState::DisabledByConfig ) + { + m_state = state; + } + emit trackingChanged(); +} + +void +TrackingStyleConfig::setConfigurationMap( const QVariantMap& config ) +{ + m_state = CalamaresUtils::getBool( config, "enabled", false ) ? DisabledByUser : DisabledByConfig; + m_policy = CalamaresUtils::getString( config, "policy" ); + if ( !QUrl( m_policy ).isValid() ) + { + if ( m_state != DisabledByConfig ) + { + cError() << "Tracking policy URL" << m_policy << "is not valid; disabling this tracking type."; + } + m_policy = QString(); + m_state = DisabledByConfig; + } + + emit policyChanged( m_policy ); + emit trackingChanged(); +} + + +Config::Config( QObject* parent ) + : QObject( parent ) + , m_installTracking( new TrackingStyleConfig( this ) ) +{ +} + +void +Config::setConfigurationMap( const QVariantMap& configurationMap ) +{ + m_generalPolicy = CalamaresUtils::getString( configurationMap, "policy" ); if ( !QUrl( m_generalPolicy ).isValid() ) { m_generalPolicy = QString(); } - emit generalPolicyChanged( m_generalPolicy ); + + bool success = false; + auto subconfig = CalamaresUtils::getSubMap( configurationMap, "install", success ); + if ( success ) + { + m_installTracking->setConfigurationMap( subconfig ); + } } QString diff --git a/src/modules/tracking/Config.h b/src/modules/tracking/Config.h index d0d6f6e0c..80f6d74d1 100644 --- a/src/modules/tracking/Config.h +++ b/src/modules/tracking/Config.h @@ -23,10 +23,77 @@ #include #include +/** @brief Base class for configuring a specific kind of tracking. + * + * All tracking types have a policy URL, which is used to explain what + * kind of tracking is involved, what data is sent, etc. The content + * of that URL is the responsibility of the distro. + * + * A tracking type is disabled by default: if it isn't specifically + * enabled (for configuration) in the config file, it will always be disabled. + * If it is enabled (for configuration) in the config file, it still + * defaults to disabled, but the user can choose to enable it. + */ +class TrackingStyleConfig : public QObject +{ + Q_OBJECT + + Q_PROPERTY( TrackingState trackingStatus READ tracking WRITE setTracking NOTIFY trackingChanged FINAL ) + Q_PROPERTY( bool isEnabled READ isEnabled NOTIFY trackingChanged FINAL ) + Q_PROPERTY( bool isConfigurable READ isConfigurable NOTIFY trackingChanged FINAL ) + Q_PROPERTY( QString policy READ policy NOTIFY policyChanged FINAL ) + +public: + TrackingStyleConfig( QObject* parent ); + virtual ~TrackingStyleConfig(); + + void setConfigurationMap( const QVariantMap& ); + + enum TrackingState + { + DisabledByConfig, + DisabledByUser, + EnabledByUser + }; + Q_ENUM( TrackingState ); + +public Q_SLOTS: + TrackingState tracking() const { return m_state; } + /// @brief Has the user specifically enabled this kind of tracking? + bool isEnabled() const { return m_state == EnabledByUser; } + /// @brief Is this tracking enabled for configuration? + bool isConfigurable() const { return m_state != DisabledByConfig; } + /** @brief Sets the tracking state + * + * Unless the tracking is enabled for configuration, it always + * remains disabled. + */ + void setTracking( TrackingState ); + /** @brief Sets the tracking state + * + * Use @c true for @c EnabledByUser, @c false for DisabledByUser, + * but keep in mind that if the tracking is not enabled for + * configuration, it will always remain disabled. + */ + void setTracking( bool ); + + /// @brief URL for the policy explaining this tracking + QString policy() const { return m_policy; } + +signals: + void trackingChanged(); + void policyChanged( QString ); + +private: + TrackingState m_state = DisabledByConfig; + QString m_policy; // URL +}; + class Config : public QObject { Q_OBJECT Q_PROPERTY( QString generalPolicy READ generalPolicy NOTIFY generalPolicyChanged FINAL ) + Q_PROPERTY( TrackingStyleConfig* installTracking READ installTracking FINAL ) public: Config( QObject* parent = nullptr ); @@ -34,12 +101,15 @@ public: public Q_SLOTS: QString generalPolicy() const; + TrackingStyleConfig* installTracking() const { return m_installTracking; } signals: void generalPolicyChanged( QString ); private: QString m_generalPolicy; + + TrackingStyleConfig* m_installTracking; }; #endif From f97a0756a9af62ce544475d6631e93de2c9f012a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 18 May 2020 17:09:01 +0200 Subject: [PATCH 08/37] [tracking] Introduce configuration for install-tracking - subclass of TrackingStyleConfig holds the URL that is pinged with information when the installation is done. --- src/modules/tracking/Config.cpp | 43 ++++++++++++++++++++++++--------- src/modules/tracking/Config.h | 18 +++++++++++++- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/modules/tracking/Config.cpp b/src/modules/tracking/Config.cpp index 217babba4..7997556bf 100644 --- a/src/modules/tracking/Config.cpp +++ b/src/modules/tracking/Config.cpp @@ -46,29 +46,50 @@ TrackingStyleConfig::setTracking( TrackingStyleConfig::TrackingState state ) emit trackingChanged(); } +void +TrackingStyleConfig::validateUrl( QString& urlString ) +{ + if ( !QUrl( urlString ).isValid() ) + { + if ( m_state != DisabledByConfig ) + { + cError() << "URL" << urlString << "is not valid; disabling this tracking type."; + m_state = DisabledByConfig; + emit trackingChanged(); + } + urlString = QString(); + } +} + + void TrackingStyleConfig::setConfigurationMap( const QVariantMap& config ) { m_state = CalamaresUtils::getBool( config, "enabled", false ) ? DisabledByUser : DisabledByConfig; m_policy = CalamaresUtils::getString( config, "policy" ); - if ( !QUrl( m_policy ).isValid() ) - { - if ( m_state != DisabledByConfig ) - { - cError() << "Tracking policy URL" << m_policy << "is not valid; disabling this tracking type."; - } - m_policy = QString(); - m_state = DisabledByConfig; - } - + validateUrl( m_policy ); emit policyChanged( m_policy ); emit trackingChanged(); } +InstallTrackingConfig::InstallTrackingConfig( QObject* parent ) + : TrackingStyleConfig( parent ) +{ +} + +void +InstallTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap ) +{ + TrackingStyleConfig::setConfigurationMap( configurationMap ); + + m_installTrackingUrl = CalamaresUtils::getString( configurationMap, "url" ); + validateUrl( m_installTrackingUrl ); +} + Config::Config( QObject* parent ) : QObject( parent ) - , m_installTracking( new TrackingStyleConfig( this ) ) + , m_installTracking( new InstallTrackingConfig( this ) ) { } diff --git a/src/modules/tracking/Config.h b/src/modules/tracking/Config.h index 80f6d74d1..0fbf8495b 100644 --- a/src/modules/tracking/Config.h +++ b/src/modules/tracking/Config.h @@ -84,11 +84,27 @@ signals: void trackingChanged(); void policyChanged( QString ); +protected: + /// @brief Validates the @p urlString, disables tracking if invalid + void validateUrl( QString& urlString ); + private: TrackingState m_state = DisabledByConfig; QString m_policy; // URL }; +class InstallTrackingConfig : public TrackingStyleConfig +{ +public: + InstallTrackingConfig( QObject* parent ); + void setConfigurationMap( const QVariantMap& configurationMap ); + + QString installTrackingUrl() { return m_installTrackingUrl; } + +private: + QString m_installTrackingUrl; +}; + class Config : public QObject { Q_OBJECT @@ -109,7 +125,7 @@ signals: private: QString m_generalPolicy; - TrackingStyleConfig* m_installTracking; + InstallTrackingConfig* m_installTracking; }; #endif From 528b98c1c4410423958c776945ec012b7876a55a Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 18 May 2020 17:42:51 +0200 Subject: [PATCH 09/37] [tracking] Configurations for machine and user tracking --- src/modules/tracking/Config.cpp | 59 +++++++++++++++++++++++++++++++++ src/modules/tracking/Config.h | 49 +++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/src/modules/tracking/Config.cpp b/src/modules/tracking/Config.cpp index 7997556bf..2c62447b1 100644 --- a/src/modules/tracking/Config.cpp +++ b/src/modules/tracking/Config.cpp @@ -46,6 +46,21 @@ TrackingStyleConfig::setTracking( TrackingStyleConfig::TrackingState state ) emit trackingChanged(); } +void +TrackingStyleConfig::validate( QString& s, std::function< bool( const QString& ) >&& pred ) +{ + if ( !pred( s ) ) + { + if ( m_state != DisabledByConfig ) + { + cError() << "Configuration string" << s << "is not valid; disabling this tracking type."; + m_state = DisabledByConfig; + emit trackingChanged(); + } + s = QString(); + } +} + void TrackingStyleConfig::validateUrl( QString& urlString ) { @@ -86,6 +101,50 @@ InstallTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap validateUrl( m_installTrackingUrl ); } +MachineTrackingConfig::MachineTrackingConfig( QObject* parent ) + : TrackingStyleConfig( parent ) +{ +} + +/** @brief Is @p s a valid machine-tracking style. */ +static bool +isValidMachineTrackingStyle( const QString& s ) +{ + static QStringList knownStyles { "neon" }; + return knownStyles.contains( s ); +} + +void +MachineTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap ) +{ + TrackingStyleConfig::setConfigurationMap( configurationMap ); + + m_machineTrackingStyle = CalamaresUtils::getString( configurationMap, "style" ); + validate( m_machineTrackingStyle, isValidMachineTrackingStyle ); +} + + +UserTrackingConfig::UserTrackingConfig( QObject* parent ) + : TrackingStyleConfig( parent ) +{ +} + +static bool +isValidUserTrackingStyle( const QString& s ) +{ + static QStringList knownStyles { "kde" }; + return knownStyles.contains( s ); +} + +void +UserTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap ) +{ + TrackingStyleConfig::setConfigurationMap( configurationMap ); + + m_userTrackingStyle = CalamaresUtils::getString( configurationMap, "style" ); + validate( m_userTrackingStyle, isValidUserTrackingStyle ); +} + Config::Config( QObject* parent ) : QObject( parent ) diff --git a/src/modules/tracking/Config.h b/src/modules/tracking/Config.h index 0fbf8495b..d9210b7ff 100644 --- a/src/modules/tracking/Config.h +++ b/src/modules/tracking/Config.h @@ -87,12 +87,21 @@ signals: protected: /// @brief Validates the @p urlString, disables tracking if invalid void validateUrl( QString& urlString ); + /// @brief Validates the @p string, disables tracking if invalid + void validate( QString& s, std::function< bool( const QString& s ) >&& pred ); private: TrackingState m_state = DisabledByConfig; QString m_policy; // URL }; +/** @brief Install tracking pings a URL at the end of installation + * + * Install tracking will do a single GET on the given URL at + * the end of installation. The information included in the GET + * request depends on the URL configuration, see also the tracking + * jobs. + */ class InstallTrackingConfig : public TrackingStyleConfig { public: @@ -105,6 +114,46 @@ private: QString m_installTrackingUrl; }; +/** @brief Machine tracking reports from the installed system + * + * When machine tracking is on, the installed system will report + * back ("call home") at some point. This can mean Debian pop-con, + * or KDE neon maching tracking, or something else. The kind + * of configuration depends on the style of tracking that is enabled. + */ +class MachineTrackingConfig : public TrackingStyleConfig +{ +public: + MachineTrackingConfig( QObject* parent ); + void setConfigurationMap( const QVariantMap& configurationMap ); + + QString machineTrackingStyle() { return m_machineTrackingStyle; } + +private: + QString m_machineTrackingStyle; +}; + +/** @brief User tracking reports user actions + * + * When user tracking is on, it is enabled for the user configured + * in Calamares -- not for users created afterwards in the target + * system, unless the target system defaults to tracking them. + * The kind of user tracking depends on the target system and + * environment; KDE user tracking is one example, which can be + * configured in a fine-grained way and defaults to off. + */ +class UserTrackingConfig : public TrackingStyleConfig +{ +public: + UserTrackingConfig( QObject* parent ); + void setConfigurationMap( const QVariantMap& configurationMap ); + + QString userTrackingStyle() { return m_userTrackingStyle; } + +private: + QString m_userTrackingStyle; +}; + class Config : public QObject { Q_OBJECT From 5763799ba9b6394a509c26a23831dda63c9a7700 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 18 May 2020 17:48:51 +0200 Subject: [PATCH 10/37] [tracking] Load all the tracking bits into the configuration --- src/modules/tracking/Config.cpp | 14 ++++++++++++++ src/modules/tracking/Config.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/src/modules/tracking/Config.cpp b/src/modules/tracking/Config.cpp index 2c62447b1..8b5decd76 100644 --- a/src/modules/tracking/Config.cpp +++ b/src/modules/tracking/Config.cpp @@ -149,6 +149,8 @@ UserTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap ) Config::Config( QObject* parent ) : QObject( parent ) , m_installTracking( new InstallTrackingConfig( this ) ) + , m_machineTracking( new MachineTrackingConfig( this ) ) + , m_userTracking( new UserTrackingConfig( this ) ) { } @@ -169,6 +171,18 @@ Config::setConfigurationMap( const QVariantMap& configurationMap ) { m_installTracking->setConfigurationMap( subconfig ); } + + subconfig = CalamaresUtils::getSubMap( configurationMap, "machine", success ); + if ( success ) + { + m_machineTracking->setConfigurationMap( subconfig ); + } + + subconfig = CalamaresUtils::getSubMap( configurationMap, "user", success ); + if ( success ) + { + m_userTracking->setConfigurationMap( subconfig ); + } } QString diff --git a/src/modules/tracking/Config.h b/src/modules/tracking/Config.h index d9210b7ff..1a451e5ce 100644 --- a/src/modules/tracking/Config.h +++ b/src/modules/tracking/Config.h @@ -175,6 +175,8 @@ private: QString m_generalPolicy; InstallTrackingConfig* m_installTracking; + MachineTrackingConfig* m_machineTracking; + UserTrackingConfig* m_userTracking; }; #endif From 309b2f872de99fb8d93ed54d531e71f798bf9157 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 18 May 2020 20:18:34 +0200 Subject: [PATCH 11/37] [tracking] Drop configuration fields from ViewStep - All the configuration lives in the Config object (or the tracking objects that it exposes). - Get data from the config object for the jobs; TODO: give the jobs a less-clunky interface. The UI isn't hooked up to the Config object yet, though. --- src/modules/tracking/Config.h | 7 ++- src/modules/tracking/TrackingViewStep.cpp | 62 +++++------------------ src/modules/tracking/TrackingViewStep.h | 35 ------------- 3 files changed, 19 insertions(+), 85 deletions(-) diff --git a/src/modules/tracking/Config.h b/src/modules/tracking/Config.h index 1a451e5ce..bd9ba520e 100644 --- a/src/modules/tracking/Config.h +++ b/src/modules/tracking/Config.h @@ -159,6 +159,8 @@ class Config : public QObject Q_OBJECT Q_PROPERTY( QString generalPolicy READ generalPolicy NOTIFY generalPolicyChanged FINAL ) Q_PROPERTY( TrackingStyleConfig* installTracking READ installTracking FINAL ) + Q_PROPERTY( TrackingStyleConfig* machineTracking READ machineTracking FINAL ) + Q_PROPERTY( TrackingStyleConfig* userTracking READ userTracking FINAL ) public: Config( QObject* parent = nullptr ); @@ -166,7 +168,10 @@ public: public Q_SLOTS: QString generalPolicy() const; - TrackingStyleConfig* installTracking() const { return m_installTracking; } + + InstallTrackingConfig* installTracking() const { return m_installTracking; } + MachineTrackingConfig* machineTracking() const { return m_machineTracking; } + UserTrackingConfig* userTracking() const { return m_userTracking; } signals: void generalPolicyChanged( QString ); diff --git a/src/modules/tracking/TrackingViewStep.cpp b/src/modules/tracking/TrackingViewStep.cpp index 6da292242..98685bfc8 100644 --- a/src/modules/tracking/TrackingViewStep.cpp +++ b/src/modules/tracking/TrackingViewStep.cpp @@ -105,12 +105,9 @@ TrackingViewStep::isAtEnd() const void TrackingViewStep::onLeave() { - m_installTracking.userEnabled = m_widget->getTrackingOption( TrackingType::InstallTracking ); - m_machineTracking.userEnabled = m_widget->getTrackingOption( TrackingType::MachineTracking ); - m_userTracking.userEnabled = m_widget->getTrackingOption( TrackingType::UserTracking ); - cDebug() << "Install tracking:" << m_installTracking.enabled(); - cDebug() << "Machine tracking:" << m_machineTracking.enabled(); - cDebug() << " User tracking:" << m_userTracking.enabled(); + cDebug() << "Install tracking:" << m_config->installTracking()->isEnabled(); + cDebug() << "Machine tracking:" << m_config->machineTracking()->isEnabled(); + cDebug() << " User tracking:" << m_config->userTracking()->isEnabled(); } @@ -120,10 +117,10 @@ TrackingViewStep::jobs() const Calamares::JobList l; cDebug() << "Creating tracking jobs .."; - if ( m_installTracking.enabled() && !m_installTrackingUrl.isEmpty() ) + if ( m_config->installTracking()->isEnabled() ) { - QString installUrl = m_installTrackingUrl; - const auto s = CalamaresUtils::System::instance(); + QString installUrl = m_config->installTracking()->installTrackingUrl(); + const auto* s = CalamaresUtils::System::instance(); QString memory, disk; memory.setNum( s->getTotalMemoryB().first ); @@ -136,58 +133,25 @@ TrackingViewStep::jobs() const l.append( Calamares::job_ptr( new TrackingInstallJob( installUrl ) ) ); } - if ( m_machineTracking.enabled() && !m_machineTrackingStyle.isEmpty() ) + if ( m_config->machineTracking()->isEnabled() ) { - Q_ASSERT( isValidStyle( m_machineTrackingStyle ) ); - if ( m_machineTrackingStyle == "neon" ) + const auto style = m_config->machineTracking()->machineTrackingStyle(); + if ( style == "neon" ) { l.append( Calamares::job_ptr( new TrackingMachineNeonJob() ) ); } + else + { + cWarning() << "Unsupported machine tracking style" << style; + } } return l; } -QVariantMap -TrackingViewStep::setTrackingOption( const QVariantMap& configurationMap, const QString& key, TrackingType t ) -{ - bool settingEnabled = false; - - bool success = false; - auto config = CalamaresUtils::getSubMap( configurationMap, key, success ); - - if ( success ) - { - settingEnabled = CalamaresUtils::getBool( config, "enabled", false ); - } - - TrackingEnabled& trackingConfiguration = tracking( t ); - trackingConfiguration.settingEnabled = settingEnabled; - trackingConfiguration.userEnabled = false; - - m_widget->enableTrackingOption( t, settingEnabled ); - m_widget->setTrackingPolicy( t, CalamaresUtils::getString( config, "policy" ) ); - - return config; -} - void TrackingViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { - QVariantMap config; - - config = setTrackingOption( configurationMap, "install", TrackingType::InstallTracking ); - m_installTrackingUrl = CalamaresUtils::getString( config, "url" ); - - config = setTrackingOption( configurationMap, "machine", TrackingType::MachineTracking ); - auto s = CalamaresUtils::getString( config, "style" ); - if ( isValidStyle( s ) ) - { - m_machineTrackingStyle = s; - } - - setTrackingOption( configurationMap, "user", TrackingType::UserTracking ); - m_config->setConfigurationMap( configurationMap ); bool ok; diff --git a/src/modules/tracking/TrackingViewStep.h b/src/modules/tracking/TrackingViewStep.h index a342dc498..b05f1b053 100644 --- a/src/modules/tracking/TrackingViewStep.h +++ b/src/modules/tracking/TrackingViewStep.h @@ -57,43 +57,8 @@ public: void setConfigurationMap( const QVariantMap& configurationMap ) override; private: - QVariantMap setTrackingOption( const QVariantMap& configurationMap, const QString& key, TrackingType t ); - Config* m_config; TrackingPage* m_widget; - QString m_installTrackingUrl; - QString m_machineTrackingStyle; - - struct TrackingEnabled - { - bool settingEnabled; // Enabled in config file - bool userEnabled; // User checked "yes" - - TrackingEnabled() - : settingEnabled( false ) - , userEnabled( false ) - { - } - - bool enabled() const { return settingEnabled && userEnabled; } - }; - TrackingEnabled m_installTracking, m_machineTracking, m_userTracking; - - inline TrackingEnabled& tracking( TrackingType t ) - { - if ( t == TrackingType::UserTracking ) - { - return m_userTracking; - } - else if ( t == TrackingType::MachineTracking ) - { - return m_machineTracking; - } - else - { - return m_installTracking; - } - } }; CALAMARES_PLUGIN_FACTORY_DECLARATION( TrackingViewStepFactory ) From 49e66b11a2938b92cd9647728de38058de921cd7 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 19 May 2020 10:42:25 +0200 Subject: [PATCH 12/37] [tracking] Refactor creation of jobs - Let the jobs handle their own styling and handling, simplify the ViewStep code. --- src/modules/tracking/TrackingJobs.cpp | 40 +++++++++++++++++++++ src/modules/tracking/TrackingJobs.h | 42 +++++++++++++++++++++-- src/modules/tracking/TrackingPage.cpp | 4 +-- src/modules/tracking/TrackingViewStep.cpp | 36 +++---------------- 4 files changed, 86 insertions(+), 36 deletions(-) diff --git a/src/modules/tracking/TrackingJobs.cpp b/src/modules/tracking/TrackingJobs.cpp index 1f284e6dd..40af355bd 100644 --- a/src/modules/tracking/TrackingJobs.cpp +++ b/src/modules/tracking/TrackingJobs.cpp @@ -18,6 +18,8 @@ #include "TrackingJobs.h" +#include "Config.h" + #include "network/Manager.h" #include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" @@ -72,6 +74,44 @@ TrackingInstallJob::exec() return Calamares::JobResult::ok(); } +void +TrackingInstallJob::addJob( Calamares::JobList& list, InstallTrackingConfig* config ) +{ + if ( config->isEnabled() ) + { + QString installUrl = config->installTrackingUrl(); + const auto* s = CalamaresUtils::System::instance(); + + QString memory, disk; + memory.setNum( s->getTotalMemoryB().first ); + disk.setNum( s->getTotalDiskB() ); + + installUrl.replace( "$CPU", s->getCpuDescription() ).replace( "$MEMORY", memory ).replace( "$DISK", disk ); + + cDebug() << Logger::SubEntry << "install-tracking URL" << installUrl; + + list.append( Calamares::job_ptr( new TrackingInstallJob( installUrl ) ) ); + } +} + +void +TrackingMachineJob::addJob( Calamares::JobList& list, MachineTrackingConfig* config ) +{ + if ( config->isEnabled() ) + { + const auto style = config->machineTrackingStyle(); + if ( style == "neon" ) + { + list.append( Calamares::job_ptr( new TrackingMachineNeonJob() ) ); + } + else + { + cWarning() << "Unsupported machine tracking style" << style; + } + } +} + + QString TrackingMachineNeonJob::prettyName() const { diff --git a/src/modules/tracking/TrackingJobs.h b/src/modules/tracking/TrackingJobs.h index 813355591..c7c2450cb 100644 --- a/src/modules/tracking/TrackingJobs.h +++ b/src/modules/tracking/TrackingJobs.h @@ -16,13 +16,35 @@ * along with Calamares. If not, see . */ -#ifndef TRACKINGJOBS -#define TRACKINGJOBS +#ifndef TRACKING_TRACKINGJOBS_H +#define TRACKING_TRACKINGJOBS_H #include "Job.h" +class InstallTrackingConfig; +class MachineTrackingConfig; + class QSemaphore; +/** @section Tracking Jobs + * + * The tracking jobs do the actual work of configuring tracking on the + * target machine. Tracking jobs may have *styles*, variations depending + * on the distro or environment of the target system. At the root of + * each family of tracking jobs (installation, machine, user) there is + * a class with static method `addJob()` that takes the configuration + * information from the relevant Config sub-object and optionally + * adds the right job (subclass!) to the list of jobs. + */ + +/** @brief Install-tracking job (gets a URL) + * + * The install-tracking job (there is only one kind) does a GET + * on a configured URL with some additional information about + * the machine (if configured into the URL). + * + * No persistent tracking is done. + */ class TrackingInstallJob : public Calamares::Job { Q_OBJECT @@ -35,11 +57,25 @@ public: QString prettyStatusMessage() const override; Calamares::JobResult exec() override; + static void addJob( Calamares::JobList& list, InstallTrackingConfig* config ); + private: const QString m_url; }; -class TrackingMachineNeonJob : public Calamares::Job +/** @brief Base class for machine-tracking jobs + * + * Machine-tracking configuraiton depends on the distro / style of machine + * being tracked, so it has subclasses to switch on the relevant kind + * of tracking. A machine is tracked persistently. + */ +class TrackingMachineJob : public Calamares::Job +{ +public: + static void addJob( Calamares::JobList& list, MachineTrackingConfig* config ); +}; + +class TrackingMachineNeonJob : public TrackingMachineJob { Q_OBJECT public: diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index ae9a04843..7572ecb68 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -165,7 +165,7 @@ TrackingPage::setTrackingPolicy( TrackingType t, QString url ) } else { - connect( button, &QToolButton::clicked, [url] { QDesktopServices::openUrl( url ); } ); + connect( button, &QToolButton::clicked, [ url ] { QDesktopServices::openUrl( url ); } ); cDebug() << "Tracking policy" << int( t ) << "set to" << url; } else @@ -186,7 +186,7 @@ TrackingPage::setGeneralPolicy( QString url ) ui->generalPolicyLabel->show(); ui->generalPolicyLabel->setTextInteractionFlags( Qt::TextBrowserInteraction ); ui->generalPolicyLabel->show(); - connect( ui->generalPolicyLabel, &QLabel::linkActivated, [url] { QDesktopServices::openUrl( url ); } ); + connect( ui->generalPolicyLabel, &QLabel::linkActivated, [ url ] { QDesktopServices::openUrl( url ); } ); } } diff --git a/src/modules/tracking/TrackingViewStep.cpp b/src/modules/tracking/TrackingViewStep.cpp index 98685bfc8..9942c2981 100644 --- a/src/modules/tracking/TrackingViewStep.cpp +++ b/src/modules/tracking/TrackingViewStep.cpp @@ -106,45 +106,19 @@ void TrackingViewStep::onLeave() { cDebug() << "Install tracking:" << m_config->installTracking()->isEnabled(); - cDebug() << "Machine tracking:" << m_config->machineTracking()->isEnabled(); - cDebug() << " User tracking:" << m_config->userTracking()->isEnabled(); + cDebug() << Logger::SubEntry << "Machine tracking:" << m_config->machineTracking()->isEnabled(); + cDebug() << Logger::SubEntry << " User tracking:" << m_config->userTracking()->isEnabled(); } Calamares::JobList TrackingViewStep::jobs() const { - Calamares::JobList l; - cDebug() << "Creating tracking jobs .."; - if ( m_config->installTracking()->isEnabled() ) - { - QString installUrl = m_config->installTracking()->installTrackingUrl(); - const auto* s = CalamaresUtils::System::instance(); - QString memory, disk; - memory.setNum( s->getTotalMemoryB().first ); - disk.setNum( s->getTotalDiskB() ); - - installUrl.replace( "$CPU", s->getCpuDescription() ).replace( "$MEMORY", memory ).replace( "$DISK", disk ); - - cDebug() << Logger::SubEntry << "install-tracking URL" << installUrl; - - l.append( Calamares::job_ptr( new TrackingInstallJob( installUrl ) ) ); - } - - if ( m_config->machineTracking()->isEnabled() ) - { - const auto style = m_config->machineTracking()->machineTrackingStyle(); - if ( style == "neon" ) - { - l.append( Calamares::job_ptr( new TrackingMachineNeonJob() ) ); - } - else - { - cWarning() << "Unsupported machine tracking style" << style; - } - } + Calamares::JobList l; + TrackingInstallJob::addJob( l, m_config->installTracking() ); + TrackingMachineJob::addJob( l, m_config->machineTracking() ); return l; } From dfd6bb6a8bf08dc8c83a228f43177917f8253972 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 19 May 2020 11:05:32 +0200 Subject: [PATCH 13/37] [tracking] Massage the displayed explanation --- src/modules/tracking/TrackingPage.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index 7572ecb68..1e30a8a3a 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -58,19 +58,21 @@ TrackingPage::retranslate() QString product = Calamares::Branding::instance()->shortProductName(); ui->retranslateUi( this ); ui->generalExplanation->setText( - tr( "Install tracking helps %1 to see how many users they have, what hardware they install %1 to and (with " - "the last two options below), get continuous information about preferred applications. To see what " + tr( "Tracking helps %1 to see how often it is installed, what hardware it is installed on and " + "which applications are used. To see what " "will be sent, please click the help icon next to each area." ) .arg( product ) ); ui->installExplanation->setText( tr( "By selecting this you will send information about your installation and hardware. This information " "will only be sent once after the installation finishes." ) ); - ui->machineExplanation->setText( tr( "By selecting this you will periodically send information about " - "your installation, hardware and applications, to %1." ) - .arg( product ) ); - ui->userExplanation->setText( tr( "By selecting this you will regularly send information about your " - "installation, hardware, applications and usage patterns, to %1." ) - .arg( product ) ); + ui->machineExplanation->setText( + tr( "By selecting this you will periodically send information about your machine installation, " + "hardware and applications, to %1." ) + .arg( product ) ); + ui->userExplanation->setText( + tr( "By selecting this you will regularly send information about your " + "user installation, hardware, applications and application usage patterns, to %1." ) + .arg( product ) ); } From a7c4e2d203a05ef94b84f1451e4f4cc3a5728272 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 19 May 2020 11:12:16 +0200 Subject: [PATCH 14/37] [tracking] Remove widget-setting stuff not needed with Config --- src/modules/tracking/TrackingPage.cpp | 100 -------------------------- src/modules/tracking/TrackingPage.h | 19 ----- 2 files changed, 119 deletions(-) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index 1e30a8a3a..82e0d99c5 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -76,106 +76,6 @@ TrackingPage::retranslate() } -void -TrackingPage::enableTrackingOption( TrackingType t, bool enabled ) -{ - QWidget* group = nullptr; - - switch ( t ) - { - case TrackingType::NoTracking: - // Nothing to do, this **has** no widget - return; - case TrackingType::InstallTracking: - group = ui->installGroup; - break; - case TrackingType::MachineTracking: - group = ui->machineGroup; - break; - case TrackingType::UserTracking: - group = ui->userGroup; - break; - } - - if ( group != nullptr ) - { - if ( enabled ) - { - group->show(); - } - else - { - group->hide(); - } - } - else - { - cWarning() << "unknown tracking option" << int( t ); - } -} - -bool -TrackingPage::getTrackingOption( TrackingType t ) -{ - bool enabled = false; - - // A tracking type is enabled if it is checked, or - // any higher level is checked. -#define ch( x ) ui->x->isChecked() - switch ( t ) - { - case TrackingType::NoTracking: - return false; - case TrackingType::InstallTracking: - enabled = ch( installRadio ) || ch( machineRadio ) || ch( userRadio ); - break; - case TrackingType::MachineTracking: - enabled = ch( machineRadio ) || ch( userRadio ); - break; - case TrackingType::UserTracking: - enabled = ch( userRadio ); - break; - } -#undef ch - return enabled; -} - -void -TrackingPage::setTrackingPolicy( TrackingType t, QString url ) -{ - QToolButton* button = nullptr; - switch ( t ) - { - case TrackingType::NoTracking: - cWarning() << "Cannot configure NoTracking widget"; - return; - case TrackingType::InstallTracking: - button = ui->installPolicyButton; - break; - case TrackingType::MachineTracking: - button = ui->machinePolicyButton; - break; - case TrackingType::UserTracking: - button = ui->userPolicyButton; - break; - } - - if ( button != nullptr ) - if ( url.isEmpty() ) - { - button->hide(); - } - else - { - connect( button, &QToolButton::clicked, [ url ] { QDesktopServices::openUrl( url ); } ); - cDebug() << "Tracking policy" << int( t ) << "set to" << url; - } - else - { - cWarning() << "unknown tracking option" << int( t ); - } -} - void TrackingPage::setGeneralPolicy( QString url ) { diff --git a/src/modules/tracking/TrackingPage.h b/src/modules/tracking/TrackingPage.h index dbc9cc20c..ce8b87729 100644 --- a/src/modules/tracking/TrackingPage.h +++ b/src/modules/tracking/TrackingPage.h @@ -37,25 +37,6 @@ class TrackingPage : public QWidget public: explicit TrackingPage( Config* config, QWidget* parent = nullptr ); - /** @brief Set initial state for each option - * - * Enables or disables the tracking-option block for the given - * tracking option @p t, and sets the initial state of the - * checkbox to the @p user default. - * - * Call this in ascending order of tracking type. - */ - void enableTrackingOption( TrackingType t, bool enabled ); - /** @brief Is the given tracking type enabled? - * - * Returns whether tracking type @p is selected by the user - * (i.e. is the radio button for that level, or for a higher - * tracking level, enabled). - */ - bool getTrackingOption( TrackingType t ); - - ///@brief Set URL for given level @p t - void setTrackingPolicy( TrackingType t, QString url ); ///@brief Select one of the four levels by name void setTrackingLevel( TrackingType t ); From 935f443a4db7085e27c44c2c061d4a5cf5881ca5 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 25 May 2020 05:24:20 -0400 Subject: [PATCH 15/37] [tracking] Simplify policy display - Don't need an own slot for this, just connect to signals from Config and the label, neither of which need any state. --- src/modules/tracking/TrackingPage.cpp | 31 ++++++++++++--------------- src/modules/tracking/TrackingPage.h | 3 --- 2 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index 82e0d99c5..000ea2002 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -48,7 +48,20 @@ TrackingPage::TrackingPage( Config* config, QWidget* parent ) group->addButton( ui->userRadio ); ui->noneRadio->setChecked( true ); - connect( config, &Config::generalPolicyChanged, this, &TrackingPage::setGeneralPolicy ); + // TODO: move to .ui file + ui->generalPolicyLabel->setTextInteractionFlags( Qt::TextBrowserInteraction ); + + connect( config, &Config::generalPolicyChanged, [ this ]( const QString& url ) { + this->ui->generalPolicyLabel->setVisible( !url.isEmpty() ); + } ); + connect( ui->generalPolicyLabel, &QLabel::linkActivated, [ config ] { + QString url( config->generalPolicy() ); + if ( !url.isEmpty() ) + { + QDesktopServices::openUrl( url ); + } + } ); + retranslate(); } @@ -76,22 +89,6 @@ TrackingPage::retranslate() } -void -TrackingPage::setGeneralPolicy( QString url ) -{ - if ( url.isEmpty() ) - { - ui->generalPolicyLabel->hide(); - } - else - { - ui->generalPolicyLabel->show(); - ui->generalPolicyLabel->setTextInteractionFlags( Qt::TextBrowserInteraction ); - ui->generalPolicyLabel->show(); - connect( ui->generalPolicyLabel, &QLabel::linkActivated, [ url ] { QDesktopServices::openUrl( url ); } ); - } -} - void TrackingPage::setTrackingLevel( TrackingType t ) { diff --git a/src/modules/tracking/TrackingPage.h b/src/modules/tracking/TrackingPage.h index ce8b87729..f63f7375c 100644 --- a/src/modules/tracking/TrackingPage.h +++ b/src/modules/tracking/TrackingPage.h @@ -41,9 +41,6 @@ public: void setTrackingLevel( TrackingType t ); public Q_SLOTS: - ///@brief Set URL for the global link - void setGeneralPolicy( QString url ); - void retranslate(); private: From 1d143d95a0ba544ff80c3738398ed29ed09bc8aa Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 25 May 2020 08:30:37 -0400 Subject: [PATCH 16/37] [tracking] Setup UI in the .ui file --- src/modules/tracking/TrackingPage.cpp | 3 --- src/modules/tracking/page_trackingstep.ui | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index 000ea2002..02bc94195 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -48,9 +48,6 @@ TrackingPage::TrackingPage( Config* config, QWidget* parent ) group->addButton( ui->userRadio ); ui->noneRadio->setChecked( true ); - // TODO: move to .ui file - ui->generalPolicyLabel->setTextInteractionFlags( Qt::TextBrowserInteraction ); - connect( config, &Config::generalPolicyChanged, [ this ]( const QString& url ) { this->ui->generalPolicyLabel->setVisible( !url.isEmpty() ); } ); diff --git a/src/modules/tracking/page_trackingstep.ui b/src/modules/tracking/page_trackingstep.ui index ae2ed11b8..9612ef2b4 100644 --- a/src/modules/tracking/page_trackingstep.ui +++ b/src/modules/tracking/page_trackingstep.ui @@ -279,6 +279,9 @@ margin-left: 2em; false + + Qt::TextBrowserInteraction + From bed884c9718a4a75bce1356cc33d4bee40c7892e Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 25 May 2020 09:21:47 -0400 Subject: [PATCH 17/37] [tracking] Move setup of initial-tracking states to Config - the *default* level from the config, can be handled inside the Config object as well; remove TrackingPage method that does the same. --- src/modules/tracking/Config.cpp | 59 +++++++++++++++++++++++ src/modules/tracking/Config.h | 3 ++ src/modules/tracking/TrackingType.h | 2 +- src/modules/tracking/TrackingViewStep.cpp | 23 --------- 4 files changed, 63 insertions(+), 24 deletions(-) diff --git a/src/modules/tracking/Config.cpp b/src/modules/tracking/Config.cpp index 8b5decd76..2dc91c2a9 100644 --- a/src/modules/tracking/Config.cpp +++ b/src/modules/tracking/Config.cpp @@ -18,11 +18,30 @@ #include "Config.h" +#include "TrackingType.h" + #include "utils/Logger.h" #include "utils/Variant.h" #include +const NamedEnumTable< TrackingType >& +trackingNames() +{ + // *INDENT-OFF* + // clang-format off + static const NamedEnumTable< TrackingType > names { + { QStringLiteral( "none" ), TrackingType::NoTracking }, + { QStringLiteral( "install" ), TrackingType::InstallTracking }, + { QStringLiteral( "machine" ), TrackingType::MachineTracking }, + { QStringLiteral( "user" ), TrackingType::UserTracking } + }; + // clang-format on + // *INDENT-ON* + + return names; +} + TrackingStyleConfig::TrackingStyleConfig( QObject* parent ) : QObject( parent ) { @@ -154,6 +173,26 @@ Config::Config( QObject* parent ) { } +static void +enableLevelsBelow( Config* config, TrackingType level ) +{ + switch( level ) + { + case TrackingType::UserTracking: + config->userTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser ); + FALLTHRU; + case TrackingType::MachineTracking: + config->machineTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser ); + FALLTHRU; + case TrackingType::InstallTracking: + config->installTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser ); + break; + case TrackingType::NoTracking: + config->noTracking( true ); + break; + } +} + void Config::setConfigurationMap( const QVariantMap& configurationMap ) { @@ -183,6 +222,14 @@ Config::setConfigurationMap( const QVariantMap& configurationMap ) { m_userTracking->setConfigurationMap( subconfig ); } + + auto level = trackingNames().find( CalamaresUtils::getString( configurationMap, "default" ), success ); + if ( !success ) + { + cWarning() << "Default tracking level unknown:" << CalamaresUtils::getString( configurationMap, "default" ); + level = TrackingType::NoTracking; + } + enableLevelsBelow( this, level ); } QString @@ -190,3 +237,15 @@ Config::generalPolicy() const { return m_generalPolicy; } + +void +Config::noTracking( bool switchOffAllTracking ) +{ + if ( !switchOffAllTracking ) + { + return; + } + m_installTracking->setTracking( TrackingStyleConfig::TrackingState::DisabledByUser ); + m_machineTracking->setTracking( TrackingStyleConfig::TrackingState::DisabledByUser ); + m_userTracking->setTracking( TrackingStyleConfig::TrackingState::DisabledByUser ); +} diff --git a/src/modules/tracking/Config.h b/src/modules/tracking/Config.h index bd9ba520e..26dcf2f4f 100644 --- a/src/modules/tracking/Config.h +++ b/src/modules/tracking/Config.h @@ -173,6 +173,9 @@ public Q_SLOTS: MachineTrackingConfig* machineTracking() const { return m_machineTracking; } UserTrackingConfig* userTracking() const { return m_userTracking; } + /// @brief Call with @c true to turn off all the trackings + void noTracking( bool ); + signals: void generalPolicyChanged( QString ); diff --git a/src/modules/tracking/TrackingType.h b/src/modules/tracking/TrackingType.h index 04e8d2ebe..22e3157d6 100644 --- a/src/modules/tracking/TrackingType.h +++ b/src/modules/tracking/TrackingType.h @@ -29,7 +29,7 @@ enum class TrackingType UserTracking // Track the user, ongoing }; -// Implemented in TrackingViewStep.cpp +// Implemented in Config.cpp const NamedEnumTable< TrackingType >& trackingNames(); #endif //TRACKINGTYPE_H diff --git a/src/modules/tracking/TrackingViewStep.cpp b/src/modules/tracking/TrackingViewStep.cpp index 9942c2981..491fef12a 100644 --- a/src/modules/tracking/TrackingViewStep.cpp +++ b/src/modules/tracking/TrackingViewStep.cpp @@ -127,28 +127,5 @@ void TrackingViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { m_config->setConfigurationMap( configurationMap ); - - bool ok; - m_widget->setTrackingLevel( trackingNames().find( CalamaresUtils::getString( configurationMap, "default" ), ok ) ); - if ( !ok ) - { - cWarning() << "Default tracking level unknown:" << CalamaresUtils::getString( configurationMap, "default" ); - } } -const NamedEnumTable< TrackingType >& -trackingNames() -{ - // *INDENT-OFF* - // clang-format off - static const NamedEnumTable< TrackingType > names { - { QStringLiteral( "none" ), TrackingType::NoTracking }, - { QStringLiteral( "install" ), TrackingType::InstallTracking }, - { QStringLiteral( "machine" ), TrackingType::MachineTracking }, - { QStringLiteral( "user" ), TrackingType::UserTracking } - }; - // clang-format on - // *INDENT-ON* - - return names; -} From fab3ff2c41dbec28a0ee307c0c35d06738aff3fb Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 25 May 2020 09:56:32 -0400 Subject: [PATCH 18/37] [tracking] Implement KUserFeedback configuration - write config files to turn on KUserFeedback (for known areas) - TODO: get the right home directory to write in --- src/modules/tracking/TrackingJobs.cpp | 69 +++++++++++++++++++++++++++ src/modules/tracking/TrackingJobs.h | 34 +++++++++++++ 2 files changed, 103 insertions(+) diff --git a/src/modules/tracking/TrackingJobs.cpp b/src/modules/tracking/TrackingJobs.cpp index 40af355bd..18d01c7ca 100644 --- a/src/modules/tracking/TrackingJobs.cpp +++ b/src/modules/tracking/TrackingJobs.cpp @@ -162,3 +162,72 @@ true tr( "Could not configure machine feedback correctly, Calamares error %1." ).arg( r ) ); } } + +void +TrackingUserJob::addJob( Calamares::JobList& list, UserTrackingConfig* config ) +{ + if ( config->isEnabled() ) + { + const auto style = config->userTrackingStyle(); + if ( style == "kuserfeedback" ) + { + list.append( Calamares::job_ptr( new TrackingKUserFeedbackJob() ) ); + } + else + { + cWarning() << "Unsupported user tracking style" << style; + } + } +} + +QString +TrackingKUserFeedbackJob::prettyName() const +{ + return tr( "KDE user feedback" ); +} + +QString +TrackingKUserFeedbackJob::prettyDescription() const +{ + return prettyName(); +} + +QString +TrackingKUserFeedbackJob::prettyStatusMessage() const +{ + return tr( "Configuring KDE user feedback." ); +} + +Calamares::JobResult +TrackingKUserFeedbackJob::exec() +{ + // This is the contents of a config file to turn on some kind + // of KUserFeedback tracking; the level (16) is chosen for minimal + // but not zero tracking. + static const char config[] = R"x([Global] +FeedbackLevel=16 +)x"; + + for ( const QString& area : QStringList { "PlasmaUserFeedback" } ) + { + // TODO: get the configured user name + QString path = QStringLiteral( "/home/%1/.config/%2" ).arg( QString(), area ); + cDebug() << "Configuring KUserFeedback" << path; + + int r = CalamaresUtils::System::instance()->createTargetFile( path, config ); + if ( r > 0 ) + { + return Calamares::JobResult::error( + tr( "Error in KDE user feedback configuration." ), + tr( "Could not configure KDE user feedback correctly, script error %1." ).arg( r ) ); + } + else if ( r < 0 ) + { + return Calamares::JobResult::error( + tr( "Error in KDE user feedback configuration." ), + tr( "Could not configure KDE user feedback correctly, Calamares error %1." ).arg( r ) ); + } + } + + return Calamares::JobResult::ok(); +} diff --git a/src/modules/tracking/TrackingJobs.h b/src/modules/tracking/TrackingJobs.h index c7c2450cb..76e7dbed9 100644 --- a/src/modules/tracking/TrackingJobs.h +++ b/src/modules/tracking/TrackingJobs.h @@ -23,6 +23,7 @@ class InstallTrackingConfig; class MachineTrackingConfig; +class UserTrackingConfig; class QSemaphore; @@ -75,6 +76,12 @@ public: static void addJob( Calamares::JobList& list, MachineTrackingConfig* config ); }; +/** @brief Tracking machines, KDE neon style + * + * The machine has a machine-id, and this is sed(1)'ed into the + * update-manager configuration, to report the machine-id back + * to KDE neon servers. + */ class TrackingMachineNeonJob : public TrackingMachineJob { Q_OBJECT @@ -85,5 +92,32 @@ public: Calamares::JobResult exec() override; }; +/** @brief Base class for user-tracking jobs + * + * User-tracking configuration depends on the distro / style of user + * tracking being implemented, so there are subclasses to switch on the + * relevant kind of tracking. Users are tracked persistently (the user + * can of course configure the tracking again once the system is restarted). + */ +class TrackingUserJob : public Calamares::Job +{ +public: + static void addJob( Calamares::JobList& list, UserTrackingConfig* config ); +}; + +/** @brief Turn on KUserFeedback in target system + * + * This writes suitable files for turning on KUserFeedback for the + * normal user configured in Calamares. The feedback can be reconfigured + * by the user through Plasma's user-feedback dialog. + */ +class TrackingKUserFeedbackJob : public Calamares::Job +{ +public: + QString prettyName() const override; + QString prettyDescription() const override; + QString prettyStatusMessage() const override; + Calamares::JobResult exec() override; +}; #endif From 60e12174fd117e78d6984f28aafe6aa2a7a69fd9 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Mon, 25 May 2020 10:32:56 -0400 Subject: [PATCH 19/37] [tracking] Switch out Radio for CheckBox - The Radio's are replaced by CheckBoxes and some logic, so that different tracking styles can be enabled independently. None of the settings end up in the Config yet, though. --- src/modules/tracking/TrackingPage.cpp | 67 +++++++++++++---------- src/modules/tracking/TrackingPage.h | 17 +++++- src/modules/tracking/page_trackingstep.ui | 8 +-- 3 files changed, 55 insertions(+), 37 deletions(-) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index 02bc94195..e42ae2312 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -40,13 +40,15 @@ TrackingPage::TrackingPage( Config* config, QWidget* parent ) ui->setupUi( this ); CALAMARES_RETRANSLATE_SLOT( &TrackingPage::retranslate ); - QButtonGroup* group = new QButtonGroup( this ); - group->setExclusive( true ); - group->addButton( ui->noneRadio ); - group->addButton( ui->installRadio ); - group->addButton( ui->machineRadio ); - group->addButton( ui->userRadio ); - ui->noneRadio->setChecked( true ); + ui->noneCheckBox->setChecked( true ); + connect( ui->noneCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::noneChecked ); + connect( ui->installCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::otherChecked ); + connect( ui->machineCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::otherChecked ); + connect( ui->userCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::otherChecked ); + + connect( ui->installCheckBox, &QCheckBox::stateChanged, [ this ]( int s ) { cDebug() << "Checkbox install changed" << s; } ); + connect( config->installTracking(), &TrackingStyleConfig::trackingChanged, [ config ]() { cDebug() << + "Install tracking changed" << config->installTracking()->isEnabled(); } ) ; connect( config, &Config::generalPolicyChanged, [ this ]( const QString& url ) { this->ui->generalPolicyLabel->setVisible( !url.isEmpty() ); @@ -85,30 +87,35 @@ TrackingPage::retranslate() .arg( product ) ); } - -void -TrackingPage::setTrackingLevel( TrackingType t ) +void TrackingPage::noneChecked(int state) { - QRadioButton* button = nullptr; - - switch ( t ) + if ( state ) { - case TrackingType::NoTracking: - button = ui->noneRadio; - break; - case TrackingType::InstallTracking: - button = ui->installRadio; - break; - case TrackingType::MachineTracking: - button = ui->machineRadio; - break; - case TrackingType::UserTracking: - button = ui->userRadio; - break; - } - - if ( button != nullptr ) - { - button->setChecked( true ); + cDebug() << "Unchecking all due to none box"; + ui->installCheckBox->setChecked( false ); + ui->machineCheckBox->setChecked( false ); + ui->userCheckBox->setChecked( false ); + } +} + +void TrackingPage::otherChecked(int state) +{ + cDebug() << "Other checked" << state; + if ( state ) + { + // Can't have none checked, if another one is + ui->noneCheckBox->setChecked( false ); + } + else + { + if ( ui->installCheckBox->isChecked() || ui->machineCheckBox->isChecked() || ui->userCheckBox->isChecked() ) + { + // One of them is still checked, leave *none* alone + ; + } + else + { + ui->noneCheckBox->setChecked( true ); + } } } diff --git a/src/modules/tracking/TrackingPage.h b/src/modules/tracking/TrackingPage.h index f63f7375c..e4c465fbc 100644 --- a/src/modules/tracking/TrackingPage.h +++ b/src/modules/tracking/TrackingPage.h @@ -37,12 +37,23 @@ class TrackingPage : public QWidget public: explicit TrackingPage( Config* config, QWidget* parent = nullptr ); - ///@brief Select one of the four levels by name - void setTrackingLevel( TrackingType t ); - public Q_SLOTS: void retranslate(); + /** @brief When the *no tracking* checkbox is changed + * + * @p state will be non-zero when the box is checked; this + * **unchecks** all the other boxes. + */ + void noneChecked( int state ); + + /** @brief Some other checkbox changed + * + * This may check the *none* button if all the others are + * now unchecked. + */ + void otherChecked( int state ); + private: Ui::TrackingPage* ui; }; diff --git a/src/modules/tracking/page_trackingstep.ui b/src/modules/tracking/page_trackingstep.ui index 9612ef2b4..4383d312d 100644 --- a/src/modules/tracking/page_trackingstep.ui +++ b/src/modules/tracking/page_trackingstep.ui @@ -32,7 +32,7 @@ margin-left: 2em; - + @@ -83,7 +83,7 @@ margin-left: 2em; - + @@ -145,7 +145,7 @@ margin-left: 2em; - + @@ -207,7 +207,7 @@ margin-left: 2em; - + From dda4ab0b2e44fc35524e1d49d94cddc178a2dff2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 10:06:33 +0200 Subject: [PATCH 20/37] [tracking] Improve naming - give the on-some-checkbox-state-changed slots better names - while here, refactor is-any-actual-tracking-option-checked - improve other debug messages, to be a whole sentence --- src/modules/tracking/TrackingPage.cpp | 30 +++++++++++++-------------- src/modules/tracking/TrackingPage.h | 11 ++++++++-- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index e42ae2312..fa5cba2bb 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -41,14 +41,14 @@ TrackingPage::TrackingPage( Config* config, QWidget* parent ) CALAMARES_RETRANSLATE_SLOT( &TrackingPage::retranslate ); ui->noneCheckBox->setChecked( true ); - connect( ui->noneCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::noneChecked ); - connect( ui->installCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::otherChecked ); - connect( ui->machineCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::otherChecked ); - connect( ui->userCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::otherChecked ); + connect( ui->noneCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonNoneChecked ); + connect( ui->installCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonChecked ); + connect( ui->machineCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonChecked ); + connect( ui->userCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonChecked ); connect( ui->installCheckBox, &QCheckBox::stateChanged, [ this ]( int s ) { cDebug() << "Checkbox install changed" << s; } ); connect( config->installTracking(), &TrackingStyleConfig::trackingChanged, [ config ]() { cDebug() << - "Install tracking changed" << config->installTracking()->isEnabled(); } ) ; + "Install tracking configuration changed to " << config->installTracking()->isEnabled(); } ) ; connect( config, &Config::generalPolicyChanged, [ this ]( const QString& url ) { this->ui->generalPolicyLabel->setVisible( !url.isEmpty() ); @@ -87,20 +87,25 @@ TrackingPage::retranslate() .arg( product ) ); } -void TrackingPage::noneChecked(int state) +bool TrackingPage::anyOtherChecked() const +{ + return ui->installCheckBox->isChecked() || ui->machineCheckBox->isChecked() || ui->userCheckBox->isChecked(); +} + + +void TrackingPage::buttonNoneChecked(int state) { if ( state ) { - cDebug() << "Unchecking all due to none box"; + cDebug() << "Unchecking all other buttons because 'None' was checked"; ui->installCheckBox->setChecked( false ); ui->machineCheckBox->setChecked( false ); ui->userCheckBox->setChecked( false ); } } -void TrackingPage::otherChecked(int state) +void TrackingPage::buttonChecked(int state) { - cDebug() << "Other checked" << state; if ( state ) { // Can't have none checked, if another one is @@ -108,12 +113,7 @@ void TrackingPage::otherChecked(int state) } else { - if ( ui->installCheckBox->isChecked() || ui->machineCheckBox->isChecked() || ui->userCheckBox->isChecked() ) - { - // One of them is still checked, leave *none* alone - ; - } - else + if ( !anyOtherChecked() ) { ui->noneCheckBox->setChecked( true ); } diff --git a/src/modules/tracking/TrackingPage.h b/src/modules/tracking/TrackingPage.h index e4c465fbc..1a995870d 100644 --- a/src/modules/tracking/TrackingPage.h +++ b/src/modules/tracking/TrackingPage.h @@ -37,6 +37,13 @@ class TrackingPage : public QWidget public: explicit TrackingPage( Config* config, QWidget* parent = nullptr ); + /** @brief is any of the enable-tracking buttons checked? + * + * Returns true if any one or more of install, machine or user + * tracking is enabled. + */ + bool anyOtherChecked() const; + public Q_SLOTS: void retranslate(); @@ -45,14 +52,14 @@ public Q_SLOTS: * @p state will be non-zero when the box is checked; this * **unchecks** all the other boxes. */ - void noneChecked( int state ); + void buttonNoneChecked( int state ); /** @brief Some other checkbox changed * * This may check the *none* button if all the others are * now unchecked. */ - void otherChecked( int state ); + void buttonChecked( int state ); private: Ui::TrackingPage* ui; From c797a30a72050a525785c24917de56a7f5a73ce4 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 10:10:20 +0200 Subject: [PATCH 21/37] [tracking] Bold more relevant parts of level-descriptions --- src/modules/tracking/TrackingPage.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index fa5cba2bb..cb7e5a10a 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -76,14 +76,14 @@ TrackingPage::retranslate() .arg( product ) ); ui->installExplanation->setText( tr( "By selecting this you will send information about your installation and hardware. This information " - "will only be sent once after the installation finishes." ) ); + "will only be sent once after the installation finishes." ) ); ui->machineExplanation->setText( - tr( "By selecting this you will periodically send information about your machine installation, " + tr( "By selecting this you will periodically send information about your machine installation, " "hardware and applications, to %1." ) .arg( product ) ); ui->userExplanation->setText( - tr( "By selecting this you will regularly send information about your " - "user installation, hardware, applications and application usage patterns, to %1." ) + tr( "By selecting this you will regularly send information about your " + "user installation, hardware, applications and application usage patterns, to %1." ) .arg( product ) ); } From 4d6a5d0cb537d9af4968f0b68a2cc274b38fa11f Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 10:36:35 +0200 Subject: [PATCH 22/37] [tracking] Use KMacroExpander instead of homebrew for install-URL --- src/modules/tracking/TrackingJobs.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/modules/tracking/TrackingJobs.cpp b/src/modules/tracking/TrackingJobs.cpp index 18d01c7ca..0b27eab05 100644 --- a/src/modules/tracking/TrackingJobs.cpp +++ b/src/modules/tracking/TrackingJobs.cpp @@ -24,6 +24,8 @@ #include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" +#include + #include #include @@ -79,14 +81,13 @@ TrackingInstallJob::addJob( Calamares::JobList& list, InstallTrackingConfig* con { if ( config->isEnabled() ) { - QString installUrl = config->installTrackingUrl(); const auto* s = CalamaresUtils::System::instance(); - - QString memory, disk; - memory.setNum( s->getTotalMemoryB().first ); - disk.setNum( s->getTotalDiskB() ); - - installUrl.replace( "$CPU", s->getCpuDescription() ).replace( "$MEMORY", memory ).replace( "$DISK", disk ); + QHash map { std::initializer_list< std::pair< QString, QString > > { + { QStringLiteral("CPU"), s->getCpuDescription() }, + { QStringLiteral("MEMORY"), QString::number( s->getTotalMemoryB().first ) }, + { QStringLiteral("DISK"), QString::number( s->getTotalDiskB() ) } + } }; + QString installUrl = KMacroExpander::expandMacros( config->installTrackingUrl(), map ); cDebug() << Logger::SubEntry << "install-tracking URL" << installUrl; From cb2909f6d875fa90f15f50f45f633ff8e8f59b13 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 10:18:08 +0200 Subject: [PATCH 23/37] [tracking] Rename "neon" tracking KDE neon does not do this kind of tracking -- although it was originally requested by KDE neon, no server roll-out was done once the privacy policy was thought out. --- src/modules/tracking/Config.cpp | 2 +- src/modules/tracking/Config.h | 2 +- src/modules/tracking/TrackingJobs.cpp | 12 ++++++------ src/modules/tracking/TrackingJobs.h | 6 +++--- src/modules/tracking/TrackingViewStep.cpp | 8 -------- src/modules/tracking/tracking.conf | 4 ++-- 6 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/modules/tracking/Config.cpp b/src/modules/tracking/Config.cpp index 2dc91c2a9..a75522529 100644 --- a/src/modules/tracking/Config.cpp +++ b/src/modules/tracking/Config.cpp @@ -129,7 +129,7 @@ MachineTrackingConfig::MachineTrackingConfig( QObject* parent ) static bool isValidMachineTrackingStyle( const QString& s ) { - static QStringList knownStyles { "neon" }; + static QStringList knownStyles { "updatemanager" }; return knownStyles.contains( s ); } diff --git a/src/modules/tracking/Config.h b/src/modules/tracking/Config.h index 26dcf2f4f..0bdff260a 100644 --- a/src/modules/tracking/Config.h +++ b/src/modules/tracking/Config.h @@ -118,7 +118,7 @@ private: * * When machine tracking is on, the installed system will report * back ("call home") at some point. This can mean Debian pop-con, - * or KDE neon maching tracking, or something else. The kind + * or updatemanager maching tracking, or something else. The kind * of configuration depends on the style of tracking that is enabled. */ class MachineTrackingConfig : public TrackingStyleConfig diff --git a/src/modules/tracking/TrackingJobs.cpp b/src/modules/tracking/TrackingJobs.cpp index 0b27eab05..70e45e2eb 100644 --- a/src/modules/tracking/TrackingJobs.cpp +++ b/src/modules/tracking/TrackingJobs.cpp @@ -101,9 +101,9 @@ TrackingMachineJob::addJob( Calamares::JobList& list, MachineTrackingConfig* con if ( config->isEnabled() ) { const auto style = config->machineTrackingStyle(); - if ( style == "neon" ) + if ( style == "updatemanager" ) { - list.append( Calamares::job_ptr( new TrackingMachineNeonJob() ) ); + list.append( Calamares::job_ptr( new TrackingMachineUpdateManagerJob() ) ); } else { @@ -114,25 +114,25 @@ TrackingMachineJob::addJob( Calamares::JobList& list, MachineTrackingConfig* con QString -TrackingMachineNeonJob::prettyName() const +TrackingMachineUpdateManagerJob::prettyName() const { return tr( "Machine feedback" ); } QString -TrackingMachineNeonJob::prettyDescription() const +TrackingMachineUpdateManagerJob::prettyDescription() const { return prettyName(); } QString -TrackingMachineNeonJob::prettyStatusMessage() const +TrackingMachineUpdateManagerJob::prettyStatusMessage() const { return tr( "Configuring machine feedback." ); } Calamares::JobResult -TrackingMachineNeonJob::exec() +TrackingMachineUpdateManagerJob::exec() { static const auto script = QStringLiteral( R"x( diff --git a/src/modules/tracking/TrackingJobs.h b/src/modules/tracking/TrackingJobs.h index 76e7dbed9..dd5ca6b92 100644 --- a/src/modules/tracking/TrackingJobs.h +++ b/src/modules/tracking/TrackingJobs.h @@ -76,13 +76,13 @@ public: static void addJob( Calamares::JobList& list, MachineTrackingConfig* config ); }; -/** @brief Tracking machines, KDE neon style +/** @brief Tracking machines, update-manager style * * The machine has a machine-id, and this is sed(1)'ed into the * update-manager configuration, to report the machine-id back - * to KDE neon servers. + * to distro servers. */ -class TrackingMachineNeonJob : public TrackingMachineJob +class TrackingMachineUpdateManagerJob : public TrackingMachineJob { Q_OBJECT public: diff --git a/src/modules/tracking/TrackingViewStep.cpp b/src/modules/tracking/TrackingViewStep.cpp index 491fef12a..2cbfe4ae2 100644 --- a/src/modules/tracking/TrackingViewStep.cpp +++ b/src/modules/tracking/TrackingViewStep.cpp @@ -34,14 +34,6 @@ CALAMARES_PLUGIN_FACTORY_DEFINITION( TrackingViewStepFactory, registerPlugin< TrackingViewStep >(); ) -/** @brief Is @p s a valid machine-tracking style. */ -static bool -isValidStyle( const QString& s ) -{ - static QStringList knownStyles { "neon" }; - return knownStyles.contains( s ); -} - TrackingViewStep::TrackingViewStep( QObject* parent ) : Calamares::ViewStep( parent ) , m_config( new Config( this ) ) diff --git a/src/modules/tracking/tracking.conf b/src/modules/tracking/tracking.conf index 46ba7fed6..8569f0935 100644 --- a/src/modules/tracking/tracking.conf +++ b/src/modules/tracking/tracking.conf @@ -77,11 +77,11 @@ install: # The machine area has one specific configuration key: # style: This string specifies what kind of tracking configuration # needs to be done. There is currently only one valid -# style, "neon", which edits two files in the installed +# style, "updatemanager", which edits two files in the installed # system to enable system-tracking. machine: enabled: false - style: neon + style: updatemanager # The user area is not yet implemented, and has no specific configuration. user: From 48d0c5beeb3587a815d990b8e95f5003eb6f99a2 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 11:02:59 +0200 Subject: [PATCH 24/37] [tracking] Do user tracking in the job queue --- src/modules/tracking/TrackingViewStep.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/tracking/TrackingViewStep.cpp b/src/modules/tracking/TrackingViewStep.cpp index 2cbfe4ae2..125d17974 100644 --- a/src/modules/tracking/TrackingViewStep.cpp +++ b/src/modules/tracking/TrackingViewStep.cpp @@ -111,6 +111,8 @@ TrackingViewStep::jobs() const Calamares::JobList l; TrackingInstallJob::addJob( l, m_config->installTracking() ); TrackingMachineJob::addJob( l, m_config->machineTracking() ); + TrackingUserJob::addJob( l, m_config->userTracking() ); + cDebug() << Logger::SubEntry << l.count() << "jobs queued."; return l; } From 9433311f2404066b94eafdf56dd041c8e370f1f8 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 11:17:48 +0200 Subject: [PATCH 25/37] [tracking] Explain which tracking style is disabled by URL-validation --- src/modules/tracking/Config.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/modules/tracking/Config.cpp b/src/modules/tracking/Config.cpp index a75522529..30c6c30d1 100644 --- a/src/modules/tracking/Config.cpp +++ b/src/modules/tracking/Config.cpp @@ -87,7 +87,7 @@ TrackingStyleConfig::validateUrl( QString& urlString ) { if ( m_state != DisabledByConfig ) { - cError() << "URL" << urlString << "is not valid; disabling this tracking type."; + cError() << "URL" << urlString << "is not valid; disabling tracking type" << objectName(); m_state = DisabledByConfig; emit trackingChanged(); } @@ -109,6 +109,7 @@ TrackingStyleConfig::setConfigurationMap( const QVariantMap& config ) InstallTrackingConfig::InstallTrackingConfig( QObject* parent ) : TrackingStyleConfig( parent ) { + setObjectName( "InstallTrackingConfig" ); } void @@ -123,6 +124,7 @@ InstallTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap MachineTrackingConfig::MachineTrackingConfig( QObject* parent ) : TrackingStyleConfig( parent ) { + setObjectName( "MachineTrackingConfig" ); } /** @brief Is @p s a valid machine-tracking style. */ @@ -146,6 +148,7 @@ MachineTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap UserTrackingConfig::UserTrackingConfig( QObject* parent ) : TrackingStyleConfig( parent ) { + setObjectName( "UserTrackingConfig" ); } static bool From 756e3084dc421a2db0cc3e0bb1110b3d3751df8d Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 11:30:12 +0200 Subject: [PATCH 26/37] [tracking] Simplify updatemanager job - sed all the URI lines with a simple replacement - document policy requirements --- src/modules/tracking/TrackingJobs.cpp | 20 +++++++++----------- src/modules/tracking/tracking.conf | 14 ++++++++++---- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/modules/tracking/TrackingJobs.cpp b/src/modules/tracking/TrackingJobs.cpp index 70e45e2eb..3d8ea27f1 100644 --- a/src/modules/tracking/TrackingJobs.cpp +++ b/src/modules/tracking/TrackingJobs.cpp @@ -134,17 +134,15 @@ TrackingMachineUpdateManagerJob::prettyStatusMessage() const Calamares::JobResult TrackingMachineUpdateManagerJob::exec() { - static const auto script = QStringLiteral( - R"x( -MACHINE_ID=`cat /etc/machine-id` -sed -i "s,URI =.*,URI = http://releases.neon.kde.org/meta-release/${MACHINE_ID}," /etc/update-manager/meta-release -sed -i "s,URI_LTS =.*,URI_LTS = http://releases.neon.kde.org/meta-release-lts/${MACHINE_ID}," /etc/update-manager/meta-release -true -)x" ); - int r = CalamaresUtils::System::instance()->targetEnvCall( "/bin/sh", - QString(), // Working dir - script, - std::chrono::seconds( 1 ) ); + static const auto script = QStringLiteral( "sed -i '/^URI/s,${MACHINE_ID},'`cat /etc/machine-id`',' /etc/update-manager/meta-release || true" ); + + auto res = CalamaresUtils::System::instance()->runCommand( + CalamaresUtils::System::RunLocation::RunInTarget, + QStringList { QStringLiteral( "/bin/sh" ) }, + QString(), // Working dir + script, // standard input + std::chrono::seconds( 1 ) ); + int r = res.first; if ( r == 0 ) { diff --git a/src/modules/tracking/tracking.conf b/src/modules/tracking/tracking.conf index 8569f0935..88d1e7b59 100644 --- a/src/modules/tracking/tracking.conf +++ b/src/modules/tracking/tracking.conf @@ -34,8 +34,10 @@ # Each area has a key *policy*, which is a Url to be opened when # the user clicks on the corresponding Help button for an explanation # of the details of that particular kind of tracking. If no policy -# is set, the help button is hidden. The example policy links -# go to Calamares' generic user manual. +# is set, that tracking style is disabled. The example policy links +# go to Calamares' generic user manual (which is a terrible idea +# for distro's: you have GDPR obligations under most of these tracking +# styles, so do your homework). # # Each area may have other configuration keys, depending on the # area and how it needs to be configured. @@ -48,8 +50,7 @@ --- # This is the global policy; it is displayed as a link on the page. # If blank or commented out, no link is displayed on the tracking -# page. It is recommended to either provide policy URLs for each -# area, *or* one general link, and not to mix them. +# page. You **must** provide policy links per-area as well. policy: "https://github.com/calamares/calamares/wiki/Use-Guide#installation-tracking" # This is the default level to enable for tracking. If commented out, @@ -79,9 +80,14 @@ install: # needs to be done. There is currently only one valid # style, "updatemanager", which edits two files in the installed # system to enable system-tracking. +# +# Per-style documentation: +# - updatemanager replaces the literal string "${MACHINE_ID}" with the contents of +# /etc/machine-id, in lines starting with "URI" in the file /etc/update-manager/meta-release machine: enabled: false style: updatemanager + policy: "https://github.com/calamares/calamares/wiki/Use-Guide#machine-tracking" # The user area is not yet implemented, and has no specific configuration. user: From 8c1685d2cf327fc97f71a37a728c21b43ac07697 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 12:20:35 +0200 Subject: [PATCH 27/37] [tracking] Connect UI to configuration - policy buttons open the policy URL - hide tracking levels that are not configurable --- src/modules/tracking/TrackingPage.cpp | 33 +++++++++++++++++++++------ src/modules/tracking/TrackingPage.h | 10 ++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index cb7e5a10a..d206a20a3 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -29,7 +29,6 @@ #include "utils/Logger.h" #include "utils/Retranslator.h" -#include #include #include @@ -42,13 +41,26 @@ TrackingPage::TrackingPage( Config* config, QWidget* parent ) ui->noneCheckBox->setChecked( true ); connect( ui->noneCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonNoneChecked ); - connect( ui->installCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonChecked ); - connect( ui->machineCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonChecked ); - connect( ui->userCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonChecked ); - connect( ui->installCheckBox, &QCheckBox::stateChanged, [ this ]( int s ) { cDebug() << "Checkbox install changed" << s; } ); - connect( config->installTracking(), &TrackingStyleConfig::trackingChanged, [ config ]() { cDebug() << - "Install tracking configuration changed to " << config->installTracking()->isEnabled(); } ) ; + // Each "panel" of configuration has the same kind of setup, + // where the xButton and xCheckBox is connected to the xTracking + // configuration object; that takes macro-trickery, unfortunately. +#define trackingSetup(x) { \ + connect( ui->x ## CheckBox, &QCheckBox::stateChanged, \ + this, &TrackingPage::buttonChecked ); \ + connect( ui->x ## CheckBox, &QCheckBox::stateChanged, \ + config->x ## Tracking(), QOverload::of( &TrackingStyleConfig::setTracking ) ); \ + connect( config->x ## Tracking(), &TrackingStyleConfig::trackingChanged, \ + this, [ this, config ]() { this->trackerChanged( config->x ## Tracking(), this->ui->x ## Group, this->ui->x ## CheckBox);} ); \ + connect( ui->x ## PolicyButton, &QAbstractButton::clicked, \ + config, [ config ] { QString url( config->x ## Tracking()->policy() ); if ( !url.isEmpty() ) { QDesktopServices::openUrl( url ); } } ); \ +} + + trackingSetup( install ) + trackingSetup( machine ) + trackingSetup( user ) + +#undef trackingSetup connect( config, &Config::generalPolicyChanged, [ this ]( const QString& url ) { this->ui->generalPolicyLabel->setVisible( !url.isEmpty() ); @@ -119,3 +131,10 @@ void TrackingPage::buttonChecked(int state) } } } + +void +TrackingPage::trackerChanged(TrackingStyleConfig* config, QWidget* panel, QCheckBox* check) +{ + panel->setVisible( config->isConfigurable() ); + check->setChecked( config->isEnabled() ); +} diff --git a/src/modules/tracking/TrackingPage.h b/src/modules/tracking/TrackingPage.h index 1a995870d..48599ead4 100644 --- a/src/modules/tracking/TrackingPage.h +++ b/src/modules/tracking/TrackingPage.h @@ -21,6 +21,7 @@ #include "TrackingType.h" +#include #include #include @@ -30,6 +31,7 @@ class TrackingPage; } class Config; +class TrackingStyleConfig; class TrackingPage : public QWidget { @@ -62,6 +64,14 @@ public Q_SLOTS: void buttonChecked( int state ); private: + /** @brief Apply the tracking configuration to the UI + * + * If the config cannot be changed (disabled in config) then + * hide the UI parts on the @p panel; otherwise show it + * and set @p check state to whether the user has enabled it. + */ + void trackerChanged( TrackingStyleConfig* subconfig, QWidget* panel, QCheckBox* check); + Ui::TrackingPage* ui; }; From 45aac7db6658eacbb8095cf712fc87e24fdb96d0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 07:53:40 -0400 Subject: [PATCH 28/37] CI: update clang-format In clang-format 10, SpaceInEmptyBlock is introduced, and defaults to true .. which is different from the earlier formatting versions did. For now, refuse clang-format 10, and search specifically also for clang-format-9.0.1 because that's what I have on my laptop. At some point, switch in the config option and then require clang-format 10 or later (because earlier versions refuse to run with an unknown config option) --- .clang-format | 1 + ci/calamaresstyle | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.clang-format b/.clang-format index cc430e627..187c3638f 100644 --- a/.clang-format +++ b/.clang-format @@ -26,6 +26,7 @@ ReflowComments: "false" SortIncludes: "true" SpaceAfterCStyleCast: "false" SpacesBeforeTrailingComments: "2" +# SpaceInEmptyBlock: "true" SpacesInAngles: "true" SpacesInParentheses: "true" SpacesInSquareBrackets: "true" diff --git a/ci/calamaresstyle b/ci/calamaresstyle index 6a8285124..44f9fe91f 100755 --- a/ci/calamaresstyle +++ b/ci/calamaresstyle @@ -13,7 +13,7 @@ export LANG LC_ALL LC_NUMERIC AS=$( which astyle ) -CF_VERSIONS="clang-format-7 clang-format-8 clang-format70 clang-format80 clang-format" +CF_VERSIONS="clang-format-7 clang-format-8 clang-format70 clang-format80 clang-format-9.0.1 clang-format" for _cf in $CF_VERSIONS do # Not an error if this particular clang-format isn't found @@ -26,6 +26,8 @@ test -n "$CF" || { echo "! No clang-format ($CF_VERSIONS) found in PATH"; exit 1 test -x "$AS" || { echo "! $AS is not executable."; exit 1 ; } test -x "$CF" || { echo "! $CF is not executable."; exit 1 ; } +expr `"$CF" --version | tr -dc '[^.0-9]' | cut -d . -f 1` '<' 10 > /dev/null || { echo "! $CF is version 10 or later, needs different .clang-format" ; exit 1 ; } + set -e any_dirs=no From 789561be6a6c4f1ff280c6c01bb4688ca3b97bfb Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 14:14:06 +0200 Subject: [PATCH 29/37] [tracking] Apply coding style --- src/modules/tracking/Config.cpp | 28 ++++++------ src/modules/tracking/TrackingJobs.cpp | 25 +++++------ src/modules/tracking/TrackingPage.cpp | 53 +++++++++++++---------- src/modules/tracking/TrackingPage.h | 2 +- src/modules/tracking/TrackingViewStep.cpp | 1 - 5 files changed, 58 insertions(+), 51 deletions(-) diff --git a/src/modules/tracking/Config.cpp b/src/modules/tracking/Config.cpp index 30c6c30d1..723465862 100644 --- a/src/modules/tracking/Config.cpp +++ b/src/modules/tracking/Config.cpp @@ -47,7 +47,7 @@ TrackingStyleConfig::TrackingStyleConfig( QObject* parent ) { } -TrackingStyleConfig::~TrackingStyleConfig() { } +TrackingStyleConfig::~TrackingStyleConfig() {} void TrackingStyleConfig::setTracking( bool enabled ) @@ -179,20 +179,20 @@ Config::Config( QObject* parent ) static void enableLevelsBelow( Config* config, TrackingType level ) { - switch( level ) + switch ( level ) { - case TrackingType::UserTracking: - config->userTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser ); - FALLTHRU; - case TrackingType::MachineTracking: - config->machineTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser ); - FALLTHRU; - case TrackingType::InstallTracking: - config->installTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser ); - break; - case TrackingType::NoTracking: - config->noTracking( true ); - break; + case TrackingType::UserTracking: + config->userTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser ); + FALLTHRU; + case TrackingType::MachineTracking: + config->machineTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser ); + FALLTHRU; + case TrackingType::InstallTracking: + config->installTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser ); + break; + case TrackingType::NoTracking: + config->noTracking( true ); + break; } } diff --git a/src/modules/tracking/TrackingJobs.cpp b/src/modules/tracking/TrackingJobs.cpp index 3d8ea27f1..cd885194c 100644 --- a/src/modules/tracking/TrackingJobs.cpp +++ b/src/modules/tracking/TrackingJobs.cpp @@ -36,7 +36,7 @@ TrackingInstallJob::TrackingInstallJob( const QString& url ) { } -TrackingInstallJob::~TrackingInstallJob() { } +TrackingInstallJob::~TrackingInstallJob() {} QString TrackingInstallJob::prettyName() const @@ -82,11 +82,10 @@ TrackingInstallJob::addJob( Calamares::JobList& list, InstallTrackingConfig* con if ( config->isEnabled() ) { const auto* s = CalamaresUtils::System::instance(); - QHash map { std::initializer_list< std::pair< QString, QString > > { - { QStringLiteral("CPU"), s->getCpuDescription() }, - { QStringLiteral("MEMORY"), QString::number( s->getTotalMemoryB().first ) }, - { QStringLiteral("DISK"), QString::number( s->getTotalDiskB() ) } - } }; + QHash< QString, QString > map { std::initializer_list< std::pair< QString, QString > > { + { QStringLiteral( "CPU" ), s->getCpuDescription() }, + { QStringLiteral( "MEMORY" ), QString::number( s->getTotalMemoryB().first ) }, + { QStringLiteral( "DISK" ), QString::number( s->getTotalDiskB() ) } } }; QString installUrl = KMacroExpander::expandMacros( config->installTrackingUrl(), map ); cDebug() << Logger::SubEntry << "install-tracking URL" << installUrl; @@ -134,14 +133,14 @@ TrackingMachineUpdateManagerJob::prettyStatusMessage() const Calamares::JobResult TrackingMachineUpdateManagerJob::exec() { - static const auto script = QStringLiteral( "sed -i '/^URI/s,${MACHINE_ID},'`cat /etc/machine-id`',' /etc/update-manager/meta-release || true" ); + static const auto script = QStringLiteral( + "sed -i '/^URI/s,${MACHINE_ID},'`cat /etc/machine-id`',' /etc/update-manager/meta-release || true" ); - auto res = CalamaresUtils::System::instance()->runCommand( - CalamaresUtils::System::RunLocation::RunInTarget, - QStringList { QStringLiteral( "/bin/sh" ) }, - QString(), // Working dir - script, // standard input - std::chrono::seconds( 1 ) ); + auto res = CalamaresUtils::System::instance()->runCommand( CalamaresUtils::System::RunLocation::RunInTarget, + QStringList { QStringLiteral( "/bin/sh" ) }, + QString(), // Working dir + script, // standard input + std::chrono::seconds( 1 ) ); int r = res.first; if ( r == 0 ) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index d206a20a3..c9234d01c 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -45,27 +45,33 @@ TrackingPage::TrackingPage( Config* config, QWidget* parent ) // Each "panel" of configuration has the same kind of setup, // where the xButton and xCheckBox is connected to the xTracking // configuration object; that takes macro-trickery, unfortunately. -#define trackingSetup(x) { \ - connect( ui->x ## CheckBox, &QCheckBox::stateChanged, \ - this, &TrackingPage::buttonChecked ); \ - connect( ui->x ## CheckBox, &QCheckBox::stateChanged, \ - config->x ## Tracking(), QOverload::of( &TrackingStyleConfig::setTracking ) ); \ - connect( config->x ## Tracking(), &TrackingStyleConfig::trackingChanged, \ - this, [ this, config ]() { this->trackerChanged( config->x ## Tracking(), this->ui->x ## Group, this->ui->x ## CheckBox);} ); \ - connect( ui->x ## PolicyButton, &QAbstractButton::clicked, \ - config, [ config ] { QString url( config->x ## Tracking()->policy() ); if ( !url.isEmpty() ) { QDesktopServices::openUrl( url ); } } ); \ -} +#define trackingSetup( x ) \ + { \ + connect( ui->x##CheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonChecked ); \ + connect( ui->x##CheckBox, \ + &QCheckBox::stateChanged, \ + config->x##Tracking(), \ + QOverload< bool >::of( &TrackingStyleConfig::setTracking ) ); \ + connect( config->x##Tracking(), &TrackingStyleConfig::trackingChanged, this, [this, config]() { \ + this->trackerChanged( config->x##Tracking(), this->ui->x##Group, this->ui->x##CheckBox ); \ + } ); \ + connect( ui->x##PolicyButton, &QAbstractButton::clicked, config, [config] { \ + QString url( config->x##Tracking()->policy() ); \ + if ( !url.isEmpty() ) \ + { \ + QDesktopServices::openUrl( url ); \ + } \ + } ); \ + } - trackingSetup( install ) - trackingSetup( machine ) - trackingSetup( user ) + trackingSetup( install ) trackingSetup( machine ) trackingSetup( user ) #undef trackingSetup - connect( config, &Config::generalPolicyChanged, [ this ]( const QString& url ) { - this->ui->generalPolicyLabel->setVisible( !url.isEmpty() ); - } ); - connect( ui->generalPolicyLabel, &QLabel::linkActivated, [ config ] { + connect( config, &Config::generalPolicyChanged, [this]( const QString& url ) { + this->ui->generalPolicyLabel->setVisible( !url.isEmpty() ); + } ); + connect( ui->generalPolicyLabel, &QLabel::linkActivated, [config] { QString url( config->generalPolicy() ); if ( !url.isEmpty() ) { @@ -99,13 +105,15 @@ TrackingPage::retranslate() .arg( product ) ); } -bool TrackingPage::anyOtherChecked() const +bool +TrackingPage::anyOtherChecked() const { - return ui->installCheckBox->isChecked() || ui->machineCheckBox->isChecked() || ui->userCheckBox->isChecked(); + return ui->installCheckBox->isChecked() || ui->machineCheckBox->isChecked() || ui->userCheckBox->isChecked(); } -void TrackingPage::buttonNoneChecked(int state) +void +TrackingPage::buttonNoneChecked( int state ) { if ( state ) { @@ -116,7 +124,8 @@ void TrackingPage::buttonNoneChecked(int state) } } -void TrackingPage::buttonChecked(int state) +void +TrackingPage::buttonChecked( int state ) { if ( state ) { @@ -133,7 +142,7 @@ void TrackingPage::buttonChecked(int state) } void -TrackingPage::trackerChanged(TrackingStyleConfig* config, QWidget* panel, QCheckBox* check) +TrackingPage::trackerChanged( TrackingStyleConfig* config, QWidget* panel, QCheckBox* check ) { panel->setVisible( config->isConfigurable() ); check->setChecked( config->isEnabled() ); diff --git a/src/modules/tracking/TrackingPage.h b/src/modules/tracking/TrackingPage.h index 48599ead4..7df43b846 100644 --- a/src/modules/tracking/TrackingPage.h +++ b/src/modules/tracking/TrackingPage.h @@ -70,7 +70,7 @@ private: * hide the UI parts on the @p panel; otherwise show it * and set @p check state to whether the user has enabled it. */ - void trackerChanged( TrackingStyleConfig* subconfig, QWidget* panel, QCheckBox* check); + void trackerChanged( TrackingStyleConfig* subconfig, QWidget* panel, QCheckBox* check ); Ui::TrackingPage* ui; }; diff --git a/src/modules/tracking/TrackingViewStep.cpp b/src/modules/tracking/TrackingViewStep.cpp index 125d17974..8a80b2b57 100644 --- a/src/modules/tracking/TrackingViewStep.cpp +++ b/src/modules/tracking/TrackingViewStep.cpp @@ -122,4 +122,3 @@ TrackingViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { m_config->setConfigurationMap( configurationMap ); } - From 5623d8086bce1785bb26d505d12c5d5595aeaa28 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 14:27:23 +0200 Subject: [PATCH 30/37] [tracking] Apply coding style - massage trackingSetup macro to look like a function call --- src/modules/tracking/TrackingPage.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index c9234d01c..2dfc6050a 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -46,6 +46,7 @@ TrackingPage::TrackingPage( Config* config, QWidget* parent ) // where the xButton and xCheckBox is connected to the xTracking // configuration object; that takes macro-trickery, unfortunately. #define trackingSetup( x ) \ + do \ { \ connect( ui->x##CheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonChecked ); \ connect( ui->x##CheckBox, \ @@ -62,15 +63,17 @@ TrackingPage::TrackingPage( Config* config, QWidget* parent ) QDesktopServices::openUrl( url ); \ } \ } ); \ - } + } while ( false ) - trackingSetup( install ) trackingSetup( machine ) trackingSetup( user ) + trackingSetup( install ); + trackingSetup( machine ); + trackingSetup( user ); #undef trackingSetup - connect( config, &Config::generalPolicyChanged, [this]( const QString& url ) { - this->ui->generalPolicyLabel->setVisible( !url.isEmpty() ); - } ); + connect( config, &Config::generalPolicyChanged, [this]( const QString& url ) { + this->ui->generalPolicyLabel->setVisible( !url.isEmpty() ); + } ); connect( ui->generalPolicyLabel, &QLabel::linkActivated, [config] { QString url( config->generalPolicy() ); if ( !url.isEmpty() ) From 3f55d415e980ef521fd538f5ee9526f53bd91f0c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 14:26:14 +0200 Subject: [PATCH 31/37] [tracking] Make names of user-tracking styles consistent - use kuserfeedback instead of "kde", to name the technology, not the community --- src/modules/tracking/Config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/tracking/Config.cpp b/src/modules/tracking/Config.cpp index 723465862..51e51e7c8 100644 --- a/src/modules/tracking/Config.cpp +++ b/src/modules/tracking/Config.cpp @@ -154,7 +154,7 @@ UserTrackingConfig::UserTrackingConfig( QObject* parent ) static bool isValidUserTrackingStyle( const QString& s ) { - static QStringList knownStyles { "kde" }; + static QStringList knownStyles { "kuserfeedback" }; return knownStyles.contains( s ); } From 98ab4330c45143201f4f5ce9202c9e95939383a0 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 14:52:48 +0200 Subject: [PATCH 32/37] [tracking] expand documentation of configuration --- src/modules/tracking/tracking.conf | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/modules/tracking/tracking.conf b/src/modules/tracking/tracking.conf index 88d1e7b59..533d0e0dd 100644 --- a/src/modules/tracking/tracking.conf +++ b/src/modules/tracking/tracking.conf @@ -28,7 +28,7 @@ # policy applies. # # Each area has a key *enabled*. If the area is enabled, it is shown to -# the user. This defaults to off, which means no tracking would be +# the user. This defaults to false, which means no tracking would be # configured or enabled by Calamares. # # Each area has a key *policy*, which is a Url to be opened when @@ -53,9 +53,11 @@ # page. You **must** provide policy links per-area as well. policy: "https://github.com/calamares/calamares/wiki/Use-Guide#installation-tracking" -# This is the default level to enable for tracking. If commented out, +# This is the default area to enable for tracking. If commented out, # empty, or otherwise invalid, "none" is used, so no tracking by default. -default: user +# Setting an area here also checks the areas before it (install, machine, +# then user) by default -- subject to those areas being enabled at all. +# default: user # The install area has one specific configuration key: # url: this URL (remember to include the protocol, and prefer https) @@ -73,22 +75,28 @@ default: user install: enabled: false policy: "https://github.com/calamares/calamares/wiki/Use-Guide#installation-tracking" - # url: "https://example.com/install.php?c=$CPU&m=$MEMORY" + url: "https://example.com/install.php?c=$CPU&m=$MEMORY" # The machine area has one specific configuration key: # style: This string specifies what kind of tracking configuration -# needs to be done. There is currently only one valid -# style, "updatemanager", which edits two files in the installed -# system to enable system-tracking. +# needs to be done. See below for valid styles. # -# Per-style documentation: -# - updatemanager replaces the literal string "${MACHINE_ID}" with the contents of +# Available styles: +# - *updatemanager* replaces the literal string "${MACHINE_ID}" with the contents of # /etc/machine-id, in lines starting with "URI" in the file /etc/update-manager/meta-release machine: enabled: false style: updatemanager policy: "https://github.com/calamares/calamares/wiki/Use-Guide#machine-tracking" -# The user area is not yet implemented, and has no specific configuration. +# The user area has one specific configuration key: +# style: This string specifies what kind of tracking configuration +# needs to be done. See below for valid styles. +# +# Available styles: +# - *kuserfeedback* sets up KUserFeedback tracking (applicable to the KDE +# Plasma Desktop) for each KUserFeedback area listed in *areas*. user: enabled: false + style: kuserfeedback + areas: [ PlasmaUserFeedback ] From e834ce532c35931386eb3e50bf3ff9cce2e84d81 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 15:02:01 +0200 Subject: [PATCH 33/37] [libcalamares] Add variant-map getStringList() convenience --- src/libcalamares/utils/Variant.cpp | 16 +++++++++++++++- src/libcalamares/utils/Variant.h | 7 ++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/libcalamares/utils/Variant.cpp b/src/libcalamares/utils/Variant.cpp index cf6ff91fe..dc20e73b2 100644 --- a/src/libcalamares/utils/Variant.cpp +++ b/src/libcalamares/utils/Variant.cpp @@ -1,5 +1,5 @@ /* === This file is part of Calamares - === - * + * * SPDX-FileCopyrightText: 2013-2016 Teo Mrnjavac * SPDX-FileCopyrightText: 2018 Adriaan de Groot * @@ -65,6 +65,20 @@ getString( const QVariantMap& map, const QString& key ) return QString(); } +QStringList +getStringList( const QVariantMap& map, const QString& key ) +{ + if ( map.contains( key ) ) + { + auto v = map.value( key ); + if ( v.type() == QVariant::StringList ) + { + return v.toStringList(); + } + } + return QStringList(); +} + qint64 getInteger( const QVariantMap& map, const QString& key, qint64 d ) { diff --git a/src/libcalamares/utils/Variant.h b/src/libcalamares/utils/Variant.h index a05d281c3..643d8ae98 100644 --- a/src/libcalamares/utils/Variant.h +++ b/src/libcalamares/utils/Variant.h @@ -1,5 +1,5 @@ /* === This file is part of Calamares - === - * + * * SPDX-FileCopyrightText: 2013-2016 Teo Mrnjavac * SPDX-FileCopyrightText: 2018 Adriaan de Groot * @@ -43,6 +43,11 @@ DLLEXPORT bool getBool( const QVariantMap& map, const QString& key, bool d ); */ DLLEXPORT QString getString( const QVariantMap& map, const QString& key ); +/** + * Get a string list from a mapping; returns empty list if no value. + */ +DLLEXPORT QStringList getStringList( const QVariantMap& map, const QString& key ); + /** * Get an integer value from a mapping; returns @p d if no value. */ From 9b8d591b5dc63279d6bcbd9b6ddb3a78cd59d9d6 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 15:11:11 +0200 Subject: [PATCH 34/37] [tracking] Configure user-tracking areas --- src/modules/tracking/Config.cpp | 2 ++ src/modules/tracking/Config.h | 2 ++ src/modules/tracking/TrackingJobs.cpp | 14 ++++++++++---- src/modules/tracking/TrackingJobs.h | 6 ++++++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/modules/tracking/Config.cpp b/src/modules/tracking/Config.cpp index 51e51e7c8..6d9dbb10b 100644 --- a/src/modules/tracking/Config.cpp +++ b/src/modules/tracking/Config.cpp @@ -165,6 +165,8 @@ UserTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap ) m_userTrackingStyle = CalamaresUtils::getString( configurationMap, "style" ); validate( m_userTrackingStyle, isValidUserTrackingStyle ); + + m_userTrackingAreas = CalamaresUtils::getStringList( configurationMap, "areas" ); } diff --git a/src/modules/tracking/Config.h b/src/modules/tracking/Config.h index 0bdff260a..fb279ea93 100644 --- a/src/modules/tracking/Config.h +++ b/src/modules/tracking/Config.h @@ -149,9 +149,11 @@ public: void setConfigurationMap( const QVariantMap& configurationMap ); QString userTrackingStyle() { return m_userTrackingStyle; } + QStringList userTrackingAreas() const { return m_userTrackingAreas; } private: QString m_userTrackingStyle; + QStringList m_userTrackingAreas; // fine-grained areas }; class Config : public QObject diff --git a/src/modules/tracking/TrackingJobs.cpp b/src/modules/tracking/TrackingJobs.cpp index cd885194c..35d51ce64 100644 --- a/src/modules/tracking/TrackingJobs.cpp +++ b/src/modules/tracking/TrackingJobs.cpp @@ -169,7 +169,8 @@ TrackingUserJob::addJob( Calamares::JobList& list, UserTrackingConfig* config ) const auto style = config->userTrackingStyle(); if ( style == "kuserfeedback" ) { - list.append( Calamares::job_ptr( new TrackingKUserFeedbackJob() ) ); + list.append( + Calamares::job_ptr( new TrackingKUserFeedbackJob( QString( "root" ), config->userTrackingAreas() ) ) ); } else { @@ -178,6 +179,12 @@ TrackingUserJob::addJob( Calamares::JobList& list, UserTrackingConfig* config ) } } +TrackingKUserFeedbackJob::TrackingKUserFeedbackJob( const QString& username, const QStringList& areas ) + : m_username( username ) + , m_areas( areas ) +{ +} + QString TrackingKUserFeedbackJob::prettyName() const { @@ -206,10 +213,9 @@ TrackingKUserFeedbackJob::exec() FeedbackLevel=16 )x"; - for ( const QString& area : QStringList { "PlasmaUserFeedback" } ) + for ( const QString& area : m_areas ) { - // TODO: get the configured user name - QString path = QStringLiteral( "/home/%1/.config/%2" ).arg( QString(), area ); + QString path = QStringLiteral( "/home/%1/.config/%2" ).arg( m_username, area ); cDebug() << "Configuring KUserFeedback" << path; int r = CalamaresUtils::System::instance()->createTargetFile( path, config ); diff --git a/src/modules/tracking/TrackingJobs.h b/src/modules/tracking/TrackingJobs.h index dd5ca6b92..c65c8f621 100644 --- a/src/modules/tracking/TrackingJobs.h +++ b/src/modules/tracking/TrackingJobs.h @@ -114,10 +114,16 @@ public: class TrackingKUserFeedbackJob : public Calamares::Job { public: + TrackingKUserFeedbackJob( const QString& username, const QStringList& areas ); + QString prettyName() const override; QString prettyDescription() const override; QString prettyStatusMessage() const override; Calamares::JobResult exec() override; + +private: + QString m_username; + QStringList m_areas; }; #endif From 47b0fa5d55f4a9f44089c3c4dba3c06fbbe2d317 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 15:24:21 +0200 Subject: [PATCH 35/37] [tracking] Get username from gs --- src/modules/tracking/TrackingJobs.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/modules/tracking/TrackingJobs.cpp b/src/modules/tracking/TrackingJobs.cpp index 35d51ce64..2087804ec 100644 --- a/src/modules/tracking/TrackingJobs.cpp +++ b/src/modules/tracking/TrackingJobs.cpp @@ -20,6 +20,8 @@ #include "Config.h" +#include "GlobalStorage.h" +#include "JobQueue.h" #include "network/Manager.h" #include "utils/CalamaresUtilsSystem.h" #include "utils/Logger.h" @@ -166,11 +168,20 @@ TrackingUserJob::addJob( Calamares::JobList& list, UserTrackingConfig* config ) { if ( config->isEnabled() ) { + const auto* gs = Calamares::JobQueue::instance()->globalStorage(); + static const auto key = QStringLiteral( "username" ); + QString username = ( gs && gs->contains( key ) ) ? gs->value( key ).toString() : QString(); + + if ( username.isEmpty() ) + { + cWarning() << "No username is set in GlobalStorage, skipping user-tracking."; + return; + } + const auto style = config->userTrackingStyle(); if ( style == "kuserfeedback" ) { - list.append( - Calamares::job_ptr( new TrackingKUserFeedbackJob( QString( "root" ), config->userTrackingAreas() ) ) ); + list.append( Calamares::job_ptr( new TrackingKUserFeedbackJob( username, config->userTrackingAreas() ) ) ); } else { From 8ad221311d64d2469bf22fa03c73961f9c3be995 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Wed, 17 Jun 2020 15:31:53 +0200 Subject: [PATCH 36/37] [tracking] Can't uncheck 'none' box by itself - If the 'no tracking' box is checked, then the way to uncheck it is to tick some **other** box. - It doesn't make sense to unselect 'none' and then have .. none selected. --- src/modules/tracking/TrackingPage.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/tracking/TrackingPage.cpp b/src/modules/tracking/TrackingPage.cpp index 2dfc6050a..618e1bc8f 100644 --- a/src/modules/tracking/TrackingPage.cpp +++ b/src/modules/tracking/TrackingPage.cpp @@ -40,6 +40,7 @@ TrackingPage::TrackingPage( Config* config, QWidget* parent ) CALAMARES_RETRANSLATE_SLOT( &TrackingPage::retranslate ); ui->noneCheckBox->setChecked( true ); + ui->noneCheckBox->setEnabled( false ); connect( ui->noneCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonNoneChecked ); // Each "panel" of configuration has the same kind of setup, @@ -124,6 +125,7 @@ TrackingPage::buttonNoneChecked( int state ) ui->installCheckBox->setChecked( false ); ui->machineCheckBox->setChecked( false ); ui->userCheckBox->setChecked( false ); + ui->noneCheckBox->setEnabled( false ); } } @@ -133,6 +135,7 @@ TrackingPage::buttonChecked( int state ) if ( state ) { // Can't have none checked, if another one is + ui->noneCheckBox->setEnabled( true ); ui->noneCheckBox->setChecked( false ); } else @@ -140,6 +143,7 @@ TrackingPage::buttonChecked( int state ) if ( !anyOtherChecked() ) { ui->noneCheckBox->setChecked( true ); + ui->noneCheckBox->setEnabled( false ); } } } From 1b11cc90c43e1d31af444c2e585be79d02e2ab80 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 18 Jun 2020 13:37:43 +0200 Subject: [PATCH 37/37] [tracking] Polish the phrase for 'none' a bit --- src/modules/tracking/page_trackingstep.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/tracking/page_trackingstep.ui b/src/modules/tracking/page_trackingstep.ui index 4383d312d..55a4df094 100644 --- a/src/modules/tracking/page_trackingstep.ui +++ b/src/modules/tracking/page_trackingstep.ui @@ -69,7 +69,7 @@ margin-left: 2em; - <html><head/><body><p>By selecting this, you will send <span style=" font-weight:600;">no information at all</span> about your installation.</p></body></html> + <html><head/><body><p>Click here to send <span style=" font-weight:600;">no information at all</span> about your installation.</p></body></html> true