| // Copyright 2014 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_GCM_DRIVER_ACCOUNT_TRACKER_H_ |
| #define COMPONENTS_GCM_DRIVER_ACCOUNT_TRACKER_H_ |
| |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/memory/scoped_refptr.h" |
| #include "base/observer_list.h" |
| #include "google_apis/gaia/gaia_oauth_client.h" |
| #include "services/identity/public/cpp/access_token_fetcher.h" |
| #include "services/identity/public/cpp/identity_manager.h" |
| |
| class GoogleServiceAuthError; |
| |
| namespace network { |
| class SharedURLLoaderFactory; |
| } |
| |
| namespace gcm { |
| |
| struct AccountIds { |
| std::string account_key; // The account ID used by OAuth2TokenService. |
| std::string gaia; |
| std::string email; |
| }; |
| |
| class AccountIdFetcher; |
| |
| // The AccountTracker keeps track of what accounts exist on the |
| // profile and the state of their credentials. The tracker fetches the |
| // gaia ID of each account it knows about. |
| // |
| // The AccountTracker maintains these invariants: |
| // 1. Events are only fired after the gaia ID has been fetched. |
| // 2. Add/Remove and SignIn/SignOut pairs are always generated in order. |
| // 3. SignIn follows Add, and there will be a SignOut between SignIn & Remove. |
| // 4. If there is no primary account, there are no other accounts. |
| class AccountTracker : public identity::IdentityManager::Observer { |
| public: |
| AccountTracker( |
| identity::IdentityManager* identity_manager, |
| scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); |
| ~AccountTracker() override; |
| |
| class Observer { |
| public: |
| virtual void OnAccountSignInChanged(const AccountIds& ids, |
| bool is_signed_in) = 0; |
| }; |
| |
| void Shutdown(); |
| |
| void AddObserver(Observer* observer); |
| void RemoveObserver(Observer* observer); |
| |
| // Returns the list of accounts that are signed in, and for which gaia IDs |
| // have been fetched. The primary account for the profile will be first |
| // in the vector. Additional accounts will be in order of their gaia IDs. |
| std::vector<AccountIds> GetAccounts() const; |
| |
| // Indicates if all user information has been fetched. If the result is false, |
| // there are still unfinished fetchers. |
| virtual bool IsAllUserInfoFetched() const; |
| |
| private: |
| friend class AccountIdFetcher; |
| |
| struct AccountState { |
| AccountIds ids; |
| bool is_signed_in; |
| }; |
| |
| // identity::IdentityManager::Observer implementation. |
| void OnPrimaryAccountSet(const AccountInfo& primary_account_info) override; |
| void OnPrimaryAccountCleared( |
| const AccountInfo& previous_primary_account_info) override; |
| void OnRefreshTokenUpdatedForAccount( |
| const AccountInfo& account_info) override; |
| void OnRefreshTokenRemovedForAccount(const std::string& account_id) override; |
| |
| void OnUserInfoFetchSuccess(AccountIdFetcher* fetcher, |
| const std::string& gaia_id); |
| void OnUserInfoFetchFailure(AccountIdFetcher* fetcher); |
| |
| void NotifySignInChanged(const AccountState& account); |
| |
| void UpdateSignInState(const std::string& account_key, bool is_signed_in); |
| |
| void StartTrackingAccount(const std::string& account_key); |
| |
| // Note: |account_key| is passed by value here, because the original |
| // object may be stored in |accounts_| and if so, it will be destroyed |
| // after erasing the key from the map. |
| void StopTrackingAccount(const std::string account_key); |
| |
| void StopTrackingAllAccounts(); |
| void StartFetchingUserInfo(const std::string& account_key); |
| void DeleteFetcher(AccountIdFetcher* fetcher); |
| |
| identity::IdentityManager* identity_manager_; |
| scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; |
| std::map<std::string, std::unique_ptr<AccountIdFetcher>> user_info_requests_; |
| std::map<std::string, AccountState> accounts_; |
| base::ObserverList<Observer>::Unchecked observer_list_; |
| bool shutdown_called_; |
| }; |
| |
| class AccountIdFetcher : public gaia::GaiaOAuthClient::Delegate { |
| public: |
| AccountIdFetcher( |
| identity::IdentityManager* identity_manager, |
| scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, |
| AccountTracker* tracker, |
| const std::string& account_key); |
| ~AccountIdFetcher() override; |
| |
| const std::string& account_key() { return account_key_; } |
| |
| void Start(); |
| |
| void AccessTokenFetched(GoogleServiceAuthError error, |
| identity::AccessTokenInfo access_token_info); |
| |
| // gaia::GaiaOAuthClient::Delegate implementation. |
| void OnGetUserIdResponse(const std::string& gaia_id) override; |
| void OnOAuthError() override; |
| void OnNetworkError(int response_code) override; |
| |
| private: |
| identity::IdentityManager* identity_manager_; |
| scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; |
| AccountTracker* tracker_; |
| const std::string account_key_; |
| |
| std::unique_ptr<identity::AccessTokenFetcher> access_token_fetcher_; |
| std::unique_ptr<gaia::GaiaOAuthClient> gaia_oauth_client_; |
| }; |
| |
| } // namespace gcm |
| |
| #endif // COMPONENTS_GCM_DRIVER_ACCOUNT_TRACKER_H_ |