| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_ASH_ACCOUNT_MANAGER_ACCOUNT_APPS_AVAILABILITY_H_ |
| #define CHROME_BROWSER_ASH_ACCOUNT_MANAGER_ACCOUNT_APPS_AVAILABILITY_H_ |
| |
| #include "base/containers/flat_set.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/observer_list.h" |
| #include "base/scoped_observation.h" |
| #include "base/sequence_checker.h" |
| #include "components/account_manager_core/account.h" |
| #include "components/account_manager_core/account_manager_facade.h" |
| #include "components/keyed_service/core/keyed_service.h" |
| #include "components/prefs/pref_registry_simple.h" |
| #include "components/signin/public/identity_manager/identity_manager.h" |
| |
| namespace ash { |
| |
| // This class is tracking which accounts from `AccountManager` should be |
| // available in apps. Currently only availability in ARC++ is being tracked. |
| // ARC++ availability may be set just after account addition or when user |
| // changes it manually in OS Settings. |
| // There should be only one instance of this class, which is attached to the |
| // only regular Ash profile. The class should exist only if Account Manager |
| // exists (if `IsAccountManagerAvailable(profile)` is `true`). |
| class AccountAppsAvailability |
| : public KeyedService, |
| public account_manager::AccountManagerFacade::Observer, |
| public signin::IdentityManager::Observer { |
| public: |
| static const char kNumAccountsInArcMetricName[]; |
| static const char kPercentAccountsInArcMetricName[]; |
| |
| class Observer : public base::CheckedObserver { |
| public: |
| Observer() = default; |
| Observer(const Observer&) = delete; |
| Observer& operator=(const Observer&) = delete; |
| ~Observer() override = default; |
| |
| // Called when the account should become available in ARC |
| // (`SetIsAccountAvailableInArc` is called with `true`). Also called when |
| // the token of an account that is already available in ARC is updated. At |
| // the time of this call the `account`'s token is already updated / |
| // available in `IdentityManager`. |
| virtual void OnAccountAvailableInArc( |
| const account_manager::Account& account) {} |
| |
| // Called when the account becomes unavailable in ARC |
| // (`SetIsAccountAvailableInArc` is called with `false`). |
| // Also called when the account is removed from Account Manager. |
| virtual void OnAccountUnavailableInArc( |
| const account_manager::Account& account) {} |
| }; |
| |
| // The parameters are not owned pointers, and should outlive this class |
| // instance. |
| AccountAppsAvailability( |
| account_manager::AccountManagerFacade* account_manager_facade, |
| signin::IdentityManager* identity_manager, |
| PrefService* prefs); |
| ~AccountAppsAvailability() override; |
| |
| AccountAppsAvailability(const AccountAppsAvailability&) = delete; |
| AccountAppsAvailability& operator=(const AccountAppsAvailability&) = delete; |
| |
| static void RegisterPrefs(PrefRegistrySimple* registry); |
| |
| // Registers an observer. |
| void AddObserver(Observer* observer); |
| // Unregisters an observer that was registered using AddObserver. |
| void RemoveObserver(Observer* observer); |
| |
| // Set whether the specified account should be available in ARC. Only Gaia |
| // accounts are supported. |
| void SetIsAccountAvailableInArc(const account_manager::Account& account, |
| bool is_available); |
| |
| // Calls the `callback` with the set of accounts that should be |
| // available in ARC. |
| // If the class is not initialized yet (`IsInitialized()` is `false`), waits |
| // for initialization to complete. |
| void GetAccountsAvailableInArc( |
| base::OnceCallback<void(const base::flat_set<account_manager::Account>&)> |
| callback); |
| |
| // Returns `true` if the class is initialized. |
| bool IsInitialized() const; |
| |
| private: |
| // `KeyedService`: |
| void Shutdown() override; |
| |
| // `IdentityManager::Observer`: |
| void OnRefreshTokenUpdatedForAccount( |
| const CoreAccountInfo& account_info) override; |
| |
| // `AccountManagerFacade::Observer`: |
| void OnAccountUpserted(const account_manager::Account& account) override; |
| void OnAccountRemoved(const account_manager::Account& account) override; |
| void OnAuthErrorChanged(const account_manager::AccountKey& account, |
| const GoogleServiceAuthError& error) override; |
| |
| // Initialize the prefs: add all Gaia accounts from Account Manager with |
| // is_available_in_arc=true. |
| void InitAccountsAvailableInArcPref( |
| const std::vector<account_manager::Account>& accounts); |
| |
| // Report metrics (e.g. number of accounts in ARC). |
| void ReportMetrics(const std::vector<account_manager::Account>& accounts); |
| |
| // Call `GetAccounts` and find the account by `gaia_id`. Call the `callback` |
| // with the resulted account or with `nullopt` if requested account is not in |
| // Account Manager. |
| void FindAccountByGaiaId( |
| const GaiaId& gaia_id, |
| base::OnceCallback<void(const std::optional<account_manager::Account>&)> |
| callback); |
| |
| // Call `NotifyObservers` if account is not `nullopt`. |
| void MaybeNotifyObservers( |
| bool is_available_in_arc, |
| const std::optional<account_manager::Account>& account); |
| |
| // Call `OnAccountAvailableInArc` if `is_available_in_arc` is `true`. |
| // Otherwise call `OnAccountUnavailableInArc`. |
| void NotifyObservers(const account_manager::Account& account, |
| bool is_available_in_arc); |
| |
| bool is_initialized_ = false; |
| |
| // Callbacks waiting on class initialization. |
| std::vector<base::OnceClosure> initialization_callbacks_; |
| |
| // Non-owning pointers: |
| const raw_ptr<account_manager::AccountManagerFacade> account_manager_facade_; |
| const raw_ptr<signin::IdentityManager> identity_manager_; |
| const raw_ptr<PrefService> prefs_; |
| |
| // A list of observers registered via `AddObserver`. |
| base::ObserverList<Observer> observer_list_; |
| |
| // An observer for `IdentityManager`. Automatically deregisters when |
| // `this` is destructed. |
| base::ScopedObservation<signin::IdentityManager, |
| signin::IdentityManager::Observer> |
| identity_manager_observation_{this}; |
| |
| // An observer for `AccountManagerFacade`. Automatically deregisters when |
| // `this` is destructed. |
| base::ScopedObservation<account_manager::AccountManagerFacade, |
| account_manager::AccountManagerFacade::Observer> |
| account_manager_facade_observation_{this}; |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| base::WeakPtrFactory<AccountAppsAvailability> weak_factory_{this}; |
| }; |
| } // namespace ash |
| |
| #endif // CHROME_BROWSER_ASH_ACCOUNT_MANAGER_ACCOUNT_APPS_AVAILABILITY_H_ |