android_profile_oauth2_token_service.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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" 87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/android/jni_string.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/logging.h" 117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/signin/signin_manager.h" 127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/signin/signin_manager_factory.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_android.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "jni/AndroidProfileOAuth2TokenServiceHelper_jni.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::AttachCurrentThread; 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::CheckException; 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 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string CombineScopes(const OAuth2TokenService::ScopeSet& scopes) { 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // The Android AccountManager supports multiple scopes separated by a space: 297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // https://code.google.com/p/google-api-java-client/wiki/OAuth2#Android 307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string scope; 317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (OAuth2TokenService::ScopeSet::const_iterator it = scopes.begin(); 327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch it != scopes.end(); ++it) { 337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!scope.empty()) 347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scope += " "; 357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scope += *it; 367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return scope; 387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} // namespace 417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AndroidProfileOAuth2TokenService::AndroidProfileOAuth2TokenService( 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::URLRequestContextGetter* getter) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : ProfileOAuth2TokenService(getter) { 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)AndroidProfileOAuth2TokenService::~AndroidProfileOAuth2TokenService() { 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<OAuth2TokenService::Request> 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AndroidProfileOAuth2TokenService::StartRequest( 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OAuth2TokenService::Consumer* consumer) { 547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& sync_username = 557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SigninManagerFactory::GetForProfile(profile())-> 567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetAuthenticatedUsername(); 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(!sync_username.empty()); 597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return StartRequestForUsername(sync_username, scopes, consumer); 607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochscoped_ptr<OAuth2TokenService::Request> 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AndroidProfileOAuth2TokenService::StartRequestForUsername( 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& username, 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const OAuth2TokenService::ScopeSet& scopes, 667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch OAuth2TokenService::Consumer* consumer) { 677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<RequestImpl> request(new RequestImpl(consumer)); 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FetchOAuth2Token( 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch username, 727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch CombineScopes(scopes), 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch base::Bind(&RequestImpl::InformConsumer, request->AsWeakPtr())); 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return request.PassAs<Request>(); 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool AndroidProfileOAuth2TokenService::RefreshTokenIsAvailable() { 787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SigninManagerBase* signin_manager = 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SigninManagerFactory::GetForProfile(profile()); 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return !signin_manager->GetAuthenticatedUsername().empty(); 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AndroidProfileOAuth2TokenService::InvalidateToken( 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ScopeSet& scopes, 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& invalid_token) { 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OAuth2TokenService::InvalidateToken(scopes, invalid_token); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch JNIEnv* env = AttachCurrentThread(); 897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedJavaLocalRef<jstring> j_invalid_token = 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ConvertUTF8ToJavaString(env, invalid_token); 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Java_AndroidProfileOAuth2TokenServiceHelper_invalidateOAuth2AuthToken( 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch env, base::android::GetApplicationContext(), 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch j_invalid_token.obj()); 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AndroidProfileOAuth2TokenService::FetchOAuth2Token( 977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& username, 987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& scope, 997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const FetchOAuth2TokenCallback& callback) { 1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch JNIEnv* env = AttachCurrentThread(); 1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedJavaLocalRef<jstring> j_username = 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ConvertUTF8ToJavaString(env, username); 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ScopedJavaLocalRef<jstring> j_scope = 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ConvertUTF8ToJavaString(env, scope); 1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Allocate a copy of the callback on the heap, because the callback 1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // needs to be passed through JNI as an int. 1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // It will be passed back to OAuth2TokenFetched(), where it will be freed. 1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<FetchOAuth2TokenCallback> heap_callback( 1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch new FetchOAuth2TokenCallback(callback)); 1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Call into Java to get a new token. 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Java_AndroidProfileOAuth2TokenServiceHelper_getOAuth2AuthToken( 1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch env, base::android::GetApplicationContext(), 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch j_username.obj(), 1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch j_scope.obj(), 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch reinterpret_cast<int>(heap_callback.release())); 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Called from Java when fetching of an OAuth2 token is finished. The 1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// |authToken| param is only valid when |result| is true. 1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenFetched(JNIEnv* env, jclass clazz, 1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch jstring authToken, 1247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch jboolean result, 1257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch jint nativeCallback) { 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch std::string token = ConvertJavaStringToUTF8(env, authToken); 1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<AndroidProfileOAuth2TokenService::FetchOAuth2TokenCallback> 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch heap_callback( 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch reinterpret_cast< 1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AndroidProfileOAuth2TokenService::FetchOAuth2TokenCallback*>( 1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch nativeCallback)); 1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GoogleServiceAuthError err(result ? 1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GoogleServiceAuthError::NONE : 1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); 1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch heap_callback->Run(err, token, base::Time()); 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool AndroidProfileOAuth2TokenService::Register(JNIEnv* env) { 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return RegisterNativesImpl(env); 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 142