Merge "Fix deadlock." into mnc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
968fc3ab75
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user