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/common/pref_names.h"
13 #include "content/public/browser/notification_service.h"
14 #include "google_apis/gaia/gaia_oauth_client.h"
16 // TODO(guohui): this class should be moved to a more generic place for reuse.
17 class SigninAccountIdHelper::AccountIdFetcher
18 : public OAuth2TokenService::Consumer
,
19 public gaia::GaiaOAuthClient::Delegate
{
21 AccountIdFetcher(Profile
* profile
,
22 SigninAccountIdHelper
* signin_account_id_helper
);
23 virtual ~AccountIdFetcher();
25 // OAuth2TokenService::Consumer implementation.
26 virtual void OnGetTokenSuccess(const OAuth2TokenService::Request
* request
,
27 const std::string
& access_token
,
28 const base::Time
& expiration_time
) OVERRIDE
;
29 virtual void OnGetTokenFailure(const OAuth2TokenService::Request
* request
,
30 const GoogleServiceAuthError
& error
) OVERRIDE
;
32 // gaia::GaiaOAuthClient::Delegate implementation.
33 virtual void OnGetUserIdResponse(const std::string
& gaia_id
) OVERRIDE
;
34 virtual void OnOAuthError() OVERRIDE
;
35 virtual void OnNetworkError(int response_code
) OVERRIDE
;
41 SigninAccountIdHelper
* signin_account_id_helper_
;
43 scoped_ptr
<OAuth2TokenService::Request
> login_token_request_
;
44 scoped_ptr
<gaia::GaiaOAuthClient
> gaia_oauth_client_
;
46 DISALLOW_COPY_AND_ASSIGN(AccountIdFetcher
);
49 SigninAccountIdHelper::AccountIdFetcher::AccountIdFetcher(
51 SigninAccountIdHelper
* signin_account_id_helper
)
52 : OAuth2TokenService::Consumer("account_id_fetcher"),
54 signin_account_id_helper_(signin_account_id_helper
) {
58 SigninAccountIdHelper::AccountIdFetcher::~AccountIdFetcher() {}
60 void SigninAccountIdHelper::AccountIdFetcher::Start() {
61 ProfileOAuth2TokenService
* service
=
62 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
);
63 login_token_request_
= service
->StartRequest(
64 service
->GetPrimaryAccountId(), OAuth2TokenService::ScopeSet(), this);
67 void SigninAccountIdHelper::AccountIdFetcher::OnGetTokenSuccess(
68 const OAuth2TokenService::Request
* request
,
69 const std::string
& access_token
,
70 const base::Time
& expiration_time
) {
71 DCHECK_EQ(request
, login_token_request_
.get());
73 gaia_oauth_client_
.reset(
74 new gaia::GaiaOAuthClient(profile_
->GetRequestContext()));
76 const int kMaxGetUserIdRetries
= 3;
77 gaia_oauth_client_
->GetUserId(access_token
, kMaxGetUserIdRetries
, this);
80 void SigninAccountIdHelper::AccountIdFetcher::OnGetTokenFailure(
81 const OAuth2TokenService::Request
* request
,
82 const GoogleServiceAuthError
& error
) {
83 VLOG(1) << "OnGetTokenFailure: " << error
.error_message();
84 DCHECK_EQ(request
, login_token_request_
.get());
85 signin_account_id_helper_
->OnPrimaryAccountIdFetched("");
88 void SigninAccountIdHelper::AccountIdFetcher::OnGetUserIdResponse(
89 const std::string
& account_id
) {
90 signin_account_id_helper_
->OnPrimaryAccountIdFetched(account_id
);
93 void SigninAccountIdHelper::AccountIdFetcher::OnOAuthError() {
94 VLOG(1) << "OnOAuthError";
97 void SigninAccountIdHelper::AccountIdFetcher::OnNetworkError(
99 VLOG(1) << "OnNetworkError " << response_code
;
102 SigninAccountIdHelper::SigninAccountIdHelper(Profile
* profile
)
103 : profile_(profile
) {
104 registrar_
.Add(this, chrome::NOTIFICATION_GOOGLE_SIGNED_OUT
,
105 content::Source
<Profile
>(profile_
));
107 ProfileOAuth2TokenService
* token_service
=
108 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
);
109 std::string primary_email
= token_service
->GetPrimaryAccountId();
110 if (!primary_email
.empty() &&
111 token_service
->RefreshTokenIsAvailable(primary_email
) &&
112 !disable_for_test_
) {
113 id_fetcher_
.reset(new AccountIdFetcher(profile_
, this));
115 token_service
->AddObserver(this);
118 SigninAccountIdHelper::~SigninAccountIdHelper() {
119 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
)->
120 RemoveObserver(this);
123 void SigninAccountIdHelper::Observe(
125 const content::NotificationSource
& source
,
126 const content::NotificationDetails
& details
) {
127 if (type
== chrome::NOTIFICATION_GOOGLE_SIGNED_OUT
)
128 profile_
->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId
);
131 void SigninAccountIdHelper::OnRefreshTokenAvailable(const std::string
& email
) {
132 ProfileOAuth2TokenService
* service
=
133 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_
);
134 if (email
== service
->GetPrimaryAccountId()) {
135 std::string current_account_id
=
136 profile_
->GetPrefs()->GetString(prefs::kGoogleServicesUserAccountId
);
137 if (current_account_id
.empty() && !disable_for_test_
) {
138 id_fetcher_
.reset(new AccountIdFetcher(profile_
, this));
143 void SigninAccountIdHelper::OnPrimaryAccountIdFetched(
144 const std::string
& account_id
) {
145 if (!account_id
.empty()) {
146 profile_
->GetPrefs()->SetString(
147 prefs::kGoogleServicesUserAccountId
, account_id
);
152 bool SigninAccountIdHelper::disable_for_test_
= false;
155 void SigninAccountIdHelper::SetDisableForTest(bool disable_for_test
) {
156 disable_for_test_
= disable_for_test
;