1 // Copyright 2013 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.
5 #include "chrome/browser/signin/signin_account_id_helper.h"
7 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/chrome_notification_types.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/signin/profile_oauth2_token_service.h"
11 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
12 #include "chrome/browser/signin/signin_manager.h"
13 #include "chrome/common/pref_names.h"
14 #include "content/public/browser/notification_service.h"
15 #include "google_apis/gaia/gaia_oauth_client.h"
17 // TODO(guohui): this class should be moved to a more generic place for reuse.
18 class SigninAccountIdHelper::GaiaIdFetcher
19 : public OAuth2TokenService::Consumer,
20 public gaia::GaiaOAuthClient::Delegate {
22 GaiaIdFetcher(SigninManagerBase* signin_manager,
23 SigninAccountIdHelper* signin_account_id_helper);
24 virtual ~GaiaIdFetcher();
26 // OAuth2TokenService::Consumer implementation.
27 virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
28 const std::string& access_token,
29 const base::Time& expiration_time) OVERRIDE;
30 virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
31 const GoogleServiceAuthError& error) OVERRIDE;
33 // gaia::GaiaOAuthClient::Delegate implementation.
34 virtual void OnGetUserIdResponse(const std::string& gaia_id) OVERRIDE;
35 virtual void OnOAuthError() OVERRIDE;
36 virtual void OnNetworkError(int response_code) OVERRIDE;
41 SigninManagerBase* signin_manager_;
42 SigninAccountIdHelper* signin_account_id_helper_;
44 scoped_ptr<OAuth2TokenService::Request> login_token_request_;
45 scoped_ptr<gaia::GaiaOAuthClient> gaia_oauth_client_;
47 DISALLOW_COPY_AND_ASSIGN(GaiaIdFetcher);
50 SigninAccountIdHelper::GaiaIdFetcher::GaiaIdFetcher(
51 SigninManagerBase* signin_manager,
52 SigninAccountIdHelper* signin_account_id_helper)
53 : OAuth2TokenService::Consumer("gaia_id_fetcher"),
54 signin_manager_(signin_manager),
55 signin_account_id_helper_(signin_account_id_helper) {
59 SigninAccountIdHelper::GaiaIdFetcher::~GaiaIdFetcher() {}
61 void SigninAccountIdHelper::GaiaIdFetcher::Start() {
62 ProfileOAuth2TokenService* service =
63 ProfileOAuth2TokenServiceFactory::GetForProfile(
64 signin_manager_->profile());
65 OAuth2TokenService::ScopeSet scopes;
66 scopes.insert("https://www.googleapis.com/auth/userinfo.profile");
67 login_token_request_ = service->StartRequest(
68 signin_manager_->GetAuthenticatedAccountId(), scopes, this);
71 void SigninAccountIdHelper::GaiaIdFetcher::OnGetTokenSuccess(
72 const OAuth2TokenService::Request* request,
73 const std::string& access_token,
74 const base::Time& expiration_time) {
75 DCHECK_EQ(request, login_token_request_.get());
77 gaia_oauth_client_.reset(
78 new gaia::GaiaOAuthClient(
79 signin_manager_->profile()->GetRequestContext()));
81 const int kMaxGetUserIdRetries = 3;
82 gaia_oauth_client_->GetUserId(access_token, kMaxGetUserIdRetries, this);
85 void SigninAccountIdHelper::GaiaIdFetcher::OnGetTokenFailure(
86 const OAuth2TokenService::Request* request,
87 const GoogleServiceAuthError& error) {
88 VLOG(1) << "OnGetTokenFailure: " << error.error_message();
89 DCHECK_EQ(request, login_token_request_.get());
90 signin_account_id_helper_->OnPrimaryAccountIdFetched("");
93 void SigninAccountIdHelper::GaiaIdFetcher::OnGetUserIdResponse(
94 const std::string& gaia_id) {
95 signin_account_id_helper_->OnPrimaryAccountIdFetched(gaia_id);
98 void SigninAccountIdHelper::GaiaIdFetcher::OnOAuthError() {
99 VLOG(1) << "OnOAuthError";
102 void SigninAccountIdHelper::GaiaIdFetcher::OnNetworkError(
104 VLOG(1) << "OnNetworkError " << response_code;
107 SigninAccountIdHelper::SigninAccountIdHelper(SigninManagerBase* signin_manager)
108 : signin_manager_(signin_manager) {
109 DCHECK(signin_manager_);
110 registrar_.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNED_OUT,
111 content::Source<Profile>(signin_manager_->profile()));
113 ProfileOAuth2TokenService* token_service =
114 ProfileOAuth2TokenServiceFactory::GetForProfile(
115 signin_manager_->profile());
116 std::string primary_email = signin_manager_->GetAuthenticatedAccountId();
117 if (!primary_email.empty() &&
118 token_service->RefreshTokenIsAvailable(primary_email) &&
119 !disable_for_test_) {
120 id_fetcher_.reset(new GaiaIdFetcher(signin_manager_, this));
122 token_service->AddObserver(this);
125 SigninAccountIdHelper::~SigninAccountIdHelper() {
126 ProfileOAuth2TokenServiceFactory::GetForProfile(signin_manager_->profile())->
127 RemoveObserver(this);
130 void SigninAccountIdHelper::Observe(
132 const content::NotificationSource& source,
133 const content::NotificationDetails& details) {
134 if (type == chrome::NOTIFICATION_GOOGLE_SIGNED_OUT) {
135 signin_manager_->profile()->GetPrefs()->
136 ClearPref(prefs::kGoogleServicesUserAccountId);
140 void SigninAccountIdHelper::OnRefreshTokenAvailable(
141 const std::string& account_id) {
142 if (account_id == signin_manager_->GetAuthenticatedAccountId()) {
143 std::string current_gaia_id =
144 signin_manager_->profile()->GetPrefs()->
145 GetString(prefs::kGoogleServicesUserAccountId);
146 if (current_gaia_id.empty() && !disable_for_test_) {
147 id_fetcher_.reset(new GaiaIdFetcher(signin_manager_, this));
152 void SigninAccountIdHelper::OnPrimaryAccountIdFetched(
153 const std::string& gaia_id) {
154 if (!gaia_id.empty()) {
155 signin_manager_->profile()->GetPrefs()->SetString(
156 prefs::kGoogleServicesUserAccountId, gaia_id);
161 bool SigninAccountIdHelper::disable_for_test_ = false;
164 void SigninAccountIdHelper::SetDisableForTest(bool disable_for_test) {
165 disable_for_test_ = disable_for_test;