#ifndef CHROME_BROWSER_ASH_FLOATING_SSO_FLOATING_SSO_SERVICE_H_
#define CHROME_BROWSER_ASH_FLOATING_SSO_FLOATING_SSO_SERVICE_H_
#include <memory>
#include "base/containers/flat_set.h"
#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "chrome/browser/ash/floating_sso/floating_sso_sync_bridge.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/sync/model/data_type_store.h"
#include "components/url_matcher/url_matcher.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_access_result.h"
#include "services/network/public/mojom/cookie_manager.mojom.h"
namespace syncer {
class DataTypeControllerDelegate;
}
class PrefService;
namespace ash::floating_sso {
class FloatingSsoService : public KeyedService,
public network::mojom::CookieChangeListener,
public FloatingSsoSyncBridge::Observer {
public:
using CookieManagerGetter =
base::RepeatingCallback<network::mojom::CookieManager*()>;
FloatingSsoService(PrefService* prefs,
std::unique_ptr<FloatingSsoSyncBridge> bridge,
CookieManagerGetter cookie_manager_getter);
FloatingSsoService(const FloatingSsoService&) = delete;
FloatingSsoService& operator=(const FloatingSsoService&) = delete;
~FloatingSsoService() override;
void Shutdown() override;
void OnCookieChange(const net::CookieChangeInfo& change) override;
void OnCookiesAddedOrUpdatedRemotely(
const std::vector<net::CanonicalCookie>& cookies) override;
void OnCookiesRemovedRemotely(
const std::vector<net::CanonicalCookie>& cookies) override;
bool IsFloatingSsoEnabled();
void RunWhenCookiesAreReady(base::OnceClosure callback);
void RunWhenCookiesAreReadyOnFirstSync(base::OnceClosure callback);
base::WeakPtr<syncer::DataTypeControllerDelegate> GetControllerDelegate();
void MarkToNotOverride(const net::CanonicalCookie& cookie);
bool ShouldSyncCookiesForUrl(const GURL& url) const;
FloatingSsoSyncBridge* GetBridgeForTesting() { return bridge_.get(); }
bool IsBoundToCookieManagerForTesting() { return receiver_.is_bound(); }
private:
void RegisterPolicyListeners();
void UpdateUrlMatchers();
void StartOrStop();
void MaybeStartListening();
void StopListening();
void BindToCookieManager();
void OnCookiesLoaded(const net::CookieList& cookies);
bool ShouldSyncCookie(const net::CanonicalCookie& cookie) const;
bool ShouldSyncSessionCookies() const;
void OnConnectionError();
bool IsDomainAllowed(const GURL& url) const;
void OnCookieSet(net::CookieAccessResult result);
void OnCookieDeleted(bool success);
void DecrementChangesCountAndMaybeNotify();
raw_ptr<PrefService> prefs_ = nullptr;
CookieManagerGetter cookie_manager_getter_;
std::unique_ptr<FloatingSsoSyncBridge> bridge_;
base::ScopedObservation<FloatingSsoSyncBridge,
FloatingSsoSyncBridge::Observer>
scoped_observation_{this};
std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_;
bool fetch_accumulated_cookies_ = true;
int changes_in_progress_count_ = 0;
base::OnceClosure on_no_changes_in_progress_callback_;
mojo::Receiver<network::mojom::CookieChangeListener> receiver_{this};
std::unique_ptr<url_matcher::URLMatcher> block_url_matcher_;
std::unique_ptr<url_matcher::URLMatcher> except_url_matcher_;
};
}
#endif