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.
5 #include "components/signin/core/browser/signin_account_id_helper.h"
7 #include "base/prefs/pref_service.h"
8 #include "base/profiler/scoped_tracker.h"
9 #include "components/signin/core/browser/profile_oauth2_token_service.h"
10 #include "components/signin/core/browser/signin_client.h"
11 #include "components/signin/core/common/signin_pref_names.h"
12 #include "google_apis/gaia/gaia_oauth_client.h"
14 // TODO(guohui): this class should be moved to a more generic place for reuse.
15 class SigninAccountIdHelper::GaiaIdFetcher
16 : public OAuth2TokenService::Consumer
,
17 public gaia::GaiaOAuthClient::Delegate
{
19 GaiaIdFetcher(SigninClient
* client
,
20 ProfileOAuth2TokenService
* token_service
,
21 SigninManagerBase
* signin_manager
,
22 SigninAccountIdHelper
* signin_account_id_helper
);
23 ~GaiaIdFetcher() override
;
25 // OAuth2TokenService::Consumer implementation.
26 void OnGetTokenSuccess(const OAuth2TokenService::Request
* request
,
27 const std::string
& access_token
,
28 const base::Time
& expiration_time
) override
;
29 void OnGetTokenFailure(const OAuth2TokenService::Request
* request
,
30 const GoogleServiceAuthError
& error
) override
;
32 // gaia::GaiaOAuthClient::Delegate implementation.
33 void OnGetUserIdResponse(const std::string
& gaia_id
) override
;
34 void OnOAuthError() override
;
35 void OnNetworkError(int response_code
) override
;
40 SigninClient
* client_
;
41 ProfileOAuth2TokenService
* token_service_
;
42 SigninManagerBase
* signin_manager_
;
43 SigninAccountIdHelper
* signin_account_id_helper_
;
45 scoped_ptr
<OAuth2TokenService::Request
> login_token_request_
;
46 scoped_ptr
<gaia::GaiaOAuthClient
> gaia_oauth_client_
;
48 DISALLOW_COPY_AND_ASSIGN(GaiaIdFetcher
);
51 SigninAccountIdHelper::GaiaIdFetcher::GaiaIdFetcher(
53 ProfileOAuth2TokenService
* token_service
,
54 SigninManagerBase
* signin_manager
,
55 SigninAccountIdHelper
* signin_account_id_helper
)
56 : OAuth2TokenService::Consumer("gaia_id_fetcher"),
58 token_service_(token_service
),
59 signin_manager_(signin_manager
),
60 signin_account_id_helper_(signin_account_id_helper
) {
64 SigninAccountIdHelper::GaiaIdFetcher::~GaiaIdFetcher() {}
66 void SigninAccountIdHelper::GaiaIdFetcher::Start() {
67 OAuth2TokenService::ScopeSet scopes
;
68 scopes
.insert("https://www.googleapis.com/auth/userinfo.profile");
69 login_token_request_
= token_service_
->StartRequest(
70 signin_manager_
->GetAuthenticatedAccountId(), scopes
, this);
73 void SigninAccountIdHelper::GaiaIdFetcher::OnGetTokenSuccess(
74 const OAuth2TokenService::Request
* request
,
75 const std::string
& access_token
,
76 const base::Time
& expiration_time
) {
77 DCHECK_EQ(request
, login_token_request_
.get());
79 gaia_oauth_client_
.reset(
80 new gaia::GaiaOAuthClient(client_
->GetURLRequestContext()));
82 const int kMaxGetUserIdRetries
= 3;
83 gaia_oauth_client_
->GetUserId(access_token
, kMaxGetUserIdRetries
, this);
86 void SigninAccountIdHelper::GaiaIdFetcher::OnGetTokenFailure(
87 const OAuth2TokenService::Request
* request
,
88 const GoogleServiceAuthError
& error
) {
89 VLOG(1) << "OnGetTokenFailure: " << error
.error_message();
90 DCHECK_EQ(request
, login_token_request_
.get());
91 signin_account_id_helper_
->OnPrimaryAccountIdFetched("");
94 void SigninAccountIdHelper::GaiaIdFetcher::OnGetUserIdResponse(
95 const std::string
& gaia_id
) {
96 signin_account_id_helper_
->OnPrimaryAccountIdFetched(gaia_id
);
99 void SigninAccountIdHelper::GaiaIdFetcher::OnOAuthError() {
100 VLOG(1) << "OnOAuthError";
103 void SigninAccountIdHelper::GaiaIdFetcher::OnNetworkError(int response_code
) {
104 VLOG(1) << "OnNetworkError " << response_code
;
107 SigninAccountIdHelper::SigninAccountIdHelper(
108 SigninClient
* client
,
109 ProfileOAuth2TokenService
* token_service
,
110 SigninManagerBase
* signin_manager
)
112 token_service_(token_service
),
113 signin_manager_(signin_manager
) {
115 DCHECK(token_service_
);
116 DCHECK(signin_manager_
);
117 signin_manager_
->AddObserver(this);
118 std::string primary_email
= signin_manager_
->GetAuthenticatedAccountId();
119 if (!primary_email
.empty() &&
120 token_service_
->RefreshTokenIsAvailable(primary_email
) &&
121 !disable_for_test_
) {
123 new GaiaIdFetcher(client_
, token_service_
, signin_manager_
, this));
125 token_service_
->AddObserver(this);
128 SigninAccountIdHelper::~SigninAccountIdHelper() {
129 signin_manager_
->RemoveObserver(this);
130 token_service_
->RemoveObserver(this);
133 void SigninAccountIdHelper::GoogleSignedOut(const std::string
& account_id
,
134 const std::string
& username
) {
135 client_
->GetPrefs()->ClearPref(prefs::kGoogleServicesUserAccountId
);
138 void SigninAccountIdHelper::OnRefreshTokenAvailable(
139 const std::string
& account_id
) {
140 // TODO(robliao): Remove ScopedTracker below once https://crbug.com/422460 is
142 tracked_objects::ScopedTracker
tracking_profile(
143 FROM_HERE_WITH_EXPLICIT_FUNCTION(
144 "422460 SigninAccountIdHelper::OnRefreshTokenAvailable"));
146 if (account_id
== signin_manager_
->GetAuthenticatedAccountId()) {
147 std::string current_gaia_id
=
148 client_
->GetPrefs()->GetString(prefs::kGoogleServicesUserAccountId
);
149 if (current_gaia_id
.empty() && !disable_for_test_
) {
151 new GaiaIdFetcher(client_
, token_service_
, signin_manager_
, this));
156 void SigninAccountIdHelper::OnPrimaryAccountIdFetched(
157 const std::string
& gaia_id
) {
158 if (!gaia_id
.empty()) {
159 client_
->GetPrefs()->SetString(prefs::kGoogleServicesUserAccountId
,
165 bool SigninAccountIdHelper::disable_for_test_
= false;
168 void SigninAccountIdHelper::SetDisableForTest(bool disable_for_test
) {
169 disable_for_test_
= disable_for_test
;