diff options
author | Carlos Valdivia <carlosvaldivia@google.com> | 2015-08-12 01:42:19 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-08-12 01:42:19 +0000 |
commit | 968fc3ab75b0de71f298c6241cab1be1e6d5c86e (patch) | |
tree | 82d5d22988d6329f2719c9fbe9049f697c893017 /services | |
parent | 77b0d6e9f001c5e08fa367bff3b3e501ab36cc77 (diff) | |
parent | a3721e1cc855436c6048ca58134997bfce12ad1a (diff) | |
download | frameworks_base-968fc3ab75b0de71f298c6241cab1be1e6d5c86e.zip frameworks_base-968fc3ab75b0de71f298c6241cab1be1e6d5c86e.tar.gz frameworks_base-968fc3ab75b0de71f298c6241cab1be1e6d5c86e.tar.bz2 |
Merge "Fix deadlock." into mnc-dev
Diffstat (limited to 'services')
-rw-r--r-- | services/core/java/com/android/server/accounts/AccountManagerService.java | 113 |
1 files changed, 59 insertions, 54 deletions
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index aab6374..8b0e6f2 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -283,7 +283,22 @@ public class AccountManagerService // Don't delete accounts when updating a authenticator's // package. if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { - purgeOldGrantsAll(); + /* Purging data requires file io, don't block the main thread. This is probably + * less than ideal because we are introducing a race condition where old grants + * could be exercised until they are purged. But that race condition existed + * anyway with the broadcast receiver. + * + * Ideally, we would completely clear the cache, purge data from the database, + * and then rebuild the cache. All under the cache lock. But that change is too + * large at this point. + */ + Runnable r = new Runnable() { + @Override + public void run() { + purgeOldGrantsAll(); + } + }; + new Thread(r).start(); } } }, intentFilter); @@ -329,52 +344,6 @@ public class AccountManagerService return mUserManager; } - /* Caller should lock mUsers */ - private UserAccounts initUserLocked(int userId) { - UserAccounts accounts = mUsers.get(userId); - if (accounts == null) { - accounts = new UserAccounts(mContext, userId); - initializeDebugDbSizeAndCompileSqlStatementForLogging( - accounts.openHelper.getWritableDatabase(), accounts); - mUsers.append(userId, accounts); - purgeOldGrants(accounts); - validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); - } - return accounts; - } - - private void purgeOldGrantsAll() { - synchronized (mUsers) { - for (int i = 0; i < mUsers.size(); i++) { - purgeOldGrants(mUsers.valueAt(i)); - } - } - } - - private void purgeOldGrants(UserAccounts accounts) { - synchronized (accounts.cacheLock) { - final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); - final Cursor cursor = db.query(TABLE_GRANTS, - new String[]{GRANTS_GRANTEE_UID}, - null, null, GRANTS_GRANTEE_UID, null, null); - try { - while (cursor.moveToNext()) { - final int uid = cursor.getInt(0); - final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null; - if (packageExists) { - continue; - } - Log.d(TAG, "deleting grants for UID " + uid - + " because its package is no longer installed"); - db.delete(TABLE_GRANTS, GRANTS_GRANTEE_UID + "=?", - new String[]{Integer.toString(uid)}); - } - } finally { - cursor.close(); - } - } - } - /** * Validate internal set of accounts against installed authenticators for * given user. Clears cached authenticators before validating. @@ -469,13 +438,49 @@ public class AccountManagerService synchronized (mUsers) { UserAccounts accounts = mUsers.get(userId); if (accounts == null) { - accounts = initUserLocked(userId); + accounts = new UserAccounts(mContext, userId); + initializeDebugDbSizeAndCompileSqlStatementForLogging( + accounts.openHelper.getWritableDatabase(), accounts); mUsers.append(userId, accounts); + purgeOldGrants(accounts); + validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); } return accounts; } } + private void purgeOldGrantsAll() { + synchronized (mUsers) { + for (int i = 0; i < mUsers.size(); i++) { + purgeOldGrants(mUsers.valueAt(i)); + } + } + } + + private void purgeOldGrants(UserAccounts accounts) { + synchronized (accounts.cacheLock) { + final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); + final Cursor cursor = db.query(TABLE_GRANTS, + new String[]{GRANTS_GRANTEE_UID}, + null, null, GRANTS_GRANTEE_UID, null, null); + try { + while (cursor.moveToNext()) { + final int uid = cursor.getInt(0); + final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null; + if (packageExists) { + continue; + } + Log.d(TAG, "deleting grants for UID " + uid + + " because its package is no longer installed"); + db.delete(TABLE_GRANTS, GRANTS_GRANTEE_UID + "=?", + new String[]{Integer.toString(uid)}); + } + } finally { + cursor.close(); + } + } + } + private void onUserRemoved(Intent intent) { int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); if (userId < 1) return; @@ -2510,8 +2515,9 @@ public class AccountManagerService } long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); return getAccountsInternal( - userId, + accounts, callingUid, null, // packageName visibleAccountTypes); @@ -2609,8 +2615,9 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { + UserAccounts accounts = getUserAccounts(userId); return getAccountsInternal( - userId, + accounts, callingUid, callingPackage, visibleAccountTypes); @@ -2620,13 +2627,11 @@ public class AccountManagerService } private Account[] getAccountsInternal( - int userId, + UserAccounts userAccounts, int callingUid, String callingPackage, List<String> visibleAccountTypes) { - UserAccounts accounts = getUserAccounts(userId); - synchronized (accounts.cacheLock) { - UserAccounts userAccounts = getUserAccounts(userId); + synchronized (userAccounts.cacheLock) { ArrayList<Account> visibleAccounts = new ArrayList<>(); for (String visibleType : visibleAccountTypes) { Account[] accountsForType = getAccountsFromCacheLocked( |