From 6eb9620ff289105c3fc4a1be28a8eebb17d044e0 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 10 Oct 2012 13:13:54 -0700 Subject: Include all accounts in dumpsys. Allow accounts to be loaded when a user is stopped, but always validate accounts against a freshly queried PMS cache when the user actually starts. Bug: 7276595 Change-Id: I0382064c73123c243bc6f6e5da8fc3d0a8b73442 --- .../android/accounts/AccountManagerService.java | 70 ++++++++++++++++------ core/java/android/content/SyncManager.java | 7 ++- 2 files changed, 58 insertions(+), 19 deletions(-) (limited to 'core') diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index dae38db..5cde65c 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -35,6 +35,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.RegisteredServicesCache; import android.content.pm.RegisteredServicesCacheListener; +import android.content.pm.UserInfo; import android.database.Cursor; import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; @@ -54,6 +55,7 @@ import android.os.UserManager; import android.text.TextUtils; import android.util.Log; import android.util.Pair; +import android.util.Slog; import android.util.SparseArray; import com.android.internal.R; @@ -70,6 +72,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; @@ -261,8 +264,7 @@ public class AccountManagerService accounts = new UserAccounts(mContext, userId); mUsers.append(userId, accounts); purgeOldGrants(accounts); - mAuthenticatorCache.invalidateCache(accounts.userId); - validateAccountsAndPopulateCache(accounts); + validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); } return accounts; } @@ -300,7 +302,28 @@ public class AccountManagerService } } - private void validateAccountsAndPopulateCache(UserAccounts accounts) { + /** + * Validate internal set of accounts against installed authenticators for + * given user. Clears cached authenticators before validating. + */ + public void validateAccounts(int userId) { + final UserAccounts accounts = getUserAccounts(userId); + + // Invalidate user-specific cache to make sure we catch any + // removed authenticators. + validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); + } + + /** + * Validate internal set of accounts against installed authenticators for + * given user. Clear cached authenticators before validating when requested. + */ + private void validateAccountsInternal( + UserAccounts accounts, boolean invalidateAuthenticatorCache) { + if (invalidateAuthenticatorCache) { + mAuthenticatorCache.invalidateCache(accounts.userId); + } + final HashSet knownAuth = Sets.newHashSet(); for (RegisteredServicesCache.ServiceInfo service : mAuthenticatorCache.getAllServices(accounts.userId)) { @@ -323,7 +346,7 @@ public class AccountManagerService final String accountName = cursor.getString(2); if (!knownAuth.contains(AuthenticatorDescription.newKey(accountType))) { - Log.d(TAG, "deleting account " + accountName + " because type " + Slog.w(TAG, "deleting account " + accountName + " because type " + accountType + " no longer has a registered authenticator"); db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null); accountDeleted = true; @@ -399,7 +422,8 @@ public class AccountManagerService @Override public void onServiceChanged(AuthenticatorDescription desc, int userId, boolean removed) { - validateAccountsAndPopulateCache(getUserAccounts(userId)); + Slog.d(TAG, "onServiceChanged() for userId " + userId); + validateAccountsInternal(getUserAccounts(userId), false /* invalidateAuthenticatorCache */); } public String getPassword(Account account) { @@ -1493,10 +1517,23 @@ public class AccountManagerService // Running in system_server; should never happen throw new RuntimeException(e); } + return getAccounts(runningUserIds); + } + + /** {@hide} */ + public AccountAndUser[] getAllAccounts() { + final List users = getUserManager().getUsers(); + final int[] userIds = new int[users.size()]; + for (int i = 0; i < userIds.length; i++) { + userIds[i] = users.get(i).id; + } + return getAccounts(userIds); + } + private AccountAndUser[] getAccounts(int[] userIds) { final ArrayList runningAccounts = Lists.newArrayList(); synchronized (mUsers) { - for (int userId : runningUserIds) { + for (int userId : userIds) { UserAccounts userAccounts = getUserAccounts(userId); if (userAccounts == null) continue; synchronized (userAccounts.cacheLock) { @@ -2006,6 +2043,7 @@ public class AccountManagerService return false; } + @Override protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) { @@ -2015,17 +2053,15 @@ public class AccountManagerService return; } final boolean isCheckinRequest = scanArgs(args, "--checkin") || scanArgs(args, "-c"); - - fout = new IndentingPrintWriter(fout, " "); - int size = mUsers.size(); - for (int i = 0; i < size; i++) { - fout.println("User " + mUsers.keyAt(i) + ":"); - ((IndentingPrintWriter) fout).increaseIndent(); - dumpUser(mUsers.valueAt(i), fd, fout, args, isCheckinRequest); - ((IndentingPrintWriter) fout).decreaseIndent(); - if (i < size - 1) { - fout.println(); - } + final IndentingPrintWriter ipw = new IndentingPrintWriter(fout, " "); + + final List users = getUserManager().getUsers(); + for (UserInfo user : users) { + ipw.println("User " + user + ":"); + ipw.increaseIndent(); + dumpUser(getUserAccounts(user.id), fd, ipw, args, isCheckinRequest); + ipw.println(); + ipw.decreaseIndent(); } } diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 053cc6f..93c9526 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -889,6 +889,9 @@ public class SyncManager { } private void onUserStarting(int userId) { + // Make sure that accounts we're about to use are valid + AccountManagerService.getSingleton().validateAccounts(userId); + mSyncAdapters.invalidateCache(userId); updateRunningAccounts(); @@ -1078,9 +1081,9 @@ public class SyncManager { } pw.print("memory low: "); pw.println(mStorageIsLow); - final AccountAndUser[] accounts = mRunningAccounts; + final AccountAndUser[] accounts = AccountManagerService.getSingleton().getAllAccounts(); - pw.print("running accounts: "); + pw.print("accounts: "); if (accounts != INITIAL_ACCOUNTS_ARRAY) { pw.println(accounts.length); } else { -- cgit v1.1