Loading services/core/java/com/android/server/accounts/AccountManagerService.java +59 −54 Original line number Original line Diff line number Diff line Loading @@ -283,8 +283,23 @@ public class AccountManagerService // Don't delete accounts when updating a authenticator's // Don't delete accounts when updating a authenticator's // package. // package. if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { /* 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(); purgeOldGrantsAll(); } } }; new Thread(r).start(); } } } }, intentFilter); }, intentFilter); Loading Loading @@ -329,52 +344,6 @@ public class AccountManagerService return mUserManager; 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 * Validate internal set of accounts against installed authenticators for * given user. Clears cached authenticators before validating. * given user. Clears cached authenticators before validating. Loading Loading @@ -469,13 +438,49 @@ public class AccountManagerService synchronized (mUsers) { synchronized (mUsers) { UserAccounts accounts = mUsers.get(userId); UserAccounts accounts = mUsers.get(userId); if (accounts == null) { if (accounts == null) { accounts = initUserLocked(userId); accounts = new UserAccounts(mContext, userId); initializeDebugDbSizeAndCompileSqlStatementForLogging( accounts.openHelper.getWritableDatabase(), accounts); mUsers.append(userId, accounts); mUsers.append(userId, accounts); purgeOldGrants(accounts); validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); } } return accounts; 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) { private void onUserRemoved(Intent intent) { int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); if (userId < 1) return; if (userId < 1) return; Loading Loading @@ -2510,8 +2515,9 @@ public class AccountManagerService } } long identityToken = clearCallingIdentity(); long identityToken = clearCallingIdentity(); try { try { UserAccounts accounts = getUserAccounts(userId); return getAccountsInternal( return getAccountsInternal( userId, accounts, callingUid, callingUid, null, // packageName null, // packageName visibleAccountTypes); visibleAccountTypes); Loading Loading @@ -2609,8 +2615,9 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); long identityToken = clearCallingIdentity(); try { try { UserAccounts accounts = getUserAccounts(userId); return getAccountsInternal( return getAccountsInternal( userId, accounts, callingUid, callingUid, callingPackage, callingPackage, visibleAccountTypes); visibleAccountTypes); Loading @@ -2620,13 +2627,11 @@ public class AccountManagerService } } private Account[] getAccountsInternal( private Account[] getAccountsInternal( int userId, UserAccounts userAccounts, int callingUid, int callingUid, String callingPackage, String callingPackage, List<String> visibleAccountTypes) { List<String> visibleAccountTypes) { UserAccounts accounts = getUserAccounts(userId); synchronized (userAccounts.cacheLock) { synchronized (accounts.cacheLock) { UserAccounts userAccounts = getUserAccounts(userId); ArrayList<Account> visibleAccounts = new ArrayList<>(); ArrayList<Account> visibleAccounts = new ArrayList<>(); for (String visibleType : visibleAccountTypes) { for (String visibleType : visibleAccountTypes) { Account[] accountsForType = getAccountsFromCacheLocked( Account[] accountsForType = getAccountsFromCacheLocked( Loading Loading
services/core/java/com/android/server/accounts/AccountManagerService.java +59 −54 Original line number Original line Diff line number Diff line Loading @@ -283,8 +283,23 @@ public class AccountManagerService // Don't delete accounts when updating a authenticator's // Don't delete accounts when updating a authenticator's // package. // package. if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { /* 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(); purgeOldGrantsAll(); } } }; new Thread(r).start(); } } } }, intentFilter); }, intentFilter); Loading Loading @@ -329,52 +344,6 @@ public class AccountManagerService return mUserManager; 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 * Validate internal set of accounts against installed authenticators for * given user. Clears cached authenticators before validating. * given user. Clears cached authenticators before validating. Loading Loading @@ -469,13 +438,49 @@ public class AccountManagerService synchronized (mUsers) { synchronized (mUsers) { UserAccounts accounts = mUsers.get(userId); UserAccounts accounts = mUsers.get(userId); if (accounts == null) { if (accounts == null) { accounts = initUserLocked(userId); accounts = new UserAccounts(mContext, userId); initializeDebugDbSizeAndCompileSqlStatementForLogging( accounts.openHelper.getWritableDatabase(), accounts); mUsers.append(userId, accounts); mUsers.append(userId, accounts); purgeOldGrants(accounts); validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */); } } return accounts; 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) { private void onUserRemoved(Intent intent) { int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); if (userId < 1) return; if (userId < 1) return; Loading Loading @@ -2510,8 +2515,9 @@ public class AccountManagerService } } long identityToken = clearCallingIdentity(); long identityToken = clearCallingIdentity(); try { try { UserAccounts accounts = getUserAccounts(userId); return getAccountsInternal( return getAccountsInternal( userId, accounts, callingUid, callingUid, null, // packageName null, // packageName visibleAccountTypes); visibleAccountTypes); Loading Loading @@ -2609,8 +2615,9 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); long identityToken = clearCallingIdentity(); try { try { UserAccounts accounts = getUserAccounts(userId); return getAccountsInternal( return getAccountsInternal( userId, accounts, callingUid, callingUid, callingPackage, callingPackage, visibleAccountTypes); visibleAccountTypes); Loading @@ -2620,13 +2627,11 @@ public class AccountManagerService } } private Account[] getAccountsInternal( private Account[] getAccountsInternal( int userId, UserAccounts userAccounts, int callingUid, int callingUid, String callingPackage, String callingPackage, List<String> visibleAccountTypes) { List<String> visibleAccountTypes) { UserAccounts accounts = getUserAccounts(userId); synchronized (userAccounts.cacheLock) { synchronized (accounts.cacheLock) { UserAccounts userAccounts = getUserAccounts(userId); ArrayList<Account> visibleAccounts = new ArrayList<>(); ArrayList<Account> visibleAccounts = new ArrayList<>(); for (String visibleType : visibleAccountTypes) { for (String visibleType : visibleAccountTypes) { Account[] accountsForType = getAccountsFromCacheLocked( Account[] accountsForType = getAccountsFromCacheLocked( Loading