/**************************************************************************** ** ** Copyright (c) 2014 - 2019 Jolla Ltd. ** Copyright (c) 2020 Open Mobile Platform LLC. ** ** This program/library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public License ** version 2.1 as published by the Free Software Foundation. ** ** This program/library 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 ** Lesser General Public License for more details. ** ** You should have received a copy of the GNU Lesser General Public ** License along with this program/library; if not, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA ** 02110-1301 USA ** ****************************************************************************/ #ifndef GOOGLETWOWAYCONTACTSYNCADAPTOR_H #define GOOGLETWOWAYCONTACTSYNCADAPTOR_H #include "googledatatypesyncadaptor.h" #include "googlepeopleapi.h" #include #include #include #include #include #include #include QTCONTACTS_USE_NAMESPACE class GoogleContactImageDownloader; class GoogleTwoWayContactSyncAdaptor; class GoogleContactSqliteSyncAdaptor : public QObject, public QtContactsSqliteExtensions::TwoWayContactSyncAdaptor { Q_OBJECT public: GoogleContactSqliteSyncAdaptor(int accountId, GoogleTwoWayContactSyncAdaptor *parent); ~GoogleContactSqliteSyncAdaptor(); bool isLocallyDeletedGuid(const QString &guid) const; virtual bool determineRemoteCollections() override; virtual bool deleteRemoteCollection(const QContactCollection &collection) override; virtual bool determineRemoteContacts(const QContactCollection &collection) override; virtual bool determineRemoteContactChanges(const QContactCollection &collection, const QList &localAddedContacts, const QList &localModifiedContacts, const QList &localDeletedContacts, const QList &localUnmodifiedContacts, QContactManager::Error *error) override; virtual bool storeLocalChangesRemotely(const QContactCollection &collection, const QList &addedContacts, const QList &modifiedContacts, const QList &deletedContacts) override; virtual void storeRemoteChangesLocally(const QContactCollection &collection, const QList &addedContacts, const QList &modifiedContacts, const QList &deletedContacts) override; virtual void syncFinishedSuccessfully() override; virtual void syncFinishedWithError() override; private: GoogleTwoWayContactSyncAdaptor *q; }; class GoogleTwoWayContactSyncAdaptor : public GoogleDataTypeSyncAdaptor { Q_OBJECT public: enum DataRequestType { ContactRequest, ContactGroupRequest }; enum ContactChangeNotifier { NoContactChangeNotifier, DetermineRemoteContacts, DetermineRemoteContactChanges }; Q_ENUM(ContactChangeNotifier) GoogleTwoWayContactSyncAdaptor(QObject *parent); ~GoogleTwoWayContactSyncAdaptor(); virtual QString syncServiceName() const override; virtual void sync(const QString &dataTypeString, int accountId) override; void requestData(DataRequestType requestType, ContactChangeNotifier contactChangeNotifier = NoContactChangeNotifier, const QString &pageToken = QString()); void upsyncLocalChanges(const QList &locallyAdded, const QList &locallyModified, const QList &locallyDeleted); void syncFinished(); protected: // implementing GoogleDataTypeSyncAdaptor interface void purgeDataForOldAccount(int oldId, SocialNetworkSyncAdaptor::PurgeMode mode) override; void beginSync(int accountId, const QString &accessToken) override; void finalize(int accountId) override; void finalCleanup() override; private: friend class GoogleContactSqliteSyncAdaptor; class BatchedUpdate { public: QMap > batch; int batchCount = 0; }; void groupsFinishedHandler(); void contactsFinishedHandler(); void continueSync(GoogleTwoWayContactSyncAdaptor::ContactChangeNotifier contactChangeNotifier); void upsyncLocalChangesList(); bool batchRemoteChanges(BatchedUpdate *batchedUpdate, QList *contacts, GooglePeopleApi::OperationType updateType); void storeToRemote(const QByteArray &encodedContactUpdates); void queueOutstandingAvatars(); bool queueAvatarForDownload(const QString &contactGuid, const QString &imageUrl); bool addAvatarToDownload(QContact *contact); void imageDownloaded(const QString &url, const QString &path, const QVariantMap &metadata); void loadCollection(const QContactCollection &collection); void purgeAccount(int pid); void postFinishedHandler(); void postErrorHandler(); QList m_remoteAdds; QList m_remoteMods; QList m_remoteDels; QList m_localAdds; QList m_localMods; QList m_localDels; QList m_localAvatarAdds; QList m_localAvatarMods; QList m_localAvatarDels; QHash m_contactEtags; // contact guid -> contact etag QHash m_contactIds; // contact guid -> contact id QHash m_contactAvatars; // contact guid -> remote avatar path QHash > m_previousAvatarUrls; QHash m_batchUpdateIndexes; QHash m_queuedAvatarsForDownload; // contact guid -> remote avatar path QContactManager *m_contactManager = nullptr; GoogleContactSqliteSyncAdaptor *m_sqliteSync = nullptr; GoogleContactImageDownloader *m_workerObject = nullptr; QContactCollection m_collection; QString m_accessToken; struct PeopleConnectionsListParameters { bool requestSyncToken; QString syncToken; QString personFields; } m_connectionsListParams; int m_accountId = 0; int m_apiRequestsRemaining = 0; bool m_retriedConnectionsList = false; bool m_allowFinalCleanup = false; }; #endif // GOOGLETWOWAYCONTACTSYNCADAPTOR_H