app/core/SettingsSyncSession.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <QObject> | ||
| 4 | #include <QThread> | ||
| 5 | #include <QVariantMap> | ||
| 6 | #include <atomic> | ||
| 7 | #include <memory> | ||
| 8 | |||
| 9 | #include "data/SettingsSyncModels.h" | ||
| 10 | |||
| 11 | class AccountSession; | ||
| 12 | class CredentialStore; | ||
| 13 | class QTimer; | ||
| 14 | class SettingsSyncWorker; | ||
| 15 | |||
| 16 | // Profile-owned settings exchange. The scene only edits configuration and | ||
| 17 | // chooses how to resolve differences. Transport, collection and application | ||
| 18 | // run on the worker with its own SQLite connection. Account switching does | ||
| 19 | // not change the explicitly selected synchronization account. | ||
| 20 | // Invariant: the keyring (QKeychain) is used only on this object's (GUI) | ||
| 21 | // thread. QKeychain jobs share a process-wide executor bound to the thread | ||
| 22 | // that first used it; a job from the worker thread crashed the process | ||
| 23 | // while the account session read its own password. The session reads the | ||
| 24 | // password and hands it to the worker. | ||
| 25 | class SettingsSyncSession final : public QObject { | ||
| 26 | 5 | Q_OBJECT | |
| 27 | Q_PROPERTY(bool enabled READ enabled NOTIFY changed) | ||
| 28 | Q_PROPERTY(QString accountId READ accountId NOTIFY changed) | ||
| 29 | Q_PROPERTY(QString folder READ folder NOTIFY changed) | ||
| 30 | Q_PROPERTY(QStringList categories READ categories NOTIFY changed) | ||
| 31 | Q_PROPERTY(QString state READ state NOTIFY changed) | ||
| 32 | Q_PROPERTY(QString error READ error NOTIFY changed) | ||
| 33 | Q_PROPERTY(QString lastSuccess READ lastSuccess NOTIFY changed) | ||
| 34 | Q_PROPERTY(QStringList differences READ differences NOTIFY changed) | ||
| 35 | public: | ||
| 36 | SettingsSyncSession(AccountSession &accounts, QString configDirectory, | ||
| 37 | QString calendarDatabase, QObject *parent = nullptr); | ||
| 38 | ~SettingsSyncSession() override; | ||
| 39 | 1512 | bool enabled() const { return m_enabled; } | |
| 40 | 6 | QString accountId() const { return m_accountId; } | |
| 41 | 14 | QString folder() const { return m_folder; } | |
| 42 | 26 | QStringList categories() const { return m_categories; } | |
| 43 | 1336 | QString state() const { return m_state; } | |
| 44 | 64 | QString error() const { return m_error; } | |
| 45 | 1 | QString lastSuccess() const { return m_lastSuccess; } | |
| 46 | 3 | QStringList differences() const { return m_differences; } | |
| 47 | Q_INVOKABLE QVariantMap configure(bool enabled, const QString &accountId, | ||
| 48 | const QString &folder, const QStringList &categories); | ||
| 49 | Q_INVOKABLE void synchronize(); | ||
| 50 | Q_INVOKABLE void useRemote(); | ||
| 51 | Q_INVOKABLE void useLocal(); | ||
| 52 | // Sprint 107: the three payloads (compact JSON) of the conflict shown to | ||
| 53 | // the user; empty unless state() is "conflict". `base` is empty when no | ||
| 54 | // agreed version is stored (two-way, D-13). | ||
| 55 | struct ConflictInputs { | ||
| 56 | QString base; | ||
| 57 | QString local; | ||
| 58 | QString remote; | ||
| 59 | }; | ||
| 60 | 10 | ConflictInputs conflictInputs() const { return m_conflictInputs; } | |
| 61 | // The identity of the displayed server version; resolveWith() is | ||
| 62 | // dropped when the server changed meanwhile (D-9). | ||
| 63 | 8 | QByteArray shownRemoteIdentity() const { return m_remoteIdentity; } | |
| 64 | // S107.3.5: adopts `resolved` (SettingsMergePlan::apply of the user's | ||
| 65 | // choices) and uploads it. False when no conflict is shown or the shown | ||
| 66 | // server version is no longer the current one. | ||
| 67 | bool resolveWith(const SyncPayload &resolved, const QByteArray &expectedRemote); | ||
| 68 | void localSettingsChanged(); | ||
| 69 | signals: | ||
| 70 | void changed(); | ||
| 71 | void settingsApplied(const QStringList &categories); | ||
| 72 | private: | ||
| 73 | friend class SettingsSyncWorker; | ||
| 74 | void restart(bool force = false); | ||
| 75 | void readPasswordThenBegin(quint64 generation); | ||
| 76 | void cancelPasswordRead(); | ||
| 77 | void retireTransport(quint64 generation); | ||
| 78 | void command(int action); | ||
| 79 | AccountSession &m_accounts; | ||
| 80 | QString m_configDirectory, m_calendarDatabase; | ||
| 81 | QString m_accountId, m_folder, m_state = QStringLiteral("disabled"), m_error, m_lastSuccess; | ||
| 82 | QStringList m_categories, m_differences; | ||
| 83 | bool m_enabled = false; | ||
| 84 | QByteArray m_configurationIdentity; | ||
| 85 | QByteArray m_remoteIdentity; | ||
| 86 | ConflictInputs m_conflictInputs; | ||
| 87 | QThread m_thread; | ||
| 88 | SettingsSyncWorker *m_worker = nullptr; | ||
| 89 | std::shared_ptr<std::atomic<quint64>> m_epoch; | ||
| 90 | CredentialStore *m_credentials = nullptr; | ||
| 91 | QTimer *m_credentialDeadline = nullptr; | ||
| 92 | }; | ||
| 93 |