| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.signin; | 5 package org.chromium.chrome.browser.signin; |
| 6 | 6 |
| 7 import android.accounts.Account; | 7 import android.accounts.Account; |
| 8 import android.content.Context; | 8 import android.content.Context; |
| 9 import android.os.StrictMode; | 9 import android.os.StrictMode; |
| 10 import android.util.Log; | 10 import android.util.Log; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 * implement this interface and register with {@link #addObserver}. | 44 * implement this interface and register with {@link #addObserver}. |
| 45 */ | 45 */ |
| 46 public interface OAuth2TokenServiceObserver { | 46 public interface OAuth2TokenServiceObserver { |
| 47 void onRefreshTokenAvailable(Account account); | 47 void onRefreshTokenAvailable(Account account); |
| 48 void onRefreshTokenRevoked(Account account); | 48 void onRefreshTokenRevoked(Account account); |
| 49 void onRefreshTokensLoaded(); | 49 void onRefreshTokensLoaded(); |
| 50 } | 50 } |
| 51 | 51 |
| 52 private static final String OAUTH2_SCOPE_PREFIX = "oauth2:"; | 52 private static final String OAUTH2_SCOPE_PREFIX = "oauth2:"; |
| 53 | 53 |
| 54 private boolean mPendingValidation; | 54 private Context mPendingValidationContext; |
| 55 private boolean mPendingValidationForceNotifications; | 55 private boolean mPendingValidationForceNotifications; |
| 56 | 56 |
| 57 private final long mNativeOAuth2TokenServiceDelegateAndroid; | 57 private final long mNativeOAuth2TokenServiceDelegateAndroid; |
| 58 private final ObserverList<OAuth2TokenServiceObserver> mObservers; | 58 private final ObserverList<OAuth2TokenServiceObserver> mObservers; |
| 59 | 59 |
| 60 private OAuth2TokenService(long nativeOAuth2Service) { | 60 private OAuth2TokenService(Context context, long nativeOAuth2Service) { |
| 61 mNativeOAuth2TokenServiceDelegateAndroid = nativeOAuth2Service; | 61 mNativeOAuth2TokenServiceDelegateAndroid = nativeOAuth2Service; |
| 62 mObservers = new ObserverList<OAuth2TokenServiceObserver>(); | 62 mObservers = new ObserverList<OAuth2TokenServiceObserver>(); |
| 63 AccountTrackerService.get().addSystemAccountsSeededListener(this); | 63 AccountTrackerService.get(context).addSystemAccountsSeededListener(this)
; |
| 64 } | 64 } |
| 65 | 65 |
| 66 public static OAuth2TokenService getForProfile(Profile profile) { | 66 public static OAuth2TokenService getForProfile(Profile profile) { |
| 67 ThreadUtils.assertOnUiThread(); | 67 ThreadUtils.assertOnUiThread(); |
| 68 return (OAuth2TokenService) nativeGetForProfile(profile); | 68 return (OAuth2TokenService) nativeGetForProfile(profile); |
| 69 } | 69 } |
| 70 | 70 |
| 71 @CalledByNative | 71 @CalledByNative |
| 72 private static OAuth2TokenService create(long nativeOAuth2Service) { | 72 private static OAuth2TokenService create(Context context, long nativeOAuth2S
ervice) { |
| 73 ThreadUtils.assertOnUiThread(); | 73 ThreadUtils.assertOnUiThread(); |
| 74 return new OAuth2TokenService(nativeOAuth2Service); | 74 return new OAuth2TokenService(context, nativeOAuth2Service); |
| 75 } | 75 } |
| 76 | 76 |
| 77 @VisibleForTesting | 77 @VisibleForTesting |
| 78 public void addObserver(OAuth2TokenServiceObserver observer) { | 78 public void addObserver(OAuth2TokenServiceObserver observer) { |
| 79 ThreadUtils.assertOnUiThread(); | 79 ThreadUtils.assertOnUiThread(); |
| 80 mObservers.addObserver(observer); | 80 mObservers.addObserver(observer); |
| 81 } | 81 } |
| 82 | 82 |
| 83 @VisibleForTesting | 83 @VisibleForTesting |
| 84 public void removeObserver(OAuth2TokenServiceObserver observer) { | 84 public void removeObserver(OAuth2TokenServiceObserver observer) { |
| 85 ThreadUtils.assertOnUiThread(); | 85 ThreadUtils.assertOnUiThread(); |
| 86 mObservers.removeObserver(observer); | 86 mObservers.removeObserver(observer); |
| 87 } | 87 } |
| 88 | 88 |
| 89 private static Account getAccountOrNullFromUsername(String username) { | 89 private static Account getAccountOrNullFromUsername(Context context, String
username) { |
| 90 if (username == null) { | 90 if (username == null) { |
| 91 Log.e(TAG, "Username is null"); | 91 Log.e(TAG, "Username is null"); |
| 92 return null; | 92 return null; |
| 93 } | 93 } |
| 94 | 94 |
| 95 AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(); | 95 AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(con
text); |
| 96 Account account = accountManagerHelper.getAccountFromName(username); | 96 Account account = accountManagerHelper.getAccountFromName(username); |
| 97 if (account == null) { | 97 if (account == null) { |
| 98 Log.e(TAG, "Account not found for provided username."); | 98 Log.e(TAG, "Account not found for provided username."); |
| 99 return null; | 99 return null; |
| 100 } | 100 } |
| 101 return account; | 101 return account; |
| 102 } | 102 } |
| 103 | 103 |
| 104 /** | 104 /** |
| 105 * Called by native to list the activite account names in the OS. | 105 * Called by native to list the activite account names in the OS. |
| 106 */ | 106 */ |
| 107 @VisibleForTesting | 107 @VisibleForTesting |
| 108 @CalledByNative | 108 @CalledByNative |
| 109 public static String[] getSystemAccountNames() { | 109 public static String[] getSystemAccountNames(Context context) { |
| 110 AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(); | 110 AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(con
text); |
| 111 java.util.List<String> accountNames = accountManagerHelper.getGoogleAcco
untNames(); | 111 java.util.List<String> accountNames = accountManagerHelper.getGoogleAcco
untNames(); |
| 112 return accountNames.toArray(new String[accountNames.size()]); | 112 return accountNames.toArray(new String[accountNames.size()]); |
| 113 } | 113 } |
| 114 | 114 |
| 115 /** | 115 /** |
| 116 * Called by native to list the accounts Id with OAuth2 refresh tokens. | 116 * Called by native to list the accounts Id with OAuth2 refresh tokens. |
| 117 * This can differ from getSystemAccountNames as the user add/remove account
s | 117 * This can differ from getSystemAccountNames as the user add/remove account
s |
| 118 * from the OS. validateAccounts should be called to keep these two | 118 * from the OS. validateAccounts should be called to keep these two |
| 119 * in sync. | 119 * in sync. |
| 120 */ | 120 */ |
| 121 @CalledByNative | 121 @CalledByNative |
| 122 public static String[] getAccounts() { | 122 public static String[] getAccounts(Context context) { |
| 123 return getStoredAccounts(); | 123 return getStoredAccounts(context); |
| 124 } | 124 } |
| 125 | 125 |
| 126 /** | 126 /** |
| 127 * Called by native to retrieve OAuth2 tokens. | 127 * Called by native to retrieve OAuth2 tokens. |
| 128 * @param username The native username (full address). | 128 * |
| 129 * @param username The native username (full address). |
| 129 * @param scope The scope to get an auth token for (without Android-style 'o
auth2:' prefix). | 130 * @param scope The scope to get an auth token for (without Android-style 'o
auth2:' prefix). |
| 130 * @param nativeCallback The pointer to the native callback that should be r
un upon completion. | 131 * @param nativeCallback The pointer to the native callback that should be r
un upon completion. |
| 131 */ | 132 */ |
| 132 @CalledByNative | 133 @CalledByNative |
| 133 public static void getOAuth2AuthToken( | 134 public static void getOAuth2AuthToken( |
| 134 String username, String scope, final long nativeCallback) { | 135 Context context, String username, String scope, final long nativeCal
lback) { |
| 135 Account account = getAccountOrNullFromUsername(username); | 136 Account account = getAccountOrNullFromUsername(context, username); |
| 136 if (account == null) { | 137 if (account == null) { |
| 137 ThreadUtils.postOnUiThread(new Runnable() { | 138 ThreadUtils.postOnUiThread(new Runnable() { |
| 138 @Override | 139 @Override |
| 139 public void run() { | 140 public void run() { |
| 140 nativeOAuth2TokenFetched(null, false, nativeCallback); | 141 nativeOAuth2TokenFetched(null, false, nativeCallback); |
| 141 } | 142 } |
| 142 }); | 143 }); |
| 143 return; | 144 return; |
| 144 } | 145 } |
| 145 String oauth2Scope = OAUTH2_SCOPE_PREFIX + scope; | 146 String oauth2Scope = OAUTH2_SCOPE_PREFIX + scope; |
| 146 | 147 |
| 147 AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(); | 148 AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(con
text); |
| 148 accountManagerHelper.getAuthToken( | 149 accountManagerHelper.getAuthToken( |
| 149 account, oauth2Scope, new AccountManagerHelper.GetAuthTokenCallb
ack() { | 150 account, oauth2Scope, new AccountManagerHelper.GetAuthTokenCallb
ack() { |
| 150 @Override | 151 @Override |
| 151 public void tokenAvailable(String token) { | 152 public void tokenAvailable(String token) { |
| 152 nativeOAuth2TokenFetched(token, false, nativeCallback); | 153 nativeOAuth2TokenFetched(token, false, nativeCallback); |
| 153 } | 154 } |
| 154 | 155 |
| 155 @Override | 156 @Override |
| 156 public void tokenUnavailable(boolean isTransientError) { | 157 public void tokenUnavailable(boolean isTransientError) { |
| 157 nativeOAuth2TokenFetched(null, isTransientError, nativeC
allback); | 158 nativeOAuth2TokenFetched(null, isTransientError, nativeC
allback); |
| 158 } | 159 } |
| 159 }); | 160 }); |
| 160 } | 161 } |
| 161 | 162 |
| 162 /** | 163 /** |
| 163 * Call this method to retrieve an OAuth2 access token for the given account
and scope. | 164 * Call this method to retrieve an OAuth2 access token for the given account
and scope. |
| 164 * | 165 * |
| 165 * @param account the account to get the access token for. | 166 * @param account the account to get the access token for. |
| 166 * @param scope The scope to get an auth token for (without Android-style 'o
auth2:' prefix). | 167 * @param scope The scope to get an auth token for (without Android-style 'o
auth2:' prefix). |
| 167 * @param callback called on successful and unsuccessful fetching of auth to
ken. | 168 * @param callback called on successful and unsuccessful fetching of auth to
ken. |
| 168 */ | 169 */ |
| 169 public static void getOAuth2AccessToken(Context context, Account account, St
ring scope, | 170 public static void getOAuth2AccessToken(Context context, Account account, St
ring scope, |
| 170 AccountManagerHelper.GetAuthTokenCallback callback) { | 171 AccountManagerHelper.GetAuthTokenCallback callback) { |
| 171 String oauth2Scope = OAUTH2_SCOPE_PREFIX + scope; | 172 String oauth2Scope = OAUTH2_SCOPE_PREFIX + scope; |
| 172 AccountManagerHelper.get().getAuthToken(account, oauth2Scope, callback); | 173 AccountManagerHelper.get(context).getAuthToken(account, oauth2Scope, cal
lback); |
| 173 } | 174 } |
| 174 | 175 |
| 175 /** | 176 /** |
| 176 * Call this method to retrieve an OAuth2 access token for the given account
and scope. This | 177 * Call this method to retrieve an OAuth2 access token for the given account
and scope. This |
| 177 * method times out after the specified timeout, and will return null if tha
t happens. | 178 * method times out after the specified timeout, and will return null if tha
t happens. |
| 178 * | 179 * |
| 179 * Given that this is a blocking method call, this should never be called fr
om the UI thread. | 180 * Given that this is a blocking method call, this should never be called fr
om the UI thread. |
| 180 * | 181 * |
| 181 * @param account the account to get the access token for. | 182 * @param account the account to get the access token for. |
| 182 * @param scope The scope to get an auth token for (without Android-style 'o
auth2:' prefix). | 183 * @param scope The scope to get an auth token for (without Android-style 'o
auth2:' prefix). |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 } catch (InterruptedException e) { | 215 } catch (InterruptedException e) { |
| 215 Log.w(TAG, "Got interrupted while waiting for auth token"); | 216 Log.w(TAG, "Got interrupted while waiting for auth token"); |
| 216 return null; | 217 return null; |
| 217 } | 218 } |
| 218 } | 219 } |
| 219 | 220 |
| 220 /** | 221 /** |
| 221 * Called by native to check wether the account has an OAuth2 refresh token. | 222 * Called by native to check wether the account has an OAuth2 refresh token. |
| 222 */ | 223 */ |
| 223 @CalledByNative | 224 @CalledByNative |
| 224 public static boolean hasOAuth2RefreshToken(String accountName) { | 225 public static boolean hasOAuth2RefreshToken(Context context, String accountN
ame) { |
| 225 // Temporarily allowing disk read while fixing. TODO: http://crbug.com/6
18096. | 226 // Temporarily allowing disk read while fixing. TODO: http://crbug.com/6
18096. |
| 226 // This function is called in RefreshTokenIsAvailable of OAuth2TokenServ
ice which is | 227 // This function is called in RefreshTokenIsAvailable of OAuth2TokenServ
ice which is |
| 227 // expected to be called in the UI thread synchronously. | 228 // expected to be called in the UI thread synchronously. |
| 228 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); | 229 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); |
| 229 try { | 230 try { |
| 230 return AccountManagerHelper.get().hasAccountForName(accountName); | 231 return AccountManagerHelper.get(context).hasAccountForName(accountNa
me); |
| 231 } finally { | 232 } finally { |
| 232 StrictMode.setThreadPolicy(oldPolicy); | 233 StrictMode.setThreadPolicy(oldPolicy); |
| 233 } | 234 } |
| 234 } | 235 } |
| 235 | 236 |
| 236 /** | 237 /** |
| 237 * Called by native to invalidate an OAuth2 token. | 238 * Called by native to invalidate an OAuth2 token. |
| 238 */ | 239 */ |
| 239 @CalledByNative | 240 @CalledByNative |
| 240 public static void invalidateOAuth2AuthToken(String accessToken) { | 241 public static void invalidateOAuth2AuthToken(Context context, String accessT
oken) { |
| 241 if (accessToken != null) { | 242 if (accessToken != null) { |
| 242 AccountManagerHelper.get().invalidateAuthToken(accessToken); | 243 AccountManagerHelper.get(context).invalidateAuthToken(accessToken); |
| 243 } | 244 } |
| 244 } | 245 } |
| 245 | 246 |
| 246 /** | 247 /** |
| 247 * Continue pending accounts validation after system accounts have been seede
d into | 248 * Continue pending accounts validation after system accounts have been seede
d into |
| 248 * AccountTrackerService. | 249 * AccountTrackerService. |
| 249 */ | 250 */ |
| 250 @Override | 251 @Override |
| 251 public void onSystemAccountsSeedingComplete() { | 252 public void onSystemAccountsSeedingComplete() { |
| 252 if (mPendingValidation) { | 253 if (mPendingValidationContext != null) { |
| 253 validateAccountsWithSignedInAccountName(mPendingValidationForceNotif
ications); | 254 validateAccountsWithSignedInAccountName( |
| 254 mPendingValidation = false; | 255 mPendingValidationContext, mPendingValidationForceNotificati
ons); |
| 256 mPendingValidationContext = null; |
| 255 mPendingValidationForceNotifications = false; | 257 mPendingValidationForceNotifications = false; |
| 256 } | 258 } |
| 257 } | 259 } |
| 258 | 260 |
| 259 /** | 261 /** |
| 260 * Clear pending accounts validation when system accounts in AccountTrackerSe
rvice were | 262 * Clear pending accounts validation when system accounts in AccountTrackerSe
rvice were |
| 261 * refreshed. | 263 * refreshed. |
| 262 */ | 264 */ |
| 263 @Override | 265 @Override |
| 264 public void onSystemAccountsChanged() { | 266 public void onSystemAccountsChanged() { |
| 267 mPendingValidationContext = null; |
| 265 mPendingValidationForceNotifications = false; | 268 mPendingValidationForceNotifications = false; |
| 266 } | 269 } |
| 267 | 270 |
| 268 @CalledByNative | 271 @CalledByNative |
| 269 public void validateAccounts(boolean forceNotifications) { | 272 public void validateAccounts(Context context, boolean forceNotifications) { |
| 270 ThreadUtils.assertOnUiThread(); | 273 ThreadUtils.assertOnUiThread(); |
| 271 if (!AccountTrackerService.get().checkAndSeedSystemAccounts()) { | 274 if (!AccountTrackerService.get(context).checkAndSeedSystemAccounts()) { |
| 272 mPendingValidation = true; | 275 mPendingValidationContext = context; |
| 273 mPendingValidationForceNotifications = forceNotifications; | 276 mPendingValidationForceNotifications = forceNotifications; |
| 274 return; | 277 return; |
| 275 } | 278 } |
| 276 | 279 |
| 277 validateAccountsWithSignedInAccountName(forceNotifications); | 280 validateAccountsWithSignedInAccountName(context, forceNotifications); |
| 278 } | 281 } |
| 279 | 282 |
| 280 private void validateAccountsWithSignedInAccountName(boolean forceNotificati
ons) { | 283 private void validateAccountsWithSignedInAccountName( |
| 281 String currentlySignedInAccount = ChromeSigninController.get().getSigned
InAccountName(); | 284 Context context, boolean forceNotifications) { |
| 285 String currentlySignedInAccount = |
| 286 ChromeSigninController.get(context).getSignedInAccountName(); |
| 282 if (currentlySignedInAccount != null | 287 if (currentlySignedInAccount != null |
| 283 && isSignedInAccountChanged(currentlySignedInAccount)) { | 288 && isSignedInAccountChanged(context, currentlySignedInAccount))
{ |
| 284 // Set currentlySignedInAccount to null for validation if signed-in
account was changed | 289 // Set currentlySignedInAccount to null for validation if signed-in
account was changed |
| 285 // (renamed or removed from the device), this will cause all credent
ials in token | 290 // (renamed or removed from the device), this will cause all credent
ials in token |
| 286 // service be revoked. | 291 // service be revoked. |
| 287 // Could only get here during Chrome cold startup. | 292 // Could only get here during Chrome cold startup. |
| 288 // After chrome started, SigninHelper and AccountsChangedReceiver wi
ll handle account | 293 // After chrome started, SigninHelper and AccountsChangedReceiver wi
ll handle account |
| 289 // change (re-signin or sign out signed-in account). | 294 // change (re-signin or sign out signed-in account). |
| 290 currentlySignedInAccount = null; | 295 currentlySignedInAccount = null; |
| 291 } | 296 } |
| 292 nativeValidateAccounts(mNativeOAuth2TokenServiceDelegateAndroid, current
lySignedInAccount, | 297 nativeValidateAccounts(mNativeOAuth2TokenServiceDelegateAndroid, current
lySignedInAccount, |
| 293 forceNotifications); | 298 forceNotifications); |
| 294 } | 299 } |
| 295 | 300 |
| 296 private boolean isSignedInAccountChanged(String signedInAccountName) { | 301 private boolean isSignedInAccountChanged(Context context, String signedInAcc
ountName) { |
| 297 String[] accountNames = getSystemAccountNames(); | 302 String[] accountNames = getSystemAccountNames(context); |
| 298 for (String accountName : accountNames) { | 303 for (String accountName : accountNames) { |
| 299 if (accountName.equals(signedInAccountName)) return false; | 304 if (accountName.equals(signedInAccountName)) return false; |
| 300 } | 305 } |
| 301 return true; | 306 return true; |
| 302 } | 307 } |
| 303 | 308 |
| 304 /** | 309 /** |
| 305 * Triggers a notification to all observers of the native and Java instance
of the | 310 * Triggers a notification to all observers of the native and Java instance
of the |
| 306 * OAuth2TokenService that a refresh token is now available. This may cause
observers to retry | 311 * OAuth2TokenService that a refresh token is now available. This may cause
observers to retry |
| 307 * operations that require authentication. | 312 * operations that require authentication. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 nativeFireRefreshTokensLoadedFromJava(mNativeOAuth2TokenServiceDelegateA
ndroid); | 359 nativeFireRefreshTokensLoadedFromJava(mNativeOAuth2TokenServiceDelegateA
ndroid); |
| 355 } | 360 } |
| 356 | 361 |
| 357 @CalledByNative | 362 @CalledByNative |
| 358 public void notifyRefreshTokensLoaded() { | 363 public void notifyRefreshTokensLoaded() { |
| 359 for (OAuth2TokenServiceObserver observer : mObservers) { | 364 for (OAuth2TokenServiceObserver observer : mObservers) { |
| 360 observer.onRefreshTokensLoaded(); | 365 observer.onRefreshTokensLoaded(); |
| 361 } | 366 } |
| 362 } | 367 } |
| 363 | 368 |
| 364 private static String[] getStoredAccounts() { | 369 private static String[] getStoredAccounts(Context context) { |
| 365 Set<String> accounts = | 370 Set<String> accounts = |
| 366 ContextUtils.getAppSharedPreferences().getStringSet(STORED_ACCOU
NTS_KEY, null); | 371 ContextUtils.getAppSharedPreferences() |
| 372 .getStringSet(STORED_ACCOUNTS_KEY, null); |
| 367 return accounts == null ? new String[]{} : accounts.toArray(new String[a
ccounts.size()]); | 373 return accounts == null ? new String[]{} : accounts.toArray(new String[a
ccounts.size()]); |
| 368 } | 374 } |
| 369 | 375 |
| 370 @CalledByNative | 376 @CalledByNative |
| 371 private static void saveStoredAccounts(String[] accounts) { | 377 private static void saveStoredAccounts(Context context, String[] accounts) { |
| 372 Set<String> set = new HashSet<String>(Arrays.asList(accounts)); | 378 Set<String> set = new HashSet<String>(Arrays.asList(accounts)); |
| 373 ContextUtils.getAppSharedPreferences().edit() | 379 ContextUtils.getAppSharedPreferences().edit() |
| 374 .putStringSet(STORED_ACCOUNTS_KEY, set).apply(); | 380 .putStringSet(STORED_ACCOUNTS_KEY, set).apply(); |
| 375 } | 381 } |
| 376 | 382 |
| 377 private static native Object nativeGetForProfile(Profile profile); | 383 private static native Object nativeGetForProfile(Profile profile); |
| 378 private static native void nativeOAuth2TokenFetched( | 384 private static native void nativeOAuth2TokenFetched( |
| 379 String authToken, boolean isTransientError, long nativeCallback); | 385 String authToken, boolean isTransientError, long nativeCallback); |
| 380 private native void nativeValidateAccounts(long nativeOAuth2TokenServiceDele
gateAndroid, | 386 private native void nativeValidateAccounts(long nativeOAuth2TokenServiceDele
gateAndroid, |
| 381 String currentlySignedInAccount, boolean forceNotifications); | 387 String currentlySignedInAccount, boolean forceNotifications); |
| 382 private native void nativeFireRefreshTokenAvailableFromJava( | 388 private native void nativeFireRefreshTokenAvailableFromJava( |
| 383 long nativeOAuth2TokenServiceDelegateAndroid, String accountName); | 389 long nativeOAuth2TokenServiceDelegateAndroid, String accountName); |
| 384 private native void nativeFireRefreshTokenRevokedFromJava( | 390 private native void nativeFireRefreshTokenRevokedFromJava( |
| 385 long nativeOAuth2TokenServiceDelegateAndroid, String accountName); | 391 long nativeOAuth2TokenServiceDelegateAndroid, String accountName); |
| 386 private native void nativeFireRefreshTokensLoadedFromJava( | 392 private native void nativeFireRefreshTokensLoadedFromJava( |
| 387 long nativeOAuth2TokenServiceDelegateAndroid); | 393 long nativeOAuth2TokenServiceDelegateAndroid); |
| 388 } | 394 } |
| OLD | NEW |