diff options
author | Dmitri Plotnikov <dplotnikov@google.com> | 2010-11-29 15:20:14 -0800 |
---|---|---|
committer | Dmitri Plotnikov <dplotnikov@google.com> | 2010-11-29 15:20:26 -0800 |
commit | 56c55827a83eef9ebafbb68beb3656c2506c1e0f (patch) | |
tree | 6296c89568e2c9f2491ff1e032a637901237f542 /src/com | |
parent | c73a333a102a409d557bdf597fbe8e511b0999e1 (diff) | |
download | packages_apps_Contacts-56c55827a83eef9ebafbb68beb3656c2506c1e0f.tar.gz packages_apps_Contacts-56c55827a83eef9ebafbb68beb3656c2506c1e0f.tar.bz2 packages_apps_Contacts-56c55827a83eef9ebafbb68beb3656c2506c1e0f.zip |
Performing all account meta-data loading on background thread.
Bug: 3228687
Change-Id: Id66989ed9a4e671019b931c172de254b8b055a4f
Diffstat (limited to 'src/com')
-rw-r--r-- | src/com/android/contacts/model/AccountTypes.java | 63 |
1 files changed, 52 insertions, 11 deletions
diff --git a/src/com/android/contacts/model/AccountTypes.java b/src/com/android/contacts/model/AccountTypes.java index 4e942483a..92ffba2bc 100644 --- a/src/com/android/contacts/model/AccountTypes.java +++ b/src/com/android/contacts/model/AccountTypes.java @@ -47,6 +47,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.concurrent.CountDownLatch; /** * Singleton holder for all parsed {@link AccountType} available on the @@ -67,12 +68,16 @@ public class AccountTypes extends BroadcastReceiver private HashMap<String, AccountType> mSources = Maps.newHashMap(); private HashSet<String> mKnownPackages = Sets.newHashSet(); - private static final int MESSAGE_PROCESS_BROADCAST_INTENT = 0; - private static final int MESSAGE_SYNC_STATUS_CHANGED = 1; + private static final int MESSAGE_LOAD_DATA = 0; + private static final int MESSAGE_PROCESS_BROADCAST_INTENT = 1; + private static final int MESSAGE_SYNC_STATUS_CHANGED = 2; private HandlerThread mListenerThread; private Handler mListenerHandler; + /* A latch that ensures that asynchronous initialization completes before data is used */ + private CountDownLatch mInitializationLatch; + private static AccountTypes sInstance = null; private static final Comparator<Account> ACCOUNT_COMPARATOR = new Comparator<Account>() { @@ -102,6 +107,8 @@ public class AccountTypes extends BroadcastReceiver * Internal constructor that only performs initial parsing. */ private AccountTypes(Context context) { + mInitializationLatch = new CountDownLatch(1); + mContext = context; mApplicationContext = context.getApplicationContext(); mAccountManager = AccountManager.get(mApplicationContext); @@ -109,19 +116,20 @@ public class AccountTypes extends BroadcastReceiver // Create fallback contacts source for on-phone contacts mFallbackSource = new FallbackAccountType(); - queryAccounts(); - mListenerThread = new HandlerThread("AccountChangeListener"); mListenerThread.start(); mListenerHandler = new Handler(mListenerThread.getLooper()) { @Override public void handleMessage(Message msg) { switch (msg.what) { + case MESSAGE_LOAD_DATA: + loadAccountsInBackground(); + break; case MESSAGE_PROCESS_BROADCAST_INTENT: processBroadcastIntent((Intent) msg.obj); break; case MESSAGE_SYNC_STATUS_CHANGED: - queryAccounts(); + loadAccountsInBackground(); break; } } @@ -146,6 +154,8 @@ public class AccountTypes extends BroadcastReceiver mAccountManager.addOnAccountsUpdatedListener(this, mListenerHandler, false); ContentResolver.addStatusChangeListener(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, this); + + mListenerHandler.sendEmptyMessage(MESSAGE_LOAD_DATA); } /** @hide exposed for unit tests */ @@ -196,7 +206,7 @@ public class AccountTypes extends BroadcastReceiver invalidateCache(packageName); } else { // Unknown source, so reload from scratch - queryAccounts(); + loadAccountsInBackground(); } } } @@ -224,13 +234,33 @@ public class AccountTypes extends BroadcastReceiver /* This notification will arrive on the background thread */ public void onAccountsUpdated(Account[] accounts) { // Refresh to catch any changed accounts - queryAccounts(); + loadAccountsInBackground(); + } + + /** + * Returns instantly if accounts and account types have already been loaded. + * Otherwise waits for the background thread to complete the loading. + */ + void ensureAccountsLoaded() { + CountDownLatch latch = mInitializationLatch; + if (latch == null) { + return; + } + while (true) { + try { + latch.await(); + return; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } } /** - * Loads all {@link AuthenticatorDescription} known by the {@link AccountManager} on the system. + * Loads account list and corresponding account types. Always called on a + * background thread. */ - protected synchronized void queryAccounts() { + protected void loadAccountsInBackground() { mSources.clear(); mKnownPackages.clear(); mAccounts.clear(); @@ -291,7 +321,7 @@ public class AccountTypes extends BroadcastReceiver if (syncable) { // Ensure we have details loaded for each account - final AccountType accountType = getInflatedSource( + final AccountType accountType = getAccountType( account.type, AccountType.LEVEL_SUMMARY); if (accountType != null) { mAccounts.add(account); @@ -304,6 +334,10 @@ public class AccountTypes extends BroadcastReceiver Collections.sort(mAccounts, ACCOUNT_COMPARATOR); Collections.sort(mWritableAccounts, ACCOUNT_COMPARATOR); + if (mInitializationLatch != null) { + mInitializationLatch.countDown(); + mInitializationLatch = null; + } } /** @@ -323,7 +357,8 @@ public class AccountTypes extends BroadcastReceiver /** * Return list of all known, writable {@link Account}'s. */ - public synchronized ArrayList<Account> getAccounts(boolean writableOnly) { + public ArrayList<Account> getAccounts(boolean writableOnly) { + ensureAccountsLoaded(); return writableOnly ? mWritableAccounts : mAccounts; } @@ -336,6 +371,7 @@ public class AccountTypes extends BroadcastReceiver */ public DataKind getKindOrFallback(String accountType, String mimeType, Context context, int inflateLevel) { + ensureAccountsLoaded(); DataKind kind = null; // Try finding source and kind matching request @@ -362,6 +398,11 @@ public class AccountTypes extends BroadcastReceiver * Return {@link AccountType} for the given account type. */ public AccountType getInflatedSource(String accountType, int inflateLevel) { + ensureAccountsLoaded(); + return getAccountType(accountType, inflateLevel); + } + + AccountType getAccountType(String accountType, int inflateLevel) { // Try finding specific source, otherwise use fallback AccountType source = mSources.get(accountType); if (source == null) source = mFallbackSource; |