Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 858511cd authored by Simranjit Kohli's avatar Simranjit Kohli
Browse files

Fix extra data in cache

Reverting the revert.
The original CL(commit a666d74d) had a 
bug in it. It was calling accountExistsCacheLocked(), while holding 
accounts.cacheLock. The function accountExistsCacheLocked, was in turn
calling into getUserAccounts, which acquires mUsers. And this causes
trouble. mUsers is a a lock on all accounts, and hence calling it after
holding accounts.cachelock is calling for trouble. Since the locks are 
acquired in other order, it causes a potential deadlock issue, which we 
discovered later on.

That bug was fixed by commit 0e592733.
We already have useraccount object and should reuse it.

This reverts commit 27d0e1fd. This 
commit was unneeded as the bug had been fixed by that time.

Change-Id: I5328c31fd485fd2c1c652cd0e7c2c4bded38a5fd
parent c1b8e883
Loading
Loading
Loading
Loading
+53 −36
Original line number Diff line number Diff line
@@ -782,7 +782,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);
        }
@@ -1869,19 +1874,34 @@ 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 : accounts.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.getWritableDatabaseUserIsUnlocked();
        final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
        db.beginTransaction();
        try {
            long accountId = getAccountIdLocked(db, account);
@@ -1897,10 +1917,9 @@ public class AccountManagerService
            } else {
                ContentValues values = new ContentValues();
                values.put(EXTRAS_VALUE, value);
                    if (1 != db.update(CE_TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) {
                if (1 != db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=" + extrasId, null)) {
                    return;
                }

            }
            writeUserDataIntoCacheLocked(accounts, db, account, key, value);
            db.setTransactionSuccessful();
@@ -1908,7 +1927,6 @@ public class AccountManagerService
            db.endTransaction();
        }
    }
    }

    private void onResult(IAccountManagerResponse response, Bundle result) {
        if (result == null) {
@@ -5262,18 +5280,17 @@ public class AccountManagerService
        }
    }

    protected String readUserDataInternal(UserAccounts accounts, Account account, String key) {
        synchronized (accounts.cacheLock) {
    protected String readUserDataInternalLocked(
            UserAccounts accounts, Account account, String key) {
        HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account);
        if (userDataForAccount == null) {
            // need to populate the cache for this account
                final SQLiteDatabase db = accounts.openHelper.getReadableDatabaseUserIsUnlocked();
            final SQLiteDatabase db = accounts.openHelper.getReadableDatabase();
            userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account);
            accounts.userDataCache.put(account, userDataForAccount);
        }
        return userDataForAccount.get(key);
    }
    }

    protected HashMap<String, String> readUserDataForAccountFromDatabaseLocked(
            final SQLiteDatabase db, Account account) {