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" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "google_apis/gaia/oauth2_access_token_fetcher.h" 174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "jni/OAuth2TokenService_jni.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::AttachCurrentThread; 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::ConvertJavaStringToUTF8; 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::ConvertUTF8ToJavaString; 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::ScopedJavaLocalRef; 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing content::BrowserThread; 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace { 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Callback from FetchOAuth2TokenWithUsername(). 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Arguments: 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// - the error, or NONE if the token fetch was successful. 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// - the OAuth2 access token. 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// - the expiry time of the token (may be null, indicating that the expiry 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// time is unknown. 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccitypedef base::Callback<void( 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GoogleServiceAuthError&, const std::string&, const base::Time&)> 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FetchOAuth2TokenCallback; 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass AndroidAccessTokenFetcher : public OAuth2AccessTokenFetcher { 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public: 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci AndroidAccessTokenFetcher(OAuth2AccessTokenConsumer* consumer, 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& account_id); 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual ~AndroidAccessTokenFetcher(); 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Overrides from OAuth2AccessTokenFetcher: 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void Start(const std::string& client_id, 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& client_secret, 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::vector<std::string>& scopes) OVERRIDE; 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci virtual void CancelRequest() OVERRIDE; 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Handles an access token response. 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void OnAccessTokenResponse(const GoogleServiceAuthError& error, 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& access_token, 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::Time& expiration_time); 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private: 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string CombineScopes(const std::vector<std::string>& scopes); 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::WeakPtrFactory<AndroidAccessTokenFetcher> weak_factory_; 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string account_id_; 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool request_was_cancelled_; 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DISALLOW_COPY_AND_ASSIGN(AndroidAccessTokenFetcher); 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}; 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciAndroidAccessTokenFetcher::AndroidAccessTokenFetcher( 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci OAuth2AccessTokenConsumer* consumer, 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& account_id) 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci : OAuth2AccessTokenFetcher(consumer), 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_(this), 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci account_id_(account_id), 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_was_cancelled_(false) { 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciAndroidAccessTokenFetcher::~AndroidAccessTokenFetcher() {} 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AndroidAccessTokenFetcher::Start(const std::string& client_id, 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& client_secret, 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::vector<std::string>& scopes) { 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci JNIEnv* env = AttachCurrentThread(); 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string scope = CombineScopes(scopes); 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedJavaLocalRef<jstring> j_username = 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ConvertUTF8ToJavaString(env, account_id_); 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedJavaLocalRef<jstring> j_scope = 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ConvertUTF8ToJavaString(env, scope); 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<FetchOAuth2TokenCallback> heap_callback( 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new FetchOAuth2TokenCallback( 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&AndroidAccessTokenFetcher::OnAccessTokenResponse, 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_.GetWeakPtr()))); 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Call into Java to get a new token. 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Java_OAuth2TokenService_getOAuth2AuthToken( 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci env, base::android::GetApplicationContext(), 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci j_username.obj(), 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci j_scope.obj(), 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci reinterpret_cast<intptr_t>(heap_callback.release())); 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AndroidAccessTokenFetcher::CancelRequest() { 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci request_was_cancelled_ = true; 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AndroidAccessTokenFetcher::OnAccessTokenResponse( 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GoogleServiceAuthError& error, 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& access_token, 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const base::Time& expiration_time) { 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (request_was_cancelled_) { 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Ignore the callback if the request was cancelled. 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error.state() == GoogleServiceAuthError::NONE) { 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FireOnGetTokenSuccess(access_token, expiration_time); 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FireOnGetTokenFailure(error); 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistd::string AndroidAccessTokenFetcher::CombineScopes( 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::vector<std::string>& scopes) { 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // The Android AccountManager supports multiple scopes separated by a space: 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // https://code.google.com/p/google-api-java-client/wiki/OAuth2#Android 1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string scope; 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci for (std::vector<std::string>::const_iterator it = scopes.begin(); 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch it != scopes.end(); ++it) { 1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!scope.empty()) 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scope += " "; 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scope += *it; 1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return scope; 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool AndroidProfileOAuth2TokenService::is_testing_profile_ = false; 134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochAndroidProfileOAuth2TokenService::AndroidProfileOAuth2TokenService() { 136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::ctor"; 1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) base::android::ScopedJavaLocalRef<jobject> local_java_ref = 139f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Java_OAuth2TokenService_create(env, reinterpret_cast<intptr_t>(this)); 1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) java_ref_.Reset(env, local_java_ref.obj()); 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)AndroidProfileOAuth2TokenService::~AndroidProfileOAuth2TokenService() {} 1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static 1464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)jobject AndroidProfileOAuth2TokenService::GetForProfile( 1474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env, jclass clazz, jobject j_profile_android) { 1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile_android); 1494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AndroidProfileOAuth2TokenService* service = 150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile(profile); 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return service->java_ref_.obj(); 1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static jobject GetForProfile(JNIEnv* env, 1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) jclass clazz, 1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) jobject j_profile_android) { 1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return AndroidProfileOAuth2TokenService::GetForProfile( 1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) env, clazz, j_profile_android); 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AndroidProfileOAuth2TokenService::Initialize(SigninClient* client) { 162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::Initialize"; 163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ProfileOAuth2TokenService::Initialize(client); 164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!is_testing_profile_) { 166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) Java_OAuth2TokenService_validateAccounts( 167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) AttachCurrentThread(), java_ref_.obj(), 168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::android::GetApplicationContext(), JNI_TRUE); 169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)} 171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool AndroidProfileOAuth2TokenService::RefreshTokenIsAvailable( 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& account_id) const { 17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedJavaLocalRef<jstring> j_account_id = 17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ConvertUTF8ToJavaString(env, account_id); 17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) jboolean refresh_token_is_available = 1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_hasOAuth2RefreshToken( 17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) env, base::android::GetApplicationContext(), 18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) j_account_id.obj()); 181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return refresh_token_is_available == JNI_TRUE; 1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AndroidProfileOAuth2TokenService::UpdateAuthError( 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& account_id, 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const GoogleServiceAuthError& error) { 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(rogerta): do we need to update anything, or does the system handle it? 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::vector<std::string> AndroidProfileOAuth2TokenService::GetAccounts() { 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::vector<std::string> accounts; 1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch JNIEnv* env = AttachCurrentThread(); 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedJavaLocalRef<jobjectArray> j_accounts = 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_getAccounts( 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) env, base::android::GetApplicationContext()); 19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // TODO(fgorski): We may decide to filter out some of the accounts. 19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::android::AppendJavaStringArrayToStringVector(env, 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) j_accounts.obj(), 19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) &accounts); 20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return accounts; 2017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustd::vector<std::string> AndroidProfileOAuth2TokenService::GetSystemAccounts() { 2045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<std::string> accounts; 2055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu JNIEnv* env = AttachCurrentThread(); 2065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ScopedJavaLocalRef<jobjectArray> j_accounts = 2075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Java_OAuth2TokenService_getSystemAccounts( 2085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu env, base::android::GetApplicationContext()); 2095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::android::AppendJavaStringArrayToStringVector(env, 2105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu j_accounts.obj(), 2115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu &accounts); 2125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return accounts; 2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)OAuth2AccessTokenFetcher* 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)AndroidProfileOAuth2TokenService::CreateAccessTokenFetcher( 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& account_id, 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::URLRequestContextGetter* getter, 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) OAuth2AccessTokenConsumer* consumer) { 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!account_id.empty()); 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return new AndroidAccessTokenFetcher(consumer, account_id); 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AndroidProfileOAuth2TokenService::InvalidateOAuth2Token( 22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& client_id, 22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token) { 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) OAuth2TokenService::InvalidateOAuth2Token(account_id, 23068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) client_id, 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes, 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) access_token); 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedJavaLocalRef<jstring> j_access_token = 23668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ConvertUTF8ToJavaString(env, access_token); 2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_invalidateOAuth2AuthToken( 23868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) env, base::android::GetApplicationContext(), 23968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) j_access_token.obj()); 24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 24168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid AndroidProfileOAuth2TokenService::ValidateAccounts( 2435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu JNIEnv* env, 2445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu jobject obj, 245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) jstring j_current_acc, 246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) jboolean j_force_notifications) { 247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts from java"; 2484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string signed_in_account = ConvertJavaStringToUTF8(env, j_current_acc); 249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) ValidateAccounts(signed_in_account, j_force_notifications != JNI_FALSE); 250a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 2514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AndroidProfileOAuth2TokenService::ValidateAccounts( 253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) const std::string& signed_in_account, 254f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool force_notifications) { 2555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<std::string> prev_ids = GetAccounts(); 2565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<std::string> curr_ids = GetSystemAccounts(); 257cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string> refreshed_ids; 258cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string> revoked_ids; 2595c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:" 261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << " sigined_in_account=" << signed_in_account 262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << " prev_ids=" << prev_ids.size() 263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << " curr_ids=" << curr_ids.size() 264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << " force=" << (force_notifications ? "true" : "false"); 265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 266f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!ValidateAccounts(signed_in_account, prev_ids, curr_ids, refreshed_ids, 267f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) revoked_ids, force_notifications)) { 2685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu curr_ids.clear(); 2695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 2704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScopedBacthChange batch(this); 272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 2735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu JNIEnv* env = AttachCurrentThread(); 2745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu ScopedJavaLocalRef<jobjectArray> java_accounts( 2755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu base::android::ToJavaArrayOfStrings(env, curr_ids)); 2765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Java_OAuth2TokenService_saveStoredAccounts( 2775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu env, base::android::GetApplicationContext(), java_accounts.obj()); 278cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 279cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (std::vector<std::string>::iterator it = refreshed_ids.begin(); 280cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != refreshed_ids.end(); it++) { 281cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FireRefreshTokenAvailable(*it); 282cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 283cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 284cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (std::vector<std::string>::iterator it = revoked_ids.begin(); 285cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != revoked_ids.end(); it++) { 286cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FireRefreshTokenRevoked(*it); 287cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 2885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 2895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 2905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool AndroidProfileOAuth2TokenService::ValidateAccounts( 2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::string& signed_in_account, 2925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const std::vector<std::string>& prev_account_ids, 293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::vector<std::string>& curr_account_ids, 294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::vector<std::string>& refreshed_ids, 295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::vector<std::string>& revoked_ids, 296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool force_notifications) { 2975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (std::find(curr_account_ids.begin(), 2985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu curr_account_ids.end(), 2995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu signed_in_account) != curr_account_ids.end()) { 3005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Test to see if an account is removed from the Android AccountManager. 3015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // If so, invoke FireRefreshTokenRevoked to notify the reconcilor. 3025c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (std::vector<std::string>::const_iterator it = prev_account_ids.begin(); 3035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu it != prev_account_ids.end(); it++) { 3045c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (*it == signed_in_account) 3055c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu continue; 3065c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 3075c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (std::find(curr_account_ids.begin(), 3085c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu curr_account_ids.end(), 3095c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu *it) == curr_account_ids.end()) { 310f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:" 311f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << "revoked=" << *it; 312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) revoked_ids.push_back(*it); 3135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 3145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (force_notifications || 317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::find(prev_account_ids.begin(), prev_account_ids.end(), 318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) signed_in_account) == prev_account_ids.end()) { 319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Always fire the primary signed in account first. 320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:" 321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << "refreshed=" << signed_in_account; 322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) refreshed_ids.push_back(signed_in_account); 323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 324a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 3255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (std::vector<std::string>::const_iterator it = curr_account_ids.begin(); 3265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu it != curr_account_ids.end(); it++) { 327a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (*it != signed_in_account) { 328f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (force_notifications || 329f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::find(prev_account_ids.begin(), 330f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) prev_account_ids.end(), 331f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) *it) == prev_account_ids.end()) { 332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:" 333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << "refreshed=" << *it; 334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) refreshed_ids.push_back(*it); 335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 336a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 337a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 3385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return true; 3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } else { 3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Currently signed in account does not any longer exist among accounts on 3415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // system together with all other accounts. 342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (std::find(prev_account_ids.begin(), prev_account_ids.end(), 343f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) signed_in_account) != prev_account_ids.end()) { 344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:" 345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << "revoked=" << signed_in_account; 346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) revoked_ids.push_back(signed_in_account); 3475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 3485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (std::vector<std::string>::const_iterator it = prev_account_ids.begin(); 3495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu it != prev_account_ids.end(); it++) { 3505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (*it == signed_in_account) 3515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu continue; 352f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:" 353f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << "revoked=" << *it; 354cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) revoked_ids.push_back(*it); 3555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 3565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return false; 3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenAvailableFromJava( 3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env, 3624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) jobject obj, 3634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const jstring account_name) { 3644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string account_id = ConvertJavaStringToUTF8(env, account_name); 3654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable(account_id); 3664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable( 3694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& account_id) { 370f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable id=" 371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << account_id; 372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 3734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Notify native observers. 3744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OAuth2TokenService::FireRefreshTokenAvailable(account_id); 3754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Notify Java observers. 3764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 3774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedJavaLocalRef<jstring> account_name = 3784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ConvertUTF8ToJavaString(env, account_id); 3794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_notifyRefreshTokenAvailable( 3804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) env, java_ref_.obj(), account_name.obj()); 3814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenRevokedFromJava( 3844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env, 3854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) jobject obj, 3864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const jstring account_name) { 3874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) std::string account_id = ConvertJavaStringToUTF8(env, account_name); 3884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked(account_id); 3894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 3904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 3914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked( 3924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const std::string& account_id) { 393f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked id=" 394f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) << account_id; 395f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 3964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Notify native observers. 3974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OAuth2TokenService::FireRefreshTokenRevoked(account_id); 3984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Notify Java observers. 3994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 4004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ScopedJavaLocalRef<jstring> account_name = 4014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) ConvertUTF8ToJavaString(env, account_id); 4024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_notifyRefreshTokenRevoked( 4034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) env, java_ref_.obj(), account_name.obj()); 4044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 4054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokensLoadedFromJava( 4074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env, 4084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) jobject obj) { 4094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded(); 4104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 4114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded() { 413f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded"; 4144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Notify native observers. 4154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) OAuth2TokenService::FireRefreshTokensLoaded(); 4164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Notify Java observers. 4174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 4184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Java_OAuth2TokenService_notifyRefreshTokensLoaded( 4194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) env, java_ref_.obj()); 4204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 4214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 4225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid AndroidProfileOAuth2TokenService::RevokeAllCredentials() { 423f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) VLOG(1) << "AndroidProfileOAuth2TokenService::RevokeAllCredentials"; 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ScopedBacthChange batch(this); 4255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu std::vector<std::string> accounts = GetAccounts(); 4265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu for (std::vector<std::string>::iterator it = accounts.begin(); 4275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu it != accounts.end(); it++) { 4285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu FireRefreshTokenRevoked(*it); 4295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Clear everything on the Java side as well. 4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::vector<std::string> empty; 4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) JNIEnv* env = AttachCurrentThread(); 4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ScopedJavaLocalRef<jobjectArray> java_accounts( 4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::android::ToJavaArrayOfStrings(env, empty)); 4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Java_OAuth2TokenService_saveStoredAccounts( 4375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) env, base::android::GetApplicationContext(), java_accounts.obj()); 4385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu} 4395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu 4407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Called from Java when fetching of an OAuth2 token is finished. The 4417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// |authToken| param is only valid when |result| is true. 4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid OAuth2TokenFetched( 4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci JNIEnv* env, 4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci jclass clazz, 4457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch jstring authToken, 4467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch jboolean result, 447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) jlong nativeCallback) { 4487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string token = ConvertJavaStringToUTF8(env, authToken); 4493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<FetchOAuth2TokenCallback> heap_callback( 4503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) reinterpret_cast<FetchOAuth2TokenCallback*>(nativeCallback)); 4514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Android does not provide enough information to know if the credentials are 4524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // wrong, so assume any error is transient by using CONNECTION_FAILED. 4537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GoogleServiceAuthError err(result ? 4547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GoogleServiceAuthError::NONE : 4554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) GoogleServiceAuthError::CONNECTION_FAILED); 4567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch heap_callback->Run(err, token, base::Time()); 4577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 4587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 4597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static 4607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool AndroidProfileOAuth2TokenService::Register(JNIEnv* env) { 4617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return RegisterNativesImpl(env); 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 463