#ifndef CHROME_BROWSER_ASH_FLOATING_SSO_FLOATING_SSO_SYNC_BRIDGE_H_
#define CHROME_BROWSER_ASH_FLOATING_SSO_FLOATING_SSO_SYNC_BRIDGE_H_
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include "base/containers/flat_set.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
#include "components/sync/model/conflict_resolution.h"
#include "components/sync/model/data_type_store.h"
#include "components/sync/model/data_type_store_base.h"
#include "components/sync/model/data_type_store_with_in_memory_cache.h"
#include "components/sync/model/data_type_sync_bridge.h"
#include "components/sync/protocol/cookie_specifics.pb.h"
namespace syncer {
class DataTypeLocalChangeProcessor;
struct EntityData;
class MetadataBatch;
class MetadataChangeList;
class ModelError;
}
namespace net {
class CanonicalCookie;
}
namespace ash::floating_sso {
class FloatingSsoSyncBridge : public syncer::DataTypeSyncBridge {
public:
class Observer : public base::CheckedObserver {
public:
virtual void OnCookiesAddedOrUpdatedRemotely(
const std::vector<net::CanonicalCookie>& cookies) = 0;
virtual void OnCookiesRemovedRemotely(
const std::vector<net::CanonicalCookie>& cookies) = 0;
};
using CookieSpecificsEntries =
std::map<std::string, sync_pb::CookieSpecifics>;
explicit FloatingSsoSyncBridge(
std::unique_ptr<syncer::DataTypeLocalChangeProcessor> change_processor,
syncer::OnceDataTypeStoreFactory create_store_callback);
~FloatingSsoSyncBridge() override;
std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList()
override;
std::optional<syncer::ModelError> MergeFullSyncData(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList remote_entities) override;
std::optional<syncer::ModelError> ApplyIncrementalSyncChanges(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_changes) override;
std::string GetStorageKey(
const syncer::EntityData& entity_data) const override;
std::string GetClientTag(
const syncer::EntityData& entity_data) const override;
bool IsEntityDataValid(const syncer::EntityData& entity_data) const override;
std::unique_ptr<syncer::DataBatch> GetDataForCommit(
StorageKeyList storage_keys) override;
std::unique_ptr<syncer::DataBatch> GetAllDataForDebugging() override;
syncer::ConflictResolution ResolveConflict(
const std::string& storage_key,
const syncer::EntityData& remote_data) const override;
void AddOrUpdateCookie(const net::CanonicalCookie& cookie);
void DeleteCookie(const net::CanonicalCookie& cookie);
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
void SetOnMergeFullSyncDataCallback(base::OnceClosure callback);
void AddToLocallyPreferredCookies(const std::string& storage_key);
const CookieSpecificsEntries& CookieSpecificsInStore() const;
bool IsInitialDataReadFinishedForTest() const;
void SetOnStoreCommitCallbackForTest(base::RepeatingClosure callback);
private:
using StoreWithCache =
syncer::DataTypeStoreWithInMemoryCache<sync_pb::CookieSpecifics>;
void OnStoreCreated(const std::optional<syncer::ModelError>& error,
std::unique_ptr<StoreWithCache> store,
std::unique_ptr<syncer::MetadataBatch> metadata_batch);
void ProcessQueuedCookies();
void OnStoreCommit(const std::optional<syncer::ModelError>& error);
void CommitToStore(std::unique_ptr<StoreWithCache::WriteBatch> batch);
bool IsCookieInStore(const std::string& storage_key) const;
void OnMergeFullSyncDataFinished();
void DeleteCookieWithKey(const std::string& storage_key);
bool is_initial_data_read_finished_ = false;
base::RepeatingClosure on_store_commit_callback_for_test_;
bool merge_full_sync_data_finished_ = false;
base::OnceClosure on_merge_full_sync_data_callback_;
std::unique_ptr<StoreWithCache> store_;
std::map<std::string, net::CanonicalCookie> deferred_cookie_additions_;
std::set<std::string> deferred_cookie_deletions_;
base::flat_set<std::string> keep_local_cookie_keys_;
base::ObserverList<Observer> observers_;
base::WeakPtrFactory<FloatingSsoSyncBridge> weak_ptr_factory_{this};
};
}
#endif