blob: 5679404d311f23dd90558bcfc7b15e72f78054f3 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SAVED_TAB_GROUPS_TAB_GROUP_SYNC_SERVICE_IMPL_H_
#define COMPONENTS_SAVED_TAB_GROUPS_TAB_GROUP_SYNC_SERVICE_IMPL_H_
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "components/saved_tab_groups/saved_tab_group.h"
#include "components/saved_tab_groups/saved_tab_group_model.h"
#include "components/saved_tab_groups/saved_tab_group_sync_bridge.h"
#include "components/saved_tab_groups/shared_tab_group_data_sync_bridge.h"
#include "components/saved_tab_groups/tab_group_store.h"
#include "components/saved_tab_groups/tab_group_sync_service.h"
#include "components/sync/model/model_type_store.h"
#include "components/sync/model/model_type_sync_bridge.h"
#include "components/sync/model/sync_data.h"
namespace tab_groups {
// The internal implementation of the TabGroupSyncService.
class TabGroupSyncServiceImpl : public TabGroupSyncService,
public SavedTabGroupModelObserver {
public:
// Configuration for a specific sync data type.
struct SyncDataTypeConfiguration {
SyncDataTypeConfiguration(
std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor,
syncer::OnceModelTypeStoreFactory model_type_store_factory);
~SyncDataTypeConfiguration();
std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor;
syncer::OnceModelTypeStoreFactory model_type_store_factory;
};
// `saved_tab_group_configuration` must not be `nullptr`.
// `shared_tab_group_configuration` should be provided if feature is enabled.
TabGroupSyncServiceImpl(
std::unique_ptr<SavedTabGroupModel> model,
std::unique_ptr<SyncDataTypeConfiguration> saved_tab_group_configuration,
std::unique_ptr<SyncDataTypeConfiguration> shared_tab_group_configuration,
std::unique_ptr<TabGroupStore> tab_group_store);
~TabGroupSyncServiceImpl() override;
// Disallow copy/assign.
TabGroupSyncServiceImpl(const TabGroupSyncServiceImpl&) = delete;
TabGroupSyncServiceImpl& operator=(const TabGroupSyncServiceImpl&) = delete;
// TabGroupSyncService implementation.
void AddGroup(const SavedTabGroup& group) override;
void RemoveGroup(const LocalTabGroupID& local_id) override;
void RemoveGroup(const base::Uuid& sync_id) override;
void UpdateVisualData(
const LocalTabGroupID local_group_id,
const tab_groups::TabGroupVisualData* visual_data) override;
void AddTab(const LocalTabGroupID& group_id,
const LocalTabID& tab_id,
const std::u16string& title,
GURL url,
std::optional<size_t> position) override;
void UpdateTab(const LocalTabGroupID& group_id,
const LocalTabID& tab_id,
const std::u16string& title,
GURL url,
std::optional<size_t> position) override;
void RemoveTab(const LocalTabGroupID& group_id,
const LocalTabID& tab_id) override;
void MoveTab(const LocalTabGroupID& group_id,
const LocalTabID& tab_id,
int new_group_index) override;
std::vector<SavedTabGroup> GetAllGroups() override;
std::optional<SavedTabGroup> GetGroup(const base::Uuid& guid) override;
std::optional<SavedTabGroup> GetGroup(LocalTabGroupID& local_id) override;
std::vector<LocalTabGroupID> GetDeletedGroupIds() override;
void UpdateLocalTabGroupMapping(const base::Uuid& sync_id,
const LocalTabGroupID& local_id) override;
void RemoveLocalTabGroupMapping(const LocalTabGroupID& local_id) override;
void UpdateLocalTabId(const LocalTabGroupID& local_group_id,
const base::Uuid& sync_tab_id,
const LocalTabID& local_tab_id) override;
base::WeakPtr<syncer::ModelTypeControllerDelegate>
GetSavedTabGroupControllerDelegate() override;
base::WeakPtr<syncer::ModelTypeControllerDelegate>
GetSharedTabGroupControllerDelegate() override;
void AddObserver(TabGroupSyncService::Observer* observer) override;
void RemoveObserver(TabGroupSyncService::Observer* observer) override;
private:
// SavedTabGroupModelObserver implementation.
void SavedTabGroupAddedFromSync(const base::Uuid& guid) override;
void SavedTabGroupAddedLocally(const base::Uuid& guid) override;
void SavedTabGroupUpdatedFromSync(
const base::Uuid& group_guid,
const std::optional<base::Uuid>& tab_guid) override;
void SavedTabGroupUpdatedLocally(
const base::Uuid& group_guid,
const std::optional<base::Uuid>& tab_guid) override;
void SavedTabGroupRemovedFromSync(
const SavedTabGroup* removed_group) override;
void SavedTabGroupRemovedLocally(const SavedTabGroup* removed_group) override;
void SavedTabGroupLocalIdChanged(const base::Uuid& saved_group_id) override;
void SavedTabGroupModelLoaded() override;
// Called on reading ID mapping from tab group store.
void OnReadTabGroupStore();
// Consolidation methods for adapting to observer signals from either
// direction (local -> remote or remote -> local).
// TODO(shaktisahu): Make SavedTabGroupModelObserver consolidate these signals
// directly at some point.
void HandleTabGroupAdded(const base::Uuid& guid, TriggerSource source);
void HandleTabGroupUpdated(const base::Uuid& group_guid,
const std::optional<base::Uuid>& tab_guid,
TriggerSource source);
void HandleTabGroupRemoved(const SavedTabGroup* removed_group,
TriggerSource source);
// The in-memory model representing the currently present saved tab groups.
std::unique_ptr<SavedTabGroupModel> model_;
// Stores SavedTabGroup data to the disk and to sync if enabled.
SavedTabGroupSyncBridge saved_bridge_;
// Stores SharedTabGroupData to the disk and to sync if enabled.
std::unique_ptr<SharedTabGroupDataSyncBridge> shared_bridge_;
// Stores tab group ID mapping (Sync ID -> Local ID) and some local metadata.
std::unique_ptr<TabGroupStore> tab_group_store_;
// Whether the initialization has been completed, i.e. all the groups and the
// ID mappings have been loaded into memory.
bool is_initialized_ = false;
// Keeps track of the ids of session restored tab groups that were once saved
// in order to link them together again once the SavedTabGroupModelLoaded is
// called. After the model is loaded, this variable is emptied to conserve
// memory.
std::vector<std::pair<base::Uuid, LocalTabGroupID>>
saved_guid_to_local_group_id_mapping_;
// Groups with zero tabs are groups that still haven't received their tabs
// from sync. UI can't handle these groups, hence the service needs to wait
// before notifying the observers.
std::set<base::Uuid> empty_groups_;
// Obsevers of the model.
base::ObserverList<TabGroupSyncService::Observer> observers_;
base::WeakPtrFactory<TabGroupSyncServiceImpl> weak_ptr_factory_{this};
};
} // namespace tab_groups
#endif // COMPONENTS_SAVED_TAB_GROUPS_TAB_GROUP_SYNC_SERVICE_IMPL_H_