Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / chromeos / login / signin / token_handle_fetcher.cc
blob3f79988b7d29ed7c08daa862fc33174f1beab686
1 // Copyright 2015 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/chromeos/login/signin/token_handle_fetcher.h"
7 #include "base/metrics/histogram_macros.h"
8 #include "chrome/browser/chromeos/login/signin/token_handle_util.h"
9 #include "chrome/browser/chromeos/profiles/profile_helper.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
12 #include "chrome/browser/signin/signin_manager_factory.h"
13 #include "chrome/browser/signin/signin_manager_factory.h"
14 #include "components/keyed_service/content/browser_context_keyed_service_shutdown_notifier_factory.h"
15 #include "components/signin/core/browser/profile_oauth2_token_service.h"
16 #include "components/signin/core/browser/signin_manager.h"
17 #include "google_apis/gaia/gaia_constants.h"
19 namespace {
20 const int kMaxRetries = 3;
22 class ShutdownNotifierFactory
23 : public BrowserContextKeyedServiceShutdownNotifierFactory {
24 public:
25 static ShutdownNotifierFactory* GetInstance() {
26 return base::Singleton<ShutdownNotifierFactory>::get();
29 private:
30 friend struct base::DefaultSingletonTraits<ShutdownNotifierFactory>;
32 ShutdownNotifierFactory()
33 : BrowserContextKeyedServiceShutdownNotifierFactory(
34 "TokenHandleFetcher") {
35 DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance());
37 ~ShutdownNotifierFactory() override {}
39 DISALLOW_COPY_AND_ASSIGN(ShutdownNotifierFactory);
42 } // namespace
44 TokenHandleFetcher::TokenHandleFetcher(TokenHandleUtil* util,
45 const user_manager::UserID& user_id)
46 : OAuth2TokenService::Consumer("user_session_manager"),
47 token_handle_util_(util),
48 user_id_(user_id),
49 token_service_(nullptr),
50 waiting_for_refresh_token_(false),
51 profile_(nullptr),
52 tokeninfo_response_start_time_(base::TimeTicks()) {
55 TokenHandleFetcher::~TokenHandleFetcher() {
56 if (waiting_for_refresh_token_)
57 token_service_->RemoveObserver(this);
60 void TokenHandleFetcher::BackfillToken(Profile* profile,
61 const TokenFetchingCallback& callback) {
62 profile_ = profile;
63 callback_ = callback;
65 token_service_ = ProfileOAuth2TokenServiceFactory::GetForProfile(profile);
66 SigninManagerBase* signin_manager =
67 SigninManagerFactory::GetForProfile(profile);
68 std::string account_id = signin_manager->GetAuthenticatedAccountId();
69 if (!token_service_->RefreshTokenIsAvailable(account_id)) {
70 account_without_token_ = account_id;
71 profile_shutdown_notification_ =
72 ShutdownNotifierFactory::GetInstance()->Get(profile)->Subscribe(
73 base::Bind(&TokenHandleFetcher::OnProfileDestroyed,
74 base::Unretained(this)));
76 token_service_->AddObserver(this);
77 waiting_for_refresh_token_ = true;
78 return;
80 RequestAccessToken(account_id);
83 void TokenHandleFetcher::OnRefreshTokenAvailable(
84 const std::string& account_id) {
85 if (account_without_token_ != account_id)
86 return;
87 waiting_for_refresh_token_ = false;
88 token_service_->RemoveObserver(this);
89 RequestAccessToken(account_id);
92 void TokenHandleFetcher::RequestAccessToken(const std::string& account_id) {
93 OAuth2TokenService::ScopeSet scopes;
94 scopes.insert(GaiaConstants::kOAuth1LoginScope);
95 oauth2_access_token_request_ =
96 token_service_->StartRequest(account_id, scopes, this);
99 void TokenHandleFetcher::OnGetTokenSuccess(
100 const OAuth2TokenService::Request* request,
101 const std::string& access_token,
102 const base::Time& expiration_time) {
103 oauth2_access_token_request_.reset();
104 FillForAccessToken(access_token);
107 void TokenHandleFetcher::OnGetTokenFailure(
108 const OAuth2TokenService::Request* request,
109 const GoogleServiceAuthError& error) {
110 oauth2_access_token_request_.reset();
111 LOG(ERROR) << "Could not get access token to backfill token handler"
112 << error.ToString();
113 callback_.Run(user_id_, false);
116 void TokenHandleFetcher::FillForNewUser(const std::string& access_token,
117 const TokenFetchingCallback& callback) {
118 profile_ = chromeos::ProfileHelper::Get()->GetSigninProfile();
119 callback_ = callback;
120 FillForAccessToken(access_token);
123 void TokenHandleFetcher::FillForAccessToken(const std::string& access_token) {
124 if (!gaia_client_.get())
125 gaia_client_.reset(
126 new gaia::GaiaOAuthClient(profile_->GetRequestContext()));
127 tokeninfo_response_start_time_ = base::TimeTicks::Now();
128 gaia_client_->GetTokenInfo(access_token, kMaxRetries, this);
131 void TokenHandleFetcher::OnOAuthError() {
132 callback_.Run(user_id_, false);
135 void TokenHandleFetcher::OnNetworkError(int response_code) {
136 callback_.Run(user_id_, false);
139 void TokenHandleFetcher::OnGetTokenInfoResponse(
140 scoped_ptr<base::DictionaryValue> token_info) {
141 bool success = false;
142 if (!token_info->HasKey("error")) {
143 std::string handle;
144 if (token_info->GetString("token_handle", &handle)) {
145 success = true;
146 token_handle_util_->StoreTokenHandle(user_id_, handle);
149 const base::TimeDelta duration =
150 base::TimeTicks::Now() - tokeninfo_response_start_time_;
151 UMA_HISTOGRAM_TIMES("Login.TokenObtainResponseTime", duration);
152 callback_.Run(user_id_, success);
155 void TokenHandleFetcher::OnProfileDestroyed() {
156 callback_.Run(user_id_, false);