| 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.app.Activity; | 8 import android.app.Activity; |
| 9 import android.content.Context; | 9 import android.content.Context; |
| 10 import android.preference.PreferenceManager; |
| 10 import android.util.Log; | 11 import android.util.Log; |
| 11 | 12 |
| 13 import com.google.common.annotations.VisibleForTesting; |
| 14 |
| 12 import org.chromium.base.CalledByNative; | 15 import org.chromium.base.CalledByNative; |
| 13 import org.chromium.base.ObserverList; | 16 import org.chromium.base.ObserverList; |
| 14 import org.chromium.base.ThreadUtils; | 17 import org.chromium.base.ThreadUtils; |
| 15 import org.chromium.chrome.browser.profiles.Profile; | 18 import org.chromium.chrome.browser.profiles.Profile; |
| 16 import org.chromium.sync.signin.AccountManagerHelper; | 19 import org.chromium.sync.signin.AccountManagerHelper; |
| 17 import org.chromium.sync.signin.ChromeSigninController; | 20 import org.chromium.sync.signin.ChromeSigninController; |
| 18 | 21 |
| 22 import java.util.Arrays; |
| 19 import java.util.concurrent.Semaphore; | 23 import java.util.concurrent.Semaphore; |
| 20 import java.util.concurrent.TimeUnit; | 24 import java.util.concurrent.TimeUnit; |
| 21 import java.util.concurrent.atomic.AtomicReference; | 25 import java.util.concurrent.atomic.AtomicReference; |
| 26 import java.util.HashSet; |
| 27 import java.util.Set; |
| 22 | 28 |
| 23 import javax.annotation.Nullable; | 29 import javax.annotation.Nullable; |
| 24 | 30 |
| 25 /** | 31 /** |
| 26 * Java instance for the native OAuth2TokenService. | 32 * Java instance for the native OAuth2TokenService. |
| 27 * <p/> | 33 * <p/> |
| 28 * This class forwards calls to request or invalidate access tokens made by nati
ve code to | 34 * This class forwards calls to request or invalidate access tokens made by nati
ve code to |
| 29 * AccountManagerHelper and forwards callbacks to native code. | 35 * AccountManagerHelper and forwards callbacks to native code. |
| 30 * <p/> | 36 * <p/> |
| 31 */ | 37 */ |
| 32 public final class OAuth2TokenService { | 38 public final class OAuth2TokenService { |
| 33 | 39 |
| 34 private static final String TAG = "OAuth2TokenService"; | 40 private static final String TAG = "OAuth2TokenService"; |
| 35 | 41 |
| 42 @VisibleForTesting |
| 43 public static final String STORED_ACCOUNTS_KEY = "google.services.stored_acc
ounts"; |
| 44 |
| 36 public interface OAuth2TokenServiceObserver { | 45 public interface OAuth2TokenServiceObserver { |
| 37 void onRefreshTokenAvailable(Account account); | 46 void onRefreshTokenAvailable(Account account); |
| 38 void onRefreshTokenRevoked(Account account); | 47 void onRefreshTokenRevoked(Account account); |
| 39 void onRefreshTokensLoaded(); | 48 void onRefreshTokensLoaded(); |
| 40 } | 49 } |
| 41 | 50 |
| 42 private static final String OAUTH2_SCOPE_PREFIX = "oauth2:"; | 51 private static final String OAUTH2_SCOPE_PREFIX = "oauth2:"; |
| 43 | 52 |
| 44 private final long mNativeProfileOAuth2TokenService; | 53 private final long mNativeProfileOAuth2TokenService; |
| 45 private final ObserverList<OAuth2TokenServiceObserver> mObservers; | 54 private final ObserverList<OAuth2TokenServiceObserver> mObservers; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(con
text); | 88 AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(con
text); |
| 80 Account account = accountManagerHelper.getAccountFromName(username); | 89 Account account = accountManagerHelper.getAccountFromName(username); |
| 81 if (account == null) { | 90 if (account == null) { |
| 82 Log.e(TAG, "Account not found for provided username."); | 91 Log.e(TAG, "Account not found for provided username."); |
| 83 return null; | 92 return null; |
| 84 } | 93 } |
| 85 return account; | 94 return account; |
| 86 } | 95 } |
| 87 | 96 |
| 88 /** | 97 /** |
| 89 * Called by native to list the accounts with OAuth2 refresh tokens. | 98 * Called by native to list the activite accounts in the OS. |
| 90 */ | 99 */ |
| 100 @VisibleForTesting |
| 91 @CalledByNative | 101 @CalledByNative |
| 92 public static String[] getAccounts(Context context) { | 102 public static String[] getSystemAccounts(Context context) { |
| 93 AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(con
text); | 103 AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(con
text); |
| 94 java.util.List<String> accountNames = accountManagerHelper.getGoogleAcco
untNames(); | 104 java.util.List<String> accountNames = accountManagerHelper.getGoogleAcco
untNames(); |
| 95 return accountNames.toArray(new String[accountNames.size()]); | 105 return accountNames.toArray(new String[accountNames.size()]); |
| 96 } | 106 } |
| 97 | 107 |
| 98 /** | 108 /** |
| 109 * Called by native to list the accounts with OAuth2 refresh tokens. |
| 110 * This can differ from getSystemAccounts as the user add/remove accounts |
| 111 * from the OS. validateAccounts should be called to keep these two |
| 112 * in sync. |
| 113 */ |
| 114 @CalledByNative |
| 115 public static String[] getAccounts(Context context) { |
| 116 return getStoredAccounts(context); |
| 117 } |
| 118 |
| 119 /** |
| 99 * Called by native to retrieve OAuth2 tokens. | 120 * Called by native to retrieve OAuth2 tokens. |
| 100 * | 121 * |
| 101 * @param username The native username (full address). | 122 * @param username The native username (full address). |
| 102 * @param scope The scope to get an auth token for (without Android-style 'o
auth2:' prefix). | 123 * @param scope The scope to get an auth token for (without Android-style 'o
auth2:' prefix). |
| 103 * @param nativeCallback The pointer to the native callback that should be r
un upon completion. | 124 * @param nativeCallback The pointer to the native callback that should be r
un upon completion. |
| 104 */ | 125 */ |
| 105 @CalledByNative | 126 @CalledByNative |
| 106 public static void getOAuth2AuthToken( | 127 public static void getOAuth2AuthToken( |
| 107 Context context, String username, String scope, final long nativeCal
lback) { | 128 Context context, String username, String scope, final long nativeCal
lback) { |
| 108 Account account = getAccountOrNullFromUsername(context, username); | 129 Account account = getAccountOrNullFromUsername(context, username); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 public static void invalidateOAuth2AuthToken(Context context, String accessT
oken) { | 216 public static void invalidateOAuth2AuthToken(Context context, String accessT
oken) { |
| 196 if (accessToken != null) { | 217 if (accessToken != null) { |
| 197 AccountManagerHelper.get(context).invalidateAuthToken(accessToken); | 218 AccountManagerHelper.get(context).invalidateAuthToken(accessToken); |
| 198 } | 219 } |
| 199 } | 220 } |
| 200 | 221 |
| 201 public void validateAccounts(Context context) { | 222 public void validateAccounts(Context context) { |
| 202 ThreadUtils.assertOnUiThread(); | 223 ThreadUtils.assertOnUiThread(); |
| 203 String currentlySignedInAccount = | 224 String currentlySignedInAccount = |
| 204 ChromeSigninController.get(context).getSignedInAccountName(); | 225 ChromeSigninController.get(context).getSignedInAccountName(); |
| 205 String[] accounts = getAccounts(context); | 226 nativeValidateAccounts(mNativeProfileOAuth2TokenService, currentlySigned
InAccount); |
| 206 nativeValidateAccounts( | |
| 207 mNativeProfileOAuth2TokenService, accounts, currentlySignedInAcc
ount); | |
| 208 } | 227 } |
| 209 | 228 |
| 210 /** | 229 /** |
| 211 * Triggers a notification to all observers of the native and Java instance
of the | 230 * Triggers a notification to all observers of the native and Java instance
of the |
| 212 * OAuth2TokenService that a refresh token is now available. This may cause
observers to retry | 231 * OAuth2TokenService that a refresh token is now available. This may cause
observers to retry |
| 213 * operations that require authentication. | 232 * operations that require authentication. |
| 214 */ | 233 */ |
| 215 public void fireRefreshTokenAvailable(Account account) { | 234 public void fireRefreshTokenAvailable(Account account) { |
| 216 ThreadUtils.assertOnUiThread(); | 235 ThreadUtils.assertOnUiThread(); |
| 217 assert account != null; | 236 assert account != null; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 nativeFireRefreshTokensLoadedFromJava(mNativeProfileOAuth2TokenService); | 274 nativeFireRefreshTokensLoadedFromJava(mNativeProfileOAuth2TokenService); |
| 256 } | 275 } |
| 257 | 276 |
| 258 @CalledByNative | 277 @CalledByNative |
| 259 public void notifyRefreshTokensLoaded() { | 278 public void notifyRefreshTokensLoaded() { |
| 260 for (OAuth2TokenServiceObserver observer : mObservers) { | 279 for (OAuth2TokenServiceObserver observer : mObservers) { |
| 261 observer.onRefreshTokensLoaded(); | 280 observer.onRefreshTokensLoaded(); |
| 262 } | 281 } |
| 263 } | 282 } |
| 264 | 283 |
| 284 private static String[] getStoredAccounts(Context context) { |
| 285 Set<String> accounts = |
| 286 PreferenceManager.getDefaultSharedPreferences(context) |
| 287 .getStringSet(STORED_ACCOUNTS_KEY, null); |
| 288 return accounts == null ? new String[]{} : accounts.toArray(new String[a
ccounts.size()]); |
| 289 } |
| 290 |
| 291 @CalledByNative |
| 292 private static void saveStoredAccounts(Context context, String[] accounts) { |
| 293 Set<String> set = new HashSet<String>(Arrays.asList(accounts)); |
| 294 PreferenceManager.getDefaultSharedPreferences(context).edit(). |
| 295 putStringSet(STORED_ACCOUNTS_KEY, set).apply(); |
| 296 } |
| 297 |
| 265 private static native Object nativeGetForProfile(Profile profile); | 298 private static native Object nativeGetForProfile(Profile profile); |
| 266 private static native void nativeOAuth2TokenFetched( | 299 private static native void nativeOAuth2TokenFetched( |
| 267 String authToken, boolean result, long nativeCallback); | 300 String authToken, boolean result, long nativeCallback); |
| 268 private native void nativeValidateAccounts( | 301 private native void nativeValidateAccounts( |
| 269 long nativeAndroidProfileOAuth2TokenService, | 302 long nativeAndroidProfileOAuth2TokenService, |
| 270 String[] accounts, String currentlySignedInAccount); | 303 String currentlySignedInAccount); |
| 271 private native void nativeFireRefreshTokenAvailableFromJava( | 304 private native void nativeFireRefreshTokenAvailableFromJava( |
| 272 long nativeAndroidProfileOAuth2TokenService, String accountName); | 305 long nativeAndroidProfileOAuth2TokenService, String accountName); |
| 273 private native void nativeFireRefreshTokenRevokedFromJava( | 306 private native void nativeFireRefreshTokenRevokedFromJava( |
| 274 long nativeAndroidProfileOAuth2TokenService, String accountName); | 307 long nativeAndroidProfileOAuth2TokenService, String accountName); |
| 275 private native void nativeFireRefreshTokensLoadedFromJava( | 308 private native void nativeFireRefreshTokensLoadedFromJava( |
| 276 long nativeAndroidProfileOAuth2TokenService); | 309 long nativeAndroidProfileOAuth2TokenService); |
| 277 } | 310 } |
| OLD | NEW |