1ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis// Copyright 2013 The Chromium Authors. All rights reserved. 29fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// Use of this source code is governed by a BSD-style license that can be 39fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// found in the LICENSE file. 49fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 59fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "chrome/browser/signin/android_profile_oauth2_token_service.h" 69fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 79fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "base/android/jni_android.h" 89fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "base/android/jni_array.h" 99fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "base/android/jni_string.h" 10ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#include "base/bind.h" 119fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "base/logging.h" 129fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "chrome/browser/profiles/profile_android.h" 139fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 14ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#include "chrome/browser/sync/profile_sync_service_android.h" 15ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis#include "content/public/browser/browser_thread.h" 169fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis#include "google_apis/gaia/oauth2_access_token_fetcher.h" 17ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek#include "jni/OAuth2TokenService_jni.h" 189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 19b3d74da3e1620c9a7a378afb5f244e4987e6713eArgyrios Kyrtzidisusing base::android::AttachCurrentThread; 209fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisusing base::android::ConvertJavaStringToUTF8; 219fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisusing base::android::ConvertUTF8ToJavaString; 229fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisusing base::android::ScopedJavaLocalRef; 239fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisusing content::BrowserThread; 249fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 259fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidisnamespace { 269fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 279fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// Callback from FetchOAuth2TokenWithUsername(). 289fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// Arguments: 299fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// - the error, or NONE if the token fetch was successful. 309fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// - the OAuth2 access token. 319fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// - the expiry time of the token (may be null, indicating that the expiry 329fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis// time is unknown. 339fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidistypedef base::Callback<void( 349fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis const GoogleServiceAuthError&, const std::string&, const base::Time&)> 359fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis FetchOAuth2TokenCallback; 369fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 37cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenkoclass AndroidAccessTokenFetcher : public OAuth2AccessTokenFetcher { 389fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis public: 399fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis AndroidAccessTokenFetcher(OAuth2AccessTokenConsumer* consumer, 409fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis const std::string& account_id); 41cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko virtual ~AndroidAccessTokenFetcher(); 429fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 439fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis // Overrides from OAuth2AccessTokenFetcher: 449fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis virtual void Start(const std::string& client_id, 459fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis const std::string& client_secret, 46769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const std::vector<std::string>& scopes) OVERRIDE; 47769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis virtual void CancelRequest() OVERRIDE; 48769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 499fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis // Handles an access token response. 509fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis void OnAccessTokenResponse(const GoogleServiceAuthError& error, 519fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis const std::string& access_token, 529fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis const base::Time& expiration_time); 539fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 549fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis private: 559fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis std::string CombineScopes(const std::vector<std::string>& scopes); 569fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 579fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis base::WeakPtrFactory<AndroidAccessTokenFetcher> weak_factory_; 589fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis std::string account_id_; 599fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis bool request_was_cancelled_; 609fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis 619fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis DISALLOW_COPY_AND_ASSIGN(AndroidAccessTokenFetcher); 62769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis}; 63769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 64769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisAndroidAccessTokenFetcher::AndroidAccessTokenFetcher( 65769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis OAuth2AccessTokenConsumer* consumer, 66769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const std::string& account_id) 679be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek : OAuth2AccessTokenFetcher(consumer), 689be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek weak_factory_(this), 699be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek account_id_(account_id), 709be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek request_was_cancelled_(false) { 719be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek} 729be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek 739be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted KremenekAndroidAccessTokenFetcher::~AndroidAccessTokenFetcher() {} 749be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek 759be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenekvoid AndroidAccessTokenFetcher::Start(const std::string& client_id, 769be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek const std::string& client_secret, 779be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek const std::vector<std::string>& scopes) { 789be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek JNIEnv* env = AttachCurrentThread(); 799be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek std::string scope = CombineScopes(scopes); 809be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek ScopedJavaLocalRef<jstring> j_username = 819be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek ConvertUTF8ToJavaString(env, account_id_); 829be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek ScopedJavaLocalRef<jstring> j_scope = 839be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek ConvertUTF8ToJavaString(env, scope); 849be6e7ce5788e50c62d40c59b0bbc2ea423683f7Ted Kremenek scoped_ptr<FetchOAuth2TokenCallback> heap_callback( 85769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis new FetchOAuth2TokenCallback( 86769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis base::Bind(&AndroidAccessTokenFetcher::OnAccessTokenResponse, 87769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis weak_factory_.GetWeakPtr()))); 88769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 89cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko // Call into Java to get a new token. 90769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Java_OAuth2TokenService_getOAuth2AuthToken( 91769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis env, base::android::GetApplicationContext(), 92769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis j_username.obj(), 93cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko j_scope.obj(), 94769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis reinterpret_cast<intptr_t>(heap_callback.release())); 95769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 96769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 97769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid AndroidAccessTokenFetcher::CancelRequest() { 98769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis request_was_cancelled_ = true; 99769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 100769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 101769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid AndroidAccessTokenFetcher::OnAccessTokenResponse( 102769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const GoogleServiceAuthError& error, 103769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const std::string& access_token, 104769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const base::Time& expiration_time) { 105769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis if (request_was_cancelled_) { 106769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis // Ignore the callback if the request was cancelled. 107769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return; 108cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko } 109769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis if (error.state() == GoogleServiceAuthError::NONE) { 110769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis FireOnGetTokenSuccess(access_token, expiration_time); 111769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } else { 112cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko FireOnGetTokenFailure(error); 113769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 114769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 115769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 116769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// static 117769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisstd::string AndroidAccessTokenFetcher::CombineScopes( 118769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis const std::vector<std::string>& scopes) { 119769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis // The Android AccountManager supports multiple scopes separated by a space: 120769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis // https://code.google.com/p/google-api-java-client/wiki/OAuth2#Android 121769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::string scope; 122769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis for (std::vector<std::string>::const_iterator it = scopes.begin(); 123769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis it != scopes.end(); ++it) { 124769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis if (!scope.empty()) 125de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose scope += " "; 126769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis scope += *it; 127769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis } 128769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return scope; 129769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 130769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 131769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} // namespace 132769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 133769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisbool AndroidProfileOAuth2TokenService::is_testing_profile_ = false; 134769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 135769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisAndroidProfileOAuth2TokenService::AndroidProfileOAuth2TokenService() { 136769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis VLOG(1) << "AndroidProfileOAuth2TokenService::ctor"; 137769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis JNIEnv* env = AttachCurrentThread(); 138769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis base::android::ScopedJavaLocalRef<jobject> local_java_ref = 139769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Java_OAuth2TokenService_create(env, reinterpret_cast<intptr_t>(this)); 140de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose java_ref_.Reset(env, local_java_ref.obj()); 141769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 142769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 143769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios KyrtzidisAndroidProfileOAuth2TokenService::~AndroidProfileOAuth2TokenService() {} 144769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 145769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis// static 146769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisjobject AndroidProfileOAuth2TokenService::GetForProfile( 147769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis JNIEnv* env, jclass clazz, jobject j_profile_android) { 148769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile_android); 149769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis AndroidProfileOAuth2TokenService* service = 150769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile(profile); 151769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis return service->java_ref_.obj(); 152769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis} 15396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose 15496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rosestatic jobject GetForProfile(JNIEnv* env, 15596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose jclass clazz, 15696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose jobject j_profile_android) { 15796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose return AndroidProfileOAuth2TokenService::GetForProfile( 15896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose env, clazz, j_profile_android); 15996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose} 16096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose 16196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rosevoid AndroidProfileOAuth2TokenService::Initialize(SigninClient* client) { 16296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose VLOG(1) << "AndroidProfileOAuth2TokenService::Initialize"; 16396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose ProfileOAuth2TokenService::Initialize(client); 16496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose 16596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose if (!is_testing_profile_) { 16696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose Java_OAuth2TokenService_validateAccounts( 16796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose AttachCurrentThread(), java_ref_.obj(), 16896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose base::android::GetApplicationContext(), JNI_TRUE); 16996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose } 17096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose} 17196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose 17296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rosebool AndroidProfileOAuth2TokenService::RefreshTokenIsAvailable( 17396479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose const std::string& account_id) const { 17496479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose JNIEnv* env = AttachCurrentThread(); 17596479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose ScopedJavaLocalRef<jstring> j_account_id = 17696479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose ConvertUTF8ToJavaString(env, account_id); 17796479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose jboolean refresh_token_is_available = 17896479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose Java_OAuth2TokenService_hasOAuth2RefreshToken( 17996479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose env, base::android::GetApplicationContext(), 18096479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose j_account_id.obj()); 18196479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose return refresh_token_is_available == JNI_TRUE; 18296479da6ad9d921d875e7be29fe1bfa127be8069Jordan Rose} 183769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 184769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisvoid AndroidProfileOAuth2TokenService::UpdateAuthError( 185390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks const std::string& account_id, 186390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks const GoogleServiceAuthError& error) { 187769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis // TODO(rogerta): do we need to update anything, or does the system handle it? 188390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks} 189769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis 190769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidisstd::vector<std::string> AndroidProfileOAuth2TokenService::GetAccounts() { 191769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis std::vector<std::string> accounts; 192769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis JNIEnv* env = AttachCurrentThread(); 193769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis ScopedJavaLocalRef<jobjectArray> j_accounts = 194769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis Java_OAuth2TokenService_getAccounts( 195769ce3e93ad35bd9ac28e4d8b8f035ae4fd9a5b5Argyrios Kyrtzidis env, base::android::GetApplicationContext()); 1969fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis // TODO(fgorski): We may decide to filter out some of the accounts. 1979fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis base::android::AppendJavaStringArrayToStringVector(env, 1989fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis j_accounts.obj(), 199312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis &accounts); 200312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis return accounts; 201390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks} 202390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks 203312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisstd::vector<std::string> AndroidProfileOAuth2TokenService::GetSystemAccounts() { 204390909c89c98ab1807e15e033a72e975f866fb23Anna Zaks std::vector<std::string> accounts; 205312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis JNIEnv* env = AttachCurrentThread(); 206312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis ScopedJavaLocalRef<jobjectArray> j_accounts = 207312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis Java_OAuth2TokenService_getSystemAccounts( 208312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis env, base::android::GetApplicationContext()); 209312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis base::android::AppendJavaStringArrayToStringVector(env, 210312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis j_accounts.obj(), 211312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis &accounts); 212312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis return accounts; 213312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis} 214312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 21530726c6baee1417307236e854f1474fdb3cedb98Argyrios KyrtzidisOAuth2AccessTokenFetcher* 21630726c6baee1417307236e854f1474fdb3cedb98Argyrios KyrtzidisAndroidProfileOAuth2TokenService::CreateAccessTokenFetcher( 21730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis const std::string& account_id, 21830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis net::URLRequestContextGetter* getter, 21930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis OAuth2AccessTokenConsumer* consumer) { 22030726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis DCHECK(!account_id.empty()); 22130726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis return new AndroidAccessTokenFetcher(consumer, account_id); 22230726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis} 22330726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis 22430726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidisvoid AndroidProfileOAuth2TokenService::InvalidateOAuth2Token( 22530726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis const std::string& account_id, 22630726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis const std::string& client_id, 22730726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis const ScopeSet& scopes, 22830726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis const std::string& access_token) { 22930726c6baee1417307236e854f1474fdb3cedb98Argyrios Kyrtzidis OAuth2TokenService::InvalidateOAuth2Token(account_id, 230344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks client_id, 231af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis scopes, 232344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks access_token); 233344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks 234344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks JNIEnv* env = AttachCurrentThread(); 235af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis ScopedJavaLocalRef<jstring> j_access_token = 236af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis ConvertUTF8ToJavaString(env, access_token); 237af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis Java_OAuth2TokenService_invalidateOAuth2AuthToken( 238af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis env, base::android::GetApplicationContext(), 239af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis j_access_token.obj()); 240344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks} 241344c77aac25e5d960aced3f45fbaa09853383f6dAnna Zaks 242af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidisvoid AndroidProfileOAuth2TokenService::ValidateAccounts( 243af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis JNIEnv* env, 244af5800a1e287990bb547e052f257adeeae5ab476Argyrios Kyrtzidis jobject obj, 245cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis jstring j_current_acc, 246cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis jboolean j_force_notifications) { 247f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts from java"; 248f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks std::string signed_in_account = ConvertJavaStringToUTF8(env, j_current_acc); 249f236b6503a4dbc44c1fccb8756bd57c9d0efdf05Anna Zaks ValidateAccounts(signed_in_account, j_force_notifications != JNI_FALSE); 250cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis} 251cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 252cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidisvoid AndroidProfileOAuth2TokenService::ValidateAccounts( 253cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis const std::string& signed_in_account, 254cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis bool force_notifications) { 255cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis std::vector<std::string> prev_ids = GetAccounts(); 256cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis std::vector<std::string> curr_ids = GetSystemAccounts(); 257cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis std::vector<std::string> refreshed_ids; 258cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis std::vector<std::string> revoked_ids; 259cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis 260cc05d511b26ac6dc80fcbcc78ac305d2755aa0b9Argyrios Kyrtzidis VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:" 261183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis << " sigined_in_account=" << signed_in_account 262183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis << " prev_ids=" << prev_ids.size() 26323111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek << " curr_ids=" << curr_ids.size() 264183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis << " force=" << (force_notifications ? "true" : "false"); 265183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 266183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis if (!ValidateAccounts(signed_in_account, prev_ids, curr_ids, refreshed_ids, 267183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis revoked_ids, force_notifications)) { 268183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis curr_ids.clear(); 269183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 270183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 271183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ScopedBacthChange batch(this); 272183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 273183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis JNIEnv* env = AttachCurrentThread(); 274183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis ScopedJavaLocalRef<jobjectArray> java_accounts( 275183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis base::android::ToJavaArrayOfStrings(env, curr_ids)); 276183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis Java_OAuth2TokenService_saveStoredAccounts( 277183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis env, base::android::GetApplicationContext(), java_accounts.obj()); 278183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 279183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis for (std::vector<std::string>::iterator it = refreshed_ids.begin(); 280183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis it != refreshed_ids.end(); it++) { 281183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis FireRefreshTokenAvailable(*it); 282183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 283183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 284183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis for (std::vector<std::string>::iterator it = revoked_ids.begin(); 285183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis it != revoked_ids.end(); it++) { 286183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis FireRefreshTokenRevoked(*it); 287183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 288183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis} 289183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 290183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidisbool AndroidProfileOAuth2TokenService::ValidateAccounts( 291183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const std::string& signed_in_account, 292183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis const std::vector<std::string>& prev_account_ids, 29323111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek const std::vector<std::string>& curr_account_ids, 29418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek std::vector<std::string>& refreshed_ids, 29523111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek std::vector<std::string>& revoked_ids, 296bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks bool force_notifications) { 297537716ad8dd10f984b6cfe6985afade1185c5e3cJordy Rose if (std::find(curr_account_ids.begin(), 29866c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks curr_account_ids.end(), 299740d490593e0de8732a697c9f77b90ddd463863bJordan Rose signed_in_account) != curr_account_ids.end()) { 30035bdbf40624beba3fc00cb72ab444659939c1a6bTed Kremenek // Test to see if an account is removed from the Android AccountManager. 30166c40400e7d6272b0cd675ada18dd62c1f0362c7Anna Zaks // If so, invoke FireRefreshTokenRevoked to notify the reconcilor. 302183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis for (std::vector<std::string>::const_iterator it = prev_account_ids.begin(); 303183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis it != prev_account_ids.end(); it++) { 30418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek if (*it == signed_in_account) 30523111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek continue; 306183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 307183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis if (std::find(curr_account_ids.begin(), 308183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis curr_account_ids.end(), 309183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis *it) == curr_account_ids.end()) { 310183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:" 311183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis << "revoked=" << *it; 312183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis revoked_ids.push_back(*it); 313183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 314183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis } 315183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis 316183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis if (force_notifications || 317183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis std::find(prev_account_ids.begin(), prev_account_ids.end(), 318183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis signed_in_account) == prev_account_ids.end()) { 319183ff98f425d470c2a0276880aaf43496c9dad14Argyrios Kyrtzidis // Always fire the primary signed in account first. 320bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:" 321bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks << "refreshed=" << signed_in_account; 322bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks refreshed_ids.push_back(signed_in_account); 323da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev } 324bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 325bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks for (std::vector<std::string>::const_iterator it = curr_account_ids.begin(); 326233e26acc0ff2a1098f4c813f69286fce840a422Anna Zaks it != curr_account_ids.end(); it++) { 32741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks if (*it != signed_in_account) { 328da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev if (force_notifications || 329da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev std::find(prev_account_ids.begin(), 330da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev prev_account_ids.end(), 331da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev *it) == prev_account_ids.end()) { 33241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:" 33341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks << "refreshed=" << *it; 33441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks refreshed_ids.push_back(*it); 335da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev } 336da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev } 337da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev } 338da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev return true; 339da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev } else { 340b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev // Currently signed in account does not any longer exist among accounts on 341b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev // system together with all other accounts. 342b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev if (std::find(prev_account_ids.begin(), prev_account_ids.end(), 343da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev signed_in_account) != prev_account_ids.end()) { 344da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:" 345da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev << "revoked=" << signed_in_account; 346da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev revoked_ids.push_back(signed_in_account); 347da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev } 348da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev for (std::vector<std::string>::const_iterator it = prev_account_ids.begin(); 349da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev it != prev_account_ids.end(); it++) { 350da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev if (*it == signed_in_account) 351da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev continue; 352bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:" 353bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks << "revoked=" << *it; 354bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks revoked_ids.push_back(*it); 355bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks } 356bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks return false; 357bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks } 358bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks} 359bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks 360bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaksvoid AndroidProfileOAuth2TokenService::FireRefreshTokenAvailableFromJava( 361bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks JNIEnv* env, 362bf53dfac8195835028bd6347433f7dbebcc29fc1Anna Zaks jobject obj, 36341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks const jstring account_name) { 36441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks std::string account_id = ConvertJavaStringToUTF8(env, account_name); 36541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable(account_id); 366da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev} 36741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks 36841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaksvoid AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable( 36941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks const std::string& account_id) { 37041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks VLOG(1) << "AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable id=" 371da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev << account_id; 372da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev 373da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev // Notify native observers. 374da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev OAuth2TokenService::FireRefreshTokenAvailable(account_id); 375da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev // Notify Java observers. 376da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev JNIEnv* env = AttachCurrentThread(); 377da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev ScopedJavaLocalRef<jstring> account_name = 378da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev ConvertUTF8ToJavaString(env, account_id); 379da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev Java_OAuth2TokenService_notifyRefreshTokenAvailable( 380b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev env, java_ref_.obj(), account_name.obj()); 381b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev} 382b7a747b0c271faeeb8d0f886f0e691eb25f637d9Anton Yartsev 383da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsevvoid AndroidProfileOAuth2TokenService::FireRefreshTokenRevokedFromJava( 384da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev JNIEnv* env, 385da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev jobject obj, 386da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev const jstring account_name) { 387da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev std::string account_id = ConvertJavaStringToUTF8(env, account_name); 388da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked(account_id); 389da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev} 390da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsev 391da8d37ce42d2db4e1e76ee6f7f38f10f6b0ef0f8Anton Yartsevvoid AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked( 39241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks const std::string& account_id) { 39341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks VLOG(1) << "AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked id=" 39441988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks << account_id; 39541988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks 39641988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks // Notify native observers. 39741988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks OAuth2TokenService::FireRefreshTokenRevoked(account_id); 39841988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks // Notify Java observers. 39941988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks JNIEnv* env = AttachCurrentThread(); 40041988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks ScopedJavaLocalRef<jstring> account_name = 40141988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks ConvertUTF8ToJavaString(env, account_id); 40241988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks Java_OAuth2TokenService_notifyRefreshTokenRevoked( 40341988f331a74a72cf243a2a68ffb56418e9a174eAnna Zaks env, java_ref_.obj(), account_name.obj()); 404deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis} 405deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 406deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidisvoid AndroidProfileOAuth2TokenService::FireRefreshTokensLoadedFromJava( 407deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis JNIEnv* env, 408deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis jobject obj) { 409deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded(); 410deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis} 411deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis 412deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidisvoid AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded() { 413deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis VLOG(1) << "AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded"; 414deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis // Notify native observers. 415deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis OAuth2TokenService::FireRefreshTokensLoaded(); 416deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis // Notify Java observers. 417deb6447d0029bdb122397fafb5fa2a4e76f2e555Argyrios Kyrtzidis JNIEnv* env = AttachCurrentThread(); 4189fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis Java_OAuth2TokenService_notifyRefreshTokensLoaded( 4199fb9474c5b267400d4abfbff63c8b39f378235d4Argyrios Kyrtzidis env, java_ref_.obj()); 420e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis} 421e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 422312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidisvoid AndroidProfileOAuth2TokenService::RevokeAllCredentials() { 423312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis VLOG(1) << "AndroidProfileOAuth2TokenService::RevokeAllCredentials"; 42423111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek ScopedBacthChange batch(this); 42523111dcd66ee242bb5caf1ecab01bd930ee42c4cTed Kremenek std::vector<std::string> accounts = GetAccounts(); 42618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek for (std::vector<std::string>::iterator it = accounts.begin(); 42718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek it != accounts.end(); it++) { 428312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis FireRefreshTokenRevoked(*it); 429312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis } 430312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis 431312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis // Clear everything on the Java side as well. 432312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis std::vector<std::string> empty; 433312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis JNIEnv* env = AttachCurrentThread(); 434312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis ScopedJavaLocalRef<jobjectArray> java_accounts( 435312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis base::android::ToJavaArrayOfStrings(env, empty)); 436312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis Java_OAuth2TokenService_saveStoredAccounts( 437312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis env, base::android::GetApplicationContext(), java_accounts.obj()); 438312dbec867f6b8d6b86fd562c53352cd4db27468Argyrios Kyrtzidis} 439e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis 440e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis// Called from Java when fetching of an OAuth2 token is finished. The 441e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis// |authToken| param is only valid when |result| is true. 442e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidisvoid OAuth2TokenFetched( 443e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis JNIEnv* env, 444e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis jclass clazz, 445e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis jstring authToken, 446e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis jboolean result, 447e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis jlong nativeCallback) { 448e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis std::string token = ConvertJavaStringToUTF8(env, authToken); 449e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis scoped_ptr<FetchOAuth2TokenCallback> heap_callback( 450e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis reinterpret_cast<FetchOAuth2TokenCallback*>(nativeCallback)); 451e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis // Android does not provide enough information to know if the credentials are 452e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis // wrong, so assume any error is transient by using CONNECTION_FAILED. 453e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis GoogleServiceAuthError err(result ? 454e1bfb7ae0dd0762c88e1fd94746e973c37f2e04eArgyrios Kyrtzidis GoogleServiceAuthError::NONE : 455ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek GoogleServiceAuthError::CONNECTION_FAILED); 456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines heap_callback->Run(err, token, base::Time()); 457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 459ca804539d908d3a0e8c72a0df5f1f571d29490bbTed Kremenek// static 460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesbool AndroidProfileOAuth2TokenService::Register(JNIEnv* env) { 461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return RegisterNativesImpl(env); 462dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose} 463dbd658e139b3e0bf084f75feaea8d844af9e319fJordy Rose