Merge branch 'usertracking'

Adds a "tracking" module which allows configuring phone-home,
machine and user tracking. Additional machine-tracking types
could be defined depending on distro needs.

This is not the final version -- there is still polishing to
do on the icons, perhaps layout.

Tested in KDE Neon devunstable by keeping an existing partition
which had an older Neon running. New machine-id is generated
and sed'ded into place.

FIXES #783
This commit is contained in:
Adriaan de Groot 2017-11-23 17:38:30 +01:00
commit e29cd7ab54
20 changed files with 1226 additions and 2 deletions

View File

@ -66,6 +66,7 @@ sequence:
- keyboard - keyboard
- partition - partition
- users - users
- tracking
- summary - summary
- exec: - exec:
# - dummycpp # - dummycpp

View File

@ -340,6 +340,18 @@ getBool( const QVariantMap& map, const QString& key, bool d )
return result; return result;
} }
QString
getString(const QVariantMap& map, const QString& key)
{
if ( map.contains( key ) )
{
auto v = map.value( key );
if ( v.type() == QVariant::String )
return v.toString();
}
return QString();
}
QVariantMap QVariantMap
getSubMap( const QVariantMap& map, const QString& key, bool& success ) getSubMap( const QVariantMap& map, const QString& key, bool& success )
{ {

View File

@ -104,6 +104,11 @@ namespace CalamaresUtils
*/ */
DLLEXPORT bool getBool( const QVariantMap& map, const QString& key, bool d ); DLLEXPORT bool getBool( const QVariantMap& map, const QString& key, bool d );
/**
* Get a string value from a mapping; returns empty QString if no value.
*/
DLLEXPORT QString getString( const QVariantMap& map, const QString& key );
/** /**
* Returns a sub-map (i.e. a nested map) from the given mapping with the * Returns a sub-map (i.e. a nested map) from the given mapping with the
* given key. @p success is set to true if the @p key exists * given key. @p success is set to true if the @p key exists

View File

@ -232,7 +232,7 @@ System::targetEnvOutput( const QString& command,
QPair<quint64, float> QPair<quint64, float>
System::getTotalMemoryB() System::getTotalMemoryB() const
{ {
#ifdef Q_OS_LINUX #ifdef Q_OS_LINUX
struct sysinfo i; struct sysinfo i;
@ -257,4 +257,33 @@ System::getTotalMemoryB()
} }
QString
System::getCpuDescription() const
{
QString model;
#ifdef Q_OS_LINUX
QFile file("/proc/cpuinfo");
if ( file.open(QIODevice::ReadOnly | QIODevice::Text) )
while ( !file.atEnd() )
{
QByteArray line = file.readLine();
if ( line.startsWith( "model name" ) && (line.indexOf( ':' ) > 0) )
{
model = QString::fromLatin1( line.right(line.length() - line.indexOf( ':' ) ) );
break;
} }
}
#elif defined( Q_OS_FREEBSD )
// This would use sysctl "hw.model", which has a string value
#endif
return model.simplified();
}
quint64
System::getTotalDiskB() const
{
return 0;
}
} // namespace

View File

@ -112,7 +112,21 @@ public:
* *
* @return size, guesstimate-factor * @return size, guesstimate-factor
*/ */
DLLEXPORT QPair<quint64, float> getTotalMemoryB(); DLLEXPORT QPair<quint64, float> getTotalMemoryB() const;
/**
* @brief getCpuDescription returns a string describing the CPU.
*
* Returns the value of the "model name" line in /proc/cpuinfo.
*/
DLLEXPORT QString getCpuDescription() const;
/**
* @brief getTotalDiskB returns the total disk attached, in bytes.
*
* If nothing can be found, returns a 0.
*/
DLLEXPORT quint64 getTotalDiskB() const;
private: private:
static System* s_instance; static System* s_instance;

View File

@ -0,0 +1,16 @@
calamares_add_plugin( tracking
TYPE viewmodule
EXPORT_MACRO PLUGINDLLEXPORT_PRO
SOURCES
TrackingJobs.cpp
TrackingPage.cpp
TrackingViewStep.cpp
UI
page_trackingstep.ui
RESOURCES
page_trackingstep.qrc
LINK_PRIVATE_LIBRARIES
calamaresui
SHARED_LIB
)

View File

@ -0,0 +1,138 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2017, Adriaan de Groot <groot@kde..org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "TrackingJobs.h"
#include "utils/CalamaresUtilsSystem.h"
#include "utils/Logger.h"
#include <QEventLoop>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QSemaphore>
#include <QTimer>
TrackingInstallJob::TrackingInstallJob( const QString& url )
: m_url( url )
, m_networkManager( nullptr )
{
}
TrackingInstallJob::~TrackingInstallJob()
{
delete m_networkManager;
}
QString TrackingInstallJob::prettyName() const
{
return tr( "Installation feedback" );
}
QString TrackingInstallJob::prettyDescription() const
{
return prettyName();
}
QString TrackingInstallJob::prettyStatusMessage() const
{
return tr( "Sending installation feedback." );
}
Calamares::JobResult TrackingInstallJob::exec()
{
m_networkManager = new QNetworkAccessManager();
QNetworkRequest request;
request.setUrl( QUrl( m_url ) );
// Follows all redirects except unsafe ones (https to http).
request.setAttribute( QNetworkRequest::FollowRedirectsAttribute, true );
// Not everybody likes the default User Agent used by this class (looking at you,
// sourceforge.net), so let's set a more descriptive one.
request.setRawHeader( "User-Agent", "Mozilla/5.0 (compatible; Calamares)" );
QTimer timeout;
timeout.setSingleShot(true);
QEventLoop loop;
connect( m_networkManager, &QNetworkAccessManager::finished,
this, &TrackingInstallJob::dataIsHere );
connect( m_networkManager, &QNetworkAccessManager::finished,
&loop, &QEventLoop::quit );
connect( &timeout, &QTimer::timeout,
&loop, &QEventLoop::quit );
m_networkManager->get( request ); // The semaphore is released when data is received
timeout.start( 5000 /* ms */ );
loop.exec();
if ( !timeout.isActive() )
{
cDebug() << "WARNING: install-tracking request timed out.";
return Calamares::JobResult::error( tr( "Internal error in install-tracking." ),
tr( "HTTP request timed out." ) );
}
timeout.stop();
return Calamares::JobResult::ok();
}
void TrackingInstallJob::dataIsHere( QNetworkReply* reply )
{
cDebug() << "Installation feedback request OK";
reply->deleteLater();
}
QString TrackingMachineNeonJob::prettyName() const
{
return tr( "Machine feedback" );
}
QString TrackingMachineNeonJob::prettyDescription() const
{
return prettyName();
}
QString TrackingMachineNeonJob::prettyStatusMessage() const
{
return tr( "Configuring machine feedback." );
}
Calamares::JobResult TrackingMachineNeonJob::exec()
{
int r = CalamaresUtils::System::instance()->targetEnvCall(
"/bin/sh",
QString(), // Working dir
QString(
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"),
1);
if ( r == 0 )
return Calamares::JobResult::ok();
else if ( r > 0 )
return Calamares::JobResult::error( tr( "Error in machine feedback configuration." ),
tr( "Could not configure machine feedback correctly, script error %1." ).arg( r ) );
else
return Calamares::JobResult::error( tr( "Error in machine feedback configuration." ),
tr( "Could not configure machine feedback correctly, Calamares error %1." ).arg( r ) );
}

View File

@ -0,0 +1,60 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2017, Adriaan de Groot <groot@kde..org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef TRACKINGJOBS
#define TRACKINGJOBS
#include "Job.h"
class QNetworkAccessManager;
class QNetworkReply;
class QSemaphore;
class TrackingInstallJob : public Calamares::Job
{
Q_OBJECT
public:
TrackingInstallJob( const QString& url );
~TrackingInstallJob();
QString prettyName() const override;
QString prettyDescription() const override;
QString prettyStatusMessage() const override;
Calamares::JobResult exec() override;
public slots:
void dataIsHere( QNetworkReply* );
private:
const QString m_url;
QNetworkAccessManager* m_networkManager;
};
class TrackingMachineNeonJob : public Calamares::Job
{
Q_OBJECT
public:
QString prettyName() const override;
QString prettyDescription() const override;
QString prettyStatusMessage() const override;
Calamares::JobResult exec() override;
};
#endif

View File

@ -0,0 +1,166 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2017, Adriaan de Groot <groot@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "TrackingPage.h"
#include "ui_page_trackingstep.h"
#include "Branding.h"
#include "JobQueue.h"
#include "GlobalStorage.h"
#include "utils/Logger.h"
#include "utils/CalamaresUtilsGui.h"
#include "utils/Retranslator.h"
#include "ViewManager.h"
#include <QButtonGroup>
#include <QDesktopServices>
#include <QLabel>
TrackingPage::TrackingPage(QWidget *parent)
: QWidget( parent )
, ui( new Ui::TrackingPage )
{
using StringEntry = Calamares::Branding::StringEntry;
ui->setupUi( this );
CALAMARES_RETRANSLATE(
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( *StringEntry::ShortProductName ) );
ui->installExplanation->setText( tr( "By selecting this you will send information about your installation and hardware. This information will <b>only be sent once</b> after the installation finishes." ) );
ui->machineExplanation->setText( tr( "By selecting this you will <b>periodically</b> send information about your installation, hardware and applications, to %1." ).arg( *StringEntry::ShortProductName ) );
ui->userExplanation->setText( tr( "By selecting this you will <b>regularly</b> send information about your installation, hardware, applications and usage patterns, to %1." ).arg( *StringEntry::ShortProductName ) );
)
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 );
}
void TrackingPage::enableTrackingOption(TrackingType t, bool enabled)
{
QWidget* group = nullptr;
switch ( t )
{
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
cDebug() << "WARNING: 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.
switch ( t )
{
case TrackingType::InstallTracking:
enabled |= ui->installRadio->isChecked();
// FALLTHRU
case TrackingType::MachineTracking:
enabled |= ui->machineRadio->isChecked();
// FALLTHRU
case TrackingType::UserTracking:
enabled |= ui->userRadio->isChecked();
}
return enabled;
}
void TrackingPage::setTrackingPolicy(TrackingType t, QString url)
{
QToolButton *button = nullptr;
switch( t )
{
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
cDebug() << "WARNING: unknown tracking option" << int(t);
}
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(const QString& l)
{
QString level = l.toLower();
QRadioButton* button = nullptr;
if (level.isEmpty() || level == "none")
button = ui->noneRadio;
else if (level == "install")
button = ui->installRadio;
else if (level == "machine")
button = ui->machineRadio;
else if (level == "user")
button = ui->userRadio;
if ( button != nullptr )
button->setChecked( true );
else
cDebug() << "WARNING: unknown default tracking level" << l;
}

View File

@ -0,0 +1,64 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2017, Adriaan de Groot <groot@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef TRACKINGPAGE_H
#define TRACKINGPAGE_H
#include "TrackingType.h"
#include <QWidget>
#include <QUrl>
namespace Ui
{
class TrackingPage;
}
class TrackingPage : public QWidget
{
Q_OBJECT
public:
explicit TrackingPage( QWidget* parent = nullptr );
/**
* 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 );
/**
* 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 */
void setTrackingPolicy( TrackingType t, QString url );
/* URL for the global link */
void setGeneralPolicy( QString url );
/* Select one of the four levels by name */
void setTrackingLevel( const QString& level );
private:
Ui::TrackingPage* ui;
};
#endif //TRACKINGPAGE_H

View File

@ -0,0 +1,29 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2017, Adriaan de Groot <groot@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef TRACKINGTYPE_H
#define TRACKINGTYPE_H
enum class TrackingType
{
InstallTracking,
MachineTracking,
UserTracking
} ;
#endif //TRACKINGTYPE_H

View File

@ -0,0 +1,195 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2017, Adriaan de Groot <groot@kde.org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "JobQueue.h"
#include "GlobalStorage.h"
#include "utils/Logger.h"
#include "utils/CalamaresUtils.h"
#include "utils/CalamaresUtilsSystem.h"
#include "TrackingJobs.h"
#include "TrackingPage.h"
#include "TrackingViewStep.h"
#include <QDesktopServices>
#include <QVariantMap>
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_widget( new TrackingPage )
{
emit nextStatusChanged( false );
}
TrackingViewStep::~TrackingViewStep()
{
if ( m_widget && m_widget->parent() == nullptr )
m_widget->deleteLater();
}
QString
TrackingViewStep::prettyName() const
{
return tr( "Feedback" );
}
QWidget*
TrackingViewStep::widget()
{
return m_widget;
}
void
TrackingViewStep::next()
{
emit done();
}
void
TrackingViewStep::back()
{}
bool
TrackingViewStep::isNextEnabled() const
{
return true;
}
bool
TrackingViewStep::isBackEnabled() const
{
return true;
}
bool
TrackingViewStep::isAtBeginning() const
{
return true;
}
bool
TrackingViewStep::isAtEnd() const
{
return true;
}
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();
}
Calamares::JobList
TrackingViewStep::jobs() const
{
Calamares::JobList l;
cDebug() << "Creating tracking jobs ..";
if ( m_installTracking.enabled() && !m_installTrackingUrl.isEmpty() )
{
QString installUrl = m_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() << " .. install-tracking URL" << installUrl;
l.append( Calamares::job_ptr( new TrackingInstallJob( installUrl ) ) );
}
if ( m_machineTracking.enabled() && !m_machineTrackingStyle.isEmpty() )
{
Q_ASSERT( isValidStyle( m_machineTrackingStyle ) );
if ( m_machineTrackingStyle == "neon" )
l.append( Calamares::job_ptr( new TrackingMachineNeonJob() ) );
}
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_widget->setGeneralPolicy( CalamaresUtils::getString( configurationMap, "policy" ) );
m_widget->setTrackingLevel( CalamaresUtils::getString( configurationMap, "default" ) );
}

View File

@ -0,0 +1,95 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2017, Adriaan de Groot <groot@kde..org>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef TRACKINGVIEWSTEP_H
#define TRACKINGVIEWSTEP_H
#include "TrackingType.h"
#include <utils/PluginFactory.h>
#include <viewpages/ViewStep.h>
#include <PluginDllMacro.h>
#include <QObject>
#include <QUrl>
#include <QVariantMap>
class TrackingPage;
class PLUGINDLLEXPORT TrackingViewStep : public Calamares::ViewStep
{
Q_OBJECT
public:
explicit TrackingViewStep( QObject* parent = nullptr );
virtual ~TrackingViewStep() override;
QString prettyName() const override;
QWidget* widget() override;
void next() override;
void back() override;
bool isNextEnabled() const override;
bool isBackEnabled() const override;
bool isAtBeginning() const override;
bool isAtEnd() const override;
void onLeave() override;
Calamares::JobList jobs() const override;
void setConfigurationMap( const QVariantMap& configurationMap ) override;
private:
QVariantMap setTrackingOption( const QVariantMap& configurationMap, const QString& key, TrackingType t );
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 )
#endif // TRACKINGVIEWSTEP_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -0,0 +1,9 @@
<RCC>
<qresource prefix="tracking">
<file>level-none.png</file>
<file>level-install.png</file>
<file>level-machine.png</file>
<file>level-user.png</file>
<file>../../../data/images/information.svgz</file>
</qresource>
</RCC>

View File

@ -0,0 +1,303 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TrackingPage</class>
<widget class="QWidget" name="TrackingPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>799</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,0,0,0,0">
<item>
<widget class="QLabel" name="generalExplanation">
<property name="styleSheet">
<string notr="true">margin-bottom: 1ex;
margin-left: 2em;</string>
</property>
<property name="text">
<string>Placeholder</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="noneGroup" native="true">
<layout class="QHBoxLayout" name="noneLayout">
<item>
<widget class="QRadioButton" name="noneRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="noneIcon">
<property name="maximumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="baseSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="page_trackingstep.qrc">:/tracking/level-none.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="noneExplanation">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;By selecting this, you will send &lt;span style=&quot; font-weight:600;&quot;&gt;no information at all&lt;/span&gt; about your installation.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="installGroup" native="true">
<layout class="QHBoxLayout" name="installLayout">
<item>
<widget class="QRadioButton" name="installRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="installIcon">
<property name="maximumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="baseSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="page_trackingstep.qrc">:/tracking/level-install.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="installExplanation">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="installPolicyButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="page_trackingstep.qrc">
<normaloff>:/tracking/data/images/information.svgz</normaloff>:/tracking/data/images/information.svgz</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="machineGroup" native="true">
<layout class="QHBoxLayout" name="machineLayout">
<item>
<widget class="QRadioButton" name="machineRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="machineIcon">
<property name="maximumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="baseSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="page_trackingstep.qrc">:/tracking/level-machine.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="machineExplanation">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="machinePolicyButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="page_trackingstep.qrc">
<normaloff>:/tracking/data/images/information.svgz</normaloff>:/tracking/data/images/information.svgz</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="userGroup" native="true">
<layout class="QHBoxLayout" name="userLayout">
<item>
<widget class="QRadioButton" name="userRadio">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="userIcon">
<property name="maximumSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="baseSize">
<size>
<width>64</width>
<height>64</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="page_trackingstep.qrc">:/tracking/level-user.png</pixmap>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="userExplanation">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="userPolicyButton">
<property name="text">
<string>...</string>
</property>
<property name="icon">
<iconset resource="page_trackingstep.qrc">
<normaloff>:/tracking/data/images/information.svgz</normaloff>:/tracking/data/images/information.svgz</iconset>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="generalPolicyLabel">
<property name="text">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;a href=&quot;placeholder&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#2980b9;&quot;&gt;Click here for more information about user feedback&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="openExternalLinks">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources>
<include location="page_trackingstep.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -0,0 +1,88 @@
# Settings for various kinds of tracking that Distributions can
# enable. Distributions looking at tracking should be aware of
# the privacy (and hence communications) impact of that tracking,
# and are advised to consult the Mozilla and KDE policies on
# privacy and user tracking.
#
# There are three areas of tracking (-configuration) supported
# by Calamares It is up to individual Distributions to create
# suitable backends / configuration scripts for each. The
# different areas are:
#
# install: This is "phone home" functionality at the end of the
# install process. When enabled, it contacts the given
# URL. The URL can contain the special token $MACHINE,
# which is replaced by the machine-id of the installed
# system (if available, blank otherwise).
#
# machine: This enables machine-level tracking on a (semi-)
# continuous basis. It is meant to keep track of installed
# systems and their continued use / updating.
#
# user: This area enables user-level tracking, along the lines
# of the KDE User Telemetry Policy. It enables specific
# collection of data at a user- and application-level,
# possibly including actions done in an application.
# For the KDE environment, this enables user tracking
# with the appropriate framework, and the KDE User Telemetry
# 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
# configured or enabled by Calamares.
#
# 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.
#
# Each area may have other configuration keys, depending on the
# area and how it needs to be configured.
#
# Globally, there are two other keys:
#
# policy: (optional) url about tracking settings for this distro.
# default: (optional) level to enable by default
#
---
# 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.
policy: "https://github.com/calamares/calamares/wiki/Users-Guide#installation-tracking"
# This is the default level to enable for tracking. If commented out,
# empty, or otherwise invalid, "none" is used, so no tracking by default.
default: user
# The install area has one specific configuration key:
# url: this URL (remember to include the protocol, and prefer https)
# is fetched (with a GET request, and the data discarded) at
# the end of the installation process. The following tokens
# are replaced in the url (possibly by blank strings, or by 0).
# - $CPU (cpu make and model)
# - $MEMORY (amount of main memory available)
# - $DISK (total amount of disk attached)
# Typically these are used as GET parameters, as in the example.
#
# Note that phone-home only works if the system has an internet
# connection; it is a good idea to require internet in the welcome
# module then.
install:
enabled: false
policy: "https://github.com/calamares/calamares/wiki/Users-Guide#installation-tracking"
# 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, "neon", which edits two files in the installed
# system to enable system-tracking.
machine:
enabled: false
style: neon
# The user area is not yet implemented, and has no specific configuration.
user:
enabled: false