|  | // Copyright 2018 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef COMPONENTS_SYNC_SESSIONS_SESSION_SYNC_BRIDGE_H_ | 
|  | #define COMPONENTS_SYNC_SESSIONS_SESSION_SYNC_BRIDGE_H_ | 
|  |  | 
|  | #include <memory> | 
|  | #include <string> | 
|  |  | 
|  | #include "base/callback_forward.h" | 
|  | #include "base/macros.h" | 
|  | #include "base/memory/weak_ptr.h" | 
|  | #include "base/time/time.h" | 
|  | #include "components/sync/model/model_error.h" | 
|  | #include "components/sync/model/model_type_store.h" | 
|  | #include "components/sync/model/model_type_sync_bridge.h" | 
|  | #include "components/sync_sessions/abstract_sessions_sync_manager.h" | 
|  | #include "components/sync_sessions/favicon_cache.h" | 
|  | #include "components/sync_sessions/local_session_event_handler_impl.h" | 
|  | #include "components/sync_sessions/open_tabs_ui_delegate_impl.h" | 
|  | #include "components/sync_sessions/session_store.h" | 
|  | #include "components/sync_sessions/sessions_global_id_mapper.h" | 
|  |  | 
|  | namespace sync_sessions { | 
|  |  | 
|  | class LocalSessionEventRouter; | 
|  | class SyncSessionsClient; | 
|  |  | 
|  | // Sync bridge implementation for SESSIONS model type. Takes care of propagating | 
|  | // local sessions to other clients as well as providing a representation of | 
|  | // foreign sessions. | 
|  | // | 
|  | // This is achieved by implementing the interface ModelTypeSyncBridge, which | 
|  | // ClientTagBasedModelTypeProcessor will use to interact, ultimately, with the | 
|  | // sync server. See | 
|  | // https://chromium.googlesource.com/chromium/src/+/lkcr/docs/sync/model_api.md#Implementing-ModelTypeSyncBridge | 
|  | // for details. | 
|  | class SessionSyncBridge : public AbstractSessionsSyncManager, | 
|  | public syncer::ModelTypeSyncBridge, | 
|  | public LocalSessionEventHandlerImpl::Delegate { | 
|  | public: | 
|  | // Raw pointers must not be null and their pointees must outlive this object. | 
|  | SessionSyncBridge( | 
|  | SyncSessionsClient* sessions_client, | 
|  | std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor); | 
|  | ~SessionSyncBridge() override; | 
|  |  | 
|  | // AbstractSessionsSyncManager implementation. | 
|  | void ScheduleGarbageCollection() override; | 
|  | FaviconCache* GetFaviconCache() override; | 
|  | SessionsGlobalIdMapper* GetGlobalIdMapper() override; | 
|  | OpenTabsUIDelegate* GetOpenTabsUIDelegate() override; | 
|  | syncer::SyncableService* GetSyncableService() override; | 
|  | syncer::ModelTypeSyncBridge* GetModelTypeSyncBridge() override; | 
|  |  | 
|  | // ModelTypeSyncBridge implementation. | 
|  | void OnSyncStarting( | 
|  | const syncer::DataTypeActivationRequest& request) override; | 
|  | std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList() | 
|  | override; | 
|  | base::Optional<syncer::ModelError> MergeSyncData( | 
|  | std::unique_ptr<syncer::MetadataChangeList> metadata_change_list, | 
|  | syncer::EntityChangeList entity_data) override; | 
|  | base::Optional<syncer::ModelError> ApplySyncChanges( | 
|  | std::unique_ptr<syncer::MetadataChangeList> metadata_change_list, | 
|  | syncer::EntityChangeList entity_changes) override; | 
|  | void GetData(StorageKeyList storage_keys, DataCallback callback) override; | 
|  | void GetAllDataForDebugging(DataCallback callback) override; | 
|  | std::string GetClientTag(const syncer::EntityData& entity_data) override; | 
|  | std::string GetStorageKey(const syncer::EntityData& entity_data) override; | 
|  | StopSyncResponse ApplyStopSyncChanges( | 
|  | std::unique_ptr<syncer::MetadataChangeList> delete_metadata_change_list) | 
|  | override; | 
|  |  | 
|  | // LocalSessionEventHandlerImpl::Delegate implementation. | 
|  | std::unique_ptr<LocalSessionEventHandlerImpl::WriteBatch> | 
|  | CreateLocalSessionWriteBatch() override; | 
|  | void TrackLocalNavigationId(base::Time timestamp, int unique_id) override; | 
|  | void OnPageFaviconUpdated(const GURL& page_url) override; | 
|  | void OnFaviconVisited(const GURL& page_url, const GURL& favicon_url) override; | 
|  |  | 
|  | private: | 
|  | void OnStoreInitialized( | 
|  | const base::Optional<syncer::ModelError>& error, | 
|  | std::unique_ptr<SessionStore> store, | 
|  | std::unique_ptr<syncer::MetadataBatch> metadata_batch); | 
|  | void StartLocalSessionEventHandler(); | 
|  | void DeleteForeignSessionFromUI(const std::string& tag); | 
|  | void DoGarbageCollection(); | 
|  | std::unique_ptr<SessionStore::WriteBatch> CreateSessionStoreWriteBatch(); | 
|  | void DeleteForeignSessionWithBatch(const std::string& session_tag, | 
|  | SessionStore::WriteBatch* batch); | 
|  | void ResubmitLocalSession(); | 
|  | void ReportError(const syncer::ModelError& error); | 
|  |  | 
|  | SyncSessionsClient* const sessions_client_; | 
|  | LocalSessionEventRouter* const local_session_event_router_; | 
|  |  | 
|  | FaviconCache favicon_cache_; | 
|  | SessionsGlobalIdMapper global_id_mapper_; | 
|  | SessionStore::Factory session_store_factory_; | 
|  |  | 
|  | // All data dependent on sync being starting or started. | 
|  | struct SyncingState { | 
|  | SyncingState(); | 
|  | ~SyncingState(); | 
|  |  | 
|  | std::unique_ptr<SessionStore> store; | 
|  | std::unique_ptr<OpenTabsUIDelegateImpl> open_tabs_ui_delegate; | 
|  | std::unique_ptr<LocalSessionEventHandlerImpl> local_session_event_handler; | 
|  |  | 
|  | // Tracks whether our local representation of which sync nodes map to what | 
|  | // tabs (belonging to the current local session) is inconsistent.  This can | 
|  | // happen if a foreign client deems our session as "stale" and decides to | 
|  | // delete it. Rather than respond by bullishly re-creating our nodes | 
|  | // immediately, which could lead to ping-pong sequences, we give the benefit | 
|  | // of the doubt and hold off until another local navigation occurs, which | 
|  | // proves that we are still relevant. | 
|  | bool local_data_out_of_sync = false; | 
|  | }; | 
|  |  | 
|  | base::Optional<SyncingState> syncing_; | 
|  |  | 
|  | base::WeakPtrFactory<SessionSyncBridge> weak_ptr_factory_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(SessionSyncBridge); | 
|  | }; | 
|  |  | 
|  | }  // namespace sync_sessions | 
|  |  | 
|  | #endif  // COMPONENTS_SYNC_SESSIONS_SESSION_SYNC_BRIDGE_H_ |