summaryrefslogtreecommitdiff
path: root/chromium/google_apis
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-05-15 10:20:33 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-05-15 10:28:57 +0000
commitd17ea114e5ef69ad5d5d7413280a13e6428098aa (patch)
tree2c01a75df69f30d27b1432467cfe7c1467a498da /chromium/google_apis
parent8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (diff)
downloadqtwebengine-chromium-d17ea114e5ef69ad5d5d7413280a13e6428098aa.tar.gz
BASELINE: Update Chromium to 67.0.3396.47
Change-Id: Idcb1341782e417561a2473eeecc82642dafda5b7 Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/google_apis')
-rw-r--r--chromium/google_apis/BUILD.gn2
-rw-r--r--chromium/google_apis/drive/drive_api_url_generator_unittest.cc7
-rw-r--r--chromium/google_apis/gaia/account_tracker.cc63
-rw-r--r--chromium/google_apis/gaia/account_tracker.h2
-rw-r--r--chromium/google_apis/gaia/account_tracker_unittest.cc121
-rw-r--r--chromium/google_apis/gaia/fake_gaia.cc3
-rw-r--r--chromium/google_apis/gaia/fake_gaia.h3
-rw-r--r--chromium/google_apis/gaia/fake_oauth2_token_service_delegate.cc12
-rw-r--r--chromium/google_apis/gaia/fake_oauth2_token_service_delegate.h8
-rw-r--r--chromium/google_apis/gaia/gaia_auth_consumer.h25
-rw-r--r--chromium/google_apis/gaia/gaia_auth_fetcher.cc58
-rw-r--r--chromium/google_apis/gaia/gaia_auth_fetcher_unittest.cc109
-rw-r--r--chromium/google_apis/gaia/google_service_auth_error.cc123
-rw-r--r--chromium/google_apis/gaia/google_service_auth_error.h41
-rw-r--r--chromium/google_apis/gaia/google_service_auth_error_unittest.cc84
-rw-r--r--chromium/google_apis/gaia/oauth2_access_token_fetcher_impl.cc11
-rw-r--r--chromium/google_apis/gaia/oauth2_api_call_flow_unittest.cc58
-rw-r--r--chromium/google_apis/gaia/oauth2_token_service.cc9
-rw-r--r--chromium/google_apis/gaia/oauth2_token_service.h13
-rw-r--r--chromium/google_apis/gaia/oauth2_token_service_delegate.cc16
-rw-r--r--chromium/google_apis/gaia/oauth2_token_service_delegate.h14
-rw-r--r--chromium/google_apis/gcm/BUILD.gn1
-rw-r--r--chromium/google_apis/gcm/DEPS1
-rw-r--r--chromium/google_apis/gcm/engine/connection_factory_impl.cc178
-rw-r--r--chromium/google_apis/gcm/engine/connection_factory_impl.h22
25 files changed, 501 insertions, 483 deletions
diff --git a/chromium/google_apis/BUILD.gn b/chromium/google_apis/BUILD.gn
index ced1cef4c71..0f966c6a50a 100644
--- a/chromium/google_apis/BUILD.gn
+++ b/chromium/google_apis/BUILD.gn
@@ -3,7 +3,7 @@
# found in the LICENSE file.
import("//build/config/features.gni")
-import("//extensions/features/features.gni")
+import("//extensions/buildflags/buildflags.gni")
import("//testing/test.gni")
declare_args() {
diff --git a/chromium/google_apis/drive/drive_api_url_generator_unittest.cc b/chromium/google_apis/drive/drive_api_url_generator_unittest.cc
index f2f4523098c..cb5490e9c74 100644
--- a/chromium/google_apis/drive/drive_api_url_generator_unittest.cc
+++ b/chromium/google_apis/drive/drive_api_url_generator_unittest.cc
@@ -29,7 +29,11 @@ class DriveApiUrlGeneratorTest : public testing::Test {
TEAM_DRIVES_INTEGRATION_DISABLED),
team_drives_url_generator_(GURL(kBaseUrlForTesting),
GURL(kBaseThumbnailUrlForTesting),
- TEAM_DRIVES_INTEGRATION_ENABLED) {}
+ TEAM_DRIVES_INTEGRATION_ENABLED) {
+ url::AddStandardScheme("chrome-extension", url::SCHEME_WITH_HOST);
+ }
+
+ ~DriveApiUrlGeneratorTest() override { url::Shutdown(); }
protected:
DriveApiUrlGenerator url_generator_;
@@ -75,7 +79,6 @@ TEST_F(DriveApiUrlGeneratorTest, GetFilesGetUrl) {
url_generator_.GetFilesGetUrl("0ADK06pfg", true, GURL()).spec());
// If |embed_origin| is not empty, it should be added as a query parameter.
- url::AddStandardScheme("chrome-extension", url::SCHEME_WITHOUT_PORT);
EXPECT_EQ(
"https://www.example.com/drive/v2/files/0ADK06pfg"
"?embedOrigin=chrome-extension%3A%2F%2Ftest",
diff --git a/chromium/google_apis/gaia/account_tracker.cc b/chromium/google_apis/gaia/account_tracker.cc
index bfab026090e..c859c2e97c7 100644
--- a/chromium/google_apis/gaia/account_tracker.cc
+++ b/chromium/google_apis/gaia/account_tracker.cc
@@ -52,8 +52,7 @@ std::vector<AccountIds> AccountTracker::GetAccounts() const {
for (std::map<std::string, AccountState>::const_iterator it =
accounts_.begin();
- it != accounts_.end();
- ++it) {
+ it != accounts_.end(); ++it) {
const AccountState& state = it->second;
bool is_visible = state.is_signed_in && !state.ids.gaia.empty();
@@ -71,10 +70,8 @@ std::vector<AccountIds> AccountTracker::GetAccounts() const {
}
void AccountTracker::OnRefreshTokenAvailable(const std::string& account_id) {
- TRACE_EVENT1("identity",
- "AccountTracker::OnRefreshTokenAvailable",
- "account_key",
- account_id);
+ TRACE_EVENT1("identity", "AccountTracker::OnRefreshTokenAvailable",
+ "account_key", account_id);
// Ignore refresh tokens if there is no active account ID at all.
if (identity_provider_->GetActiveAccountId().empty())
@@ -85,10 +82,8 @@ void AccountTracker::OnRefreshTokenAvailable(const std::string& account_id) {
}
void AccountTracker::OnRefreshTokenRevoked(const std::string& account_id) {
- TRACE_EVENT1("identity",
- "AccountTracker::OnRefreshTokenRevoked",
- "account_key",
- account_id);
+ TRACE_EVENT1("identity", "AccountTracker::OnRefreshTokenRevoked",
+ "account_key", account_id);
DVLOG(1) << "REVOKED " << account_id;
UpdateSignInState(account_id, false);
@@ -103,8 +98,7 @@ void AccountTracker::OnActiveAccountLogin() {
DVLOG(1) << "LOGIN " << accounts.size() << " accounts available.";
for (std::vector<std::string>::const_iterator it = accounts.begin();
- it != accounts.end();
- ++it) {
+ it != accounts.end(); ++it) {
OnRefreshTokenAvailable(*it);
}
}
@@ -125,8 +119,7 @@ void AccountTracker::SetAccountStateForTest(AccountIds ids, bool is_signed_in) {
if (VLOG_IS_ON(1)) {
for (std::map<std::string, AccountState>::const_iterator it =
accounts_.begin();
- it != accounts_.end();
- ++it) {
+ it != accounts_.end(); ++it) {
DVLOG(1) << it->first << ":" << it->second.is_signed_in;
}
}
@@ -191,9 +184,7 @@ void AccountTracker::StartFetchingUserInfo(const std::string& account_key) {
DVLOG(1) << "StartFetching " << account_key;
AccountIdFetcher* fetcher =
new AccountIdFetcher(identity_provider_->GetTokenService(),
- request_context_getter_.get(),
- this,
- account_key);
+ request_context_getter_.get(), this, account_key);
user_info_requests_[account_key] = base::WrapUnique(fetcher);
fetcher->Start();
}
@@ -237,8 +228,8 @@ AccountIdFetcher::AccountIdFetcher(
request_context_getter_(request_context_getter),
tracker_(tracker),
account_key_(account_key) {
- TRACE_EVENT_ASYNC_BEGIN1(
- "identity", "AccountIdFetcher", this, "account_key", account_key);
+ TRACE_EVENT_ASYNC_BEGIN1("identity", "AccountIdFetcher", this, "account_key",
+ account_key);
}
AccountIdFetcher::~AccountIdFetcher() {
@@ -248,16 +239,16 @@ AccountIdFetcher::~AccountIdFetcher() {
void AccountIdFetcher::Start() {
OAuth2TokenService::ScopeSet scopes;
scopes.insert("https://www.googleapis.com/auth/userinfo.profile");
- login_token_request_ = token_service_->StartRequest(
- account_key_, scopes, this);
+ login_token_request_ =
+ token_service_->StartRequest(account_key_, scopes, this);
}
void AccountIdFetcher::OnGetTokenSuccess(
const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) {
- TRACE_EVENT_ASYNC_STEP_PAST0(
- "identity", "AccountIdFetcher", this, "OnGetTokenSuccess");
+ TRACE_EVENT_ASYNC_STEP_PAST0("identity", "AccountIdFetcher", this,
+ "OnGetTokenSuccess");
DCHECK_EQ(request, login_token_request_.get());
gaia_oauth_client_.reset(new gaia::GaiaOAuthClient(request_context_getter_));
@@ -269,11 +260,8 @@ void AccountIdFetcher::OnGetTokenSuccess(
void AccountIdFetcher::OnGetTokenFailure(
const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) {
- TRACE_EVENT_ASYNC_STEP_PAST1("identity",
- "AccountIdFetcher",
- this,
- "OnGetTokenFailure",
- "google_service_auth_error",
+ TRACE_EVENT_ASYNC_STEP_PAST1("identity", "AccountIdFetcher", this,
+ "OnGetTokenFailure", "google_service_auth_error",
error.ToString());
LOG(ERROR) << "OnGetTokenFailure: " << error.ToString();
DCHECK_EQ(request, login_token_request_.get());
@@ -281,28 +269,21 @@ void AccountIdFetcher::OnGetTokenFailure(
}
void AccountIdFetcher::OnGetUserIdResponse(const std::string& gaia_id) {
- TRACE_EVENT_ASYNC_STEP_PAST1("identity",
- "AccountIdFetcher",
- this,
- "OnGetUserIdResponse",
- "gaia_id",
- gaia_id);
+ TRACE_EVENT_ASYNC_STEP_PAST1("identity", "AccountIdFetcher", this,
+ "OnGetUserIdResponse", "gaia_id", gaia_id);
tracker_->OnUserInfoFetchSuccess(this, gaia_id);
}
void AccountIdFetcher::OnOAuthError() {
- TRACE_EVENT_ASYNC_STEP_PAST0(
- "identity", "AccountIdFetcher", this, "OnOAuthError");
+ TRACE_EVENT_ASYNC_STEP_PAST0("identity", "AccountIdFetcher", this,
+ "OnOAuthError");
LOG(ERROR) << "OnOAuthError";
tracker_->OnUserInfoFetchFailure(this);
}
void AccountIdFetcher::OnNetworkError(int response_code) {
- TRACE_EVENT_ASYNC_STEP_PAST1("identity",
- "AccountIdFetcher",
- this,
- "OnNetworkError",
- "response_code",
+ TRACE_EVENT_ASYNC_STEP_PAST1("identity", "AccountIdFetcher", this,
+ "OnNetworkError", "response_code",
response_code);
LOG(ERROR) << "OnNetworkError " << response_code;
tracker_->OnUserInfoFetchFailure(this);
diff --git a/chromium/google_apis/gaia/account_tracker.h b/chromium/google_apis/gaia/account_tracker.h
index 19aa28f54e1..99cbaf6e6de 100644
--- a/chromium/google_apis/gaia/account_tracker.h
+++ b/chromium/google_apis/gaia/account_tracker.h
@@ -148,6 +148,6 @@ class AccountIdFetcher : public OAuth2TokenService::Consumer,
std::unique_ptr<gaia::GaiaOAuthClient> gaia_oauth_client_;
};
-} // namespace extensions
+} // namespace gaia
#endif // GOOGLE_APIS_GAIA_ACCOUNT_TRACKER_H_
diff --git a/chromium/google_apis/gaia/account_tracker_unittest.cc b/chromium/google_apis/gaia/account_tracker_unittest.cc
index c4451c180a8..a3a999a7d24 100644
--- a/chromium/google_apis/gaia/account_tracker_unittest.cc
+++ b/chromium/google_apis/gaia/account_tracker_unittest.cc
@@ -22,10 +22,7 @@ namespace {
const char kPrimaryAccountKey[] = "primary_account@example.com";
-enum TrackingEventType {
- SIGN_IN,
- SIGN_OUT
-};
+enum TrackingEventType { SIGN_IN, SIGN_OUT };
std::string AccountKeyToObfuscatedId(const std::string& email) {
return "obfid-" + email;
@@ -36,23 +33,20 @@ class TrackingEvent {
TrackingEvent(TrackingEventType type,
const std::string& account_key,
const std::string& gaia_id)
- : type_(type),
- account_key_(account_key),
- gaia_id_(gaia_id) {}
+ : type_(type), account_key_(account_key), gaia_id_(gaia_id) {}
- TrackingEvent(TrackingEventType type,
- const std::string& account_key)
+ TrackingEvent(TrackingEventType type, const std::string& account_key)
: type_(type),
account_key_(account_key),
gaia_id_(AccountKeyToObfuscatedId(account_key)) {}
bool operator==(const TrackingEvent& event) const {
return type_ == event.type_ && account_key_ == event.account_key_ &&
- gaia_id_ == event.gaia_id_;
+ gaia_id_ == event.gaia_id_;
}
std::string ToString() const {
- const char * typestr = "INVALID";
+ const char* typestr = "INVALID";
switch (type_) {
case SIGN_IN:
typestr = " IN";
@@ -61,10 +55,8 @@ class TrackingEvent {
typestr = "OUT";
break;
}
- return base::StringPrintf("{ type: %s, email: %s, gaia: %s }",
- typestr,
- account_key_.c_str(),
- gaia_id_.c_str());
+ return base::StringPrintf("{ type: %s, email: %s, gaia: %s }", typestr,
+ account_key_.c_str(), gaia_id_.c_str());
}
private:
@@ -82,8 +74,8 @@ bool CompareByUser(TrackingEvent a, TrackingEvent b) {
std::string Str(const std::vector<TrackingEvent>& events) {
std::string str = "[";
bool needs_comma = false;
- for (std::vector<TrackingEvent>::const_iterator it =
- events.begin(); it != events.end(); ++it) {
+ for (std::vector<TrackingEvent>::const_iterator it = events.begin();
+ it != events.end(); ++it) {
if (needs_comma)
str += ",\n ";
needs_comma = true;
@@ -254,10 +246,9 @@ class IdentityAccountTrackerTest : public testing::Test {
fake_identity_provider_.reset(
new FakeIdentityProvider(fake_oauth2_token_service_.get()));
- account_tracker_.reset(
- new AccountTracker(fake_identity_provider_.get(),
- new net::TestURLRequestContextGetter(
- message_loop_.task_runner())));
+ account_tracker_.reset(new AccountTracker(
+ fake_identity_provider_.get(),
+ new net::TestURLRequestContextGetter(message_loop_.task_runner())));
account_tracker_->AddObserver(&observer_);
}
@@ -266,13 +257,9 @@ class IdentityAccountTrackerTest : public testing::Test {
account_tracker_->Shutdown();
}
- AccountTrackerObserver* observer() {
- return &observer_;
- }
+ AccountTrackerObserver* observer() { return &observer_; }
- AccountTracker* account_tracker() {
- return account_tracker_.get();
- }
+ AccountTracker* account_tracker() { return account_tracker_.get(); }
// Helpers to pass fake events to the tracker.
@@ -338,8 +325,7 @@ class IdentityAccountTrackerTest : public testing::Test {
void IdentityAccountTrackerTest::ReturnOAuthUrlFetchResults(
int fetcher_id,
net::HttpStatusCode response_code,
- const std::string& response_string) {
-
+ const std::string& response_string) {
net::TestURLFetcher* fetcher =
test_fetcher_factory_.GetFetcherByID(fetcher_id);
ASSERT_TRUE(fetcher);
@@ -351,16 +337,15 @@ void IdentityAccountTrackerTest::ReturnOAuthUrlFetchResults(
void IdentityAccountTrackerTest::ReturnOAuthUrlFetchSuccess(
const std::string& account_key) {
IssueAccessToken(account_key);
- ReturnOAuthUrlFetchResults(gaia::GaiaOAuthClient::kUrlFetcherId,
- net::HTTP_OK,
+ ReturnOAuthUrlFetchResults(gaia::GaiaOAuthClient::kUrlFetcherId, net::HTTP_OK,
GetValidTokenInfoResponse(account_key));
}
void IdentityAccountTrackerTest::ReturnOAuthUrlFetchFailure(
const std::string& account_key) {
IssueAccessToken(account_key);
- ReturnOAuthUrlFetchResults(
- gaia::GaiaOAuthClient::kUrlFetcherId, net::HTTP_BAD_REQUEST, "");
+ ReturnOAuthUrlFetchResults(gaia::GaiaOAuthClient::kUrlFetcherId,
+ net::HTTP_BAD_REQUEST, "");
}
// Primary tests just involve the Active account
@@ -460,8 +445,8 @@ TEST_F(IdentityAccountTrackerTest, PrimaryLogoutFetchCancelAvailable) {
NotifyLogin(kPrimaryAccountKey);
NotifyTokenAvailable(kPrimaryAccountKey);
ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey);
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, kPrimaryAccountKey)));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, kPrimaryAccountKey)));
}
// Non-primary accounts
@@ -473,8 +458,8 @@ TEST_F(IdentityAccountTrackerTest, Available) {
EXPECT_TRUE(observer()->CheckEvents());
ReturnOAuthUrlFetchSuccess("user@example.com");
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, "user@example.com")));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, "user@example.com")));
}
TEST_F(IdentityAccountTrackerTest, Revoke) {
@@ -490,13 +475,13 @@ TEST_F(IdentityAccountTrackerTest, AvailableRevokeAvailable) {
NotifyTokenAvailable("user@example.com");
ReturnOAuthUrlFetchSuccess("user@example.com");
NotifyTokenRevoked("user@example.com");
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, "user@example.com"),
- TrackingEvent(SIGN_OUT, "user@example.com")));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, "user@example.com"),
+ TrackingEvent(SIGN_OUT, "user@example.com")));
NotifyTokenAvailable("user@example.com");
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, "user@example.com")));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, "user@example.com")));
}
TEST_F(IdentityAccountTrackerTest, AvailableRevokeAvailableWithPendingFetch) {
@@ -508,8 +493,8 @@ TEST_F(IdentityAccountTrackerTest, AvailableRevokeAvailableWithPendingFetch) {
NotifyTokenAvailable("user@example.com");
ReturnOAuthUrlFetchSuccess("user@example.com");
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, "user@example.com")));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, "user@example.com")));
}
TEST_F(IdentityAccountTrackerTest, AvailableRevokeRevoke) {
@@ -518,9 +503,9 @@ TEST_F(IdentityAccountTrackerTest, AvailableRevokeRevoke) {
NotifyTokenAvailable("user@example.com");
ReturnOAuthUrlFetchSuccess("user@example.com");
NotifyTokenRevoked("user@example.com");
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, "user@example.com"),
- TrackingEvent(SIGN_OUT, "user@example.com")));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, "user@example.com"),
+ TrackingEvent(SIGN_OUT, "user@example.com")));
NotifyTokenRevoked("user@example.com");
EXPECT_TRUE(observer()->CheckEvents());
@@ -531,8 +516,8 @@ TEST_F(IdentityAccountTrackerTest, AvailableAvailable) {
NotifyTokenAvailable("user@example.com");
ReturnOAuthUrlFetchSuccess("user@example.com");
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, "user@example.com")));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, "user@example.com")));
NotifyTokenAvailable("user@example.com");
EXPECT_TRUE(observer()->CheckEvents());
@@ -543,21 +528,21 @@ TEST_F(IdentityAccountTrackerTest, TwoAccounts) {
NotifyTokenAvailable("alpha@example.com");
ReturnOAuthUrlFetchSuccess("alpha@example.com");
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, "alpha@example.com")));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, "alpha@example.com")));
NotifyTokenAvailable("beta@example.com");
ReturnOAuthUrlFetchSuccess("beta@example.com");
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, "beta@example.com")));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, "beta@example.com")));
NotifyTokenRevoked("alpha@example.com");
EXPECT_TRUE(
observer()->CheckEvents(TrackingEvent(SIGN_OUT, "alpha@example.com")));
NotifyTokenRevoked("beta@example.com");
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_OUT, "beta@example.com")));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_OUT, "beta@example.com")));
}
TEST_F(IdentityAccountTrackerTest, AvailableTokenFetchFailAvailable) {
@@ -569,8 +554,8 @@ TEST_F(IdentityAccountTrackerTest, AvailableTokenFetchFailAvailable) {
NotifyTokenAvailable("user@example.com");
ReturnOAuthUrlFetchSuccess("user@example.com");
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, "user@example.com")));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, "user@example.com")));
}
TEST_F(IdentityAccountTrackerTest, MultiSignOutSignIn) {
@@ -582,9 +567,9 @@ TEST_F(IdentityAccountTrackerTest, MultiSignOutSignIn) {
ReturnOAuthUrlFetchSuccess("beta@example.com");
observer()->SortEventsByUser();
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, "alpha@example.com"),
- TrackingEvent(SIGN_IN, "beta@example.com")));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, "alpha@example.com"),
+ TrackingEvent(SIGN_IN, "beta@example.com")));
NotifyLogout();
observer()->SortEventsByUser();
@@ -605,19 +590,19 @@ TEST_F(IdentityAccountTrackerTest, MultiSignOutSignIn) {
ReturnOAuthUrlFetchSuccess("gamma@example.com");
ReturnOAuthUrlFetchSuccess(kPrimaryAccountKey);
observer()->SortEventsByUser();
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, "beta@example.com"),
- TrackingEvent(SIGN_IN, "gamma@example.com"),
- TrackingEvent(SIGN_IN, kPrimaryAccountKey)));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, "beta@example.com"),
+ TrackingEvent(SIGN_IN, "gamma@example.com"),
+ TrackingEvent(SIGN_IN, kPrimaryAccountKey)));
// Revoking the primary token does not affect other accounts.
NotifyTokenRevoked(kPrimaryAccountKey);
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_OUT, kPrimaryAccountKey)));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_OUT, kPrimaryAccountKey)));
NotifyTokenAvailable(kPrimaryAccountKey);
- EXPECT_TRUE(observer()->CheckEvents(
- TrackingEvent(SIGN_IN, kPrimaryAccountKey)));
+ EXPECT_TRUE(
+ observer()->CheckEvents(TrackingEvent(SIGN_IN, kPrimaryAccountKey)));
}
// Primary/non-primary interactions
diff --git a/chromium/google_apis/gaia/fake_gaia.cc b/chromium/google_apis/gaia/fake_gaia.cc
index 5c130de2186..1e76b22b39a 100644
--- a/chromium/google_apis/gaia/fake_gaia.cc
+++ b/chromium/google_apis/gaia/fake_gaia.cc
@@ -149,6 +149,7 @@ void FakeGaia::MergeSessionParams::Update(const MergeSessionParams& update) {
maybe_update_field(&MergeSessionParams::auth_code);
maybe_update_field(&MergeSessionParams::refresh_token);
maybe_update_field(&MergeSessionParams::access_token);
+ maybe_update_field(&MergeSessionParams::id_token);
maybe_update_field(&MergeSessionParams::gaia_uber_token);
maybe_update_field(&MergeSessionParams::session_sid_cookie);
maybe_update_field(&MergeSessionParams::session_lsid_cookie);
@@ -709,6 +710,8 @@ void FakeGaia::HandleAuthToken(const HttpRequest& request,
device_id;
response_dict.SetString("access_token",
merge_session_params_.access_token);
+ if (!merge_session_params_.id_token.empty())
+ response_dict.SetString("id_token", merge_session_params_.id_token);
response_dict.SetInteger("expires_in", 3600);
FormatJSONResponse(response_dict, http_response);
return;
diff --git a/chromium/google_apis/gaia/fake_gaia.h b/chromium/google_apis/gaia/fake_gaia.h
index 9909539e7c1..fbb5ff9fcb0 100644
--- a/chromium/google_apis/gaia/fake_gaia.h
+++ b/chromium/google_apis/gaia/fake_gaia.h
@@ -67,10 +67,11 @@ class FakeGaia {
// auth_code cookie value response for /o/oauth2/programmatic_auth call.
std::string auth_code;
- // OAuth2 refresh and access token generated by /oauth2/v4/token call
+ // OAuth2 refresh access and id token generated by /oauth2/v4/token call
// with "...&grant_type=authorization_code".
std::string refresh_token;
std::string access_token;
+ std::string id_token;
// Uber token response from /OAuthLogin call.
std::string gaia_uber_token;
diff --git a/chromium/google_apis/gaia/fake_oauth2_token_service_delegate.cc b/chromium/google_apis/gaia/fake_oauth2_token_service_delegate.cc
index 1ce991cb20a..4ae2b786524 100644
--- a/chromium/google_apis/gaia/fake_oauth2_token_service_delegate.cc
+++ b/chromium/google_apis/gaia/fake_oauth2_token_service_delegate.cc
@@ -34,11 +34,11 @@ bool FakeOAuth2TokenServiceDelegate::RefreshTokenIsAvailable(
return !GetRefreshToken(account_id).empty();
}
-bool FakeOAuth2TokenServiceDelegate::RefreshTokenHasError(
+GoogleServiceAuthError FakeOAuth2TokenServiceDelegate::GetAuthError(
const std::string& account_id) const {
auto it = refresh_tokens_.find(account_id);
- // TODO(rogerta): should we distinguish between transient and persistent?
- return it == refresh_tokens_.end() ? false : IsError(it->second->error);
+ return (it == refresh_tokens_.end()) ? GoogleServiceAuthError::AuthErrorNone()
+ : it->second->error;
}
std::string FakeOAuth2TokenServiceDelegate::GetRefreshToken(
@@ -101,10 +101,14 @@ FakeOAuth2TokenServiceDelegate::GetRequestContext() const {
return request_context_.get();
}
-void FakeOAuth2TokenServiceDelegate::SetLastErrorForAccount(
+void FakeOAuth2TokenServiceDelegate::UpdateAuthError(
const std::string& account_id,
const GoogleServiceAuthError& error) {
+ if (GetAuthError(account_id) == error)
+ return;
+
auto it = refresh_tokens_.find(account_id);
DCHECK(it != refresh_tokens_.end());
it->second->error = error;
+ FireAuthErrorChanged(account_id, error);
}
diff --git a/chromium/google_apis/gaia/fake_oauth2_token_service_delegate.h b/chromium/google_apis/gaia/fake_oauth2_token_service_delegate.h
index 0000f697469..45a80def350 100644
--- a/chromium/google_apis/gaia/fake_oauth2_token_service_delegate.h
+++ b/chromium/google_apis/gaia/fake_oauth2_token_service_delegate.h
@@ -23,7 +23,10 @@ class FakeOAuth2TokenServiceDelegate : public OAuth2TokenServiceDelegate {
// Overriden to make sure it works on Android.
bool RefreshTokenIsAvailable(const std::string& account_id) const override;
- bool RefreshTokenHasError(const std::string& account_id) const override;
+ GoogleServiceAuthError GetAuthError(
+ const std::string& account_id) const override;
+ void UpdateAuthError(const std::string& account_id,
+ const GoogleServiceAuthError& error) override;
std::vector<std::string> GetAccounts() override;
void RevokeAllCredentials() override;
@@ -40,9 +43,6 @@ class FakeOAuth2TokenServiceDelegate : public OAuth2TokenServiceDelegate {
request_context_ = request_context;
}
- void SetLastErrorForAccount(const std::string& account_id,
- const GoogleServiceAuthError& error);
-
std::string GetRefreshToken(const std::string& account_id) const;
private:
diff --git a/chromium/google_apis/gaia/gaia_auth_consumer.h b/chromium/google_apis/gaia/gaia_auth_consumer.h
index 542c145f89c..1ec5bde5560 100644
--- a/chromium/google_apis/gaia/gaia_auth_consumer.h
+++ b/chromium/google_apis/gaia/gaia_auth_consumer.h
@@ -65,6 +65,29 @@ class GaiaAuthConsumer {
bool is_child_account;
};
+ // Possible server responses to a token revocation request.
+ // Used in UMA, do not delete or reorder values.
+ enum class TokenRevocationStatus {
+ // Token revocation succeeded.
+ kSuccess = 0,
+ // Network connection was canceled, no response was received.
+ kConnectionCanceled = 1,
+ // Network connection failed, no response was received.
+ kConnectionFailed = 2,
+ // Network connection timed out, no response was received.
+ kConnectionTimeout = 3,
+ // The token is unknown or invalid.
+ kInvalidToken = 4,
+ // The request was malformed.
+ kInvalidRequest = 5,
+ // Internal server error.
+ kServerError = 6,
+ // Other error.
+ kUnknownError = 7,
+
+ kMaxValue = kUnknownError
+ };
+
virtual ~GaiaAuthConsumer() {}
virtual void OnClientLoginSuccess(const ClientLoginResult& result) {}
@@ -79,7 +102,7 @@ class GaiaAuthConsumer {
virtual void OnClientOAuthSuccess(const ClientOAuthResult& result) {}
virtual void OnClientOAuthFailure(const GoogleServiceAuthError& error) {}
- virtual void OnOAuth2RevokeTokenCompleted() {}
+ virtual void OnOAuth2RevokeTokenCompleted(TokenRevocationStatus status) {}
virtual void OnGetUserInfoSuccess(const UserInfoMap& data) {}
virtual void OnGetUserInfoFailure(const GoogleServiceAuthError& error) {}
diff --git a/chromium/google_apis/gaia/gaia_auth_fetcher.cc b/chromium/google_apis/gaia/gaia_auth_fetcher.cc
index b15f2fec173..f4039e49bed 100644
--- a/chromium/google_apis/gaia/gaia_auth_fetcher.cc
+++ b/chromium/google_apis/gaia/gaia_auth_fetcher.cc
@@ -33,6 +33,7 @@
#include "net/url_request/url_request_status.h"
namespace {
+
const int kLoadFlagsIgnoreCookies = net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SAVE_COOKIES;
@@ -89,6 +90,34 @@ void GetCookiesFromResponse(const net::HttpResponseHeaders* headers,
}
}
+// Parses server responses for token revocation.
+GaiaAuthConsumer::TokenRevocationStatus
+GetTokenRevocationStatusFromResponseData(const std::string& data,
+ int response_code) {
+ if (response_code == net::HTTP_OK)
+ return GaiaAuthConsumer::TokenRevocationStatus::kSuccess;
+
+ if (response_code == net::HTTP_INTERNAL_SERVER_ERROR)
+ return GaiaAuthConsumer::TokenRevocationStatus::kServerError;
+
+ std::unique_ptr<base::Value> value = base::JSONReader::Read(data);
+ if (!value.get() || value->type() != base::Value::Type::DICTIONARY)
+ return GaiaAuthConsumer::TokenRevocationStatus::kUnknownError;
+
+ base::DictionaryValue* dict =
+ static_cast<base::DictionaryValue*>(value.get());
+ std::string error;
+ if (!dict->GetStringWithoutPathExpansion("error", &error))
+ return GaiaAuthConsumer::TokenRevocationStatus::kUnknownError;
+
+ if (error == "invalid_token")
+ return GaiaAuthConsumer::TokenRevocationStatus::kInvalidToken;
+ if (error == "invalid_request")
+ return GaiaAuthConsumer::TokenRevocationStatus::kInvalidRequest;
+
+ return GaiaAuthConsumer::TokenRevocationStatus::kUnknownError;
+}
+
} // namespace
// static
@@ -900,7 +929,9 @@ GoogleServiceAuthError GaiaAuthFetcher::GenerateAuthError(
return GoogleServiceAuthError(GoogleServiceAuthError::ACCOUNT_DISABLED);
if (error == kBadAuthenticationError) {
return GoogleServiceAuthError(
- GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
+ GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
+ GoogleServiceAuthError::InvalidGaiaCredentialsReason::
+ CREDENTIALS_REJECTED_BY_SERVER));
}
if (error == kServiceUnavailableError) {
return GoogleServiceAuthError(
@@ -969,7 +1000,30 @@ void GaiaAuthFetcher::OnOAuth2RevokeTokenFetched(
const std::string& data,
const net::URLRequestStatus& status,
int response_code) {
- consumer_->OnOAuth2RevokeTokenCompleted();
+ GaiaAuthConsumer::TokenRevocationStatus revocation_status =
+ GaiaAuthConsumer::TokenRevocationStatus::kUnknownError;
+
+ switch (status.status()) {
+ case net::URLRequestStatus::SUCCESS:
+ revocation_status =
+ GetTokenRevocationStatusFromResponseData(data, response_code);
+ break;
+ case net::URLRequestStatus::IO_PENDING:
+ NOTREACHED();
+ break;
+ case net::URLRequestStatus::FAILED:
+ revocation_status =
+ (status.ToNetError() == net::ERR_TIMED_OUT)
+ ? GaiaAuthConsumer::TokenRevocationStatus::kConnectionTimeout
+ : GaiaAuthConsumer::TokenRevocationStatus::kConnectionFailed;
+ break;
+ case net::URLRequestStatus::CANCELED:
+ revocation_status =
+ GaiaAuthConsumer::TokenRevocationStatus::kConnectionCanceled;
+ break;
+ }
+
+ consumer_->OnOAuth2RevokeTokenCompleted(revocation_status);
}
void GaiaAuthFetcher::OnListAccountsFetched(const std::string& data,
diff --git a/chromium/google_apis/gaia/gaia_auth_fetcher_unittest.cc b/chromium/google_apis/gaia/gaia_auth_fetcher_unittest.cc
index 68340c049a9..9f47cc81da7 100644
--- a/chromium/google_apis/gaia/gaia_auth_fetcher_unittest.cc
+++ b/chromium/google_apis/gaia/gaia_auth_fetcher_unittest.cc
@@ -187,6 +187,8 @@ class MockGaiaConsumer : public GaiaAuthConsumer {
const GoogleServiceAuthError& error));
MOCK_METHOD1(OnClientOAuthFailure,
void(const GoogleServiceAuthError& error));
+ MOCK_METHOD1(OnOAuth2RevokeTokenCompleted,
+ void(GaiaAuthConsumer::TokenRevocationStatus status));
MOCK_METHOD1(OnMergeSessionFailure, void(
const GoogleServiceAuthError& error));
MOCK_METHOD1(OnUberAuthTokenFailure, void(
@@ -685,3 +687,110 @@ TEST_F(GaiaAuthFetcherTest, GetCheckConnectionInfo) {
status, net::HTTP_OK, data, net::URLFetcher::GET, &auth);
auth.OnURLFetchComplete(&mock_fetcher);
}
+
+TEST_F(GaiaAuthFetcherTest, RevokeOAuth2TokenSuccess) {
+ std::string data("{}");
+ MockGaiaConsumer consumer;
+ EXPECT_CALL(consumer, OnOAuth2RevokeTokenCompleted(
+ GaiaAuthConsumer::TokenRevocationStatus::kSuccess))
+ .Times(1);
+
+ GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
+ net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
+ MockFetcher mock_fetcher(GaiaUrls::GetInstance()->oauth2_revoke_url(), status,
+ net::HTTP_OK, data, net::URLFetcher::GET, &auth);
+ auth.OnURLFetchComplete(&mock_fetcher);
+}
+
+TEST_F(GaiaAuthFetcherTest, RevokeOAuth2TokenCanceled) {
+ MockGaiaConsumer consumer;
+ EXPECT_CALL(consumer,
+ OnOAuth2RevokeTokenCompleted(
+ GaiaAuthConsumer::TokenRevocationStatus::kConnectionCanceled))
+ .Times(1);
+
+ GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
+ net::URLRequestStatus status(net::URLRequestStatus::CANCELED,
+ net::ERR_ABORTED);
+ MockFetcher mock_fetcher(GaiaUrls::GetInstance()->oauth2_revoke_url(), status,
+ 0, std::string(), net::URLFetcher::GET, &auth);
+ auth.OnURLFetchComplete(&mock_fetcher);
+}
+
+TEST_F(GaiaAuthFetcherTest, RevokeOAuth2TokenFailed) {
+ MockGaiaConsumer consumer;
+ EXPECT_CALL(consumer,
+ OnOAuth2RevokeTokenCompleted(
+ GaiaAuthConsumer::TokenRevocationStatus::kConnectionFailed))
+ .Times(1);
+
+ GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
+ int error_no = net::ERR_CERT_CONTAINS_ERRORS;
+ net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
+ MockFetcher mock_fetcher(GaiaUrls::GetInstance()->oauth2_revoke_url(), status,
+ 0, std::string(), net::URLFetcher::GET, &auth);
+ auth.OnURLFetchComplete(&mock_fetcher);
+}
+
+TEST_F(GaiaAuthFetcherTest, RevokeOAuth2TokenTimeout) {
+ MockGaiaConsumer consumer;
+ EXPECT_CALL(consumer,
+ OnOAuth2RevokeTokenCompleted(
+ GaiaAuthConsumer::TokenRevocationStatus::kConnectionTimeout))
+ .Times(1);
+
+ GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
+ int error_no = net::ERR_TIMED_OUT;
+ net::URLRequestStatus status(net::URLRequestStatus::FAILED, error_no);
+ MockFetcher mock_fetcher(GaiaUrls::GetInstance()->oauth2_revoke_url(), status,
+ 0, std::string(), net::URLFetcher::GET, &auth);
+ auth.OnURLFetchComplete(&mock_fetcher);
+}
+
+TEST_F(GaiaAuthFetcherTest, RevokeOAuth2TokenInvalidToken) {
+ std::string data("{\"error\" : \"invalid_token\"}");
+ MockGaiaConsumer consumer;
+ EXPECT_CALL(consumer,
+ OnOAuth2RevokeTokenCompleted(
+ GaiaAuthConsumer::TokenRevocationStatus::kInvalidToken))
+ .Times(1);
+
+ GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
+ net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
+ MockFetcher mock_fetcher(GaiaUrls::GetInstance()->oauth2_revoke_url(), status,
+ net::HTTP_BAD_REQUEST, data, net::URLFetcher::GET,
+ &auth);
+ auth.OnURLFetchComplete(&mock_fetcher);
+}
+
+TEST_F(GaiaAuthFetcherTest, RevokeOAuth2TokenInvalidRequest) {
+ std::string data("{\"error\" : \"invalid_request\"}");
+ MockGaiaConsumer consumer;
+ EXPECT_CALL(consumer,
+ OnOAuth2RevokeTokenCompleted(
+ GaiaAuthConsumer::TokenRevocationStatus::kInvalidRequest))
+ .Times(1);
+
+ GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
+ net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
+ MockFetcher mock_fetcher(GaiaUrls::GetInstance()->oauth2_revoke_url(), status,
+ net::HTTP_BAD_REQUEST, data, net::URLFetcher::GET,
+ &auth);
+ auth.OnURLFetchComplete(&mock_fetcher);
+}
+
+TEST_F(GaiaAuthFetcherTest, RevokeOAuth2TokenServerError) {
+ std::string data("{}");
+ MockGaiaConsumer consumer;
+ EXPECT_CALL(consumer,
+ OnOAuth2RevokeTokenCompleted(
+ GaiaAuthConsumer::TokenRevocationStatus::kServerError))
+ .Times(1);
+
+ GaiaAuthFetcher auth(&consumer, std::string(), GetRequestContext());
+ net::URLRequestStatus status(net::URLRequestStatus::SUCCESS, 0);
+ MockFetcher mock_fetcher(GaiaUrls::GetInstance()->oauth2_revoke_url(), status,
+ net::HTTP_INTERNAL_SERVER_ERROR, data,
+ net::URLFetcher::GET, &auth);
+ auth.OnURLFetchComplete(&mock_fetcher);
+}
diff --git a/chromium/google_apis/gaia/google_service_auth_error.cc b/chromium/google_apis/gaia/google_service_auth_error.cc
index 79f445caf88..d28bc258fb9 100644
--- a/chromium/google_apis/gaia/google_service_auth_error.cc
+++ b/chromium/google_apis/gaia/google_service_auth_error.cc
@@ -8,11 +8,8 @@
#include <string>
#include <utility>
-#include "base/json/json_reader.h"
#include "base/logging.h"
-#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
-#include "base/values.h"
#include "net/base/net_errors.h"
GoogleServiceAuthError::Captcha::Captcha() : image_width(0), image_height(0) {
@@ -77,23 +74,17 @@ bool GoogleServiceAuthError::operator!=(
}
GoogleServiceAuthError::GoogleServiceAuthError()
- : state_(NONE), network_error_(0) {}
+ : GoogleServiceAuthError(NONE) {}
GoogleServiceAuthError::GoogleServiceAuthError(State s)
- : state_(s),
- network_error_(0) {
- // If the caller has no idea, then we just set it to a generic failure.
- if (s == CONNECTION_FAILED) {
- network_error_ = net::ERR_FAILED;
- }
-}
-
-GoogleServiceAuthError::GoogleServiceAuthError(
- State state,
- const std::string& error_message)
- : state_(state),
- network_error_(0),
- error_message_(error_message) {
+ : GoogleServiceAuthError(s, std::string()) {}
+
+GoogleServiceAuthError::GoogleServiceAuthError(State state,
+ const std::string& error_message)
+ : GoogleServiceAuthError(
+ state,
+ (state == CONNECTION_FAILED) ? net::ERR_FAILED : 0) {
+ error_message_ = error_message;
}
GoogleServiceAuthError::GoogleServiceAuthError(
@@ -106,6 +97,14 @@ GoogleServiceAuthError
}
// static
+GoogleServiceAuthError GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
+ InvalidGaiaCredentialsReason reason) {
+ GoogleServiceAuthError error(INVALID_GAIA_CREDENTIALS);
+ error.invalid_gaia_credentials_reason_ = reason;
+ return error;
+}
+
+// static
GoogleServiceAuthError GoogleServiceAuthError::FromClientLoginCaptchaChallenge(
const std::string& captcha_token,
const GURL& captcha_image_url,
@@ -171,53 +170,10 @@ const std::string& GoogleServiceAuthError::error_message() const {
return error_message_;
}
-base::DictionaryValue* GoogleServiceAuthError::ToValue() const {
- base::DictionaryValue* value = new base::DictionaryValue();
- std::string state_str;
- switch (state_) {
-#define STATE_CASE(x) case x: state_str = #x; break
- STATE_CASE(NONE);
- STATE_CASE(INVALID_GAIA_CREDENTIALS);
- STATE_CASE(USER_NOT_SIGNED_UP);
- STATE_CASE(CONNECTION_FAILED);
- STATE_CASE(CAPTCHA_REQUIRED);
- STATE_CASE(ACCOUNT_DELETED);
- STATE_CASE(ACCOUNT_DISABLED);
- STATE_CASE(SERVICE_UNAVAILABLE);
- STATE_CASE(TWO_FACTOR);
- STATE_CASE(REQUEST_CANCELED);
- STATE_CASE(UNEXPECTED_SERVICE_RESPONSE);
- STATE_CASE(SERVICE_ERROR);
- STATE_CASE(WEB_LOGIN_REQUIRED);
-#undef STATE_CASE
- default:
- NOTREACHED();
- break;
- }
- value->SetString("state", state_str);
- if (!error_message_.empty()) {
- value->SetString("errorMessage", error_message_);
- }
- if (state_ == CAPTCHA_REQUIRED) {
- auto captcha_value = std::make_unique<base::DictionaryValue>();
- captcha_value->SetString("token", captcha_.token);
- captcha_value->SetString("audioUrl", captcha_.audio_url.spec());
- captcha_value->SetString("imageUrl", captcha_.image_url.spec());
- captcha_value->SetString("unlockUrl", captcha_.unlock_url.spec());
- captcha_value->SetInteger("imageWidth", captcha_.image_width);
- captcha_value->SetInteger("imageHeight", captcha_.image_height);
- value->Set("captcha", std::move(captcha_value));
- } else if (state_ == CONNECTION_FAILED) {
- value->SetString("networkError", net::ErrorToString(network_error_));
- } else if (state_ == TWO_FACTOR) {
- auto two_factor_value = std::make_unique<base::DictionaryValue>();
- two_factor_value->SetString("token", second_factor_.token);
- two_factor_value->SetString("promptText", second_factor_.prompt_text);
- two_factor_value->SetString("alternateText", second_factor_.alternate_text);
- two_factor_value->SetInteger("fieldLength", second_factor_.field_length);
- value->Set("two_factor", std::move(two_factor_value));
- }
- return value;
+GoogleServiceAuthError::InvalidGaiaCredentialsReason
+GoogleServiceAuthError::GetInvalidGaiaCredentialsReason() const {
+ DCHECK_EQ(INVALID_GAIA_CREDENTIALS, state());
+ return invalid_gaia_credentials_reason_;
}
std::string GoogleServiceAuthError::ToString() const {
@@ -225,7 +181,9 @@ std::string GoogleServiceAuthError::ToString() const {
case NONE:
return std::string();
case INVALID_GAIA_CREDENTIALS:
- return "Invalid credentials.";
+ return base::StringPrintf(
+ "Invalid credentials (%d).",
+ static_cast<int>(invalid_gaia_credentials_reason_));
case USER_NOT_SIGNED_UP:
return "Not authorized.";
case CONNECTION_FAILED:
@@ -280,19 +238,22 @@ bool GoogleServiceAuthError::IsTransientError() const {
GoogleServiceAuthError::GoogleServiceAuthError(State s, int error)
: state_(s),
- network_error_(error) {
-}
-
-GoogleServiceAuthError::GoogleServiceAuthError(
- State s,
- const std::string& captcha_token,
- const GURL& captcha_audio_url,
- const GURL& captcha_image_url,
- const GURL& captcha_unlock_url,
- int image_width,
- int image_height)
+ network_error_(error),
+ invalid_gaia_credentials_reason_(InvalidGaiaCredentialsReason::UNKNOWN) {}
+
+GoogleServiceAuthError::GoogleServiceAuthError(State s,
+ const std::string& captcha_token,
+ const GURL& captcha_audio_url,
+ const GURL& captcha_image_url,
+ const GURL& captcha_unlock_url,
+ int image_width,
+ int image_height)
: state_(s),
- captcha_(captcha_token, captcha_audio_url, captcha_image_url,
- captcha_unlock_url, image_width, image_height),
- network_error_(0) {
-}
+ captcha_(captcha_token,
+ captcha_audio_url,
+ captcha_image_url,
+ captcha_unlock_url,
+ image_width,
+ image_height),
+ network_error_((state_ == CONNECTION_FAILED) ? net::ERR_FAILED : net::OK),
+ invalid_gaia_credentials_reason_(InvalidGaiaCredentialsReason::UNKNOWN) {}
diff --git a/chromium/google_apis/gaia/google_service_auth_error.h b/chromium/google_apis/gaia/google_service_auth_error.h
index 5e845991543..8ed19a90b82 100644
--- a/chromium/google_apis/gaia/google_service_auth_error.h
+++ b/chromium/google_apis/gaia/google_service_auth_error.h
@@ -8,17 +8,6 @@
// Accounts (e.g expired credentials). It may contain additional data such as
// captcha or OTP challenges.
-// A GoogleServiceAuthError without additional data is just a State, defined
-// below. A case could be made to have this relation implicit, to allow raising
-// error events concisely by doing OnAuthError(GoogleServiceAuthError::NONE),
-// for example. But the truth is this class is ever so slightly more than a
-// transparent wrapper around 'State' due to additional Captcha data
-// (e.g consider operator=), and this would violate the style guide. Thus,
-// you must explicitly use the constructor when all you have is a State.
-// The good news is the implementation nests the enum inside a class, so you
-// may forward declare and typedef GoogleServiceAuthError to something shorter
-// in the comfort of your own translation unit.
-
#ifndef GOOGLE_APIS_GAIA_GOOGLE_SERVICE_AUTH_ERROR_H_
#define GOOGLE_APIS_GAIA_GOOGLE_SERVICE_AUTH_ERROR_H_
@@ -34,10 +23,6 @@ class GoogleServiceAuthErrorDataView;
}
}
-namespace base {
-class DictionaryValue;
-}
-
class GoogleServiceAuthError {
public:
//
@@ -101,6 +86,23 @@ class GoogleServiceAuthError {
NUM_STATES = 14,
};
+ // Error reason for invalid credentials. Only used when the error is
+ // INVALID_GAIA_CREDENTIALS.
+ // Used by UMA histograms: do not remove or reorder values, add new values at
+ // the end.
+ enum class InvalidGaiaCredentialsReason {
+ // The error was not specified.
+ UNKNOWN = 0,
+ // Credentials were rejectedby the Gaia server.
+ CREDENTIALS_REJECTED_BY_SERVER,
+ // Credentials were invalidated locally by Chrome.
+ CREDENTIALS_REJECTED_BY_CLIENT,
+ // Credentials are missing (e.g. could not be loaded from disk).
+ CREDENTIALS_MISSING,
+
+ NUM_REASONS
+ };
+
// Additional data for CAPTCHA_REQUIRED errors.
struct Captcha {
Captcha();
@@ -164,6 +166,9 @@ class GoogleServiceAuthError {
// It will be created with CONNECTION_FAILED set.
static GoogleServiceAuthError FromConnectionError(int error);
+ static GoogleServiceAuthError FromInvalidGaiaCredentialsReason(
+ InvalidGaiaCredentialsReason reason);
+
// Construct a CAPTCHA_REQUIRED error with CAPTCHA challenge data from the
// the ClientLogin endpoint.
// TODO(rogerta): once ClientLogin is no longer used, may be able to get
@@ -198,9 +203,8 @@ class GoogleServiceAuthError {
const std::string& token() const;
const std::string& error_message() const;
- // Returns info about this object in a dictionary. Caller takes
- // ownership of returned dictionary.
- base::DictionaryValue* ToValue() const;
+ // Should only be used when the error state is INVALID_GAIA_CREDENTIALS.
+ InvalidGaiaCredentialsReason GetInvalidGaiaCredentialsReason() const;
// Returns a message describing the error.
std::string ToString() const;
@@ -234,6 +238,7 @@ class GoogleServiceAuthError {
SecondFactor second_factor_;
int network_error_;
std::string error_message_;
+ InvalidGaiaCredentialsReason invalid_gaia_credentials_reason_;
};
#endif // GOOGLE_APIS_GAIA_GOOGLE_SERVICE_AUTH_ERROR_H_
diff --git a/chromium/google_apis/gaia/google_service_auth_error_unittest.cc b/chromium/google_apis/gaia/google_service_auth_error_unittest.cc
index 2fec3ead4d0..4035256cf54 100644
--- a/chromium/google_apis/gaia/google_service_auth_error_unittest.cc
+++ b/chromium/google_apis/gaia/google_service_auth_error_unittest.cc
@@ -7,49 +7,73 @@
#include <memory>
#include <string>
-#include "base/test/values_test_util.h"
-#include "base/values.h"
#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
-using base::ExpectDictStringValue;
+TEST(GoogleServiceAuthErrorTest, State) {
+ for (GoogleServiceAuthError::State i = GoogleServiceAuthError::NONE;
+ i < GoogleServiceAuthError::NUM_STATES;
+ i = GoogleServiceAuthError::State(i + 1)) {
+ GoogleServiceAuthError error(i);
+ EXPECT_EQ(i, error.state());
+ EXPECT_TRUE(error.error_message().empty());
-class GoogleServiceAuthErrorTest : public testing::Test {};
+ if (i == GoogleServiceAuthError::CONNECTION_FAILED)
+ EXPECT_EQ(net::ERR_FAILED, error.network_error());
+ else
+ EXPECT_EQ(net::OK, error.network_error());
-void TestSimpleState(GoogleServiceAuthError::State state) {
- GoogleServiceAuthError error(state);
- std::unique_ptr<base::DictionaryValue> value(error.ToValue());
- EXPECT_EQ(1u, value->size());
- std::string state_str;
- EXPECT_TRUE(value->GetString("state", &state_str));
- EXPECT_FALSE(state_str.empty());
- EXPECT_NE("CONNECTION_FAILED", state_str);
- EXPECT_NE("CAPTCHA_REQUIRED", state_str);
-}
+ if (i == GoogleServiceAuthError::NONE) {
+ EXPECT_FALSE(error.IsTransientError());
+ EXPECT_FALSE(error.IsPersistentError());
+ } else if ((i == GoogleServiceAuthError::CONNECTION_FAILED) ||
+ (i == GoogleServiceAuthError::SERVICE_UNAVAILABLE) ||
+ (i == GoogleServiceAuthError::REQUEST_CANCELED)) {
+ EXPECT_TRUE(error.IsTransientError());
+ EXPECT_FALSE(error.IsPersistentError());
+ } else {
+ EXPECT_FALSE(error.IsTransientError());
+ EXPECT_TRUE(error.IsPersistentError());
+ }
-TEST_F(GoogleServiceAuthErrorTest, SimpleToValue) {
- for (int i = GoogleServiceAuthError::NONE;
- i <= GoogleServiceAuthError::USER_NOT_SIGNED_UP; ++i) {
- TestSimpleState(static_cast<GoogleServiceAuthError::State>(i));
+ if (i == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS) {
+ EXPECT_EQ(GoogleServiceAuthError::InvalidGaiaCredentialsReason::UNKNOWN,
+ error.GetInvalidGaiaCredentialsReason());
+ }
}
}
-TEST_F(GoogleServiceAuthErrorTest, None) {
- GoogleServiceAuthError error(GoogleServiceAuthError::AuthErrorNone());
- std::unique_ptr<base::DictionaryValue> value(error.ToValue());
- EXPECT_EQ(1u, value->size());
- ExpectDictStringValue("NONE", *value, "state");
+TEST(GoogleServiceAuthErrorTest, FromConnectionError) {
+ GoogleServiceAuthError error =
+ GoogleServiceAuthError::FromConnectionError(net::ERR_TIMED_OUT);
+ EXPECT_EQ(GoogleServiceAuthError::CONNECTION_FAILED, error.state());
+ EXPECT_EQ(net::ERR_TIMED_OUT, error.network_error());
+}
+
+TEST(GoogleServiceAuthErrorTest, FromServiceError) {
+ GoogleServiceAuthError error =
+ GoogleServiceAuthError::FromServiceError("Foo");
+ EXPECT_EQ(GoogleServiceAuthError::SERVICE_ERROR, error.state());
+ EXPECT_EQ("Foo", error.error_message());
+}
+
+TEST(GoogleServiceAuthErrorTest, FromInvalidGaiaCredentialsReason) {
+ GoogleServiceAuthError error =
+ GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
+ GoogleServiceAuthError::InvalidGaiaCredentialsReason::
+ CREDENTIALS_REJECTED_BY_SERVER);
+ EXPECT_EQ(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS, error.state());
+ EXPECT_EQ(GoogleServiceAuthError::InvalidGaiaCredentialsReason::
+ CREDENTIALS_REJECTED_BY_SERVER,
+ error.GetInvalidGaiaCredentialsReason());
+ EXPECT_EQ("Invalid credentials (1).", error.ToString());
}
-TEST_F(GoogleServiceAuthErrorTest, ConnectionFailed) {
- GoogleServiceAuthError error(
- GoogleServiceAuthError::FromConnectionError(net::OK));
- std::unique_ptr<base::DictionaryValue> value(error.ToValue());
- EXPECT_EQ(2u, value->size());
- ExpectDictStringValue("CONNECTION_FAILED", *value, "state");
- ExpectDictStringValue("net::OK", *value, "networkError");
+TEST(GoogleServiceAuthErrorTest, AuthErrorNone) {
+ EXPECT_EQ(GoogleServiceAuthError(GoogleServiceAuthError::NONE),
+ GoogleServiceAuthError::AuthErrorNone());
}
} // namespace
diff --git a/chromium/google_apis/gaia/oauth2_access_token_fetcher_impl.cc b/chromium/google_apis/gaia/oauth2_access_token_fetcher_impl.cc
index ac1aabe0760..32d762aa61c 100644
--- a/chromium/google_apis/gaia/oauth2_access_token_fetcher_impl.cc
+++ b/chromium/google_apis/gaia/oauth2_access_token_fetcher_impl.cc
@@ -236,8 +236,9 @@ void OAuth2AccessTokenFetcherImpl::EndGetAccessToken(
OnGetTokenFailure(
access_error == OAUTH2_ACCESS_ERROR_INVALID_GRANT
- ? GoogleServiceAuthError(
- GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS)
+ ? GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
+ GoogleServiceAuthError::InvalidGaiaCredentialsReason::
+ CREDENTIALS_REJECTED_BY_SERVER)
: GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_ERROR));
return;
}
@@ -250,8 +251,10 @@ void OAuth2AccessTokenFetcherImpl::EndGetAccessToken(
// The other errors are treated as permanent error.
DLOG(ERROR) << "Unexpected persistent error: http_status="
<< source->GetResponseCode();
- OnGetTokenFailure(GoogleServiceAuthError(
- GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
+ OnGetTokenFailure(
+ GoogleServiceAuthError::FromInvalidGaiaCredentialsReason(
+ GoogleServiceAuthError::InvalidGaiaCredentialsReason::
+ CREDENTIALS_REJECTED_BY_SERVER));
}
return;
}
diff --git a/chromium/google_apis/gaia/oauth2_api_call_flow_unittest.cc b/chromium/google_apis/gaia/oauth2_api_call_flow_unittest.cc
index c95a14ae5f6..04666db9ca6 100644
--- a/chromium/google_apis/gaia/oauth2_api_call_flow_unittest.cc
+++ b/chromium/google_apis/gaia/oauth2_api_call_flow_unittest.cc
@@ -8,7 +8,7 @@
#include <memory>
#include <string>
-#include <vector>
+#include <utility>
#include "base/message_loop/message_loop.h"
#include "base/time/time.h"
@@ -39,6 +39,7 @@ using net::URLFetcherFactory;
using net::URLRequestContextGetter;
using net::URLRequestStatus;
using testing::_;
+using testing::ByMove;
using testing::Return;
using testing::StrictMock;
@@ -64,13 +65,13 @@ class MockUrlFetcherFactory : public ScopedURLFetcherFactory,
}
virtual ~MockUrlFetcherFactory() {}
- MOCK_METHOD5(
- CreateURLFetcherMock,
- URLFetcher*(int id,
- const GURL& url,
- URLFetcher::RequestType request_type,
- URLFetcherDelegate* d,
- net::NetworkTrafficAnnotationTag traffic_annotation));
+ MOCK_METHOD5(CreateURLFetcherMock,
+ std::unique_ptr<URLFetcher>(
+ int id,
+ const GURL& url,
+ URLFetcher::RequestType request_type,
+ URLFetcherDelegate* d,
+ net::NetworkTrafficAnnotationTag traffic_annotation));
std::unique_ptr<URLFetcher> CreateURLFetcher(
int id,
@@ -78,8 +79,7 @@ class MockUrlFetcherFactory : public ScopedURLFetcherFactory,
URLFetcher::RequestType request_type,
URLFetcherDelegate* d,
net::NetworkTrafficAnnotationTag traffic_annotation) override {
- return std::unique_ptr<URLFetcher>(
- CreateURLFetcherMock(id, url, request_type, d, traffic_annotation));
+ return CreateURLFetcherMock(id, url, request_type, d, traffic_annotation);
}
};
@@ -88,16 +88,13 @@ class MockApiCallFlow : public OAuth2ApiCallFlow {
MockApiCallFlow() {}
~MockApiCallFlow() {}
- MOCK_METHOD0(CreateApiCallUrl, GURL ());
- MOCK_METHOD0(CreateApiCallBody, std::string ());
- MOCK_METHOD1(ProcessApiCallSuccess,
- void (const URLFetcher* source));
- MOCK_METHOD1(ProcessApiCallFailure,
- void (const URLFetcher* source));
- MOCK_METHOD1(ProcessNewAccessToken,
- void (const std::string& access_token));
+ MOCK_METHOD0(CreateApiCallUrl, GURL());
+ MOCK_METHOD0(CreateApiCallBody, std::string());
+ MOCK_METHOD1(ProcessApiCallSuccess, void(const URLFetcher* source));
+ MOCK_METHOD1(ProcessApiCallFailure, void(const URLFetcher* source));
+ MOCK_METHOD1(ProcessNewAccessToken, void(const std::string& access_token));
MOCK_METHOD1(ProcessMintAccessTokenFailure,
- void (const GoogleServiceAuthError& error));
+ void(const GoogleServiceAuthError& error));
net::PartialNetworkTrafficAnnotationTag GetNetworkTrafficAnnotationTag() {
return PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS;
@@ -109,13 +106,15 @@ class MockApiCallFlow : public OAuth2ApiCallFlow {
class OAuth2ApiCallFlowTest : public testing::Test {
protected:
OAuth2ApiCallFlowTest()
- : request_context_getter_(new net::TestURLRequestContextGetter(
- message_loop_.task_runner())) {}
-
- TestURLFetcher* CreateURLFetcher(
- const GURL& url, bool fetch_succeeds,
- int response_code, const std::string& body) {
- TestURLFetcher* url_fetcher = new TestURLFetcher(0, url, &flow_);
+ : request_context_getter_(
+ base::MakeRefCounted<net::TestURLRequestContextGetter>(
+ message_loop_.task_runner())) {}
+
+ std::unique_ptr<TestURLFetcher> CreateURLFetcher(const GURL& url,
+ bool fetch_succeeds,
+ int response_code,
+ const std::string& body) {
+ auto url_fetcher = std::make_unique<TestURLFetcher>(0, url, &flow_);
net::Error error = fetch_succeeds ? net::OK : net::ERR_FAILED;
url_fetcher->set_status(URLRequestStatus::FromError(error));
@@ -133,11 +132,12 @@ class OAuth2ApiCallFlowTest : public testing::Test {
GURL url(CreateApiUrl());
EXPECT_CALL(flow_, CreateApiCallBody()).WillOnce(Return(body));
EXPECT_CALL(flow_, CreateApiCallUrl()).WillOnce(Return(url));
- TestURLFetcher* url_fetcher =
+ std::unique_ptr<TestURLFetcher> url_fetcher =
CreateURLFetcher(url, succeeds, status, std::string());
+ TestURLFetcher* url_fetcher_ptr = url_fetcher.get();
EXPECT_CALL(factory_, CreateURLFetcherMock(_, url, _, _, _))
- .WillOnce(Return(url_fetcher));
- return url_fetcher;
+ .WillOnce(Return(ByMove(std::move(url_fetcher))));
+ return url_fetcher_ptr;
}
base::MessageLoop message_loop_;
diff --git a/chromium/google_apis/gaia/oauth2_token_service.cc b/chromium/google_apis/gaia/oauth2_token_service.cc
index c75a1407dd4..542435cbb90 100644
--- a/chromium/google_apis/gaia/oauth2_token_service.cc
+++ b/chromium/google_apis/gaia/oauth2_token_service.cc
@@ -574,7 +574,14 @@ bool OAuth2TokenService::RefreshTokenIsAvailable(
bool OAuth2TokenService::RefreshTokenHasError(
const std::string& account_id) const {
- return delegate_->RefreshTokenHasError(account_id);
+ return GetAuthError(account_id) != GoogleServiceAuthError::AuthErrorNone();
+}
+
+GoogleServiceAuthError OAuth2TokenService::GetAuthError(
+ const std::string& account_id) const {
+ GoogleServiceAuthError error = delegate_->GetAuthError(account_id);
+ DCHECK(!error.IsTransientError());
+ return error;
}
void OAuth2TokenService::RevokeAllCredentials() {
diff --git a/chromium/google_apis/gaia/oauth2_token_service.h b/chromium/google_apis/gaia/oauth2_token_service.h
index f1e0f88107c..9f279c52502 100644
--- a/chromium/google_apis/gaia/oauth2_token_service.h
+++ b/chromium/google_apis/gaia/oauth2_token_service.h
@@ -110,6 +110,11 @@ class OAuth2TokenService {
virtual void OnStartBatchChanges() {}
// Sent after a batch of refresh token changes is done.
virtual void OnEndBatchChanges() {}
+ // Called when the authentication error state for |account_id| has changed.
+ // Note: It is always called after |OnRefreshTokenAvailable| when refresh
+ // token is updated. It is not called when the refresh token is revoked.
+ virtual void OnAuthErrorChanged(const std::string& account_id,
+ const GoogleServiceAuthError& auth_error) {}
protected:
virtual ~Observer() {}
@@ -186,10 +191,14 @@ class OAuth2TokenService {
// |StartRequest| will result in a Consumer::OnGetTokenFailure callback.
bool RefreshTokenIsAvailable(const std::string& account_id) const;
- // Returns true if a refresh token exists for |account_id| and it is in an
- // error state.
+ // Returns true if a refresh token exists for |account_id| and it is in a
+ // persistent error state.
bool RefreshTokenHasError(const std::string& account_id) const;
+ // Returns the auth error associated with |account_id|. Only persistent errors
+ // will be returned.
+ GoogleServiceAuthError GetAuthError(const std::string& account_id) const;
+
// This method cancels all token requests, revoke all refresh tokens and
// cached access tokens.
void RevokeAllCredentials();
diff --git a/chromium/google_apis/gaia/oauth2_token_service_delegate.cc b/chromium/google_apis/gaia/oauth2_token_service_delegate.cc
index ce2f37ef6f9..aa143e02e6a 100644
--- a/chromium/google_apis/gaia/oauth2_token_service_delegate.cc
+++ b/chromium/google_apis/gaia/oauth2_token_service_delegate.cc
@@ -51,11 +51,6 @@ void OAuth2TokenServiceDelegate::RemoveObserver(
observer_list_.RemoveObserver(observer);
}
-// static
-bool OAuth2TokenServiceDelegate::IsError(const GoogleServiceAuthError& error) {
- return error.IsPersistentError();
-}
-
void OAuth2TokenServiceDelegate::StartBatchChanges() {
++batch_change_depth_;
if (batch_change_depth_ == 1) {
@@ -90,14 +85,21 @@ void OAuth2TokenServiceDelegate::FireRefreshTokensLoaded() {
observer.OnRefreshTokensLoaded();
}
+void OAuth2TokenServiceDelegate::FireAuthErrorChanged(
+ const std::string& account_id,
+ const GoogleServiceAuthError& error) {
+ for (auto& observer : observer_list_)
+ observer.OnAuthErrorChanged(account_id, error);
+}
+
net::URLRequestContextGetter* OAuth2TokenServiceDelegate::GetRequestContext()
const {
return nullptr;
}
-bool OAuth2TokenServiceDelegate::RefreshTokenHasError(
+GoogleServiceAuthError OAuth2TokenServiceDelegate::GetAuthError(
const std::string& account_id) const {
- return false;
+ return GoogleServiceAuthError::AuthErrorNone();
}
std::vector<std::string> OAuth2TokenServiceDelegate::GetAccounts() {
diff --git a/chromium/google_apis/gaia/oauth2_token_service_delegate.h b/chromium/google_apis/gaia/oauth2_token_service_delegate.h
index 283d4f25f0f..101fb8e2c98 100644
--- a/chromium/google_apis/gaia/oauth2_token_service_delegate.h
+++ b/chromium/google_apis/gaia/oauth2_token_service_delegate.h
@@ -40,7 +40,8 @@ class OAuth2TokenServiceDelegate {
OAuth2AccessTokenConsumer* consumer) = 0;
virtual bool RefreshTokenIsAvailable(const std::string& account_id) const = 0;
- virtual bool RefreshTokenHasError(const std::string& account_id) const;
+ virtual GoogleServiceAuthError GetAuthError(
+ const std::string& account_id) const;
virtual void UpdateAuthError(const std::string& account_id,
const GoogleServiceAuthError& error) {}
@@ -75,10 +76,13 @@ class OAuth2TokenServiceDelegate {
virtual LoadCredentialsState GetLoadCredentialsState() const;
protected:
- // Called by subclasses to notify observers.
+ // Called by subclasses to notify observers. Some are virtual to allow Android
+ // to broadcast the notifications to Java code.
virtual void FireRefreshTokenAvailable(const std::string& account_id);
virtual void FireRefreshTokenRevoked(const std::string& account_id);
virtual void FireRefreshTokensLoaded();
+ void FireAuthErrorChanged(const std::string& account_id,
+ const GoogleServiceAuthError& error);
// Helper class to scope batch changes.
class ScopedBatchChange {
@@ -91,12 +95,6 @@ class OAuth2TokenServiceDelegate {
DISALLOW_COPY_AND_ASSIGN(ScopedBatchChange);
};
- // This function is called by derived classes to help implement
- // RefreshTokenHasError(). It centralizes the code for determining if
- // |error| is worthy of being reported as an error for purposes of
- // RefreshTokenHasError().
- static bool IsError(const GoogleServiceAuthError& error);
-
private:
// List of observers to notify when refresh token availability changes.
// Makes sure list is empty on destruction.
diff --git a/chromium/google_apis/gcm/BUILD.gn b/chromium/google_apis/gcm/BUILD.gn
index 298b5de84a2..0a6ccbb80d5 100644
--- a/chromium/google_apis/gcm/BUILD.gn
+++ b/chromium/google_apis/gcm/BUILD.gn
@@ -67,6 +67,7 @@ component("gcm") {
"//base",
"//base/third_party/dynamic_annotations",
"//net",
+ "//services/network:network_service",
"//third_party/leveldatabase",
"//url",
]
diff --git a/chromium/google_apis/gcm/DEPS b/chromium/google_apis/gcm/DEPS
index 047dc1564b5..a044cbe8349 100644
--- a/chromium/google_apis/gcm/DEPS
+++ b/chromium/google_apis/gcm/DEPS
@@ -10,4 +10,5 @@ include_rules = [
"+google", # For third_party/protobuf/src.
"+net",
"+third_party/leveldatabase",
+ "+services/network",
]
diff --git a/chromium/google_apis/gcm/engine/connection_factory_impl.cc b/chromium/google_apis/gcm/engine/connection_factory_impl.cc
index cfffcb20ba7..31942daa297 100644
--- a/chromium/google_apis/gcm/engine/connection_factory_impl.cc
+++ b/chromium/google_apis/gcm/engine/connection_factory_impl.cc
@@ -18,11 +18,13 @@
#include "net/base/net_errors.h"
#include "net/http/http_network_session.h"
#include "net/http/http_request_headers.h"
+#include "net/http/proxy_fallback.h"
#include "net/log/net_log_source_type.h"
#include "net/proxy_resolution/proxy_info.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/client_socket_pool_manager.h"
#include "net/ssl/ssl_config_service.h"
+#include "services/network/proxy_resolving_client_socket.h"
namespace gcm {
@@ -60,9 +62,6 @@ ConnectionFactoryImpl::ConnectionFactoryImpl(
backoff_policy_(backoff_policy),
gcm_network_session_(gcm_network_session),
http_network_session_(http_network_session),
- net_log_(
- net::NetLogWithSource::Make(net_log, net::NetLogSourceType::SOCKET)),
- proxy_resolve_request_(NULL),
connecting_(false),
waiting_for_backoff_(false),
waiting_for_network_online_(false),
@@ -78,11 +77,6 @@ ConnectionFactoryImpl::ConnectionFactoryImpl(
ConnectionFactoryImpl::~ConnectionFactoryImpl() {
CloseSocket();
net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
- if (proxy_resolve_request_) {
- gcm_network_session_->proxy_resolution_service()->CancelRequest(
- proxy_resolve_request_);
- proxy_resolve_request_ = NULL;
- }
}
void ConnectionFactoryImpl::Initialize(
@@ -298,11 +292,11 @@ GURL ConnectionFactoryImpl::GetCurrentEndpoint() const {
}
net::IPEndPoint ConnectionFactoryImpl::GetPeerIP() {
- if (!socket_handle_.socket())
+ if (!socket_)
return net::IPEndPoint();
net::IPEndPoint ip_endpoint;
- int result = socket_handle_.socket()->GetPeerAddress(&ip_endpoint);
+ int result = socket_->GetPeerAddress(&ip_endpoint);
if (result != net::OK)
return net::IPEndPoint();
@@ -317,7 +311,7 @@ void ConnectionFactoryImpl::ConnectImpl() {
void ConnectionFactoryImpl::StartConnection() {
DCHECK(!IsEndpointReachable());
// TODO(zea): Make this a dcheck again. crbug.com/462319
- CHECK(!socket_handle_.socket());
+ CHECK(!socket_);
// TODO(zea): if the network is offline, don't attempt to connect.
// See crbug.com/396687
@@ -326,13 +320,14 @@ void ConnectionFactoryImpl::StartConnection() {
GURL current_endpoint = GetCurrentEndpoint();
recorder_->RecordConnectionInitiated(current_endpoint.host());
UpdateFromHttpNetworkSession();
- int status = gcm_network_session_->proxy_resolution_service()->ResolveProxy(
- current_endpoint, std::string(), &proxy_info_,
- base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone,
- weak_ptr_factory_.GetWeakPtr()),
- &proxy_resolve_request_, NULL, net_log_);
+ net::SSLConfig ssl_config;
+ gcm_network_session_->ssl_config_service()->GetSSLConfig(&ssl_config);
+ socket_ = std::make_unique<network::ProxyResolvingClientSocket>(
+ gcm_network_session_, ssl_config, current_endpoint, true /*use_tls*/);
+ int status = socket_->Connect(base::BindRepeating(
+ &ConnectionFactoryImpl::OnConnectDone, weak_ptr_factory_.GetWeakPtr()));
if (status != net::ERR_IO_PENDING)
- OnProxyResolveDone(status);
+ OnConnectDone(status);
}
void ConnectionFactoryImpl::InitHandler() {
@@ -380,8 +375,7 @@ void ConnectionFactoryImpl::InitHandler() {
"but does not have any effect on other Google Cloud messages."
)");
- connection_handler_->Init(login_request, traffic_annotation,
- socket_handle_.socket());
+ connection_handler_->Init(login_request, traffic_annotation, socket_.get());
}
std::unique_ptr<net::BackoffEntry> ConnectionFactoryImpl::CreateBackoffEntry(
@@ -404,15 +398,8 @@ base::TimeTicks ConnectionFactoryImpl::NowTicks() {
}
void ConnectionFactoryImpl::OnConnectDone(int result) {
+ DCHECK_NE(net::ERR_IO_PENDING, result);
if (result != net::OK) {
- // If the connection fails, try another proxy.
- result = ReconsiderProxyAfterError(result);
- // ReconsiderProxyAfterError either returns an error (in which case it is
- // not reconsidering a proxy) or returns ERR_IO_PENDING if it is considering
- // another proxy.
- DCHECK_NE(result, net::OK);
- if (result == net::ERR_IO_PENDING)
- return; // Proxy reconsideration pending. Return.
LOG(ERROR) << "Failed to connect to MCS endpoint with error " << result;
UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", false);
recorder_->RecordConnectionFailure(result);
@@ -435,9 +422,6 @@ void ConnectionFactoryImpl::OnConnectDone(int result) {
UMA_HISTOGRAM_BOOLEAN("GCM.ConnectionSuccessRate", true);
UMA_HISTOGRAM_COUNTS("GCM.ConnectionEndpoint", next_endpoint_);
- UMA_HISTOGRAM_BOOLEAN("GCM.ConnectedViaProxy",
- !(proxy_info_.is_empty() || proxy_info_.is_direct()));
- ReportSuccessfulProxyConnection();
recorder_->RecordConnectionSuccess();
// Reset the endpoint back to the default.
@@ -477,143 +461,15 @@ void ConnectionFactoryImpl::ConnectionHandlerCallback(int result) {
listener_->OnConnected(GetCurrentEndpoint(), GetPeerIP());
}
-// This has largely been copied from
-// HttpStreamFactoryImpl::Job::DoResolveProxyComplete. This should be
-// refactored into some common place.
-void ConnectionFactoryImpl::OnProxyResolveDone(int status) {
- proxy_resolve_request_ = NULL;
- DVLOG(1) << "Proxy resolution status: " << status;
-
- DCHECK_NE(status, net::ERR_IO_PENDING);
- if (status == net::OK) {
- // Remove unsupported proxies from the list.
- proxy_info_.RemoveProxiesWithoutScheme(
- net::ProxyServer::SCHEME_DIRECT |
- net::ProxyServer::SCHEME_HTTP | net::ProxyServer::SCHEME_HTTPS |
- net::ProxyServer::SCHEME_SOCKS4 | net::ProxyServer::SCHEME_SOCKS5);
-
- if (proxy_info_.is_empty()) {
- // No proxies/direct to choose from. This happens when we don't support
- // any of the proxies in the returned list.
- status = net::ERR_NO_SUPPORTED_PROXIES;
- }
- }
-
- if (status != net::OK) {
- // Failed to resolve proxy. Retry later.
- OnConnectDone(status);
- return;
- }
-
- DVLOG(1) << "Resolved proxy with PAC:" << proxy_info_.ToPacString();
-
- net::SSLConfig ssl_config;
- gcm_network_session_->ssl_config_service()->GetSSLConfig(&ssl_config);
- status = net::InitSocketHandleForTlsConnect(
- net::HostPortPair::FromURL(GetCurrentEndpoint()),
- gcm_network_session_,
- proxy_info_,
- ssl_config,
- ssl_config,
- net::PRIVACY_MODE_DISABLED,
- net_log_,
- &socket_handle_,
- base::Bind(&ConnectionFactoryImpl::OnConnectDone,
- weak_ptr_factory_.GetWeakPtr()));
- if (status != net::ERR_IO_PENDING)
- OnConnectDone(status);
-}
-
-// This has largely been copied from
-// HttpStreamFactoryImpl::Job::ReconsiderProxyAfterError. This should be
-// refactored into some common place.
-// This method reconsiders the proxy on certain errors. If it does reconsider
-// a proxy it always returns ERR_IO_PENDING and posts a call to
-// OnProxyResolveDone with the result of the reconsideration.
-int ConnectionFactoryImpl::ReconsiderProxyAfterError(int error) {
- DCHECK(!proxy_resolve_request_);
- DCHECK_NE(error, net::OK);
- DCHECK_NE(error, net::ERR_IO_PENDING);
- // A failure to resolve the hostname or any error related to establishing a
- // TCP connection could be grounds for trying a new proxy configuration.
- //
- // Why do this when a hostname cannot be resolved? Some URLs only make sense
- // to proxy servers. The hostname in those URLs might fail to resolve if we
- // are still using a non-proxy config. We need to check if a proxy config
- // now exists that corresponds to a proxy server that could load the URL.
- //
- switch (error) {
- case net::ERR_PROXY_CONNECTION_FAILED:
- case net::ERR_NAME_NOT_RESOLVED:
- case net::ERR_INTERNET_DISCONNECTED:
- case net::ERR_ADDRESS_UNREACHABLE:
- case net::ERR_CONNECTION_CLOSED:
- case net::ERR_CONNECTION_TIMED_OUT:
- case net::ERR_CONNECTION_RESET:
- case net::ERR_CONNECTION_REFUSED:
- case net::ERR_CONNECTION_ABORTED:
- case net::ERR_TIMED_OUT:
- case net::ERR_TUNNEL_CONNECTION_FAILED:
- case net::ERR_SOCKS_CONNECTION_FAILED:
- // This can happen in the case of trying to talk to a proxy using SSL, and
- // ending up talking to a captive portal that supports SSL instead.
- case net::ERR_PROXY_CERTIFICATE_INVALID:
- // This can happen when trying to talk SSL to a non-SSL server (Like a
- // captive portal).
- case net::ERR_SSL_PROTOCOL_ERROR:
- break;
- case net::ERR_SOCKS_CONNECTION_HOST_UNREACHABLE:
- // Remap the SOCKS-specific "host unreachable" error to a more
- // generic error code (this way consumers like the link doctor
- // know to substitute their error page).
- //
- // Note that if the host resolving was done by the SOCKS5 proxy, we can't
- // differentiate between a proxy-side "host not found" versus a proxy-side
- // "address unreachable" error, and will report both of these failures as
- // ERR_ADDRESS_UNREACHABLE.
- return net::ERR_ADDRESS_UNREACHABLE;
- default:
- return error;
- }
-
- net::SSLConfig ssl_config;
- gcm_network_session_->ssl_config_service()->GetSSLConfig(&ssl_config);
- if (proxy_info_.is_https() && ssl_config.send_client_cert) {
- gcm_network_session_->ssl_client_auth_cache()->Remove(
- proxy_info_.proxy_server().host_port_pair());
- }
-
- if (!proxy_info_.Fallback(error, net_log_)) {
- // There was nothing left to fall-back to, so fail the transaction
- // with the last connection error we got.
- return error;
- }
-
- CloseSocket();
-
- // If there is new proxy info, post OnProxyResolveDone to retry it.
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&ConnectionFactoryImpl::OnProxyResolveDone,
- weak_ptr_factory_.GetWeakPtr(), net::OK));
-
- return net::ERR_IO_PENDING;
-}
-
-void ConnectionFactoryImpl::ReportSuccessfulProxyConnection() {
- if (gcm_network_session_ && gcm_network_session_->proxy_resolution_service())
- gcm_network_session_->proxy_resolution_service()->ReportSuccess(proxy_info_,
- NULL);
-}
-
void ConnectionFactoryImpl::CloseSocket() {
// The connection handler needs to be reset, else it'll attempt to keep using
// the destroyed socket.
if (connection_handler_)
connection_handler_->Reset();
- if (socket_handle_.socket() && socket_handle_.socket()->IsConnected())
- socket_handle_.socket()->Disconnect();
- socket_handle_.Reset();
+ if (socket_)
+ socket_->Disconnect();
+ socket_ = nullptr;
}
void ConnectionFactoryImpl::UpdateFromHttpNetworkSession() {
diff --git a/chromium/google_apis/gcm/engine/connection_factory_impl.h b/chromium/google_apis/gcm/engine/connection_factory_impl.h
index 4fa1456a4d7..2b718aa9eaa 100644
--- a/chromium/google_apis/gcm/engine/connection_factory_impl.h
+++ b/chromium/google_apis/gcm/engine/connection_factory_impl.h
@@ -18,11 +18,12 @@
#include "net/base/backoff_entry.h"
#include "net/base/network_change_notifier.h"
#include "net/log/net_log_with_source.h"
-#include "net/proxy_resolution/proxy_info.h"
-#include "net/proxy_resolution/proxy_service.h"
-#include "net/socket/client_socket_handle.h"
#include "url/gurl.h"
+namespace network {
+class ProxyResolvingClientSocket;
+}
+
namespace net {
class HttpNetworkSession;
class NetLog;
@@ -123,12 +124,6 @@ class GCM_EXPORT ConnectionFactoryImpl :
// handshake. On connection/handshake failure, goes into backoff.
void ConnectImpl();
- // Proxy resolution and connection functions.
- void OnProxyResolveDone(int status);
- void OnProxyConnectDone(int status);
- int ReconsiderProxyAfterError(int error);
- void ReportSuccessfulProxyConnection();
-
// Closes the local socket if one is present, and resets connection handler.
void CloseSocket();
@@ -157,15 +152,8 @@ class GCM_EXPORT ConnectionFactoryImpl :
// HTTP Network session. If set, is used for extracting proxy auth
// credentials. If nullptr, is ignored.
net::HttpNetworkSession* http_network_session_;
- // Net log to use in connection attempts.
- net::NetLogWithSource net_log_;
- // The current proxy resolution request, if one exists. Owned by the proxy
- // service.
- net::ProxyResolutionService::Request* proxy_resolve_request_;
- // The current proxy info.
- net::ProxyInfo proxy_info_;
// The handle to the socket for the current connection, if one exists.
- net::ClientSocketHandle socket_handle_;
+ std::unique_ptr<network::ProxyResolvingClientSocket> socket_;
// Current backoff entry.
std::unique_ptr<net::BackoffEntry> backoff_entry_;
// Backoff entry from previous connection attempt. Updated on each login