Chromium Code Reviews| 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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 124 scope += " "; | 124 scope += " "; |
| 125 scope += *it; | 125 scope += *it; |
| 126 } | 126 } |
| 127 return scope; | 127 return scope; |
| 128 } | 128 } |
| 129 | 129 |
| 130 } // namespace | 130 } // namespace |
| 131 | 131 |
| 132 bool OAuth2TokenServiceDelegateAndroid::is_testing_profile_ = false; | 132 bool OAuth2TokenServiceDelegateAndroid::is_testing_profile_ = false; |
| 133 | 133 |
| 134 OAuth2TokenServiceDelegateAndroid::OAuth2TokenServiceDelegateAndroid() { | 134 OAuth2TokenServiceDelegateAndroid::OAuth2TokenServiceDelegateAndroid() |
| 135 : account_tracker_service_(nullptr), | |
| 136 accounts_have_been_validated_(false), | |
| 137 should_fire_refresh_token_loaded_(false) { | |
| 135 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ctor"; | 138 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ctor"; |
| 136 JNIEnv* env = AttachCurrentThread(); | 139 JNIEnv* env = AttachCurrentThread(); |
| 137 base::android::ScopedJavaLocalRef<jobject> local_java_ref = | 140 base::android::ScopedJavaLocalRef<jobject> local_java_ref = |
| 138 Java_OAuth2TokenService_create(env, reinterpret_cast<intptr_t>(this)); | 141 Java_OAuth2TokenService_create(env, reinterpret_cast<intptr_t>(this)); |
| 139 java_ref_.Reset(env, local_java_ref.obj()); | 142 java_ref_.Reset(env, local_java_ref.obj()); |
| 140 } | 143 } |
| 141 | 144 |
| 142 OAuth2TokenServiceDelegateAndroid::~OAuth2TokenServiceDelegateAndroid() { | 145 OAuth2TokenServiceDelegateAndroid::~OAuth2TokenServiceDelegateAndroid() { |
| 143 } | 146 } |
| 144 | 147 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 155 ->java_ref_.obj(); | 158 ->java_ref_.obj(); |
| 156 } | 159 } |
| 157 | 160 |
| 158 static jobject GetForProfile(JNIEnv* env, | 161 static jobject GetForProfile(JNIEnv* env, |
| 159 jclass clazz, | 162 jclass clazz, |
| 160 jobject j_profile_android) { | 163 jobject j_profile_android) { |
| 161 return OAuth2TokenServiceDelegateAndroid::GetForProfile(env, clazz, | 164 return OAuth2TokenServiceDelegateAndroid::GetForProfile(env, clazz, |
| 162 j_profile_android); | 165 j_profile_android); |
| 163 } | 166 } |
| 164 | 167 |
| 165 void OAuth2TokenServiceDelegateAndroid::Initialize() { | 168 void OAuth2TokenServiceDelegateAndroid::Initialize( |
| 169 AccountTrackerService* account_tracker_service) { | |
| 166 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::Initialize"; | 170 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::Initialize"; |
| 171 | |
| 172 account_tracker_service_ = account_tracker_service; | |
| 173 DCHECK(account_tracker_service_); | |
| 174 if (account_tracker_service_->GetMigrationState() == | |
| 175 AccountTrackerService::MIGRATION_IN_PROGRESS) { | |
| 176 std::vector<std::string> accounts = GetAccounts(); | |
| 177 std::vector<std::string> accounts_id; | |
| 178 for (std::vector<std::string>::iterator it = accounts.begin(); | |
| 179 it != accounts.end(); ++it) { | |
| 180 AccountTrackerService::AccountInfo account_info = | |
| 181 account_tracker_service_->FindAccountInfoByEmail(*it); | |
| 182 if (account_info.gaia.empty()) | |
| 183 accounts_id.push_back(*it); | |
|
Roger Tawa OOO till Jul 10th
2015/08/14 15:01:22
If this is empty there is a bug. I don't think it
gogerald1
2015/08/18 01:14:27
Done.
| |
| 184 else | |
| 185 accounts_id.push_back(account_info.gaia); | |
| 186 } | |
| 187 JNIEnv* env = AttachCurrentThread(); | |
| 188 ScopedJavaLocalRef<jobjectArray> java_accounts( | |
| 189 base::android::ToJavaArrayOfStrings(env, accounts_id)); | |
| 190 Java_OAuth2TokenService_saveStoredAccounts( | |
| 191 env, base::android::GetApplicationContext(), java_accounts.obj()); | |
| 192 } | |
| 193 | |
| 167 if (!is_testing_profile_) { | 194 if (!is_testing_profile_) { |
| 168 Java_OAuth2TokenService_validateAccounts( | 195 Java_OAuth2TokenService_validateAccounts( |
| 169 AttachCurrentThread(), java_ref_.obj(), | 196 AttachCurrentThread(), java_ref_.obj(), |
| 170 base::android::GetApplicationContext(), JNI_TRUE); | 197 base::android::GetApplicationContext(), JNI_TRUE); |
| 171 } | 198 } |
| 172 } | 199 } |
| 173 | 200 |
| 174 bool OAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable( | 201 bool OAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable( |
| 175 const std::string& account_id) const { | 202 const std::string& account_id) const { |
| 203 std::string account_name = MapAccountIdToAccountName(account_id); | |
| 176 JNIEnv* env = AttachCurrentThread(); | 204 JNIEnv* env = AttachCurrentThread(); |
| 177 ScopedJavaLocalRef<jstring> j_account_id = | 205 ScopedJavaLocalRef<jstring> j_account_id = |
| 178 ConvertUTF8ToJavaString(env, account_id); | 206 ConvertUTF8ToJavaString(env, account_name); |
| 179 jboolean refresh_token_is_available = | 207 jboolean refresh_token_is_available = |
| 180 Java_OAuth2TokenService_hasOAuth2RefreshToken( | 208 Java_OAuth2TokenService_hasOAuth2RefreshToken( |
| 181 env, base::android::GetApplicationContext(), j_account_id.obj()); | 209 env, base::android::GetApplicationContext(), j_account_id.obj()); |
| 182 return refresh_token_is_available == JNI_TRUE; | 210 return refresh_token_is_available == JNI_TRUE; |
| 183 } | 211 } |
| 184 | 212 |
| 185 void OAuth2TokenServiceDelegateAndroid::UpdateAuthError( | 213 void OAuth2TokenServiceDelegateAndroid::UpdateAuthError( |
| 186 const std::string& account_id, | 214 const std::string& account_id, |
| 187 const GoogleServiceAuthError& error) { | 215 const GoogleServiceAuthError& error) { |
| 188 // TODO(rogerta): do we need to update anything, or does the system handle it? | 216 // TODO(rogerta): do we need to update anything, or does the system handle it? |
| 189 } | 217 } |
| 190 | 218 |
| 191 std::vector<std::string> OAuth2TokenServiceDelegateAndroid::GetAccounts() { | 219 std::vector<std::string> OAuth2TokenServiceDelegateAndroid::GetAccounts() { |
| 192 std::vector<std::string> accounts; | 220 std::vector<std::string> accounts; |
| 193 JNIEnv* env = AttachCurrentThread(); | 221 JNIEnv* env = AttachCurrentThread(); |
| 194 ScopedJavaLocalRef<jobjectArray> j_accounts = | 222 ScopedJavaLocalRef<jobjectArray> j_accounts = |
| 195 Java_OAuth2TokenService_getAccounts( | 223 Java_OAuth2TokenService_getAccounts( |
| 196 env, base::android::GetApplicationContext()); | 224 env, base::android::GetApplicationContext()); |
| 197 // TODO(fgorski): We may decide to filter out some of the accounts. | 225 // TODO(fgorski): We may decide to filter out some of the accounts. |
| 198 base::android::AppendJavaStringArrayToStringVector(env, j_accounts.obj(), | 226 base::android::AppendJavaStringArrayToStringVector(env, j_accounts.obj(), |
| 199 &accounts); | 227 &accounts); |
| 200 return accounts; | 228 return accounts; |
| 201 } | 229 } |
| 202 | 230 |
| 203 std::vector<std::string> | 231 std::vector<std::string> |
| 204 OAuth2TokenServiceDelegateAndroid::GetSystemAccounts() { | 232 OAuth2TokenServiceDelegateAndroid::GetSystemAccountNames() { |
| 205 std::vector<std::string> accounts; | 233 std::vector<std::string> account_names; |
| 206 JNIEnv* env = AttachCurrentThread(); | 234 JNIEnv* env = AttachCurrentThread(); |
| 207 ScopedJavaLocalRef<jobjectArray> j_accounts = | 235 ScopedJavaLocalRef<jobjectArray> j_accounts = |
| 208 Java_OAuth2TokenService_getSystemAccounts( | 236 Java_OAuth2TokenService_getSystemAccountNames( |
| 209 env, base::android::GetApplicationContext()); | 237 env, base::android::GetApplicationContext()); |
| 210 base::android::AppendJavaStringArrayToStringVector(env, j_accounts.obj(), | 238 base::android::AppendJavaStringArrayToStringVector(env, j_accounts.obj(), |
| 211 &accounts); | 239 &account_names); |
| 212 return accounts; | 240 return account_names; |
| 213 } | 241 } |
| 214 | 242 |
| 215 OAuth2AccessTokenFetcher* | 243 OAuth2AccessTokenFetcher* |
| 216 OAuth2TokenServiceDelegateAndroid::CreateAccessTokenFetcher( | 244 OAuth2TokenServiceDelegateAndroid::CreateAccessTokenFetcher( |
| 217 const std::string& account_id, | 245 const std::string& account_id, |
| 218 net::URLRequestContextGetter* getter, | 246 net::URLRequestContextGetter* getter, |
| 219 OAuth2AccessTokenConsumer* consumer) { | 247 OAuth2AccessTokenConsumer* consumer) { |
| 220 ValidateAccountId(account_id); | 248 std::string account_name = MapAccountIdToAccountName(account_id); |
| 221 return new AndroidAccessTokenFetcher(consumer, account_id); | 249 ValidateAccountId(account_name); |
|
Roger Tawa OOO till Jul 10th
2015/08/14 15:01:22
There is no need to map the account_id to a userna
gogerald1
2015/08/18 01:14:27
Done.
| |
| 250 return new AndroidAccessTokenFetcher(consumer, account_name); | |
| 222 } | 251 } |
| 223 | 252 |
| 224 void OAuth2TokenServiceDelegateAndroid::InvalidateAccessToken( | 253 void OAuth2TokenServiceDelegateAndroid::InvalidateAccessToken( |
| 225 const std::string& account_id, | 254 const std::string& account_id, |
| 226 const std::string& client_id, | 255 const std::string& client_id, |
| 227 const OAuth2TokenService::ScopeSet& scopes, | 256 const OAuth2TokenService::ScopeSet& scopes, |
| 228 const std::string& access_token) { | 257 const std::string& access_token) { |
| 229 ValidateAccountId(account_id); | 258 ValidateAccountId(MapAccountIdToAccountName(account_id)); |
| 230 JNIEnv* env = AttachCurrentThread(); | 259 JNIEnv* env = AttachCurrentThread(); |
| 231 ScopedJavaLocalRef<jstring> j_access_token = | 260 ScopedJavaLocalRef<jstring> j_access_token = |
| 232 ConvertUTF8ToJavaString(env, access_token); | 261 ConvertUTF8ToJavaString(env, access_token); |
| 233 Java_OAuth2TokenService_invalidateOAuth2AuthToken( | 262 Java_OAuth2TokenService_invalidateOAuth2AuthToken( |
| 234 env, base::android::GetApplicationContext(), j_access_token.obj()); | 263 env, base::android::GetApplicationContext(), j_access_token.obj()); |
| 235 } | 264 } |
| 236 | 265 |
| 237 void OAuth2TokenServiceDelegateAndroid::ValidateAccounts( | 266 void OAuth2TokenServiceDelegateAndroid::ValidateAccounts( |
| 238 JNIEnv* env, | 267 JNIEnv* env, |
| 239 jobject obj, | 268 jobject obj, |
| 240 jstring j_current_acc, | 269 jstring j_current_acc, |
| 241 jboolean j_force_notifications) { | 270 jboolean j_force_notifications) { |
| 242 std::string signed_in_account; | 271 std::string signed_in_account; |
| 243 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts from java"; | 272 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts from java"; |
| 244 if (j_current_acc) | 273 if (j_current_acc) |
| 245 signed_in_account = ConvertJavaStringToUTF8(env, j_current_acc); | 274 signed_in_account = ConvertJavaStringToUTF8(env, j_current_acc); |
| 246 if (!signed_in_account.empty()) | 275 if (!signed_in_account.empty()) |
| 247 signed_in_account = gaia::CanonicalizeEmail(signed_in_account); | 276 signed_in_account = gaia::CanonicalizeEmail(signed_in_account); |
| 248 ValidateAccounts(signed_in_account, j_force_notifications != JNI_FALSE); | 277 ValidateAccounts(MapAccountNameToAccountId(signed_in_account), |
| 278 j_force_notifications != JNI_FALSE); | |
| 249 } | 279 } |
| 250 | 280 |
| 251 void OAuth2TokenServiceDelegateAndroid::ValidateAccounts( | 281 void OAuth2TokenServiceDelegateAndroid::ValidateAccounts( |
| 252 const std::string& signed_in_account, | 282 const std::string& signed_in_account, |
| 253 bool force_notifications) { | 283 bool force_notifications) { |
| 254 std::vector<std::string> prev_ids = GetAccounts(); | 284 std::vector<std::string> prev_ids = GetAccounts(); |
| 255 std::vector<std::string> curr_ids = GetSystemAccounts(); | 285 std::vector<std::string> curr_ids = GetSystemAccountNames(); |
| 256 std::vector<std::string> refreshed_ids; | 286 std::vector<std::string> refreshed_ids; |
| 257 std::vector<std::string> revoked_ids; | 287 std::vector<std::string> revoked_ids; |
| 258 | 288 |
| 259 // Canonicalize system accounts. |prev_ids| is already done. | |
| 260 for (size_t i = 0; i < curr_ids.size(); ++i) | 289 for (size_t i = 0; i < curr_ids.size(); ++i) |
| 261 curr_ids[i] = gaia::CanonicalizeEmail(curr_ids[i]); | 290 curr_ids[i] = MapAccountNameToAccountId(curr_ids[i]); |
| 291 | |
| 262 for (size_t i = 0; i < prev_ids.size(); ++i) | 292 for (size_t i = 0; i < prev_ids.size(); ++i) |
| 263 ValidateAccountId(prev_ids[i]); | 293 ValidateAccountId(prev_ids[i]); |
| 264 | 294 |
| 265 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts:" | 295 DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ValidateAccounts:" |
| 266 << " sigined_in_account=" << signed_in_account | 296 << " sigined_in_account=" << signed_in_account |
| 267 << " prev_ids=" << prev_ids.size() << " curr_ids=" << curr_ids.size() | 297 << " prev_ids=" << prev_ids.size() << " curr_ids=" << curr_ids.size() |
| 268 << " force=" << (force_notifications ? "true" : "false"); | 298 << " force=" << (force_notifications ? "true" : "false"); |
| 269 | 299 |
| 270 if (!ValidateAccounts(signed_in_account, prev_ids, curr_ids, refreshed_ids, | 300 if (!ValidateAccounts(signed_in_account, prev_ids, curr_ids, refreshed_ids, |
| 271 revoked_ids, force_notifications)) { | 301 revoked_ids, force_notifications)) { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 282 | 312 |
| 283 for (std::vector<std::string>::iterator it = refreshed_ids.begin(); | 313 for (std::vector<std::string>::iterator it = refreshed_ids.begin(); |
| 284 it != refreshed_ids.end(); it++) { | 314 it != refreshed_ids.end(); it++) { |
| 285 FireRefreshTokenAvailable(*it); | 315 FireRefreshTokenAvailable(*it); |
| 286 } | 316 } |
| 287 | 317 |
| 288 for (std::vector<std::string>::iterator it = revoked_ids.begin(); | 318 for (std::vector<std::string>::iterator it = revoked_ids.begin(); |
| 289 it != revoked_ids.end(); it++) { | 319 it != revoked_ids.end(); it++) { |
| 290 FireRefreshTokenRevoked(*it); | 320 FireRefreshTokenRevoked(*it); |
| 291 } | 321 } |
| 322 | |
| 323 accounts_have_been_validated_ = true; | |
| 324 lock_.Acquire(); | |
| 325 if (should_fire_refresh_token_loaded_) { | |
| 326 should_fire_refresh_token_loaded_ = false; | |
| 327 FireRefreshTokensLoaded(); | |
| 328 } | |
| 329 lock_.Release(); | |
|
Roger Tawa OOO till Jul 10th
2015/08/14 15:01:22
There is no need for a lock. All places that touc
gogerald1
2015/08/18 01:14:27
Done.
| |
| 292 } | 330 } |
| 293 | 331 |
| 294 bool OAuth2TokenServiceDelegateAndroid::ValidateAccounts( | 332 bool OAuth2TokenServiceDelegateAndroid::ValidateAccounts( |
| 295 const std::string& signed_in_account, | 333 const std::string& signed_in_account, |
| 296 const std::vector<std::string>& prev_account_ids, | 334 const std::vector<std::string>& prev_account_ids, |
| 297 const std::vector<std::string>& curr_account_ids, | 335 const std::vector<std::string>& curr_account_ids, |
| 298 std::vector<std::string>& refreshed_ids, | 336 std::vector<std::string>& refreshed_ids, |
| 299 std::vector<std::string>& revoked_ids, | 337 std::vector<std::string>& revoked_ids, |
| 300 bool force_notifications) { | 338 bool force_notifications) { |
| 301 if (std::find(curr_account_ids.begin(), curr_account_ids.end(), | 339 if (std::find(curr_account_ids.begin(), curr_account_ids.end(), |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 425 | 463 |
| 426 // Clear everything on the Java side as well. | 464 // Clear everything on the Java side as well. |
| 427 std::vector<std::string> empty; | 465 std::vector<std::string> empty; |
| 428 JNIEnv* env = AttachCurrentThread(); | 466 JNIEnv* env = AttachCurrentThread(); |
| 429 ScopedJavaLocalRef<jobjectArray> java_accounts( | 467 ScopedJavaLocalRef<jobjectArray> java_accounts( |
| 430 base::android::ToJavaArrayOfStrings(env, empty)); | 468 base::android::ToJavaArrayOfStrings(env, empty)); |
| 431 Java_OAuth2TokenService_saveStoredAccounts( | 469 Java_OAuth2TokenService_saveStoredAccounts( |
| 432 env, base::android::GetApplicationContext(), java_accounts.obj()); | 470 env, base::android::GetApplicationContext(), java_accounts.obj()); |
| 433 } | 471 } |
| 434 | 472 |
| 473 void OAuth2TokenServiceDelegateAndroid::LoadCredentials( | |
| 474 const std::string& primary_account_id) { | |
| 475 lock_.Acquire(); | |
| 476 if (accounts_have_been_validated_) | |
| 477 FireRefreshTokensLoaded(); | |
| 478 else | |
| 479 should_fire_refresh_token_loaded_ = true; | |
|
Roger Tawa OOO till Jul 10th
2015/08/14 15:01:22
Why do you need two bools? I think accounts_have_
gogerald1
2015/08/18 01:14:27
The reason is that we don't want fire refresh toke
| |
| 480 lock_.Release(); | |
| 481 } | |
| 482 | |
| 483 std::string OAuth2TokenServiceDelegateAndroid::MapAccountIdToAccountName( | |
| 484 const std::string& account_id) const { | |
| 485 if (account_tracker_service_->GetMigrationState() != | |
| 486 AccountTrackerService::MIGRATION_NOT_STARTED) { | |
| 487 return account_tracker_service_->GetAccountInfo(account_id).email; | |
| 488 } | |
| 489 return account_id; | |
|
Roger Tawa OOO till Jul 10th
2015/08/14 15:01:22
You don't need the if, it should work in any state
gogerald1
2015/08/18 01:14:27
Acknowledged. Always over worried about the effici
| |
| 490 } | |
| 491 | |
| 492 std::string OAuth2TokenServiceDelegateAndroid::MapAccountNameToAccountId( | |
| 493 const std::string& account_name) const { | |
| 494 if (account_tracker_service_->GetMigrationState() != | |
| 495 AccountTrackerService::MIGRATION_NOT_STARTED) { | |
| 496 return account_tracker_service_->FindAccountInfoByEmail(account_name) | |
| 497 .account_id; | |
| 498 } | |
| 499 | |
| 500 return account_name; | |
|
Roger Tawa OOO till Jul 10th
2015/08/14 15:01:22
You don't need the if, it should work in any state
gogerald1
2015/08/18 01:14:26
Done.
| |
| 501 } | |
| 502 | |
| 435 // Called from Java when fetching of an OAuth2 token is finished. The | 503 // Called from Java when fetching of an OAuth2 token is finished. The |
| 436 // |authToken| param is only valid when |result| is true. | 504 // |authToken| param is only valid when |result| is true. |
| 437 void OAuth2TokenFetched(JNIEnv* env, | 505 void OAuth2TokenFetched(JNIEnv* env, |
| 438 jclass clazz, | 506 jclass clazz, |
| 439 jstring authToken, | 507 jstring authToken, |
| 440 jlong nativeCallback) { | 508 jlong nativeCallback) { |
| 441 std::string token; | 509 std::string token; |
| 442 if (authToken) | 510 if (authToken) |
| 443 token = ConvertJavaStringToUTF8(env, authToken); | 511 token = ConvertJavaStringToUTF8(env, authToken); |
| 444 scoped_ptr<FetchOAuth2TokenCallback> heap_callback( | 512 scoped_ptr<FetchOAuth2TokenCallback> heap_callback( |
| 445 reinterpret_cast<FetchOAuth2TokenCallback*>(nativeCallback)); | 513 reinterpret_cast<FetchOAuth2TokenCallback*>(nativeCallback)); |
| 446 // Android does not provide enough information to know if the credentials are | 514 // Android does not provide enough information to know if the credentials are |
| 447 // wrong, so assume any error is transient by using CONNECTION_FAILED. | 515 // wrong, so assume any error is transient by using CONNECTION_FAILED. |
| 448 GoogleServiceAuthError err(authToken | 516 GoogleServiceAuthError err(authToken |
| 449 ? GoogleServiceAuthError::NONE | 517 ? GoogleServiceAuthError::NONE |
| 450 : GoogleServiceAuthError::CONNECTION_FAILED); | 518 : GoogleServiceAuthError::CONNECTION_FAILED); |
| 451 heap_callback->Run(err, token, base::Time()); | 519 heap_callback->Run(err, token, base::Time()); |
| 452 } | 520 } |
| 453 | 521 |
| 454 // static | 522 // static |
| 455 bool OAuth2TokenServiceDelegateAndroid::Register(JNIEnv* env) { | 523 bool OAuth2TokenServiceDelegateAndroid::Register(JNIEnv* env) { |
| 456 return RegisterNativesImpl(env); | 524 return RegisterNativesImpl(env); |
| 457 } | 525 } |
| OLD | NEW |