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