Home | History | Annotate | Download | only in gcm
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_SERVICES_GCM_GCM_ACCOUNT_TRACKER_H_
      6 #define CHROME_BROWSER_SERVICES_GCM_GCM_ACCOUNT_TRACKER_H_
      7 
      8 #include <map>
      9 #include <string>
     10 
     11 #include "base/memory/scoped_vector.h"
     12 #include "google_apis/gaia/account_tracker.h"
     13 #include "google_apis/gaia/oauth2_token_service.h"
     14 
     15 namespace gcm {
     16 
     17 // Class for reporting back which accounts are signed into. It is only meant to
     18 // be used when the user is signed into sync.
     19 class GCMAccountTracker : public gaia::AccountTracker::Observer,
     20                           public OAuth2TokenService::Consumer {
     21  public:
     22   // State of the account.
     23   // Allowed transitions:
     24   // TOKEN_NEEDED - account info was created.
     25   // TOKEN_NEEDED -> GETTING_TOKEN - access token was requested.
     26   // GETTING_TOKEN -> TOKEN_NEEDED - access token fetching failed.
     27   // GETTING_TOKEN -> TOKEN_PRESENT - access token fetching succeeded.
     28   // GETTING_TOKEN -> ACCOUNT_REMOVED - account was removed.
     29   // TOKEN_NEEDED -> ACCOUNT_REMOVED - account was removed.
     30   // TOKEN_PRESENT -> ACCOUNT_REMOVED - account was removed.
     31   enum AccountState {
     32     TOKEN_NEEDED,     // Needs a token (AccountInfo was recently created or
     33                       // token request failed).
     34     GETTING_TOKEN,    // There is a pending token request.
     35     TOKEN_PRESENT,    // We have a token for the account.
     36     ACCOUNT_REMOVED,  // Account was removed, and we didn't report it yet.
     37   };
     38 
     39   // Stores necessary account information and state of token fetching.
     40   struct AccountInfo {
     41     AccountInfo(const std::string& email, AccountState state);
     42     ~AccountInfo();
     43 
     44     // Email address of the tracked account.
     45     std::string email;
     46     // OAuth2 access token, when |state| is TOKEN_PRESENT.
     47     std::string access_token;
     48     // Status of the token fetching.
     49     AccountState state;
     50   };
     51 
     52   // Callback for the GetAccountsForCheckin call. |account_tokens| maps email
     53   // addresses to OAuth2 access tokens.
     54   typedef base::Callback<void(const std::map<std::string, std::string>&
     55                                   account_tokens)> UpdateAccountsCallback;
     56 
     57   // Creates an instance of GCMAccountTracker. |account_tracker| is used to
     58   // deliver information about the account, while |callback| will be called
     59   // once all of the accounts have been fetched a necessary OAuth2 token, as
     60   // many times as the list of accounts is stable, meaning that all accounts
     61   // are known and there is no related activity in progress for them, like
     62   // fetching OAuth2 tokens.
     63   GCMAccountTracker(scoped_ptr<gaia::AccountTracker> account_tracker,
     64                     const UpdateAccountsCallback& callback);
     65   virtual ~GCMAccountTracker();
     66 
     67   // Shuts down the tracker ensuring a proper clean up. After Shutdown() is
     68   // called Start() and Stop() should no longer be used. Must be called before
     69   // destruction.
     70   void Shutdown();
     71 
     72   // Starts tracking accounts.
     73   void Start();
     74   // Stops tracking accounts. Cancels all of the pending token requests.
     75   void Stop();
     76 
     77  private:
     78   // Maps account keys to account states. Keyed by account_ids as used by
     79   // OAuth2TokenService.
     80   typedef std::map<std::string, AccountInfo> AccountInfos;
     81 
     82   // AccountTracker::Observer overrides.
     83   virtual void OnAccountAdded(const gaia::AccountIds& ids) OVERRIDE;
     84   virtual void OnAccountRemoved(const gaia::AccountIds& ids) OVERRIDE;
     85   virtual void OnAccountSignInChanged(const gaia::AccountIds& ids,
     86                                       bool is_signed_in) OVERRIDE;
     87 
     88   // OAuth2TokenService::Consumer overrides.
     89   virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
     90                                  const std::string& access_token,
     91                                  const base::Time& expiration_time) OVERRIDE;
     92   virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
     93                                  const GoogleServiceAuthError& error) OVERRIDE;
     94 
     95   // Report the list of accounts with OAuth2 tokens back using the |callback_|
     96   // function. If there are token requests in progress, do nothing.
     97   void CompleteCollectingTokens();
     98   // Deletes a token request. Should be called from OnGetTokenSuccess(..) or
     99   // OnGetTokenFailure(..).
    100   void DeleteTokenRequest(const OAuth2TokenService::Request* request);
    101   // Checks on all known accounts, and calls GetToken(..) for those with
    102   // |state == TOKEN_NEEDED|.
    103   void GetAllNeededTokens();
    104   // Starts fetching the OAuth2 token for the GCM group scope.
    105   void GetToken(AccountInfos::iterator& account_iter);
    106 
    107   // Handling of actual sign in and sign out for accounts.
    108   void OnAccountSignedIn(const gaia::AccountIds& ids);
    109   void OnAccountSignedOut(const gaia::AccountIds& ids);
    110 
    111   OAuth2TokenService* GetTokenService();
    112 
    113   // Account tracker.
    114   scoped_ptr<gaia::AccountTracker> account_tracker_;
    115 
    116   // Callback to be called after all of the account and OAuth2 tokens are
    117   // collected.
    118   UpdateAccountsCallback callback_;
    119 
    120   // State of the account.
    121   AccountInfos account_infos_;
    122 
    123   // Indicates whether shutdown has been called.
    124   bool shutdown_called_;
    125 
    126   ScopedVector<OAuth2TokenService::Request> pending_token_requests_;
    127 
    128   DISALLOW_COPY_AND_ASSIGN(GCMAccountTracker);
    129 };
    130 
    131 }  // namespace gcm
    132 
    133 #endif  // CHROME_BROWSER_SERVICES_GCM_GCM_ACCOUNT_TRACKER_H_
    134