From a666d74d4bc7e1298314c516d1309571fb87c212 Mon Sep 17 00:00:00 2001 From: Simranjit Singh Kohli Date: Fri, 7 Aug 2015 13:34:09 -0700 Subject: [PATCH] [Fix extra data in cache] It seems that some account authenticators call getData before account is added, which initializes the cache for that account. 1. We now don't initialize the cache if the account is not on the device. 2. We now use locking. Bug: 23018710 Bug: 20071745 Change-Id: Ie59ca6b4e575f524a9d3bf286c3bd95abce4a596 --- .../accounts/AccountManagerService.java | 90 +++++++++++-------- 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index ca1e3719c037b..163b9be2374b1 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -660,7 +660,12 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { UserAccounts accounts = getUserAccounts(userId); - return readUserDataInternal(accounts, account, key); + synchronized (accounts.cacheLock) { + if (!accountExistsCacheLocked(accounts, account)) { + return null; + } + return readUserDataInternalLocked(accounts, account, key); + } } finally { restoreCallingIdentity(identityToken); } @@ -1716,44 +1721,58 @@ public class AccountManagerService long identityToken = clearCallingIdentity(); try { UserAccounts accounts = getUserAccounts(userId); - setUserdataInternal(accounts, account, key, value); + synchronized (accounts.cacheLock) { + if (!accountExistsCacheLocked(accounts, account)) { + return; + } + setUserdataInternalLocked(accounts, account, key, value); + } } finally { restoreCallingIdentity(identityToken); } } - private void setUserdataInternal(UserAccounts accounts, Account account, String key, + private boolean accountExistsCacheLocked(UserAccounts accounts, Account account) { + if (accounts.accountCache.containsKey(account.type)) { + for (Account acc : getUserAccountsForCaller().accountCache.get(account.type)) { + if (acc.name.equals(account.name)) { + return true; + } + } + } + return false; + } + + private void setUserdataInternalLocked(UserAccounts accounts, Account account, String key, String value) { if (account == null || key == null) { return; } - synchronized (accounts.cacheLock) { - final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); - db.beginTransaction(); - try { - long accountId = getAccountIdLocked(db, account); - if (accountId < 0) { + final SQLiteDatabase db = accounts.openHelper.getWritableDatabase(); + db.beginTransaction(); + try { + long accountId = getAccountIdLocked(db, account); + if (accountId < 0) { + return; + } + long extrasId = getExtrasIdLocked(db, accountId, key); + if (extrasId < 0) { + extrasId = insertExtraLocked(db, accountId, key, value); + if (extrasId < 0) { return; } - long extrasId = getExtrasIdLocked(db, accountId, key); - if (extrasId < 0 ) { - extrasId = insertExtraLocked(db, accountId, key, value); - if (extrasId < 0) { - return; - } - } else { - ContentValues values = new ContentValues(); - values.put(EXTRAS_VALUE, value); - if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) { - return; - } - + } else { + ContentValues values = new ContentValues(); + values.put(EXTRAS_VALUE, value); + if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) { + return; } - writeUserDataIntoCacheLocked(accounts, db, account, key, value); - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); + } + writeUserDataIntoCacheLocked(accounts, db, account, key, value); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); } } @@ -4788,17 +4807,16 @@ public class AccountManagerService } } - protected String readUserDataInternal(UserAccounts accounts, Account account, String key) { - synchronized (accounts.cacheLock) { - HashMap userDataForAccount = accounts.userDataCache.get(account); - if (userDataForAccount == null) { - // need to populate the cache for this account - final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); - userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account); - accounts.userDataCache.put(account, userDataForAccount); - } - return userDataForAccount.get(key); + protected String readUserDataInternalLocked( + UserAccounts accounts, Account account, String key) { + HashMap userDataForAccount = accounts.userDataCache.get(account); + if (userDataForAccount == null) { + // need to populate the cache for this account + final SQLiteDatabase db = accounts.openHelper.getReadableDatabase(); + userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account); + accounts.userDataCache.put(account, userDataForAccount); } + return userDataForAccount.get(key); } protected HashMap readUserDataForAccountFromDatabaseLocked(