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

Commit 79d2402f authored by Fyodor Kupolov's avatar Fyodor Kupolov Committed by android-build-merger
Browse files

Merge "Allow deleting accounts when user is locked" into nyc-dev

am: f3d24148

* commit 'f3d24148':
  Allow deleting accounts when user is locked

Change-Id: I06cf0ba96fcd0f7c3e13d29daa01f56b04c0e5ac
parents 8615cb59 f3d24148
Loading
Loading
Loading
Loading
+66 −12
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ import android.util.SparseBooleanArray;
import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.google.android.collect.Lists;
@@ -553,7 +554,7 @@ public class AccountManagerService
                    CeDatabaseHelper.create(mContext, userId);
                    accounts.openHelper.attachCeDatabase();
                }
                // TODO Synchronize accounts by removing CE account not available in DE
                syncDeCeAccountsLocked(accounts);
            }
            if (validateAccounts) {
                validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
@@ -562,6 +563,21 @@ public class AccountManagerService
        }
    }

    private void syncDeCeAccountsLocked(UserAccounts accounts) {
        Preconditions.checkState(Thread.holdsLock(mUsers), "mUsers lock must be held");
        final SQLiteDatabase db = accounts.openHelper.getReadableDatabaseUserIsUnlocked();
        List<Account> accountsToRemove = CeDatabaseHelper.findCeAccountsNotInDe(db);
        if (!accountsToRemove.isEmpty()) {
            Slog.i(TAG, "Accounts " + accountsToRemove + " were previously deleted while user "
                    + accounts.userId + " was locked. Removing accounts from CE tables");
            logRecord(accounts, DebugDbHelper.ACTION_SYNC_DE_CE_ACCOUNTS, TABLE_ACCOUNTS);

            for (Account account : accountsToRemove) {
                removeAccountInternal(accounts, account, Process.myUid());
            }
        }
    }

    private void purgeOldGrantsAll() {
        synchronized (mUsers) {
            for (int i = 0; i < mUsers.size(); i++) {
@@ -1543,21 +1559,35 @@ public class AccountManagerService
    }

    private boolean removeAccountInternal(UserAccounts accounts, Account account, int callingUid) {
        // For now user is required to be unlocked. TODO: Handle both cases in the future
        int deleted;
        boolean userUnlocked = isUserUnlocked(accounts.userId);
        if (!userUnlocked) {
            Slog.i(TAG, "Removing account " + account + " while user "+ accounts.userId
                    + " is still locked. CE data will be removed later");
        }
        synchronized (accounts.cacheLock) {
            final SQLiteDatabase db = accounts.openHelper.getWritableDatabaseUserIsUnlocked();
            final SQLiteDatabase db = userUnlocked
                    ? accounts.openHelper.getWritableDatabaseUserIsUnlocked()
                    : accounts.openHelper.getWritableDatabase();
            final long accountId = getAccountIdLocked(db, account);
            db.beginTransaction();
            try {
                deleted = db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
                    + "=?",
                    new String[]{account.name, account.type});
                                + "=?", new String[]{account.name, account.type});
                if (userUnlocked) {
                    // Delete from CE table
            db.delete(CE_TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
                    new String[]{account.name, account.type});
                    deleted = db.delete(CE_TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
                            + "=?", new String[]{account.name, account.type});
                }
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
            removeAccountFromCacheLocked(accounts, account);
            sendAccountsChangedBroadcast(accounts.userId);

            logRecord(db, DebugDbHelper.ACTION_ACCOUNT_REMOVE, TABLE_ACCOUNTS, accountId, accounts);
            String action = userUnlocked ? DebugDbHelper.ACTION_ACCOUNT_REMOVE
                    : DebugDbHelper.ACTION_ACCOUNT_REMOVE_DE;
            logRecord(db, action, TABLE_ACCOUNTS, accountId, accounts);
        }
        long id = Binder.clearCallingIdentity();
        try {
@@ -4072,6 +4102,7 @@ public class AccountManagerService
        private static String ACTION_CLEAR_PASSWORD = "action_clear_password";
        private static String ACTION_ACCOUNT_ADD = "action_account_add";
        private static String ACTION_ACCOUNT_REMOVE = "action_account_remove";
        private static String ACTION_ACCOUNT_REMOVE_DE = "action_account_remove_de";
        private static String ACTION_AUTHENTICATOR_REMOVE = "action_authenticator_remove";
        private static String ACTION_ACCOUNT_RENAME = "action_account_rename";

@@ -4082,6 +4113,7 @@ public class AccountManagerService
        // who called.
        private static String ACTION_CALLED_ACCOUNT_ADD = "action_called_account_add";
        private static String ACTION_CALLED_ACCOUNT_REMOVE = "action_called_account_remove";
        private static String ACTION_SYNC_DE_CE_ACCOUNTS = "action_sync_de_ce_accounts";

        //This action doesn't add account to accountdb. Account is only
        // added in finishSession which may be in a different user profile.
@@ -4580,6 +4612,28 @@ public class AccountManagerService
            }
        }

        static List<Account> findCeAccountsNotInDe(SQLiteDatabase db) {
            // Select accounts from CE that do not exist in DE
            Cursor cursor = db.rawQuery(
                    "SELECT " + ACCOUNTS_NAME + "," + ACCOUNTS_TYPE
                            + " FROM " + CE_TABLE_ACCOUNTS
                            + " WHERE NOT EXISTS "
                            + " (SELECT " + ACCOUNTS_ID + " FROM " + TABLE_ACCOUNTS
                            + " WHERE " + ACCOUNTS_ID + "=" + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_ID
                            + " )", null);
            try {
                List<Account> accounts = new ArrayList<>(cursor.getCount());
                while (cursor.moveToNext()) {
                    String accountName = cursor.getString(0);
                    String accountType = cursor.getString(1);
                    accounts.add(new Account(accountName, accountType));
                }
                return accounts;
            } finally {
                cursor.close();
            }
        }

        /**
         * Creates a new {@code CeDatabaseHelper}. If pre-N db file is present at the old location,
         * it also performs migration to the new CE database.