Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java |
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1b4d5dcc1448149859099cf1903c92d3d801d092 |
| --- /dev/null |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/signin/AccountTrackerService.java |
| @@ -0,0 +1,156 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +package org.chromium.chrome.browser.signin; |
| + |
| +import android.content.Context; |
| +import android.os.AsyncTask; |
| +import android.util.Log; |
| + |
| +import org.chromium.base.ObserverList; |
| +import org.chromium.base.ThreadUtils; |
| +import org.chromium.sync.signin.AccountManagerHelper; |
| + |
| +import java.util.concurrent.Semaphore; |
| + |
| +/** |
| +* Android wrapper of AccountTrackerService which provides access from the java layer. |
| +* It offers the capability of fetching and seeding system accounts into AccountTrackerService in C++ |
| +* layer, and notifies observers when it is complete. |
| +*/ |
| +public class AccountTrackerService { |
| + private static final String TAG = "AccountTrackerService"; |
| + private static AccountTrackerService sAccountTrackerService; |
| + private static SystemAccountsSeedingStatus sSystemAccountsSeedingStatus = |
| + SystemAccountsSeedingStatus.SEEDING_NOT_STARTED; |
| + |
| + private final Context mContext; |
| + private final long mNativeAccountTrackerService; |
| + private final Semaphore mSemaphore = new Semaphore(1, true); |
| + |
| + private enum SystemAccountsSeedingStatus { |
| + SEEDING_NOT_STARTED, |
| + SEEDING_IN_PROGRESS, |
| + SEEDING_DONE |
| + } |
| + |
| + /** |
| + * Classes that want to listen for system accounts fetching and seeding should implement |
| + * this interface and register with {@link #addSystemAccountsSeededListener}. |
| + */ |
| + public interface OnSystemAccountsSeededListener { |
| + void onSystemAccountsSeedingComplete(); |
| + void onSystemAccountsForceRefreshed(); |
| + } |
| + |
| + private static final ObserverList<OnSystemAccountsSeededListener> |
| + sSystemAccountsSeedingObservers = new ObserverList<OnSystemAccountsSeededListener>(); |
| + |
| + public static AccountTrackerService get(Context context) { |
| + ThreadUtils.assertOnUiThread(); |
| + if (sAccountTrackerService == null) { |
| + sAccountTrackerService = new AccountTrackerService(context); |
| + } |
| + return sAccountTrackerService; |
| + } |
| + |
| + private AccountTrackerService(Context context) { |
| + mContext = context; |
| + mNativeAccountTrackerService = nativeInit(); |
| + } |
| + |
| + /** |
| + * Check whether systems accounts have been seeded into AccountTrackerService in C++ layer. |
| + */ |
| + public boolean isSystemAccountsSeeded() { |
| + ThreadUtils.assertOnUiThread(); |
| + if (sSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_DONE) { |
| + return true; |
| + } |
| + |
| + if (sSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_NOT_STARTED) { |
| + seedSystemAccounts(); |
| + } |
| + |
| + return false; |
| + } |
| + |
| + /** |
| + * Register an |observer| to observe system accounts seeding status. |
| + */ |
| + public static void addSystemAccountsSeededListener(OnSystemAccountsSeededListener observer) { |
| + ThreadUtils.assertOnUiThread(); |
| + sSystemAccountsSeedingObservers.addObserver(observer); |
| + if (sSystemAccountsSeedingStatus == SystemAccountsSeedingStatus.SEEDING_DONE) { |
| + observer.onSystemAccountsSeedingComplete(); |
| + } |
| + } |
| + |
| + private void seedSystemAccounts() { |
| + AccountManagerHelper accountManagerHelper = AccountManagerHelper.get(mContext); |
| + java.util.List<String> accountNamesList = accountManagerHelper.getGoogleAccountNames(); |
| + final String[] accountNames = accountNamesList.toArray(new String[accountNamesList.size()]); |
| + new AsyncTask<Void, Void, String[]>() { |
| + @Override |
| + public String[] doInBackground(Void... params) { |
| + try { |
| + mSemaphore.acquire(); |
|
Roger Tawa OOO till Jul 10th
2015/08/19 14:37:26
seedSystemAccounts() can only be called from UI th
gogerald1
2015/08/20 15:48:49
Done. Add one more flag to get rid of semaphore.
|
| + } catch (InterruptedException e) { |
| + Log.w(TAG, "Got InterruptedException while waiting for semaphore"); |
| + return new String[0]; |
| + } |
| + if (sSystemAccountsSeedingStatus |
| + == SystemAccountsSeedingStatus.SEEDING_NOT_STARTED) { |
| + Log.d(TAG, "Getting id/email mapping"); |
| + sSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_IN_PROGRESS; |
| + String[] accountIds = new String[accountNames.length]; |
| + AccountIdProvider provider = AccountIdProvider.getInstance(); |
| + for (int i = 0; i < accountIds.length; ++i) { |
| + accountIds[i] = provider.getAccountId(mContext, accountNames[i]); |
| + } |
| + return accountIds; |
| + } |
| + return new String[0]; |
| + } |
| + @Override |
| + public void onPostExecute(String[] accountIds) { |
| + if (sSystemAccountsSeedingStatus |
| + == SystemAccountsSeedingStatus.SEEDING_IN_PROGRESS) { |
| + nativeSeedAccountsInfo(mNativeAccountTrackerService, accountIds, accountNames); |
| + sSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_DONE; |
| + notifyObserversOnSeedingComplete(); |
| + } |
| + mSemaphore.release(); |
| + } |
| + |
| + }.execute(); |
| + } |
| + |
| + private void notifyObserversOnSeedingComplete() { |
| + for (OnSystemAccountsSeededListener observer : sSystemAccountsSeedingObservers) { |
| + observer.onSystemAccountsSeedingComplete(); |
| + } |
| + } |
| + |
| + /** |
| + * Force AccountTrackerService refresh/update systems accounts. |
| + */ |
| + public void forceRefresh() { |
| + ThreadUtils.assertOnUiThread(); |
| + sSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_NOT_STARTED; |
| + notifyObserversOnForceRefreshed(); |
| + seedSystemAccounts(); |
| + } |
| + |
| + private void notifyObserversOnForceRefreshed() { |
| + for (OnSystemAccountsSeededListener observer : sSystemAccountsSeedingObservers) { |
| + observer.onSystemAccountsForceRefreshed(); |
| + } |
| + } |
| + |
| + // Native methods. |
| + private native long nativeInit(); |
| + private native void nativeSeedAccountsInfo( |
| + long nativeAccountTrackerServiceAndroid, String[] gaiaIds, String[] accountNames); |
| +} |