android_profile_oauth2_token_service.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/signin/android_profile_oauth2_token_service.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/android/jni_android.h"
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/android/jni_array.h"
97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/android/jni_string.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h"
117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/logging.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/profiles/profile_android.h"
134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/sync/profile_sync_service_android.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/browser_thread.h"
164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "jni/OAuth2TokenService_jni.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::AttachCurrentThread;
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::ConvertJavaStringToUTF8;
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::ConvertUTF8ToJavaString;
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing base::android::ScopedJavaLocalRef;
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochusing content::BrowserThread;
237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace {
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochstd::string CombineScopes(const OAuth2TokenService::ScopeSet& scopes) {
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // The Android AccountManager supports multiple scopes separated by a space:
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // https://code.google.com/p/google-api-java-client/wiki/OAuth2#Android
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string scope;
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  for (OAuth2TokenService::ScopeSet::const_iterator it = scopes.begin();
317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch       it != scopes.end(); ++it) {
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    if (!scope.empty())
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      scope += " ";
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scope += *it;
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return scope;
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Callback from FetchOAuth2TokenWithUsername().
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// Arguments:
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - the error, or NONE if the token fetch was successful.
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - the OAuth2 access token.
433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// - the expiry time of the token (may be null, indicating that the expiry
443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)//   time is unknown.
453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)typedef base::Callback<void(
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const GoogleServiceAuthError&, const std::string&, const base::Time&)>
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        FetchOAuth2TokenCallback;
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)bool AndroidProfileOAuth2TokenService::is_testing_profile_ = false;
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
53ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochAndroidProfileOAuth2TokenService::AndroidProfileOAuth2TokenService() {
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  VLOG(1) << "AndroidProfileOAuth2TokenService::ctor";
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::android::ScopedJavaLocalRef<jobject> local_java_ref =
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      Java_OAuth2TokenService_create(env, reinterpret_cast<intptr_t>(this));
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  java_ref_.Reset(env, local_java_ref.obj());
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)AndroidProfileOAuth2TokenService::~AndroidProfileOAuth2TokenService() {}
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// static
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)jobject AndroidProfileOAuth2TokenService::GetForProfile(
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    JNIEnv* env, jclass clazz, jobject j_profile_android) {
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile_android);
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AndroidProfileOAuth2TokenService* service =
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      ProfileOAuth2TokenServiceFactory::GetPlatformSpecificForProfile(profile);
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return service->java_ref_.obj();
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)static jobject GetForProfile(JNIEnv* env,
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             jclass clazz,
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             jobject j_profile_android) {
754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return AndroidProfileOAuth2TokenService::GetForProfile(
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      env, clazz, j_profile_android);
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void AndroidProfileOAuth2TokenService::Initialize(SigninClient* client) {
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  VLOG(1) << "AndroidProfileOAuth2TokenService::Initialize";
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ProfileOAuth2TokenService::Initialize(client);
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!is_testing_profile_) {
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    Java_OAuth2TokenService_validateAccounts(
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        AttachCurrentThread(), java_ref_.obj(),
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::android::GetApplicationContext(), JNI_TRUE);
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  }
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool AndroidProfileOAuth2TokenService::RefreshTokenIsAvailable(
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& account_id) const {
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ScopedJavaLocalRef<jstring> j_account_id =
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ConvertUTF8ToJavaString(env, account_id);
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  jboolean refresh_token_is_available =
964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      Java_OAuth2TokenService_hasOAuth2RefreshToken(
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          env, base::android::GetApplicationContext(),
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          j_account_id.obj());
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return refresh_token_is_available == JNI_TRUE;
1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::vector<std::string> AndroidProfileOAuth2TokenService::GetAccounts() {
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::vector<std::string> accounts;
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  JNIEnv* env = AttachCurrentThread();
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ScopedJavaLocalRef<jobjectArray> j_accounts =
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      Java_OAuth2TokenService_getAccounts(
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          env, base::android::GetApplicationContext());
10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // TODO(fgorski): We may decide to filter out some of the accounts.
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::android::AppendJavaStringArrayToStringVector(env,
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                     j_accounts.obj(),
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                                     &accounts);
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return accounts;
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustd::vector<std::string> AndroidProfileOAuth2TokenService::GetSystemAccounts() {
1165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::vector<std::string> accounts;
1175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  JNIEnv* env = AttachCurrentThread();
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ScopedJavaLocalRef<jobjectArray> j_accounts =
1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      Java_OAuth2TokenService_getSystemAccounts(
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu          env, base::android::GetApplicationContext());
1215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  base::android::AppendJavaStringArrayToStringVector(env,
1225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                                     j_accounts.obj(),
1235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                                     &accounts);
1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return accounts;
1255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid AndroidProfileOAuth2TokenService::FetchOAuth2Token(
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    RequestImpl* request,
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& account_id,
1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    net::URLRequestContextGetter* getter,
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& client_id,
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const std::string& client_secret,
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const OAuth2TokenService::ScopeSet& scopes) {
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(!account_id.empty());
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  JNIEnv* env = AttachCurrentThread();
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string scope = CombineScopes(scopes);
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ScopedJavaLocalRef<jstring> j_username =
14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ConvertUTF8ToJavaString(env, account_id);
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ScopedJavaLocalRef<jstring> j_scope =
1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      ConvertUTF8ToJavaString(env, scope);
1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Allocate a copy of the request WeakPtr on the heap, because the object
1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // needs to be passed through JNI as an int.
1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // It will be passed back to OAuth2TokenFetched(), where it will be freed.
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<FetchOAuth2TokenCallback> heap_callback(
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new FetchOAuth2TokenCallback(base::Bind(&RequestImpl::InformConsumer,
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                              request->AsWeakPtr())));
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Call into Java to get a new token.
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Java_OAuth2TokenService_getOAuth2AuthToken(
1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      env, base::android::GetApplicationContext(),
1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      j_username.obj(),
1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      j_scope.obj(),
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      reinterpret_cast<intptr_t>(heap_callback.release()));
1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)OAuth2AccessTokenFetcher*
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)AndroidProfileOAuth2TokenService::CreateAccessTokenFetcher(
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const std::string& account_id,
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    net::URLRequestContextGetter* getter,
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    OAuth2AccessTokenConsumer* consumer) {
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  NOTREACHED();
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return NULL;
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AndroidProfileOAuth2TokenService::InvalidateOAuth2Token(
16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& account_id,
17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& client_id,
17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const ScopeSet& scopes,
17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const std::string& access_token) {
17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  OAuth2TokenService::InvalidateOAuth2Token(account_id,
17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                            client_id,
17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                            scopes,
17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                            access_token);
17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  ScopedJavaLocalRef<jstring> j_access_token =
18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ConvertUTF8ToJavaString(env, access_token);
1814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Java_OAuth2TokenService_invalidateOAuth2AuthToken(
18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      env, base::android::GetApplicationContext(),
18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      j_access_token.obj());
18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid AndroidProfileOAuth2TokenService::ValidateAccounts(
1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    JNIEnv* env,
1885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    jobject obj,
189f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    jstring j_current_acc,
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    jboolean j_force_notifications) {
191f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts from java";
1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string signed_in_account = ConvertJavaStringToUTF8(env, j_current_acc);
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ValidateAccounts(signed_in_account, j_force_notifications != JNI_FALSE);
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
1954e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AndroidProfileOAuth2TokenService::ValidateAccounts(
197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const std::string& signed_in_account,
198f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool force_notifications) {
1995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::vector<std::string> prev_ids = GetAccounts();
2005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::vector<std::string> curr_ids = GetSystemAccounts();
201cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<std::string> refreshed_ids;
202cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  std::vector<std::string> revoked_ids;
2035c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:"
205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          << " sigined_in_account=" << signed_in_account
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          << " prev_ids=" << prev_ids.size()
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          << " curr_ids=" << curr_ids.size()
208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          << " force=" << (force_notifications ? "true" : "false");
209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!ValidateAccounts(signed_in_account, prev_ids, curr_ids, refreshed_ids,
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                        revoked_ids, force_notifications)) {
2125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    curr_ids.clear();
2135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
2144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  JNIEnv* env = AttachCurrentThread();
2165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  ScopedJavaLocalRef<jobjectArray> java_accounts(
2175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      base::android::ToJavaArrayOfStrings(env, curr_ids));
2185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  Java_OAuth2TokenService_saveStoredAccounts(
2195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      env, base::android::GetApplicationContext(), java_accounts.obj());
220cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
221cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (std::vector<std::string>::iterator it = refreshed_ids.begin();
222cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       it != refreshed_ids.end(); it++) {
223cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FireRefreshTokenAvailable(*it);
224cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
225cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
226cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (std::vector<std::string>::iterator it = revoked_ids.begin();
227cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       it != revoked_ids.end(); it++) {
228cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    FireRefreshTokenRevoked(*it);
229cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
2305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
2315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liubool AndroidProfileOAuth2TokenService::ValidateAccounts(
2335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const std::string& signed_in_account,
2345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    const std::vector<std::string>& prev_account_ids,
235cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const std::vector<std::string>& curr_account_ids,
236cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    std::vector<std::string>& refreshed_ids,
237f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    std::vector<std::string>& revoked_ids,
238f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    bool force_notifications) {
2395c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (std::find(curr_account_ids.begin(),
2405c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                curr_account_ids.end(),
2415c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                signed_in_account) != curr_account_ids.end()) {
2425c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // Test to see if an account is removed from the Android AccountManager.
2435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // If so, invoke FireRefreshTokenRevoked to notify the reconcilor.
2445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    for (std::vector<std::string>::const_iterator it = prev_account_ids.begin();
2455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu         it != prev_account_ids.end(); it++) {
2465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      if (*it == signed_in_account)
2475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        continue;
2485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
2495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      if (std::find(curr_account_ids.begin(),
2505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                    curr_account_ids.end(),
2515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                    *it) == curr_account_ids.end()) {
252f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:"
253f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                << "revoked=" << *it;
254cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        revoked_ids.push_back(*it);
2555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      }
2565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (force_notifications ||
259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        std::find(prev_account_ids.begin(), prev_account_ids.end(),
260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  signed_in_account) == prev_account_ids.end()) {
261f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      // Always fire the primary signed in account first.
262f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:"
263f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              << "refreshed=" << signed_in_account;
264f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      refreshed_ids.push_back(signed_in_account);
265f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    }
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
2675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    for (std::vector<std::string>::const_iterator it = curr_account_ids.begin();
2685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu         it != curr_account_ids.end(); it++) {
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (*it != signed_in_account) {
270f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        if (force_notifications ||
271f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)            std::find(prev_account_ids.begin(),
272f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      prev_account_ids.end(),
273f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                      *it) == prev_account_ids.end()) {
274f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:"
275f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  << "refreshed=" << *it;
276f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          refreshed_ids.push_back(*it);
277f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        }
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
279a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    }
2805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return true;
2814e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  } else {
2824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    // Currently signed in account does not any longer exist among accounts on
2835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    // system together with all other accounts.
284f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    if (std::find(prev_account_ids.begin(), prev_account_ids.end(),
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                  signed_in_account) != prev_account_ids.end()) {
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:"
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              << "revoked=" << signed_in_account;
288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      revoked_ids.push_back(signed_in_account);
2895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
2905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    for (std::vector<std::string>::const_iterator it = prev_account_ids.begin();
2915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu         it != prev_account_ids.end(); it++) {
2925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      if (*it == signed_in_account)
2935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        continue;
294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      VLOG(1) << "AndroidProfileOAuth2TokenService::ValidateAccounts:"
295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)              << "revoked=" << *it;
296cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      revoked_ids.push_back(*it);
2975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
2985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return false;
2994e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
3004e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenAvailableFromJava(
3034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    JNIEnv* env,
3044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    jobject obj,
3054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const jstring account_name) {
3064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string account_id = ConvertJavaStringToUTF8(env, account_name);
3074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable(account_id);
3084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable(
3114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& account_id) {
312f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  VLOG(1) << "AndroidProfileOAuth2TokenService::FireRefreshTokenAvailable id="
313f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          << account_id;
314f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify native observers.
3164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  OAuth2TokenService::FireRefreshTokenAvailable(account_id);
3174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify Java observers.
3184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
3194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedJavaLocalRef<jstring> account_name =
3204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ConvertUTF8ToJavaString(env, account_id);
3214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Java_OAuth2TokenService_notifyRefreshTokenAvailable(
3224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      env, java_ref_.obj(), account_name.obj());
3234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenRevokedFromJava(
3264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    JNIEnv* env,
3274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    jobject obj,
3284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const jstring account_name) {
3294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string account_id = ConvertJavaStringToUTF8(env, account_name);
3304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked(account_id);
3314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked(
3344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const std::string& account_id) {
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  VLOG(1) << "AndroidProfileOAuth2TokenService::FireRefreshTokenRevoked id="
336f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          << account_id;
337f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify native observers.
3394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  OAuth2TokenService::FireRefreshTokenRevoked(account_id);
3404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify Java observers.
3414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
3424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  ScopedJavaLocalRef<jstring> account_name =
3434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      ConvertUTF8ToJavaString(env, account_id);
3444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Java_OAuth2TokenService_notifyRefreshTokenRevoked(
3454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      env, java_ref_.obj(), account_name.obj());
3464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokensLoadedFromJava(
3494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    JNIEnv* env,
3504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    jobject obj) {
3514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded();
3524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)void AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded() {
355f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  VLOG(1) << "AndroidProfileOAuth2TokenService::FireRefreshTokensLoaded";
3564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify native observers.
3574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  OAuth2TokenService::FireRefreshTokensLoaded();
3584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Notify Java observers.
3594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
3604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  Java_OAuth2TokenService_notifyRefreshTokensLoaded(
3614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      env, java_ref_.obj());
3624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
3634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
3645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid AndroidProfileOAuth2TokenService::RevokeAllCredentials() {
365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  VLOG(1) << "AndroidProfileOAuth2TokenService::RevokeAllCredentials";
3665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  std::vector<std::string> accounts = GetAccounts();
3675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  for (std::vector<std::string>::iterator it = accounts.begin();
3685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu       it != accounts.end(); it++) {
3695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    FireRefreshTokenRevoked(*it);
3705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
3715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
3725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
3737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Called from Java when fetching of an OAuth2 token is finished. The
3747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// |authToken| param is only valid when |result| is true.
3757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenFetched(JNIEnv* env, jclass clazz,
3767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    jstring authToken,
3777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    jboolean result,
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    jlong nativeCallback) {
3797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::string token = ConvertJavaStringToUTF8(env, authToken);
3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<FetchOAuth2TokenCallback> heap_callback(
3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      reinterpret_cast<FetchOAuth2TokenCallback*>(nativeCallback));
3824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Android does not provide enough information to know if the credentials are
3834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // wrong, so assume any error is transient by using CONNECTION_FAILED.
3847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  GoogleServiceAuthError err(result ?
3857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                             GoogleServiceAuthError::NONE :
3864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                             GoogleServiceAuthError::CONNECTION_FAILED);
3877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  heap_callback->Run(err, token, base::Time());
3887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
3897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// static
3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochbool AndroidProfileOAuth2TokenService::Register(JNIEnv* env) {
3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return RegisterNativesImpl(env);
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
394