| 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/jni_android.h" | 7 #include "base/android/jni_android.h" |
| 8 #include "base/android/jni_array.h" | 8 #include "base/android/jni_array.h" |
| 9 #include "base/android/jni_string.h" | 9 #include "base/android/jni_string.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 | 131 |
| 132 bool OAuth2TokenServiceDelegateAndroid::is_testing_profile_ = false; | 132 bool OAuth2TokenServiceDelegateAndroid::is_testing_profile_ = false; |
| 133 | 133 |
| 134 OAuth2TokenServiceDelegateAndroid::ErrorInfo::ErrorInfo() | 134 OAuth2TokenServiceDelegateAndroid::ErrorInfo::ErrorInfo() |
| 135 : error(GoogleServiceAuthError::NONE) {} | 135 : error(GoogleServiceAuthError::NONE) {} |
| 136 | 136 |
| 137 OAuth2TokenServiceDelegateAndroid::ErrorInfo::ErrorInfo( | 137 OAuth2TokenServiceDelegateAndroid::ErrorInfo::ErrorInfo( |
| 138 const GoogleServiceAuthError& error) | 138 const GoogleServiceAuthError& error) |
| 139 : error(error) {} | 139 : error(error) {} |
| 140 | 140 |
| 141 OAuth2TokenServiceDelegateAndroid::OAuth2TokenServiceDelegateAndroid() { | 141 OAuth2TokenServiceDelegateAndroid::OAuth2TokenServiceDelegateAndroid( |
| 142 AccountTrackerService* account_tracker_service) |
| 143 : account_tracker_service_(account_tracker_service), |
| 144 fire_refresh_token_loaded_(RT_LOAD_NOT_START) { |
| 142 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ctor"; | 145 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ctor"; |
| 146 DCHECK(account_tracker_service_); |
| 143 JNIEnv* env = AttachCurrentThread(); | 147 JNIEnv* env = AttachCurrentThread(); |
| 144 base::android::ScopedJavaLocalRef<jobject> local_java_ref = | 148 base::android::ScopedJavaLocalRef<jobject> local_java_ref = |
| 145 Java_OAuth2TokenService_create(env, reinterpret_cast<intptr_t>(this)); | 149 Java_OAuth2TokenService_create(env, reinterpret_cast<intptr_t>(this)); |
| 146 java_ref_.Reset(env, local_java_ref.obj()); | 150 java_ref_.Reset(env, local_java_ref.obj()); |
| 151 |
| 152 if (account_tracker_service_->GetMigrationState() == |
| 153 AccountTrackerService::MIGRATION_IN_PROGRESS) { |
| 154 std::vector<std::string> accounts = GetAccounts(); |
| 155 std::vector<std::string> accounts_id; |
| 156 for (auto account_name : accounts) { |
| 157 AccountTrackerService::AccountInfo account_info = |
| 158 account_tracker_service_->FindAccountInfoByEmail(account_name); |
| 159 DCHECK(!account_info.gaia.empty()); |
| 160 accounts_id.push_back(account_info.gaia); |
| 161 } |
| 162 ScopedJavaLocalRef<jobjectArray> java_accounts( |
| 163 base::android::ToJavaArrayOfStrings(env, accounts_id)); |
| 164 Java_OAuth2TokenService_saveStoredAccounts( |
| 165 env, base::android::GetApplicationContext(), java_accounts.obj()); |
| 166 } |
| 167 |
| 168 if (!is_testing_profile_) { |
| 169 Java_OAuth2TokenService_validateAccounts( |
| 170 AttachCurrentThread(), java_ref_.obj(), |
| 171 base::android::GetApplicationContext(), JNI_TRUE); |
| 172 } |
| 147 } | 173 } |
| 148 | 174 |
| 149 OAuth2TokenServiceDelegateAndroid::~OAuth2TokenServiceDelegateAndroid() { | 175 OAuth2TokenServiceDelegateAndroid::~OAuth2TokenServiceDelegateAndroid() { |
| 150 } | 176 } |
| 151 | 177 |
| 152 // static | 178 // static |
| 153 jobject OAuth2TokenServiceDelegateAndroid::GetForProfile( | 179 jobject OAuth2TokenServiceDelegateAndroid::GetForProfile( |
| 154 JNIEnv* env, | 180 JNIEnv* env, |
| 155 jclass clazz, | 181 jclass clazz, |
| 156 jobject j_profile_android) { | 182 jobject j_profile_android) { |
| 157 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile_android); | 183 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile_android); |
| 158 ProfileOAuth2TokenService* service = | 184 ProfileOAuth2TokenService* service = |
| 159 ProfileOAuth2TokenServiceFactory::GetForProfile(profile); | 185 ProfileOAuth2TokenServiceFactory::GetForProfile(profile); |
| 160 OAuth2TokenServiceDelegate* delegate = service->GetDelegate(); | 186 OAuth2TokenServiceDelegate* delegate = service->GetDelegate(); |
| 161 return static_cast<OAuth2TokenServiceDelegateAndroid*>(delegate) | 187 return static_cast<OAuth2TokenServiceDelegateAndroid*>(delegate) |
| 162 ->java_ref_.obj(); | 188 ->java_ref_.obj(); |
| 163 } | 189 } |
| 164 | 190 |
| 165 static jobject GetForProfile(JNIEnv* env, | 191 static jobject GetForProfile(JNIEnv* env, |
| 166 jclass clazz, | 192 jclass clazz, |
| 167 jobject j_profile_android) { | 193 jobject j_profile_android) { |
| 168 return OAuth2TokenServiceDelegateAndroid::GetForProfile(env, clazz, | 194 return OAuth2TokenServiceDelegateAndroid::GetForProfile(env, clazz, |
| 169 j_profile_android); | 195 j_profile_android); |
| 170 } | 196 } |
| 171 | 197 |
| 172 void OAuth2TokenServiceDelegateAndroid::Initialize() { | |
| 173 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::Initialize"; | |
| 174 if (!is_testing_profile_) { | |
| 175 Java_OAuth2TokenService_validateAccounts( | |
| 176 AttachCurrentThread(), java_ref_.obj(), | |
| 177 base::android::GetApplicationContext(), JNI_TRUE); | |
| 178 } | |
| 179 } | |
| 180 | |
| 181 bool OAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable( | 198 bool OAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable( |
| 182 const std::string& account_id) const { | 199 const std::string& account_id) const { |
| 200 std::string account_name = MapAccountIdToAccountName(account_id); |
| 183 JNIEnv* env = AttachCurrentThread(); | 201 JNIEnv* env = AttachCurrentThread(); |
| 184 ScopedJavaLocalRef<jstring> j_account_id = | 202 ScopedJavaLocalRef<jstring> j_account_id = |
| 185 ConvertUTF8ToJavaString(env, account_id); | 203 ConvertUTF8ToJavaString(env, account_name); |
| 186 jboolean refresh_token_is_available = | 204 jboolean refresh_token_is_available = |
| 187 Java_OAuth2TokenService_hasOAuth2RefreshToken( | 205 Java_OAuth2TokenService_hasOAuth2RefreshToken( |
| 188 env, base::android::GetApplicationContext(), j_account_id.obj()); | 206 env, base::android::GetApplicationContext(), j_account_id.obj()); |
| 189 return refresh_token_is_available == JNI_TRUE; | 207 return refresh_token_is_available == JNI_TRUE; |
| 190 } | 208 } |
| 191 | 209 |
| 192 bool OAuth2TokenServiceDelegateAndroid::RefreshTokenHasError( | 210 bool OAuth2TokenServiceDelegateAndroid::RefreshTokenHasError( |
| 193 const std::string& account_id) const { | 211 const std::string& account_id) const { |
| 194 auto it = errors_.find(account_id); | 212 auto it = errors_.find(account_id); |
| 195 // TODO(rogerta): should we distinguish between transient and persistent? | 213 // TODO(rogerta): should we distinguish between transient and persistent? |
| (...skipping 17 matching lines...) Expand all Loading... |
| 213 ScopedJavaLocalRef<jobjectArray> j_accounts = | 231 ScopedJavaLocalRef<jobjectArray> j_accounts = |
| 214 Java_OAuth2TokenService_getAccounts( | 232 Java_OAuth2TokenService_getAccounts( |
| 215 env, base::android::GetApplicationContext()); | 233 env, base::android::GetApplicationContext()); |
| 216 // TODO(fgorski): We may decide to filter out some of the accounts. | 234 // TODO(fgorski): We may decide to filter out some of the accounts. |
| 217 base::android::AppendJavaStringArrayToStringVector(env, j_accounts.obj(), | 235 base::android::AppendJavaStringArrayToStringVector(env, j_accounts.obj(), |
| 218 &accounts); | 236 &accounts); |
| 219 return accounts; | 237 return accounts; |
| 220 } | 238 } |
| 221 | 239 |
| 222 std::vector<std::string> | 240 std::vector<std::string> |
| 223 OAuth2TokenServiceDelegateAndroid::GetSystemAccounts() { | 241 OAuth2TokenServiceDelegateAndroid::GetSystemAccountNames() { |
| 224 std::vector<std::string> accounts; | 242 std::vector<std::string> account_names; |
| 225 JNIEnv* env = AttachCurrentThread(); | 243 JNIEnv* env = AttachCurrentThread(); |
| 226 ScopedJavaLocalRef<jobjectArray> j_accounts = | 244 ScopedJavaLocalRef<jobjectArray> j_accounts = |
| 227 Java_OAuth2TokenService_getSystemAccounts( | 245 Java_OAuth2TokenService_getSystemAccountNames( |
| 228 env, base::android::GetApplicationContext()); | 246 env, base::android::GetApplicationContext()); |
| 229 base::android::AppendJavaStringArrayToStringVector(env, j_accounts.obj(), | 247 base::android::AppendJavaStringArrayToStringVector(env, j_accounts.obj(), |
| 230 &accounts); | 248 &account_names); |
| 231 return accounts; | 249 return account_names; |
| 232 } | 250 } |
| 233 | 251 |
| 234 OAuth2AccessTokenFetcher* | 252 OAuth2AccessTokenFetcher* |
| 235 OAuth2TokenServiceDelegateAndroid::CreateAccessTokenFetcher( | 253 OAuth2TokenServiceDelegateAndroid::CreateAccessTokenFetcher( |
| 236 const std::string& account_id, | 254 const std::string& account_id, |
| 237 net::URLRequestContextGetter* getter, | 255 net::URLRequestContextGetter* getter, |
| 238 OAuth2AccessTokenConsumer* consumer) { | 256 OAuth2AccessTokenConsumer* consumer) { |
| 239 ValidateAccountId(account_id); | 257 ValidateAccountId(account_id); |
| 240 return new AndroidAccessTokenFetcher(consumer, account_id); | 258 return new AndroidAccessTokenFetcher(consumer, |
| 259 MapAccountIdToAccountName(account_id)); |
| 241 } | 260 } |
| 242 | 261 |
| 243 void OAuth2TokenServiceDelegateAndroid::InvalidateAccessToken( | 262 void OAuth2TokenServiceDelegateAndroid::InvalidateAccessToken( |
| 244 const std::string& account_id, | 263 const std::string& account_id, |
| 245 const std::string& client_id, | 264 const std::string& client_id, |
| 246 const OAuth2TokenService::ScopeSet& scopes, | 265 const OAuth2TokenService::ScopeSet& scopes, |
| 247 const std::string& access_token) { | 266 const std::string& access_token) { |
| 248 ValidateAccountId(account_id); | 267 ValidateAccountId(account_id); |
| 249 JNIEnv* env = AttachCurrentThread(); | 268 JNIEnv* env = AttachCurrentThread(); |
| 250 ScopedJavaLocalRef<jstring> j_access_token = | 269 ScopedJavaLocalRef<jstring> j_access_token = |
| 251 ConvertUTF8ToJavaString(env, access_token); | 270 ConvertUTF8ToJavaString(env, access_token); |
| 252 Java_OAuth2TokenService_invalidateOAuth2AuthToken( | 271 Java_OAuth2TokenService_invalidateOAuth2AuthToken( |
| 253 env, base::android::GetApplicationContext(), j_access_token.obj()); | 272 env, base::android::GetApplicationContext(), j_access_token.obj()); |
| 254 } | 273 } |
| 255 | 274 |
| 256 void OAuth2TokenServiceDelegateAndroid::ValidateAccounts( | 275 void OAuth2TokenServiceDelegateAndroid::ValidateAccounts( |
| 257 JNIEnv* env, | 276 JNIEnv* env, |
| 258 jobject obj, | 277 jobject obj, |
| 259 jstring j_current_acc, | 278 jstring j_current_acc, |
| 260 jboolean j_force_notifications) { | 279 jboolean j_force_notifications) { |
| 261 std::string signed_in_account; | 280 std::string signed_in_account; |
| 262 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts from java"; | 281 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts from java"; |
| 263 if (j_current_acc) | 282 if (j_current_acc) |
| 264 signed_in_account = ConvertJavaStringToUTF8(env, j_current_acc); | 283 signed_in_account = ConvertJavaStringToUTF8(env, j_current_acc); |
| 265 if (!signed_in_account.empty()) | 284 if (!signed_in_account.empty()) |
| 266 signed_in_account = gaia::CanonicalizeEmail(signed_in_account); | 285 signed_in_account = gaia::CanonicalizeEmail(signed_in_account); |
| 267 ValidateAccounts(signed_in_account, j_force_notifications != JNI_FALSE); | 286 ValidateAccounts(MapAccountNameToAccountId(signed_in_account), |
| 287 j_force_notifications != JNI_FALSE); |
| 268 } | 288 } |
| 269 | 289 |
| 270 void OAuth2TokenServiceDelegateAndroid::ValidateAccounts( | 290 void OAuth2TokenServiceDelegateAndroid::ValidateAccounts( |
| 271 const std::string& signed_in_account, | 291 const std::string& signed_in_account, |
| 272 bool force_notifications) { | 292 bool force_notifications) { |
| 273 std::vector<std::string> prev_ids = GetAccounts(); | 293 std::vector<std::string> prev_ids = GetAccounts(); |
| 274 std::vector<std::string> curr_ids = GetSystemAccounts(); | 294 std::vector<std::string> curr_ids = GetSystemAccountNames(); |
| 275 std::vector<std::string> refreshed_ids; | 295 std::vector<std::string> refreshed_ids; |
| 276 std::vector<std::string> revoked_ids; | 296 std::vector<std::string> revoked_ids; |
| 277 | 297 |
| 278 // Canonicalize system accounts. |prev_ids| is already done. | |
| 279 for (size_t i = 0; i < curr_ids.size(); ++i) | 298 for (size_t i = 0; i < curr_ids.size(); ++i) |
| 280 curr_ids[i] = gaia::CanonicalizeEmail(curr_ids[i]); | 299 curr_ids[i] = MapAccountNameToAccountId(curr_ids[i]); |
| 300 |
| 281 for (size_t i = 0; i < prev_ids.size(); ++i) | 301 for (size_t i = 0; i < prev_ids.size(); ++i) |
| 282 ValidateAccountId(prev_ids[i]); | 302 ValidateAccountId(prev_ids[i]); |
| 283 | 303 |
| 284 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts:" | 304 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts:" |
| 285 << " sigined_in_account=" << signed_in_account | 305 << " sigined_in_account=" << signed_in_account |
| 286 << " prev_ids=" << prev_ids.size() << " curr_ids=" << curr_ids.size() | 306 << " prev_ids=" << prev_ids.size() << " curr_ids=" << curr_ids.size() |
| 287 << " force=" << (force_notifications ? "true" : "false"); | 307 << " force=" << (force_notifications ? "true" : "false"); |
| 288 | 308 |
| 289 if (!ValidateAccounts(signed_in_account, prev_ids, curr_ids, refreshed_ids, | 309 if (!ValidateAccounts(signed_in_account, prev_ids, curr_ids, refreshed_ids, |
| 290 revoked_ids, force_notifications)) { | 310 revoked_ids, force_notifications)) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 301 | 321 |
| 302 for (std::vector<std::string>::iterator it = refreshed_ids.begin(); | 322 for (std::vector<std::string>::iterator it = refreshed_ids.begin(); |
| 303 it != refreshed_ids.end(); it++) { | 323 it != refreshed_ids.end(); it++) { |
| 304 FireRefreshTokenAvailable(*it); | 324 FireRefreshTokenAvailable(*it); |
| 305 } | 325 } |
| 306 | 326 |
| 307 for (std::vector<std::string>::iterator it = revoked_ids.begin(); | 327 for (std::vector<std::string>::iterator it = revoked_ids.begin(); |
| 308 it != revoked_ids.end(); it++) { | 328 it != revoked_ids.end(); it++) { |
| 309 FireRefreshTokenRevoked(*it); | 329 FireRefreshTokenRevoked(*it); |
| 310 } | 330 } |
| 331 |
| 332 if (fire_refresh_token_loaded_ == RT_WAIT_FOR_VALIDATION) { |
| 333 fire_refresh_token_loaded_ = RT_LOADED; |
| 334 FireRefreshTokensLoaded(); |
| 335 } else if (fire_refresh_token_loaded_ == RT_LOAD_NOT_START) { |
| 336 fire_refresh_token_loaded_ = RT_HAS_BEEN_VALIDATED; |
| 337 } |
| 311 } | 338 } |
| 312 | 339 |
| 313 bool OAuth2TokenServiceDelegateAndroid::ValidateAccounts( | 340 bool OAuth2TokenServiceDelegateAndroid::ValidateAccounts( |
| 314 const std::string& signed_in_account, | 341 const std::string& signed_in_account, |
| 315 const std::vector<std::string>& prev_account_ids, | 342 const std::vector<std::string>& prev_account_ids, |
| 316 const std::vector<std::string>& curr_account_ids, | 343 const std::vector<std::string>& curr_account_ids, |
| 317 std::vector<std::string>& refreshed_ids, | 344 std::vector<std::string>& refreshed_ids, |
| 318 std::vector<std::string>& revoked_ids, | 345 std::vector<std::string>& revoked_ids, |
| 319 bool force_notifications) { | 346 bool force_notifications) { |
| 320 if (std::find(curr_account_ids.begin(), curr_account_ids.end(), | 347 if (std::find(curr_account_ids.begin(), curr_account_ids.end(), |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 | 471 |
| 445 // Clear everything on the Java side as well. | 472 // Clear everything on the Java side as well. |
| 446 std::vector<std::string> empty; | 473 std::vector<std::string> empty; |
| 447 JNIEnv* env = AttachCurrentThread(); | 474 JNIEnv* env = AttachCurrentThread(); |
| 448 ScopedJavaLocalRef<jobjectArray> java_accounts( | 475 ScopedJavaLocalRef<jobjectArray> java_accounts( |
| 449 base::android::ToJavaArrayOfStrings(env, empty)); | 476 base::android::ToJavaArrayOfStrings(env, empty)); |
| 450 Java_OAuth2TokenService_saveStoredAccounts( | 477 Java_OAuth2TokenService_saveStoredAccounts( |
| 451 env, base::android::GetApplicationContext(), java_accounts.obj()); | 478 env, base::android::GetApplicationContext(), java_accounts.obj()); |
| 452 } | 479 } |
| 453 | 480 |
| 481 void OAuth2TokenServiceDelegateAndroid::LoadCredentials( |
| 482 const std::string& primary_account_id) { |
| 483 if (fire_refresh_token_loaded_ == RT_HAS_BEEN_VALIDATED) { |
| 484 fire_refresh_token_loaded_ = RT_LOADED; |
| 485 FireRefreshTokensLoaded(); |
| 486 } else if (fire_refresh_token_loaded_ == RT_LOAD_NOT_START) { |
| 487 fire_refresh_token_loaded_ = RT_WAIT_FOR_VALIDATION; |
| 488 } |
| 489 } |
| 490 |
| 491 std::string OAuth2TokenServiceDelegateAndroid::MapAccountIdToAccountName( |
| 492 const std::string& account_id) const { |
| 493 std::string account_name = |
| 494 account_tracker_service_->GetAccountInfo(account_id).email; |
| 495 DCHECK(!account_name.empty() || account_id.empty()); |
| 496 return account_name; |
| 497 } |
| 498 |
| 499 std::string OAuth2TokenServiceDelegateAndroid::MapAccountNameToAccountId( |
| 500 const std::string& account_name) const { |
| 501 std::string account_id = |
| 502 account_tracker_service_->FindAccountInfoByEmail(account_name).account_id; |
| 503 DCHECK(!account_id.empty() || account_name.empty()); |
| 504 return account_id; |
| 505 } |
| 506 |
| 454 // Called from Java when fetching of an OAuth2 token is finished. The | 507 // Called from Java when fetching of an OAuth2 token is finished. The |
| 455 // |authToken| param is only valid when |result| is true. | 508 // |authToken| param is only valid when |result| is true. |
| 456 void OAuth2TokenFetched(JNIEnv* env, | 509 void OAuth2TokenFetched(JNIEnv* env, |
| 457 jclass clazz, | 510 jclass clazz, |
| 458 jstring authToken, | 511 jstring authToken, |
| 459 jlong nativeCallback) { | 512 jlong nativeCallback) { |
| 460 std::string token; | 513 std::string token; |
| 461 if (authToken) | 514 if (authToken) |
| 462 token = ConvertJavaStringToUTF8(env, authToken); | 515 token = ConvertJavaStringToUTF8(env, authToken); |
| 463 scoped_ptr<FetchOAuth2TokenCallback> heap_callback( | 516 scoped_ptr<FetchOAuth2TokenCallback> heap_callback( |
| 464 reinterpret_cast<FetchOAuth2TokenCallback*>(nativeCallback)); | 517 reinterpret_cast<FetchOAuth2TokenCallback*>(nativeCallback)); |
| 465 // Android does not provide enough information to know if the credentials are | 518 // Android does not provide enough information to know if the credentials are |
| 466 // wrong, so assume any error is transient by using CONNECTION_FAILED. | 519 // wrong, so assume any error is transient by using CONNECTION_FAILED. |
| 467 GoogleServiceAuthError err(authToken | 520 GoogleServiceAuthError err(authToken |
| 468 ? GoogleServiceAuthError::NONE | 521 ? GoogleServiceAuthError::NONE |
| 469 : GoogleServiceAuthError::CONNECTION_FAILED); | 522 : GoogleServiceAuthError::CONNECTION_FAILED); |
| 470 heap_callback->Run(err, token, base::Time()); | 523 heap_callback->Run(err, token, base::Time()); |
| 471 } | 524 } |
| 472 | 525 |
| 473 // static | 526 // static |
| 474 bool OAuth2TokenServiceDelegateAndroid::Register(JNIEnv* env) { | 527 bool OAuth2TokenServiceDelegateAndroid::Register(JNIEnv* env) { |
| 475 return RegisterNativesImpl(env); | 528 return RegisterNativesImpl(env); |
| 476 } | 529 } |
| OLD | NEW |