android_profile_oauth2_token_service.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
1efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris// Copyright 2013 The Chromium Authors. All rights reserved. 2efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris// Use of this source code is governed by a BSD-style license that can be 3efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris// found in the LICENSE file. 4efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 51acb3f0c936b75afede6795288a745ce7343fa8dChristopher Ferris#include "chrome/browser/signin/android_profile_oauth2_token_service.h" 6efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 7efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris#include "base/android/jni_android.h" 8efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris#include "base/android/jni_string.h" 9efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris#include "base/bind.h" 10efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris#include "base/logging.h" 11efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris#include "chrome/browser/signin/signin_manager.h" 12efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris#include "chrome/browser/signin/signin_manager_factory.h" 13efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris#include "chrome/browser/sync/profile_sync_service_android.h" 14efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris#include "content/public/browser/browser_thread.h" 15efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris#include "jni/AndroidProfileOAuth2TokenServiceHelper_jni.h" 16efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 17efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferrisusing base::android::AttachCurrentThread; 18cc6cc088ba4077f5b6cfa3931a1737b03fc0446eChristopher Ferrisusing base::android::CheckException; 19cc6cc088ba4077f5b6cfa3931a1737b03fc0446eChristopher Ferrisusing base::android::ConvertJavaStringToUTF8; 20cc6cc088ba4077f5b6cfa3931a1737b03fc0446eChristopher Ferrisusing base::android::ConvertUTF8ToJavaString; 21efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferrisusing base::android::ScopedJavaLocalRef; 22efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferrisusing content::BrowserThread; 23efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 24efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferrisnamespace { 25efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 26efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferrisstd::string CombineScopes(const OAuth2TokenService::ScopeSet& scopes) { 27efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris // The Android AccountManager supports multiple scopes separated by a space: 28efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris // https://code.google.com/p/google-api-java-client/wiki/OAuth2#Android 29efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris std::string scope; 30efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris for (OAuth2TokenService::ScopeSet::const_iterator it = scopes.begin(); 31efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris it != scopes.end(); ++it) { 32efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris if (!scope.empty()) 33efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris scope += " "; 34efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris scope += *it; 35efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris } 36efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris return scope; 37efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris} 38efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 39efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris} // namespace 40fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris 41fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher FerrisAndroidProfileOAuth2TokenService::AndroidProfileOAuth2TokenService() { 42fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris} 43efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 44fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher FerrisAndroidProfileOAuth2TokenService::~AndroidProfileOAuth2TokenService() { 45efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris} 46efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 47efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferrisscoped_ptr<OAuth2TokenService::Request> 48efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris AndroidProfileOAuth2TokenService::StartRequest( 49efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris const OAuth2TokenService::ScopeSet& scopes, 50efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris OAuth2TokenService::Consumer* consumer) { 51efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris const std::string& sync_username = 52efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris SigninManagerFactory::GetForProfile(profile())-> 53efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris GetAuthenticatedUsername(); 54efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 55efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris DCHECK(!sync_username.empty()); 56efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris return StartRequestForUsername(sync_username, scopes, consumer); 57efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris} 58efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 59efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferrisscoped_ptr<OAuth2TokenService::Request> 60efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris AndroidProfileOAuth2TokenService::StartRequestForUsername( 61efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris const std::string& username, 62efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris const OAuth2TokenService::ScopeSet& scopes, 63efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris OAuth2TokenService::Consumer* consumer) { 64efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 65efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 66efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris scoped_ptr<RequestImpl> request(new RequestImpl(consumer)); 67efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris FetchOAuth2Token( 68fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris username, 69fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris CombineScopes(scopes), 70fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris base::Bind(&RequestImpl::InformConsumer, request->AsWeakPtr())); 71efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris return request.PassAs<Request>(); 72fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris} 73fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris 74fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferrisbool AndroidProfileOAuth2TokenService::RefreshTokenIsAvailable() { 75fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris SigninManagerBase* signin_manager = 76fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris SigninManagerFactory::GetForProfile(profile()); 77fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris return !signin_manager->GetAuthenticatedUsername().empty(); 78fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris} 79fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferris 80fb2fafb9daf5b9f5119d5550a68ebdc3d0564b06Christopher Ferrisvoid AndroidProfileOAuth2TokenService::InvalidateToken( 81efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris const ScopeSet& scopes, 82efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris const std::string& invalid_token) { 83efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris OAuth2TokenService::InvalidateToken(scopes, invalid_token); 84efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 85efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris JNIEnv* env = AttachCurrentThread(); 86efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris ScopedJavaLocalRef<jstring> j_invalid_token = 87efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris ConvertUTF8ToJavaString(env, invalid_token); 88efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris Java_AndroidProfileOAuth2TokenServiceHelper_invalidateOAuth2AuthToken( 89efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris env, base::android::GetApplicationContext(), 90efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris j_invalid_token.obj()); 91efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris} 92efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 93efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferrisvoid AndroidProfileOAuth2TokenService::FetchOAuth2Token( 94efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris const std::string& username, 95efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris const std::string& scope, 96efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris const FetchOAuth2TokenCallback& callback) { 97efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris JNIEnv* env = AttachCurrentThread(); 98efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris ScopedJavaLocalRef<jstring> j_username = 99efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris ConvertUTF8ToJavaString(env, username); 100efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris ScopedJavaLocalRef<jstring> j_scope = 101efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris ConvertUTF8ToJavaString(env, scope); 102efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 103efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris // Allocate a copy of the callback on the heap, because the callback 104efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris // needs to be passed through JNI as an int. 105efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris // It will be passed back to OAuth2TokenFetched(), where it will be freed. 106efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris scoped_ptr<FetchOAuth2TokenCallback> heap_callback( 107efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris new FetchOAuth2TokenCallback(callback)); 108efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 109efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris // Call into Java to get a new token. 110efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris Java_AndroidProfileOAuth2TokenServiceHelper_getOAuth2AuthToken( 111efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris env, base::android::GetApplicationContext(), 112efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris j_username.obj(), 113efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris j_scope.obj(), 114efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris reinterpret_cast<int>(heap_callback.release())); 115efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris} 116efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 117efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris// Called from Java when fetching of an OAuth2 token is finished. The 118efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris// |authToken| param is only valid when |result| is true. 119efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferrisvoid OAuth2TokenFetched(JNIEnv* env, jclass clazz, 120efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris jstring authToken, 121efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris jboolean result, 122efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris jint nativeCallback) { 123efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris std::string token = ConvertJavaStringToUTF8(env, authToken); 124efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris scoped_ptr<AndroidProfileOAuth2TokenService::FetchOAuth2TokenCallback> 125efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris heap_callback( 126efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris reinterpret_cast< 127efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris AndroidProfileOAuth2TokenService::FetchOAuth2TokenCallback*>( 128efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris nativeCallback)); 129efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris GoogleServiceAuthError err(result ? 130efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris GoogleServiceAuthError::NONE : 131efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); 132efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris heap_callback->Run(err, token, base::Time()); 133efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris} 134efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris 135efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris// static 136efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferrisbool AndroidProfileOAuth2TokenService::Register(JNIEnv* env) { 137efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris return RegisterNativesImpl(env); 138efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris} 139efb75a0b84fed700173700a2e4fee153ba491b32Christopher Ferris