| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 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/signin/oauth2_token_service_delegate_android.h" | 5 #include "chrome/browser/signin/oauth2_token_service_delegate_android.h" |
| 6 | 6 |
| 7 #include "base/android/context_utils.h" | 7 #include "base/android/context_utils.h" |
| 8 #include "base/android/jni_android.h" | 8 #include "base/android/jni_android.h" |
| 9 #include "base/android/jni_array.h" | 9 #include "base/android/jni_array.h" |
| 10 #include "base/android/jni_string.h" | 10 #include "base/android/jni_string.h" |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 ScopedJavaLocalRef<jstring> j_username = | 88 ScopedJavaLocalRef<jstring> j_username = |
| 89 ConvertUTF8ToJavaString(env, account_id_); | 89 ConvertUTF8ToJavaString(env, account_id_); |
| 90 ScopedJavaLocalRef<jstring> j_scope = ConvertUTF8ToJavaString(env, scope); | 90 ScopedJavaLocalRef<jstring> j_scope = ConvertUTF8ToJavaString(env, scope); |
| 91 std::unique_ptr<FetchOAuth2TokenCallback> heap_callback( | 91 std::unique_ptr<FetchOAuth2TokenCallback> heap_callback( |
| 92 new FetchOAuth2TokenCallback( | 92 new FetchOAuth2TokenCallback( |
| 93 base::Bind(&AndroidAccessTokenFetcher::OnAccessTokenResponse, | 93 base::Bind(&AndroidAccessTokenFetcher::OnAccessTokenResponse, |
| 94 weak_factory_.GetWeakPtr()))); | 94 weak_factory_.GetWeakPtr()))); |
| 95 | 95 |
| 96 // Call into Java to get a new token. | 96 // Call into Java to get a new token. |
| 97 Java_OAuth2TokenService_getOAuth2AuthToken( | 97 Java_OAuth2TokenService_getOAuth2AuthToken( |
| 98 env, base::android::GetApplicationContext(), j_username.obj(), | 98 env, base::android::GetApplicationContext(), j_username, j_scope, |
| 99 j_scope.obj(), reinterpret_cast<intptr_t>(heap_callback.release())); | 99 reinterpret_cast<intptr_t>(heap_callback.release())); |
| 100 } | 100 } |
| 101 | 101 |
| 102 void AndroidAccessTokenFetcher::CancelRequest() { | 102 void AndroidAccessTokenFetcher::CancelRequest() { |
| 103 request_was_cancelled_ = true; | 103 request_was_cancelled_ = true; |
| 104 } | 104 } |
| 105 | 105 |
| 106 void AndroidAccessTokenFetcher::OnAccessTokenResponse( | 106 void AndroidAccessTokenFetcher::OnAccessTokenResponse( |
| 107 const GoogleServiceAuthError& error, | 107 const GoogleServiceAuthError& error, |
| 108 const std::string& access_token, | 108 const std::string& access_token, |
| 109 const base::Time& expiration_time) { | 109 const base::Time& expiration_time) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 std::vector<std::string> accounts_id; | 163 std::vector<std::string> accounts_id; |
| 164 for (auto account_name : accounts) { | 164 for (auto account_name : accounts) { |
| 165 AccountInfo account_info = | 165 AccountInfo account_info = |
| 166 account_tracker_service_->FindAccountInfoByEmail(account_name); | 166 account_tracker_service_->FindAccountInfoByEmail(account_name); |
| 167 DCHECK(!account_info.gaia.empty()); | 167 DCHECK(!account_info.gaia.empty()); |
| 168 accounts_id.push_back(account_info.gaia); | 168 accounts_id.push_back(account_info.gaia); |
| 169 } | 169 } |
| 170 ScopedJavaLocalRef<jobjectArray> java_accounts( | 170 ScopedJavaLocalRef<jobjectArray> java_accounts( |
| 171 base::android::ToJavaArrayOfStrings(env, accounts_id)); | 171 base::android::ToJavaArrayOfStrings(env, accounts_id)); |
| 172 Java_OAuth2TokenService_saveStoredAccounts( | 172 Java_OAuth2TokenService_saveStoredAccounts( |
| 173 env, base::android::GetApplicationContext(), java_accounts.obj()); | 173 env, base::android::GetApplicationContext(), java_accounts); |
| 174 } | 174 } |
| 175 | 175 |
| 176 if (!is_testing_profile_) { | 176 if (!is_testing_profile_) { |
| 177 Java_OAuth2TokenService_validateAccounts( | 177 Java_OAuth2TokenService_validateAccounts( |
| 178 AttachCurrentThread(), java_ref_.obj(), | 178 AttachCurrentThread(), java_ref_, |
| 179 base::android::GetApplicationContext(), JNI_TRUE); | 179 base::android::GetApplicationContext(), JNI_TRUE); |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 | 182 |
| 183 OAuth2TokenServiceDelegateAndroid::~OAuth2TokenServiceDelegateAndroid() { | 183 OAuth2TokenServiceDelegateAndroid::~OAuth2TokenServiceDelegateAndroid() { |
| 184 } | 184 } |
| 185 | 185 |
| 186 // static | 186 // static |
| 187 ScopedJavaLocalRef<jobject> OAuth2TokenServiceDelegateAndroid::GetForProfile( | 187 ScopedJavaLocalRef<jobject> OAuth2TokenServiceDelegateAndroid::GetForProfile( |
| 188 JNIEnv* env, | 188 JNIEnv* env, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 207 bool OAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable( | 207 bool OAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable( |
| 208 const std::string& account_id) const { | 208 const std::string& account_id) const { |
| 209 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable" | 209 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable" |
| 210 << " account= " << account_id; | 210 << " account= " << account_id; |
| 211 std::string account_name = MapAccountIdToAccountName(account_id); | 211 std::string account_name = MapAccountIdToAccountName(account_id); |
| 212 JNIEnv* env = AttachCurrentThread(); | 212 JNIEnv* env = AttachCurrentThread(); |
| 213 ScopedJavaLocalRef<jstring> j_account_id = | 213 ScopedJavaLocalRef<jstring> j_account_id = |
| 214 ConvertUTF8ToJavaString(env, account_name); | 214 ConvertUTF8ToJavaString(env, account_name); |
| 215 jboolean refresh_token_is_available = | 215 jboolean refresh_token_is_available = |
| 216 Java_OAuth2TokenService_hasOAuth2RefreshToken( | 216 Java_OAuth2TokenService_hasOAuth2RefreshToken( |
| 217 env, base::android::GetApplicationContext(), j_account_id.obj()); | 217 env, base::android::GetApplicationContext(), j_account_id); |
| 218 return refresh_token_is_available == JNI_TRUE; | 218 return refresh_token_is_available == JNI_TRUE; |
| 219 } | 219 } |
| 220 | 220 |
| 221 bool OAuth2TokenServiceDelegateAndroid::RefreshTokenHasError( | 221 bool OAuth2TokenServiceDelegateAndroid::RefreshTokenHasError( |
| 222 const std::string& account_id) const { | 222 const std::string& account_id) const { |
| 223 auto it = errors_.find(account_id); | 223 auto it = errors_.find(account_id); |
| 224 // TODO(rogerta): should we distinguish between transient and persistent? | 224 // TODO(rogerta): should we distinguish between transient and persistent? |
| 225 return it == errors_.end() ? false : IsError(it->second.error); | 225 return it == errors_.end() ? false : IsError(it->second.error); |
| 226 } | 226 } |
| 227 | 227 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 void OAuth2TokenServiceDelegateAndroid::InvalidateAccessToken( | 278 void OAuth2TokenServiceDelegateAndroid::InvalidateAccessToken( |
| 279 const std::string& account_id, | 279 const std::string& account_id, |
| 280 const std::string& client_id, | 280 const std::string& client_id, |
| 281 const OAuth2TokenService::ScopeSet& scopes, | 281 const OAuth2TokenService::ScopeSet& scopes, |
| 282 const std::string& access_token) { | 282 const std::string& access_token) { |
| 283 ValidateAccountId(account_id); | 283 ValidateAccountId(account_id); |
| 284 JNIEnv* env = AttachCurrentThread(); | 284 JNIEnv* env = AttachCurrentThread(); |
| 285 ScopedJavaLocalRef<jstring> j_access_token = | 285 ScopedJavaLocalRef<jstring> j_access_token = |
| 286 ConvertUTF8ToJavaString(env, access_token); | 286 ConvertUTF8ToJavaString(env, access_token); |
| 287 Java_OAuth2TokenService_invalidateOAuth2AuthToken( | 287 Java_OAuth2TokenService_invalidateOAuth2AuthToken( |
| 288 env, base::android::GetApplicationContext(), j_access_token.obj()); | 288 env, base::android::GetApplicationContext(), j_access_token); |
| 289 } | 289 } |
| 290 | 290 |
| 291 void OAuth2TokenServiceDelegateAndroid::ValidateAccounts( | 291 void OAuth2TokenServiceDelegateAndroid::ValidateAccounts( |
| 292 JNIEnv* env, | 292 JNIEnv* env, |
| 293 const JavaParamRef<jobject>& obj, | 293 const JavaParamRef<jobject>& obj, |
| 294 const JavaParamRef<jstring>& j_current_acc, | 294 const JavaParamRef<jstring>& j_current_acc, |
| 295 jboolean j_force_notifications) { | 295 jboolean j_force_notifications) { |
| 296 std::string signed_in_account_name; | 296 std::string signed_in_account_name; |
| 297 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts from java"; | 297 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts from java"; |
| 298 if (j_current_acc) | 298 if (j_current_acc) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 if (currently_signed_in) { | 340 if (currently_signed_in) { |
| 341 java_accounts = base::android::ToJavaArrayOfStrings(env, curr_ids); | 341 java_accounts = base::android::ToJavaArrayOfStrings(env, curr_ids); |
| 342 } else { | 342 } else { |
| 343 java_accounts = | 343 java_accounts = |
| 344 base::android::ToJavaArrayOfStrings(env, std::vector<std::string>()); | 344 base::android::ToJavaArrayOfStrings(env, std::vector<std::string>()); |
| 345 } | 345 } |
| 346 | 346 |
| 347 // Save the current accounts in the token service before calling | 347 // Save the current accounts in the token service before calling |
| 348 // FireRefreshToken* methods. | 348 // FireRefreshToken* methods. |
| 349 Java_OAuth2TokenService_saveStoredAccounts( | 349 Java_OAuth2TokenService_saveStoredAccounts( |
| 350 env, base::android::GetApplicationContext(), java_accounts.obj()); | 350 env, base::android::GetApplicationContext(), java_accounts); |
| 351 | 351 |
| 352 for (const std::string& refreshed_id : refreshed_ids) | 352 for (const std::string& refreshed_id : refreshed_ids) |
| 353 FireRefreshTokenAvailable(refreshed_id); | 353 FireRefreshTokenAvailable(refreshed_id); |
| 354 for (const std::string& revoked_id : revoked_ids) | 354 for (const std::string& revoked_id : revoked_ids) |
| 355 FireRefreshTokenRevoked(revoked_id); | 355 FireRefreshTokenRevoked(revoked_id); |
| 356 if (fire_refresh_token_loaded_ == RT_WAIT_FOR_VALIDATION) { | 356 if (fire_refresh_token_loaded_ == RT_WAIT_FOR_VALIDATION) { |
| 357 fire_refresh_token_loaded_ = RT_LOADED; | 357 fire_refresh_token_loaded_ = RT_LOADED; |
| 358 FireRefreshTokensLoaded(); | 358 FireRefreshTokensLoaded(); |
| 359 } else if (fire_refresh_token_loaded_ == RT_LOAD_NOT_START) { | 359 } else if (fire_refresh_token_loaded_ == RT_LOAD_NOT_START) { |
| 360 fire_refresh_token_loaded_ = RT_HAS_BEEN_VALIDATED; | 360 fire_refresh_token_loaded_ = RT_HAS_BEEN_VALIDATED; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 442 void OAuth2TokenServiceDelegateAndroid::FireRefreshTokenAvailable( | 442 void OAuth2TokenServiceDelegateAndroid::FireRefreshTokenAvailable( |
| 443 const std::string& account_id) { | 443 const std::string& account_id) { |
| 444 DCHECK(!account_id.empty()); | 444 DCHECK(!account_id.empty()); |
| 445 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::FireRefreshTokenAvailable id=" | 445 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::FireRefreshTokenAvailable id=" |
| 446 << account_id; | 446 << account_id; |
| 447 std::string account_name = MapAccountIdToAccountName(account_id); | 447 std::string account_name = MapAccountIdToAccountName(account_id); |
| 448 DCHECK(!account_name.empty()); | 448 DCHECK(!account_name.empty()); |
| 449 JNIEnv* env = AttachCurrentThread(); | 449 JNIEnv* env = AttachCurrentThread(); |
| 450 ScopedJavaLocalRef<jstring> j_account_name = | 450 ScopedJavaLocalRef<jstring> j_account_name = |
| 451 ConvertUTF8ToJavaString(env, account_name); | 451 ConvertUTF8ToJavaString(env, account_name); |
| 452 Java_OAuth2TokenService_notifyRefreshTokenAvailable(env, java_ref_.obj(), | 452 Java_OAuth2TokenService_notifyRefreshTokenAvailable(env, java_ref_, |
| 453 j_account_name.obj()); | 453 j_account_name); |
| 454 OAuth2TokenServiceDelegate::FireRefreshTokenAvailable(account_id); | 454 OAuth2TokenServiceDelegate::FireRefreshTokenAvailable(account_id); |
| 455 } | 455 } |
| 456 | 456 |
| 457 void OAuth2TokenServiceDelegateAndroid::FireRefreshTokenRevokedFromJava( | 457 void OAuth2TokenServiceDelegateAndroid::FireRefreshTokenRevokedFromJava( |
| 458 JNIEnv* env, | 458 JNIEnv* env, |
| 459 const JavaParamRef<jobject>& obj, | 459 const JavaParamRef<jobject>& obj, |
| 460 const JavaParamRef<jstring>& account_name) { | 460 const JavaParamRef<jstring>& account_name) { |
| 461 std::string account_id = | 461 std::string account_id = |
| 462 MapAccountNameToAccountId(ConvertJavaStringToUTF8(env, account_name)); | 462 MapAccountNameToAccountId(ConvertJavaStringToUTF8(env, account_name)); |
| 463 // Notify native observers. | 463 // Notify native observers. |
| 464 FireRefreshTokenRevoked(account_id); | 464 FireRefreshTokenRevoked(account_id); |
| 465 } | 465 } |
| 466 | 466 |
| 467 void OAuth2TokenServiceDelegateAndroid::FireRefreshTokenRevoked( | 467 void OAuth2TokenServiceDelegateAndroid::FireRefreshTokenRevoked( |
| 468 const std::string& account_id) { | 468 const std::string& account_id) { |
| 469 DCHECK(!account_id.empty()); | 469 DCHECK(!account_id.empty()); |
| 470 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::FireRefreshTokenRevoked id=" | 470 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::FireRefreshTokenRevoked id=" |
| 471 << account_id; | 471 << account_id; |
| 472 std::string account_name = MapAccountIdToAccountName(account_id); | 472 std::string account_name = MapAccountIdToAccountName(account_id); |
| 473 if (!account_name.empty()) { | 473 if (!account_name.empty()) { |
| 474 JNIEnv* env = AttachCurrentThread(); | 474 JNIEnv* env = AttachCurrentThread(); |
| 475 ScopedJavaLocalRef<jstring> j_account_name = | 475 ScopedJavaLocalRef<jstring> j_account_name = |
| 476 ConvertUTF8ToJavaString(env, account_name); | 476 ConvertUTF8ToJavaString(env, account_name); |
| 477 Java_OAuth2TokenService_notifyRefreshTokenRevoked(env, java_ref_.obj(), | 477 Java_OAuth2TokenService_notifyRefreshTokenRevoked(env, java_ref_, |
| 478 j_account_name.obj()); | 478 j_account_name); |
| 479 } else { | 479 } else { |
| 480 // Current prognosis is that we have an unmigrated account which is due for | 480 // Current prognosis is that we have an unmigrated account which is due for |
| 481 // deletion. Record a histogram to debug this. | 481 // deletion. Record a histogram to debug this. |
| 482 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.AccountRevoked.MigrationState", | 482 UMA_HISTOGRAM_ENUMERATION("OAuth2Login.AccountRevoked.MigrationState", |
| 483 account_tracker_service_->GetMigrationState(), | 483 account_tracker_service_->GetMigrationState(), |
| 484 AccountTrackerService::NUM_MIGRATION_STATES); | 484 AccountTrackerService::NUM_MIGRATION_STATES); |
| 485 bool is_email_id = account_id.find('@') != std::string::npos; | 485 bool is_email_id = account_id.find('@') != std::string::npos; |
| 486 UMA_HISTOGRAM_BOOLEAN("OAuth2Login.AccountRevoked.IsEmailId", is_email_id); | 486 UMA_HISTOGRAM_BOOLEAN("OAuth2Login.AccountRevoked.IsEmailId", is_email_id); |
| 487 } | 487 } |
| 488 OAuth2TokenServiceDelegate::FireRefreshTokenRevoked(account_id); | 488 OAuth2TokenServiceDelegate::FireRefreshTokenRevoked(account_id); |
| 489 } | 489 } |
| 490 | 490 |
| 491 void OAuth2TokenServiceDelegateAndroid::FireRefreshTokensLoadedFromJava( | 491 void OAuth2TokenServiceDelegateAndroid::FireRefreshTokensLoadedFromJava( |
| 492 JNIEnv* env, | 492 JNIEnv* env, |
| 493 const JavaParamRef<jobject>& obj) { | 493 const JavaParamRef<jobject>& obj) { |
| 494 // Notify native observers. | 494 // Notify native observers. |
| 495 FireRefreshTokensLoaded(); | 495 FireRefreshTokensLoaded(); |
| 496 } | 496 } |
| 497 | 497 |
| 498 void OAuth2TokenServiceDelegateAndroid::FireRefreshTokensLoaded() { | 498 void OAuth2TokenServiceDelegateAndroid::FireRefreshTokensLoaded() { |
| 499 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::FireRefreshTokensLoaded"; | 499 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::FireRefreshTokensLoaded"; |
| 500 JNIEnv* env = AttachCurrentThread(); | 500 JNIEnv* env = AttachCurrentThread(); |
| 501 Java_OAuth2TokenService_notifyRefreshTokensLoaded(env, java_ref_.obj()); | 501 Java_OAuth2TokenService_notifyRefreshTokensLoaded(env, java_ref_); |
| 502 OAuth2TokenServiceDelegate::FireRefreshTokensLoaded(); | 502 OAuth2TokenServiceDelegate::FireRefreshTokensLoaded(); |
| 503 } | 503 } |
| 504 | 504 |
| 505 void OAuth2TokenServiceDelegateAndroid::RevokeAllCredentials() { | 505 void OAuth2TokenServiceDelegateAndroid::RevokeAllCredentials() { |
| 506 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::RevokeAllCredentials"; | 506 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::RevokeAllCredentials"; |
| 507 ScopedBatchChange batch(this); | 507 ScopedBatchChange batch(this); |
| 508 std::vector<std::string> accounts_to_revoke = GetAccounts(); | 508 std::vector<std::string> accounts_to_revoke = GetAccounts(); |
| 509 | 509 |
| 510 // Clear accounts in the token service before calling | 510 // Clear accounts in the token service before calling |
| 511 // |FireRefreshTokenRevoked|. | 511 // |FireRefreshTokenRevoked|. |
| 512 JNIEnv* env = AttachCurrentThread(); | 512 JNIEnv* env = AttachCurrentThread(); |
| 513 ScopedJavaLocalRef<jobjectArray> java_accounts( | 513 ScopedJavaLocalRef<jobjectArray> java_accounts( |
| 514 base::android::ToJavaArrayOfStrings(env, std::vector<std::string>())); | 514 base::android::ToJavaArrayOfStrings(env, std::vector<std::string>())); |
| 515 Java_OAuth2TokenService_saveStoredAccounts( | 515 Java_OAuth2TokenService_saveStoredAccounts( |
| 516 env, base::android::GetApplicationContext(), java_accounts.obj()); | 516 env, base::android::GetApplicationContext(), java_accounts); |
| 517 | 517 |
| 518 for (const std::string& account : accounts_to_revoke) | 518 for (const std::string& account : accounts_to_revoke) |
| 519 FireRefreshTokenRevoked(account); | 519 FireRefreshTokenRevoked(account); |
| 520 } | 520 } |
| 521 | 521 |
| 522 void OAuth2TokenServiceDelegateAndroid::LoadCredentials( | 522 void OAuth2TokenServiceDelegateAndroid::LoadCredentials( |
| 523 const std::string& primary_account_id) { | 523 const std::string& primary_account_id) { |
| 524 if (primary_account_id.empty()) { | 524 if (primary_account_id.empty()) { |
| 525 FireRefreshTokensLoaded(); | 525 FireRefreshTokensLoaded(); |
| 526 return; | 526 return; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 : isTransientError | 567 : isTransientError |
| 568 ? GoogleServiceAuthError::CONNECTION_FAILED | 568 ? GoogleServiceAuthError::CONNECTION_FAILED |
| 569 : GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); | 569 : GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); |
| 570 heap_callback->Run(err, token, base::Time()); | 570 heap_callback->Run(err, token, base::Time()); |
| 571 } | 571 } |
| 572 | 572 |
| 573 // static | 573 // static |
| 574 bool OAuth2TokenServiceDelegateAndroid::Register(JNIEnv* env) { | 574 bool OAuth2TokenServiceDelegateAndroid::Register(JNIEnv* env) { |
| 575 return RegisterNativesImpl(env); | 575 return RegisterNativesImpl(env); |
| 576 } | 576 } |
| OLD | NEW |