Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: chrome/browser/chromeos/arc/arc_auth_context.cc

Issue 2887093003: arc: Implement retry logic for transient errors (Closed)
Patch Set: nits Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/chromeos/arc/arc_auth_context.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/chromeos/arc/arc_auth_context.h" 5 #include "chrome/browser/chromeos/arc/arc_auth_context.h"
6 6
7 #include "base/callback_helpers.h" 7 #include "base/callback_helpers.h"
8 #include "base/strings/stringprintf.h" 8 #include "base/strings/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/chromeos/arc/arc_support_host.h" 10 #include "chrome/browser/chromeos/arc/arc_support_host.h"
11 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 12 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
13 #include "chrome/browser/signin/signin_manager_factory.h" 13 #include "chrome/browser/signin/signin_manager_factory.h"
14 #include "chrome/browser/signin/signin_ui_util.h" 14 #include "chrome/browser/signin/signin_ui_util.h"
15 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" 15 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
16 #include "components/signin/core/browser/profile_oauth2_token_service.h" 16 #include "components/signin/core/browser/profile_oauth2_token_service.h"
17 #include "components/signin/core/browser/signin_manager_base.h" 17 #include "components/signin/core/browser/signin_manager_base.h"
18 #include "content/public/browser/browser_context.h" 18 #include "content/public/browser/browser_context.h"
19 #include "content/public/browser/storage_partition.h" 19 #include "content/public/browser/storage_partition.h"
20 #include "content/public/common/url_constants.h" 20 #include "content/public/common/url_constants.h"
21 #include "google_apis/gaia/gaia_auth_fetcher.h" 21 #include "google_apis/gaia/gaia_auth_fetcher.h"
22 #include "google_apis/gaia/gaia_constants.h" 22 #include "google_apis/gaia/gaia_constants.h"
23 23
24 namespace arc { 24 namespace arc {
25 25
26 namespace { 26 namespace {
27 27
28 constexpr int kMaxRetryAttempts = 3;
29
28 constexpr base::TimeDelta kRefreshTokenTimeout = 30 constexpr base::TimeDelta kRefreshTokenTimeout =
29 base::TimeDelta::FromSeconds(10); 31 base::TimeDelta::FromSeconds(10);
30 32
33 constexpr base::TimeDelta kRetryTimeout = base::TimeDelta::FromSeconds(10);
34
31 } // namespace 35 } // namespace
32 36
33 ArcAuthContext::ArcAuthContext(Profile* profile) { 37 ArcAuthContext::ArcAuthContext(Profile* profile) {
34 // Reuse storage used in ARC OptIn platform app. 38 // Reuse storage used in ARC OptIn platform app.
35 const std::string site_url = 39 const std::string site_url =
36 base::StringPrintf("%s://%s/persist?%s", content::kGuestScheme, 40 base::StringPrintf("%s://%s/persist?%s", content::kGuestScheme,
37 kPlayStoreAppId, ArcSupportHost::kStorageId); 41 kPlayStoreAppId, ArcSupportHost::kStorageId);
38 storage_partition_ = content::BrowserContext::GetStoragePartitionForSite( 42 storage_partition_ = content::BrowserContext::GetStoragePartitionForSite(
39 profile, GURL(site_url)); 43 profile, GURL(site_url));
40 CHECK(storage_partition_); 44 CHECK(storage_partition_);
(...skipping 15 matching lines...) Expand all
56 60
57 void ArcAuthContext::Prepare(const PrepareCallback& callback) { 61 void ArcAuthContext::Prepare(const PrepareCallback& callback) {
58 if (context_prepared_) { 62 if (context_prepared_) {
59 callback.Run(storage_partition_->GetURLRequestContext()); 63 callback.Run(storage_partition_->GetURLRequestContext());
60 return; 64 return;
61 } 65 }
62 66
63 callback_ = callback; 67 callback_ = callback;
64 token_service_->RemoveObserver(this); 68 token_service_->RemoveObserver(this);
65 refresh_token_timeout_.Stop(); 69 refresh_token_timeout_.Stop();
70 ResetFetchers();
66 71
67 if (!token_service_->RefreshTokenIsAvailable(account_id_)) { 72 if (!token_service_->RefreshTokenIsAvailable(account_id_)) {
68 token_service_->AddObserver(this); 73 token_service_->AddObserver(this);
69 refresh_token_timeout_.Start(FROM_HERE, kRefreshTokenTimeout, this, 74 refresh_token_timeout_.Start(FROM_HERE, kRefreshTokenTimeout, this,
70 &ArcAuthContext::OnRefreshTokenTimeout); 75 &ArcAuthContext::OnRefreshTokenTimeout);
71 return; 76 return;
72 } 77 }
73 78
79 retry_attempt_count_ = 0;
xiyuan 2017/05/17 22:09:16 Do we add this before the StartFetchers() call in
khmel 2017/05/17 22:43:55 Good point. Moved here up.
74 StartFetchers(); 80 StartFetchers();
75 } 81 }
76 82
77 void ArcAuthContext::OnRefreshTokenAvailable(const std::string& account_id) { 83 void ArcAuthContext::OnRefreshTokenAvailable(const std::string& account_id) {
78 if (account_id != account_id_) 84 if (account_id != account_id_)
79 return; 85 return;
80 OnRefreshTokensLoaded(); 86 OnRefreshTokensLoaded();
81 } 87 }
82 88
83 void ArcAuthContext::OnRefreshTokensLoaded() { 89 void ArcAuthContext::OnRefreshTokensLoaded() {
(...skipping 10 matching lines...) Expand all
94 100
95 void ArcAuthContext::StartFetchers() { 101 void ArcAuthContext::StartFetchers() {
96 DCHECK(!refresh_token_timeout_.IsRunning()); 102 DCHECK(!refresh_token_timeout_.IsRunning());
97 ResetFetchers(); 103 ResetFetchers();
98 ubertoken_fetcher_.reset( 104 ubertoken_fetcher_.reset(
99 new UbertokenFetcher(token_service_, this, GaiaConstants::kChromeOSSource, 105 new UbertokenFetcher(token_service_, this, GaiaConstants::kChromeOSSource,
100 storage_partition_->GetURLRequestContext())); 106 storage_partition_->GetURLRequestContext()));
101 ubertoken_fetcher_->StartFetchingToken(account_id_); 107 ubertoken_fetcher_->StartFetchingToken(account_id_);
102 } 108 }
103 109
110 void ArcAuthContext::ResetFetchers() {
111 merger_fetcher_.reset();
112 ubertoken_fetcher_.reset();
113 retry_timeout_.Stop();
114 }
115
116 void ArcAuthContext::OnFetcherError(const GoogleServiceAuthError& error) {
117 ResetFetchers();
118 DCHECK(error.state() != GoogleServiceAuthError::NONE);
119 if (error.IsTransientError()) {
120 if (retry_attempt_count_ < kMaxRetryAttempts) {
121 ++retry_attempt_count_;
xiyuan 2017/05/17 22:09:16 Not needed for this CL but do you want to use net:
khmel 2017/05/17 22:43:55 Nice example. Thanks
122 LOG(WARNING) << "Found transient error. Retry attempt "
123 << retry_attempt_count_;
124 refresh_token_timeout_.Start(FROM_HERE, kRetryTimeout, this,
125 &ArcAuthContext::StartFetchers);
126 return;
127 }
128 LOG(WARNING) << "Too many transient errors. Stop retrying.";
129 }
130 base::ResetAndReturn(&callback_).Run(nullptr);
131 }
132
104 void ArcAuthContext::OnUbertokenSuccess(const std::string& token) { 133 void ArcAuthContext::OnUbertokenSuccess(const std::string& token) {
105 ResetFetchers(); 134 ResetFetchers();
106 merger_fetcher_.reset( 135 merger_fetcher_.reset(
107 new GaiaAuthFetcher(this, GaiaConstants::kChromeOSSource, 136 new GaiaAuthFetcher(this, GaiaConstants::kChromeOSSource,
108 storage_partition_->GetURLRequestContext())); 137 storage_partition_->GetURLRequestContext()));
109 merger_fetcher_->StartMergeSession(token, std::string()); 138 merger_fetcher_->StartMergeSession(token, std::string());
110 } 139 }
111 140
112 void ArcAuthContext::OnUbertokenFailure(const GoogleServiceAuthError& error) { 141 void ArcAuthContext::OnUbertokenFailure(const GoogleServiceAuthError& error) {
113 LOG(WARNING) << "Failed to get ubertoken " << error.ToString() << "."; 142 LOG(WARNING) << "Failed to get ubertoken " << error.ToString() << ".";
114 ResetFetchers(); 143 OnFetcherError(error);
115 base::ResetAndReturn(&callback_).Run(nullptr);
116 } 144 }
117 145
118 void ArcAuthContext::OnMergeSessionSuccess(const std::string& data) { 146 void ArcAuthContext::OnMergeSessionSuccess(const std::string& data) {
147 if (retry_attempt_count_)
148 VLOG(1) << "Auth context was successfully prepared after retry.";
xiyuan 2017/05/17 22:09:16 nit: VLOG_IF(1, retry_attempt_count_) << ...
khmel 2017/05/17 22:43:55 Done.
119 context_prepared_ = true; 149 context_prepared_ = true;
120 ResetFetchers(); 150 ResetFetchers();
121 base::ResetAndReturn(&callback_) 151 base::ResetAndReturn(&callback_)
122 .Run(storage_partition_->GetURLRequestContext()); 152 .Run(storage_partition_->GetURLRequestContext());
123 } 153 }
124 154
125 void ArcAuthContext::OnMergeSessionFailure( 155 void ArcAuthContext::OnMergeSessionFailure(
126 const GoogleServiceAuthError& error) { 156 const GoogleServiceAuthError& error) {
127 LOG(WARNING) << "Failed to merge gaia session " << error.ToString() << "."; 157 LOG(WARNING) << "Failed to merge gaia session " << error.ToString() << ".";
128 ResetFetchers(); 158 OnFetcherError(error);
129 base::ResetAndReturn(&callback_).Run(nullptr);
130 }
131
132 void ArcAuthContext::ResetFetchers() {
133 merger_fetcher_.reset();
134 ubertoken_fetcher_.reset();
135 } 159 }
136 160
137 } // namespace arc 161 } // namespace arc
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/arc/arc_auth_context.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698