android_profile_oauth2_token_service.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/signin/android_profile_oauth2_token_service.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/android/jni_android.h" 868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/android/jni_array.h" 97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/android/jni_string.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/logging.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/profiles/profile_android.h" 134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_android.h" 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "jni/OAuth2TokenService_jni.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::AttachCurrentThread; 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::ConvertJavaStringToUTF8; 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::ConvertUTF8ToJavaString; 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::ScopedJavaLocalRef; 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing content::BrowserThread; 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace { 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string CombineScopes(const OAuth2TokenService::ScopeSet& scopes) { 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // The Android AccountManager supports multiple scopes separated by a space: 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // https://code.google.com/p/google-api-java-client/wiki/OAuth2#Android 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string scope; 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (OAuth2TokenService::ScopeSet::const_iterator it = scopes.begin(); 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch it != scopes.end(); ++it) { 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!scope.empty()) 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scope += " "; 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scope += *it; 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return scope; 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Callback from FetchOAuth2TokenWithUsername(). 403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Arguments: 413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - the error, or NONE if the token fetch was successful. 423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - the OAuth2 access token. 433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - the expiry time of the token (may be null, indicating that the expiry 443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// time is unknown. 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)typedef base::Callback<void( 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const GoogleServiceAuthError&, const std::string&, const base::Time&)> 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FetchOAuth2TokenCallback; 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace 507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochAndroidProfileOAuth2TokenService::AndroidProfileOAuth2TokenService() { 524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::android::ScopedJavaLocalRef<jobject> local_java_ref = 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Java_OAuth2TokenService_create(env, reinterpret_cast<intptr_t>(this)); 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) java_ref_.Reset(env, local_java_ref.obj()); 56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)AndroidProfileOAuth2TokenService::~AndroidProfileOAuth2TokenService() {} 594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)jobject AndroidProfileOAuth2TokenService::GetForProfile( 624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env, jclass clazz, jobject j_profile_android) { 634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile_android); 644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AndroidProfileOAuth2TokenService* service = 65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile(profile); 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return service->java_ref_.obj(); 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static jobject GetForProfile(JNIEnv* env, 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) jclass clazz, 714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) jobject j_profile_android) { 724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return AndroidProfileOAuth2TokenService::GetForProfile( 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) env, clazz, j_profile_android); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool AndroidProfileOAuth2TokenService::RefreshTokenIsAvailable( 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& account_id) const { 7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedJavaLocalRef<jstring> j_account_id = 8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ConvertUTF8ToJavaString(env, account_id); 8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) jboolean refresh_token_is_available = 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_hasOAuth2RefreshToken( 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) env, base::android::GetApplicationContext(), 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) j_account_id.obj()); 8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return refresh_token_is_available != JNI_FALSE; 867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::vector<std::string> AndroidProfileOAuth2TokenService::GetAccounts() { 8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<std::string> accounts; 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch JNIEnv* env = AttachCurrentThread(); 9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedJavaLocalRef<jobjectArray> j_accounts = 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_getAccounts( 9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) env, base::android::GetApplicationContext()); 9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // TODO(fgorski): We may decide to filter out some of the accounts. 9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::android::AppendJavaStringArrayToStringVector(env, 9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) j_accounts.obj(), 9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &accounts); 9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return accounts; 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustd::vector<std::string> AndroidProfileOAuth2TokenService::GetSystemAccounts() { 1025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<std::string> accounts; 1035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu JNIEnv* env = AttachCurrentThread(); 1045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ScopedJavaLocalRef<jobjectArray> j_accounts = 1055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Java_OAuth2TokenService_getSystemAccounts( 1065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu env, base::android::GetApplicationContext()); 1075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::android::AppendJavaStringArrayToStringVector(env, 1085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu j_accounts.obj(), 1095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &accounts); 1105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return accounts; 1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AndroidProfileOAuth2TokenService::FetchOAuth2Token( 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RequestImpl* request, 11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::URLRequestContextGetter* getter, 1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& client_id, 1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& client_secret, 1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes) { 1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(!account_id.empty()); 1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch JNIEnv* env = AttachCurrentThread(); 1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::string scope = CombineScopes(scopes); 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedJavaLocalRef<jstring> j_username = 12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ConvertUTF8ToJavaString(env, account_id); 1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedJavaLocalRef<jstring> j_scope = 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ConvertUTF8ToJavaString(env, scope); 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Allocate a copy of the request WeakPtr on the heap, because the object 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // needs to be passed through JNI as an int. 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // It will be passed back to OAuth2TokenFetched(), where it will be freed. 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<FetchOAuth2TokenCallback> heap_callback( 1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) new FetchOAuth2TokenCallback(base::Bind(&RequestImpl::InformConsumer, 1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request->AsWeakPtr()))); 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Call into Java to get a new token. 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_getOAuth2AuthToken( 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch env, base::android::GetApplicationContext(), 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch j_username.obj(), 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch j_scope.obj(), 142f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) reinterpret_cast<intptr_t>(heap_callback.release())); 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)OAuth2AccessTokenFetcher* 146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)AndroidProfileOAuth2TokenService::CreateAccessTokenFetcher( 147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& account_id, 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequestContextGetter* getter, 149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OAuth2AccessTokenConsumer* consumer) { 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) NOTREACHED(); 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NULL; 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AndroidProfileOAuth2TokenService::InvalidateOAuth2Token( 15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& client_id, 15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token) { 15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) OAuth2TokenService::InvalidateOAuth2Token(account_id, 16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) client_id, 16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes, 16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) access_token); 16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedJavaLocalRef<jstring> j_access_token = 16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ConvertUTF8ToJavaString(env, access_token); 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_invalidateOAuth2AuthToken( 16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) env, base::android::GetApplicationContext(), 16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) j_access_token.obj()); 17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 1725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid AndroidProfileOAuth2TokenService::ValidateAccounts( 1735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu JNIEnv* env, 1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu jobject obj, 1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu jstring j_current_acc) { 1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string signed_in_account = ConvertJavaStringToUTF8(env, j_current_acc); 1775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ValidateAccounts(signed_in_account); 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AndroidProfileOAuth2TokenService::ValidateAccounts( 1815c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& signed_in_account) { 1825c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<std::string> prev_ids = GetAccounts(); 1835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<std::string> curr_ids = GetSystemAccounts(); 184cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string> refreshed_ids; 185cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string> revoked_ids; 1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 187cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!ValidateAccounts( 188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) signed_in_account, prev_ids, curr_ids, refreshed_ids, revoked_ids)) { 1895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu curr_ids.clear(); 1905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu JNIEnv* env = AttachCurrentThread(); 1935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ScopedJavaLocalRef<jobjectArray> java_accounts( 1945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::android::ToJavaArrayOfStrings(env, curr_ids)); 1955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Java_OAuth2TokenService_saveStoredAccounts( 1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu env, base::android::GetApplicationContext(), java_accounts.obj()); 197cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 198cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (std::vector<std::string>::iterator it = refreshed_ids.begin(); 199cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != refreshed_ids.end(); it++) { 200cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FireRefreshTokenAvailable(*it); 201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 203cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (std::vector<std::string>::iterator it = revoked_ids.begin(); 204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != revoked_ids.end(); it++) { 205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FireRefreshTokenRevoked(*it); 206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 2075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool AndroidProfileOAuth2TokenService::ValidateAccounts( 2105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& signed_in_account, 2115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::vector<std::string>& prev_account_ids, 212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<std::string>& curr_account_ids, 213cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string>& refreshed_ids, 214cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string>& revoked_ids) { 2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (std::find(curr_account_ids.begin(), 2165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu curr_account_ids.end(), 2175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu signed_in_account) != curr_account_ids.end()) { 2185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Test to see if an account is removed from the Android AccountManager. 2195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // If so, invoke FireRefreshTokenRevoked to notify the reconcilor. 2205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (std::vector<std::string>::const_iterator it = prev_account_ids.begin(); 2215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu it != prev_account_ids.end(); it++) { 2225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (*it == signed_in_account) 2235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu continue; 2245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (std::find(curr_account_ids.begin(), 2265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu curr_account_ids.end(), 2275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *it) == curr_account_ids.end()) { 228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) revoked_ids.push_back(*it); 2295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) // Always fire the primary signed in account first. 233cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) refreshed_ids.push_back(signed_in_account); 234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (std::vector<std::string>::const_iterator it = curr_account_ids.begin(); 2365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu it != curr_account_ids.end(); it++) { 237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (*it != signed_in_account) { 238cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) refreshed_ids.push_back(*it); 239a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 2415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Currently signed in account does not any longer exist among accounts on 2445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // system together with all other accounts. 2455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!signed_in_account.empty()) { 246cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) revoked_ids.push_back(signed_in_account); 2475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (std::vector<std::string>::const_iterator it = prev_account_ids.begin(); 2495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu it != prev_account_ids.end(); it++) { 2505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (*it == signed_in_account) 2515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu continue; 252cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) revoked_ids.push_back(*it); 2535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 2554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenAvailableFromJava( 2594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env, 2604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) jobject obj, 2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const jstring account_name) { 2624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string account_id = ConvertJavaStringToUTF8(env, account_name); 2634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable(account_id); 2644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable( 2674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& account_id) { 2684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Notify native observers. 2694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OAuth2TokenService::FireRefreshTokenAvailable(account_id); 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Notify Java observers. 2714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 2724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedJavaLocalRef<jstring> account_name = 2734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ConvertUTF8ToJavaString(env, account_id); 2744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_notifyRefreshTokenAvailable( 2754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) env, java_ref_.obj(), account_name.obj()); 2764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenRevokedFromJava( 2794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env, 2804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) jobject obj, 2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const jstring account_name) { 2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string account_id = ConvertJavaStringToUTF8(env, account_name); 2834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked(account_id); 2844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked( 2874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& account_id) { 2884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Notify native observers. 2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OAuth2TokenService::FireRefreshTokenRevoked(account_id); 2904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Notify Java observers. 2914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 2924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedJavaLocalRef<jstring> account_name = 2934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ConvertUTF8ToJavaString(env, account_id); 2944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_notifyRefreshTokenRevoked( 2954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) env, java_ref_.obj(), account_name.obj()); 2964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokensLoadedFromJava( 2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env, 3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) jobject obj) { 3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded(); 3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded() { 3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Notify native observers. 3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OAuth2TokenService::FireRefreshTokensLoaded(); 3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Notify Java observers. 3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_notifyRefreshTokensLoaded( 3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) env, java_ref_.obj()); 3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid AndroidProfileOAuth2TokenService::RevokeAllCredentials() { 3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<std::string> accounts = GetAccounts(); 3155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (std::vector<std::string>::iterator it = accounts.begin(); 3165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu it != accounts.end(); it++) { 3175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FireRefreshTokenRevoked(*it); 3185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 3195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 3205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Called from Java when fetching of an OAuth2 token is finished. The 3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// |authToken| param is only valid when |result| is true. 3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenFetched(JNIEnv* env, jclass clazz, 3247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch jstring authToken, 3257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch jboolean result, 326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) jlong nativeCallback) { 3277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string token = ConvertJavaStringToUTF8(env, authToken); 3283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<FetchOAuth2TokenCallback> heap_callback( 3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) reinterpret_cast<FetchOAuth2TokenCallback*>(nativeCallback)); 3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Android does not provide enough information to know if the credentials are 3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // wrong, so assume any error is transient by using CONNECTION_FAILED. 3327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GoogleServiceAuthError err(result ? 3337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GoogleServiceAuthError::NONE : 3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GoogleServiceAuthError::CONNECTION_FAILED); 3357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch heap_callback->Run(err, token, base::Time()); 3367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static 3397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool AndroidProfileOAuth2TokenService::Register(JNIEnv* env) { 3407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return RegisterNativesImpl(env); 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 342