android_profile_oauth2_token_service.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
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"
147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/signin/signin_manager.h"
157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/signin/signin_manager_factory.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_android.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "jni/OAuth2TokenService_jni.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::AttachCurrentThread;
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::ConvertJavaStringToUTF8;
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::ConvertUTF8ToJavaString;
237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::ScopedJavaLocalRef;
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing content::BrowserThread;
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace {
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string CombineScopes(const OAuth2TokenService::ScopeSet& scopes) {
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The Android AccountManager supports multiple scopes separated by a space:
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // https://code.google.com/p/google-api-java-client/wiki/OAuth2#Android
317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string scope;
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (OAuth2TokenService::ScopeSet::const_iterator it = scopes.begin();
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       it != scopes.end(); ++it) {
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!scope.empty())
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      scope += " ";
367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scope += *it;
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return scope;
397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Callback from FetchOAuth2TokenWithUsername().
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Arguments:
433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - the error, or NONE if the token fetch was successful.
443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - the OAuth2 access token.
453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - the expiry time of the token (may be null, indicating that the expiry
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//   time is unknown.
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)typedef base::Callback<void(
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const GoogleServiceAuthError&, const std::string&, const base::Time&)>
493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        FetchOAuth2TokenCallback;
503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace
527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochAndroidProfileOAuth2TokenService::AndroidProfileOAuth2TokenService() {
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::android::ScopedJavaLocalRef<jobject> local_java_ref =
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Java_OAuth2TokenService_create(env, reinterpret_cast<intptr_t>(this));
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  java_ref_.Reset(env, local_java_ref.obj());
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)AndroidProfileOAuth2TokenService::~AndroidProfileOAuth2TokenService() {}
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)jobject AndroidProfileOAuth2TokenService::GetForProfile(
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    JNIEnv* env, jclass clazz, jobject j_profile_android) {
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile_android);
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AndroidProfileOAuth2TokenService* service =
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile(profile);
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return service->java_ref_.obj();
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static jobject GetForProfile(JNIEnv* env,
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             jclass clazz,
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             jobject j_profile_android) {
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return AndroidProfileOAuth2TokenService::GetForProfile(
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      env, clazz, j_profile_android);
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool AndroidProfileOAuth2TokenService::RefreshTokenIsAvailable(
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& account_id) {
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ScopedJavaLocalRef<jstring> j_account_id =
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ConvertUTF8ToJavaString(env, account_id);
8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  jboolean refresh_token_is_available =
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      Java_OAuth2TokenService_hasOAuth2RefreshToken(
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          env, base::android::GetApplicationContext(),
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          j_account_id.obj());
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return refresh_token_is_available != JNI_FALSE;
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::vector<std::string> AndroidProfileOAuth2TokenService::GetAccounts() {
9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::vector<std::string> accounts;
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  JNIEnv* env = AttachCurrentThread();
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ScopedJavaLocalRef<jobjectArray> j_accounts =
944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      Java_OAuth2TokenService_getAccounts(
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          env, base::android::GetApplicationContext());
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // TODO(fgorski): We may decide to filter out some of the accounts.
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::android::AppendJavaStringArrayToStringVector(env,
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                     j_accounts.obj(),
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                     &accounts);
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return accounts;
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AndroidProfileOAuth2TokenService::FetchOAuth2Token(
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    RequestImpl* request,
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& account_id,
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    net::URLRequestContextGetter* getter,
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& client_id,
1083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& client_secret,
1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const OAuth2TokenService::ScopeSet& scopes) {
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(!account_id.empty());
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  JNIEnv* env = AttachCurrentThread();
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string scope = CombineScopes(scopes);
1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ScopedJavaLocalRef<jstring> j_username =
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ConvertUTF8ToJavaString(env, account_id);
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ScopedJavaLocalRef<jstring> j_scope =
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      ConvertUTF8ToJavaString(env, scope);
1197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Allocate a copy of the request WeakPtr on the heap, because the object
1217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // needs to be passed through JNI as an int.
1227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // It will be passed back to OAuth2TokenFetched(), where it will be freed.
1237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<FetchOAuth2TokenCallback> heap_callback(
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new FetchOAuth2TokenCallback(base::Bind(&RequestImpl::InformConsumer,
1253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                              request->AsWeakPtr())));
1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Call into Java to get a new token.
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Java_OAuth2TokenService_getOAuth2AuthToken(
1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      env, base::android::GetApplicationContext(),
1307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      j_username.obj(),
1317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      j_scope.obj(),
132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      reinterpret_cast<intptr_t>(heap_callback.release()));
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AndroidProfileOAuth2TokenService::InvalidateOAuth2Token(
13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& account_id,
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& client_id,
13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const ScopeSet& scopes,
13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& access_token) {
14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  OAuth2TokenService::InvalidateOAuth2Token(account_id,
14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                            client_id,
14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                            scopes,
14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                            access_token);
14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ScopedJavaLocalRef<jstring> j_access_token =
14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ConvertUTF8ToJavaString(env, access_token);
1484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Java_OAuth2TokenService_invalidateOAuth2AuthToken(
14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      env, base::android::GetApplicationContext(),
15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      j_access_token.obj());
15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::ValidateAccounts(JNIEnv* env,
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                                        jobject obj,
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                                        jobjectArray accounts,
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                                        jstring j_current_acc) {
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::vector<std::string> account_ids;
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::android::AppendJavaStringArrayToStringVector(env,
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                                     accounts,
1604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                                     &account_ids);
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string signed_in_account = ConvertJavaStringToUTF8(env, j_current_acc);
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ValidateAccounts(signed_in_account, account_ids);
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AndroidProfileOAuth2TokenService::ValidateAccounts(
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::string& signed_in_account,
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const std::vector<std::string>& account_ids) {
1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (signed_in_account.empty())
1694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return;
1704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (std::find(account_ids.begin(),
1724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                account_ids.end(),
1734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                signed_in_account) != account_ids.end()) {
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Currently signed in account still exists among accounts on system.
175a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    std::vector<std::string> ids = GetAccounts();
176a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    // Always fire the primary signed in account first.
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FireRefreshTokenAvailable(signed_in_account);
179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    for (std::vector<std::string>::iterator it = ids.begin();
181a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        it != ids.end(); it++) {
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (*it != signed_in_account) {
183a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        FireRefreshTokenAvailable(*it);
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Currently signed in account does not any longer exist among accounts on
1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // system.
1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FireRefreshTokenRevoked(signed_in_account);
1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenAvailableFromJava(
1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    JNIEnv* env,
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    jobject obj,
1964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const jstring account_name) {
1974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string account_id = ConvertJavaStringToUTF8(env, account_name);
1984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable(account_id);
1994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable(
2024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& account_id) {
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify native observers.
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  OAuth2TokenService::FireRefreshTokenAvailable(account_id);
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify Java observers.
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedJavaLocalRef<jstring> account_name =
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ConvertUTF8ToJavaString(env, account_id);
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Java_OAuth2TokenService_notifyRefreshTokenAvailable(
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      env, java_ref_.obj(), account_name.obj());
2114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenRevokedFromJava(
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    JNIEnv* env,
2154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    jobject obj,
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const jstring account_name) {
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string account_id = ConvertJavaStringToUTF8(env, account_name);
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked(account_id);
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked(
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& account_id) {
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify native observers.
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  OAuth2TokenService::FireRefreshTokenRevoked(account_id);
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify Java observers.
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedJavaLocalRef<jstring> account_name =
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ConvertUTF8ToJavaString(env, account_id);
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Java_OAuth2TokenService_notifyRefreshTokenRevoked(
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      env, java_ref_.obj(), account_name.obj());
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokensLoadedFromJava(
2344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    JNIEnv* env,
2354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    jobject obj) {
2364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded();
2374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded() {
2404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify native observers.
2414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  OAuth2TokenService::FireRefreshTokensLoaded();
2424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify Java observers.
2434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
2444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Java_OAuth2TokenService_notifyRefreshTokensLoaded(
2454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      env, java_ref_.obj());
2464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
2474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Called from Java when fetching of an OAuth2 token is finished. The
2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// |authToken| param is only valid when |result| is true.
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenFetched(JNIEnv* env, jclass clazz,
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    jstring authToken,
2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    jboolean result,
253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    jlong nativeCallback) {
2547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string token = ConvertJavaStringToUTF8(env, authToken);
2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<FetchOAuth2TokenCallback> heap_callback(
2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      reinterpret_cast<FetchOAuth2TokenCallback*>(nativeCallback));
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Android does not provide enough information to know if the credentials are
2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // wrong, so assume any error is transient by using CONNECTION_FAILED.
2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  GoogleServiceAuthError err(result ?
2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                             GoogleServiceAuthError::NONE :
2614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             GoogleServiceAuthError::CONNECTION_FAILED);
2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  heap_callback->Run(err, token, base::Time());
2637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static
2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool AndroidProfileOAuth2TokenService::Register(JNIEnv* env) {
2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return RegisterNativesImpl(env);
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
269