1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// found in the LICENSE file.
4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#ifndef CHROME_BROWSER_SERVICES_GCM_GCM_ACCOUNT_TRACKER_H_
6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#define CHROME_BROWSER_SERVICES_GCM_GCM_ACCOUNT_TRACKER_H_
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <map>
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <string>
10116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/memory/scoped_vector.h"
12116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "google_apis/gaia/account_tracker.h"
13116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "google_apis/gaia/oauth2_token_service.h"
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace gcm {
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// Class for reporting back which accounts are signed into. It is only meant to
18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// be used when the user is signed into sync.
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass GCMAccountTracker : public gaia::AccountTracker::Observer,
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          public OAuth2TokenService::Consumer {
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch public:
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // State of the account.
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Allowed transitions:
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TOKEN_NEEDED - account info was created.
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TOKEN_NEEDED -> GETTING_TOKEN - access token was requested.
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // GETTING_TOKEN -> TOKEN_NEEDED - access token fetching failed.
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // GETTING_TOKEN -> TOKEN_PRESENT - access token fetching succeeded.
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // GETTING_TOKEN -> ACCOUNT_REMOVED - account was removed.
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TOKEN_NEEDED -> ACCOUNT_REMOVED - account was removed.
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // TOKEN_PRESENT -> ACCOUNT_REMOVED - account was removed.
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  enum AccountState {
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TOKEN_NEEDED,     // Needs a token (AccountInfo was recently created or
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      // token request failed).
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GETTING_TOKEN,    // There is a pending token request.
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TOKEN_PRESENT,    // We have a token for the account.
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ACCOUNT_REMOVED,  // Account was removed, and we didn't report it yet.
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  };
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Stores necessary account information and state of token fetching.
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  struct AccountInfo {
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AccountInfo(const std::string& email, AccountState state);
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ~AccountInfo();
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Email address of the tracked account.
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string email;
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // OAuth2 access token, when |state| is TOKEN_PRESENT.
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    std::string access_token;
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Status of the token fetching.
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AccountState state;
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  };
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Callback for the GetAccountsForCheckin call. |account_tokens| maps email
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // addresses to OAuth2 access tokens.
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  typedef base::Callback<void(const std::map<std::string, std::string>&
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  account_tokens)> UpdateAccountsCallback;
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Creates an instance of GCMAccountTracker. |account_tracker| is used to
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // deliver information about the account, while |callback| will be called
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // once all of the accounts have been fetched a necessary OAuth2 token, as
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // many times as the list of accounts is stable, meaning that all accounts
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // are known and there is no related activity in progress for them, like
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // fetching OAuth2 tokens.
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GCMAccountTracker(scoped_ptr<gaia::AccountTracker> account_tracker,
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                    const UpdateAccountsCallback& callback);
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual ~GCMAccountTracker();
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Shuts down the tracker ensuring a proper clean up. After Shutdown() is
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // called Start() and Stop() should no longer be used. Must be called before
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // destruction.
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void Shutdown();
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Starts tracking accounts.
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void Start();
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Stops tracking accounts. Cancels all of the pending token requests.
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void Stop();
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch private:
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Maps account keys to account states. Keyed by account_ids as used by
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // OAuth2TokenService.
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  typedef std::map<std::string, AccountInfo> AccountInfos;
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // AccountTracker::Observer overrides.
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnAccountAdded(const gaia::AccountIds& ids) OVERRIDE;
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnAccountRemoved(const gaia::AccountIds& ids) OVERRIDE;
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnAccountSignInChanged(const gaia::AccountIds& ids,
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                      bool is_signed_in) OVERRIDE;
87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // OAuth2TokenService::Consumer overrides.
89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 const std::string& access_token,
91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 const base::Time& expiration_time) OVERRIDE;
92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 const GoogleServiceAuthError& error) OVERRIDE;
94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Report the list of accounts with OAuth2 tokens back using the |callback_|
96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // function. If there are token requests in progress, do nothing.
97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void CompleteCollectingTokens();
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Deletes a token request. Should be called from OnGetTokenSuccess(..) or
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // OnGetTokenFailure(..).
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void DeleteTokenRequest(const OAuth2TokenService::Request* request);
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Checks on all known accounts, and calls GetToken(..) for those with
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // |state == TOKEN_NEEDED|.
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void GetAllNeededTokens();
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Starts fetching the OAuth2 token for the GCM group scope.
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void GetToken(AccountInfos::iterator& account_iter);
106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Handling of actual sign in and sign out for accounts.
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnAccountSignedIn(const gaia::AccountIds& ids);
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnAccountSignedOut(const gaia::AccountIds& ids);
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  OAuth2TokenService* GetTokenService();
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Account tracker.
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<gaia::AccountTracker> account_tracker_;
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Callback to be called after all of the account and OAuth2 tokens are
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // collected.
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  UpdateAccountsCallback callback_;
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // State of the account.
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AccountInfos account_infos_;
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Indicates whether shutdown has been called.
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool shutdown_called_;
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ScopedVector<OAuth2TokenService::Request> pending_token_requests_;
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(GCMAccountTracker);
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch};
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace gcm
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif  // CHROME_BROWSER_SERVICES_GCM_GCM_ACCOUNT_TRACKER_H_
134