File indexing completed on 2024-12-15 03:45:04

0001 /*
0002     SPDX-FileCopyrightText: 2016 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: MIT
0005 */
0006 
0007 #ifndef KUSERFEEDBACK_PROVIDER_H
0008 #define KUSERFEEDBACK_PROVIDER_H
0009 
0010 #include "kuserfeedbackcore_export.h"
0011 
0012 #include <QMetaType>
0013 #include <QObject>
0014 #include <QUrl>
0015 
0016 namespace KUserFeedback {
0017 
0018 class AbstractDataSource;
0019 class ProviderPrivate;
0020 class SurveyInfo;
0021 
0022 /*! The central object managing data sources and transmitting feedback to the server.
0023  *
0024  *  The defaults for this class are very defensive, so in order to make it actually
0025  *  operational and submit data, there is a number of settings you need to set in
0026  *  code, namely submission intervals, encouragement settings and adding data sources.
0027  *  The settings about what data to submit (telemetryMode) and how often
0028  *  to bother the user with surveys (surveyInterval) should not be set to hardcoded
0029  *  values in code, but left as choices to the user.
0030  */
0031 class KUSERFEEDBACKCORE_EXPORT Provider : public QObject
0032 {
0033     Q_OBJECT
0034     /*! The global enabled state of the feedback functionality.
0035      *  If this is @c false, all feedback functionality has to be disabled completely.
0036      */
0037     Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled NOTIFY enabledChanged)
0038 
0039     /*! The interval in which the user accepts surveys.
0040      *  This should be configurable for the user.
0041      *  @c -1 indicates surveys are disabled.
0042      *  @see surveyInterval(), setSurveyInterval()
0043      */
0044     Q_PROPERTY(int surveyInterval READ surveyInterval WRITE setSurveyInterval NOTIFY surveyIntervalChanged)
0045 
0046     /*! The telemetry mode the user has configured.
0047      * This should be configurable for the user.
0048      * @see telemetryMode(), setTelemetryMode()
0049      */
0050     Q_PROPERTY(TelemetryMode telemetryMode READ telemetryMode WRITE setTelemetryMode NOTIFY telemetryModeChanged)
0051 
0052     /*! Unique product id as set on the feedback server.
0053      *  @see setProductIdentifier
0054      */
0055     Q_PROPERTY(QString productIdentifier READ productIdentifier WRITE setProductIdentifier NOTIFY providerSettingsChanged)
0056 
0057     /*! URL of the feedback server.
0058      *  @see setFeedbackServer
0059      */
0060     Q_PROPERTY(QUrl feedbackServer READ feedbackServer WRITE setFeedbackServer NOTIFY providerSettingsChanged)
0061 
0062     /*! Submission interval in days.
0063      *  @see setSubmissionInterval
0064      */
0065     Q_PROPERTY(int submissionInterval READ submissionInterval WRITE setSubmissionInterval NOTIFY providerSettingsChanged)
0066 
0067     /*! Times the application has to be started before an encouragement message is shown.
0068      *  @see setApplicationStartsUntilEncouragement
0069      */
0070     Q_PROPERTY(int applicationStartsUntilEncouragement
0071                 READ applicationStartsUntilEncouragement
0072                 WRITE setApplicationStartsUntilEncouragement
0073                 NOTIFY providerSettingsChanged)
0074 
0075     /*! Application usage time in seconds before an encouragement message is shown.
0076      *  @see setApplicationUsageTimeUntilEncouragement
0077      */
0078     Q_PROPERTY(int applicationUsageTimeUntilEncouragement
0079                 READ applicationUsageTimeUntilEncouragement
0080                 WRITE setApplicationUsageTimeUntilEncouragement
0081                 NOTIFY providerSettingsChanged)
0082 
0083     /*! Encouragement delay after application start in seconds.
0084      *  @see setEncouragementDelay
0085      */
0086     Q_PROPERTY(int encouragementDelay READ encouragementDelay WRITE setEncouragementDelay NOTIFY providerSettingsChanged)
0087 
0088     /*! Encouragement interval.
0089      *  @see setEncouragementInterval
0090      */
0091     Q_PROPERTY(int encouragementInterval READ encouragementInterval WRITE setEncouragementInterval NOTIFY providerSettingsChanged)
0092 
0093     /*!
0094      */
0095     Q_PROPERTY(QString describeDataSources READ describeDataSources NOTIFY dataSourcesChanged)
0096 
0097 public:
0098     /*! Telemetry collection modes.
0099      *  Collection modes are inclusive, ie. higher modes always imply data from
0100      *  lower modes too.
0101      */
0102     enum TelemetryMode {
0103         NoTelemetry, ///< Transmit no data at all.
0104         BasicSystemInformation = 0x10, ///< Transmit basic information about the system.
0105         BasicUsageStatistics = 0x20, ///< Transmit basic usage statistics.
0106         DetailedSystemInformation = 0x30, ///< Transmit detailed system information.
0107         DetailedUsageStatistics = 0x40, ///< Transmit detailed usage statistics.
0108     };
0109     Q_ENUM(TelemetryMode)
0110 
0111     /*! Create a new feedback provider.
0112      *  @param parent The parent object.
0113      */
0114     explicit Provider(QObject *parent = nullptr);
0115     ~Provider() override;
0116 
0117     /*! Returns whether feedback functionality is enabled on this system.
0118      *  This should be checked everywhere showing feedback UI to the user
0119      *  to respect the global "kill switch" for this. Provider does check
0120      *  this internally for encouragements, surveys and telemetry submission.
0121      */
0122     bool isEnabled() const;
0123     /*! Set the global (user-wide) activation state for feedback functionality.
0124      *  @see isEnabled
0125      */
0126     void setEnabled(bool enabled);
0127 
0128     /*! Set the telemetry mode and the survey interval back to their default values.
0129      *  @see telemetryMode(), surveyInterval()
0130      *  @since 1.1.0
0131      */
0132     void restoreDefaults();
0133 
0134     /*! Returns the current product identifier. */
0135     QString productIdentifier() const;
0136     /*! Set the product identifier.
0137      *  This is used to distinguish independent products on the same server.
0138      *  If this is not specified, the product identifier is derived from the application name
0139      *  organisation domain specified in QCoreApplication.
0140      *  @param productId Unique product identifier, as configured on the feedback server.
0141      */
0142     void setProductIdentifier(const QString &productId);
0143 
0144     /*! Returns the current feedback server URL. */
0145     QUrl feedbackServer() const;
0146     /*! Set the feedback server URL.
0147      *  This must be called with an appropriate URL for this class to be operational.
0148      *  @param url The URL of the feedback server.
0149      */
0150     void setFeedbackServer(const QUrl &url);
0151 
0152     /*! Returns the current submission interval.
0153      *  @return Days between telemetry submissions, or -1 if submission is off.
0154      */
0155     int submissionInterval() const;
0156     /*! Set the automatic submission interval in days.
0157      *  This must be called with a positive number for this class to be operational,
0158      *  as the default is -1 (no submission ever).
0159      */
0160     void setSubmissionInterval(int days);
0161 
0162     /*! Returns the current telemetry collection mode.
0163      *  The default is NoTelemetry.
0164      */
0165     TelemetryMode telemetryMode() const;
0166 
0167     /*! Set which telemetry data should be submitted. */
0168     void setTelemetryMode(TelemetryMode mode);
0169 
0170     /*! Adds a data source for telemetry data collection.
0171      *  @param source The data source to add. The Provider takes ownership of @p source.
0172      */
0173     void addDataSource(AbstractDataSource *source);
0174 
0175     /*! Returns all data sources that have been added to this provider.
0176      *  @see addDataSource
0177      */
0178     QVector<AbstractDataSource*> dataSources() const;
0179 
0180     /*! Returns a data source with matched @p id
0181      * @param id data source unique identifier
0182      * @return pointer to found data source or nullptr if data source is not found
0183      */
0184     AbstractDataSource *dataSource(const QString &id) const;
0185 
0186     /*! Returns the minimum time between two surveys in days.
0187      *  The default is -1 (no surveys enabled).
0188      */
0189     int surveyInterval() const;
0190 
0191     /*! Sets the minimum time in days between two surveys.
0192      *  @c -1 indicates no surveys should be requested.
0193      *  @c 0 indicates no minimum time between surveys at all (i.e. bother the user as often as you want).
0194      */
0195     void setSurveyInterval(int days);
0196 
0197     /*! Returns the amount of application starts before an encouragement message is shown. */
0198     int applicationStartsUntilEncouragement() const;
0199     /*! Set the amount of application starts until the encouragement message should be shown.
0200      *  The default is -1, ie. no encouragement based on application starts.
0201      *  @param starts The amount of application starts after which an encouragement
0202      *  message should be displayed.
0203      */
0204     void setApplicationStartsUntilEncouragement(int starts);
0205 
0206     /*! Returns the amount of application usage time before an encouragement message is shown. */
0207     int applicationUsageTimeUntilEncouragement() const;
0208     /*! Set the amount of usage time until the encouragement message should be shown.
0209      *  The default is -1, ie. no encouragement based on application usage time.
0210      *  @param secs Amount of seconds until the encouragement should be shown.
0211      */
0212     void setApplicationUsageTimeUntilEncouragement(int secs);
0213 
0214     /*! Returns the current encouragement delay in seconds. */
0215     int encouragementDelay() const;
0216     /*! Set the delay after application start for the earliest display of the encouragement message.
0217      *  The default is 300, ie. 5 minutes after the application start.
0218      *  @note This only adds an additional constraint on usage time and startup count based
0219      *  encouragement messages, it does not actually trigger encouragement messages itself.
0220      *
0221      *  @param secs Amount of seconds after the application start for the earliest display
0222      *  of an encouragement message.
0223      *
0224      *  @see setApplicationStartsUntilEncouragement, setApplicationUsageTimeUntilEncouragement
0225      */
0226     void setEncouragementDelay(int secs);
0227 
0228     /*! Returns the current encouragement interval. */
0229     int encouragementInterval() const;
0230     /*! Sets the interval after the encouragement should be repeated.
0231      *  Encouragement messages are only repeated if no feedback options have been enabled.
0232      *  The default is -1, that is no repeated encouragement at all.
0233      *  @param days Days between encouragement messages, 0 disables repeated encouragements.
0234      */
0235     void setEncouragementInterval(int days);
0236 
0237     /*! Returns a string with each source and its enable mode. */
0238     QString describeDataSources() const;
0239 
0240 public Q_SLOTS:
0241     /*! Manually submit currently recorded data. */
0242     void submit();
0243 
0244     /*! Marks the given survey as completed. This avoids getting further notification
0245      *  about the same survey.
0246      */
0247     void surveyCompleted(const KUserFeedback::SurveyInfo &info);
0248 
0249     /*! Manually load settings of the provider and all added data sources.
0250      *  Automatically invoked after object construction and changing product ID.
0251      *  @note Potentially long operation.
0252      */
0253     void load();
0254 
0255     /*! Manually store settings of the provider and all added data sources.
0256      *  Will be automatically invoked upon @p QCoreApplication::aboutToQuit signal.
0257      *  @note Potentially long operation.
0258      */
0259     void store();
0260 
0261 Q_SIGNALS:
0262     /*! Emitted whenever there is a new survey available that can be presented
0263      *  to the user.
0264      */
0265     void surveyAvailable(const KUserFeedback::SurveyInfo &survey);
0266 
0267     /*! Indicate that the encouragement notice should be shown. */
0268     void showEncouragementMessage();
0269 
0270     /*! Emitted when the survey interval changed. */
0271     void surveyIntervalChanged();
0272 
0273     /*! Emitted when the telemetry collection mode has changed. */
0274     void telemetryModeChanged();
0275 
0276     /*! Emitted when any provider setting changed. */
0277     void providerSettingsChanged();
0278 
0279     /*! Emitted when the global enabled state changed. */
0280     void enabledChanged();
0281 
0282     /*! Emitted when a data source is added or removed. */
0283     void dataSourcesChanged();
0284 
0285 private:
0286     friend class ProviderPrivate;
0287     ProviderPrivate * const d;
0288     // for UI
0289     Q_PRIVATE_SLOT(d, QByteArray jsonData(KUserFeedback::Provider::TelemetryMode))
0290     // for testing
0291     Q_PRIVATE_SLOT(d, bool selectSurvey(const KUserFeedback::SurveyInfo&))
0292 };
0293 
0294 }
0295 
0296 Q_DECLARE_METATYPE(KUserFeedback::Provider::TelemetryMode)
0297 
0298 #endif // KUSERFEEDBACK_PROVIDER_H