Merge "Allow deleting accounts when user is locked" into nyc-dev
am: f3d2414
* commit 'f3d241486b17cbfef7ad9b57aef3454ac3e0e769':
Allow deleting accounts when user is locked
Change-Id: I06cf0ba96fcd0f7c3e13d29daa01f56b04c0e5ac
This commit is contained in:
@@ -87,6 +87,7 @@ import android.util.SparseBooleanArray;
|
|||||||
import com.android.internal.R;
|
import com.android.internal.R;
|
||||||
import com.android.internal.util.ArrayUtils;
|
import com.android.internal.util.ArrayUtils;
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
|
import com.android.internal.util.Preconditions;
|
||||||
import com.android.server.FgThread;
|
import com.android.server.FgThread;
|
||||||
import com.android.server.LocalServices;
|
import com.android.server.LocalServices;
|
||||||
import com.google.android.collect.Lists;
|
import com.google.android.collect.Lists;
|
||||||
@@ -553,7 +554,7 @@ public class AccountManagerService
|
|||||||
CeDatabaseHelper.create(mContext, userId);
|
CeDatabaseHelper.create(mContext, userId);
|
||||||
accounts.openHelper.attachCeDatabase();
|
accounts.openHelper.attachCeDatabase();
|
||||||
}
|
}
|
||||||
// TODO Synchronize accounts by removing CE account not available in DE
|
syncDeCeAccountsLocked(accounts);
|
||||||
}
|
}
|
||||||
if (validateAccounts) {
|
if (validateAccounts) {
|
||||||
validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
|
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() {
|
private void purgeOldGrantsAll() {
|
||||||
synchronized (mUsers) {
|
synchronized (mUsers) {
|
||||||
for (int i = 0; i < mUsers.size(); i++) {
|
for (int i = 0; i < mUsers.size(); i++) {
|
||||||
@@ -799,7 +815,7 @@ public class AccountManagerService
|
|||||||
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
if (Log.isLoggable(TAG, Log.VERBOSE)) {
|
||||||
Log.v(TAG, "getAuthenticatorTypes: "
|
Log.v(TAG, "getAuthenticatorTypes: "
|
||||||
+ "for user id " + userId
|
+ "for user id " + userId
|
||||||
+ "caller's uid " + callingUid
|
+ " caller's uid " + callingUid
|
||||||
+ ", pid " + Binder.getCallingPid());
|
+ ", pid " + Binder.getCallingPid());
|
||||||
}
|
}
|
||||||
// Only allow the system process to read accounts of other users
|
// Only allow the system process to read accounts of other users
|
||||||
@@ -1543,21 +1559,35 @@ public class AccountManagerService
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean removeAccountInternal(UserAccounts accounts, Account account, int callingUid) {
|
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;
|
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) {
|
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);
|
final long accountId = getAccountIdLocked(db, account);
|
||||||
deleted = db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
|
db.beginTransaction();
|
||||||
+ "=?",
|
try {
|
||||||
new String[]{account.name, account.type});
|
deleted = db.delete(TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE
|
||||||
// Delete from CE table
|
+ "=?", new String[]{account.name, account.type});
|
||||||
db.delete(CE_TABLE_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
|
if (userUnlocked) {
|
||||||
new String[]{account.name, account.type});
|
// Delete from CE table
|
||||||
|
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);
|
removeAccountFromCacheLocked(accounts, account);
|
||||||
sendAccountsChangedBroadcast(accounts.userId);
|
sendAccountsChangedBroadcast(accounts.userId);
|
||||||
|
String action = userUnlocked ? DebugDbHelper.ACTION_ACCOUNT_REMOVE
|
||||||
logRecord(db, DebugDbHelper.ACTION_ACCOUNT_REMOVE, TABLE_ACCOUNTS, accountId, accounts);
|
: DebugDbHelper.ACTION_ACCOUNT_REMOVE_DE;
|
||||||
|
logRecord(db, action, TABLE_ACCOUNTS, accountId, accounts);
|
||||||
}
|
}
|
||||||
long id = Binder.clearCallingIdentity();
|
long id = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
@@ -4072,6 +4102,7 @@ public class AccountManagerService
|
|||||||
private static String ACTION_CLEAR_PASSWORD = "action_clear_password";
|
private static String ACTION_CLEAR_PASSWORD = "action_clear_password";
|
||||||
private static String ACTION_ACCOUNT_ADD = "action_account_add";
|
private static String ACTION_ACCOUNT_ADD = "action_account_add";
|
||||||
private static String ACTION_ACCOUNT_REMOVE = "action_account_remove";
|
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_AUTHENTICATOR_REMOVE = "action_authenticator_remove";
|
||||||
private static String ACTION_ACCOUNT_RENAME = "action_account_rename";
|
private static String ACTION_ACCOUNT_RENAME = "action_account_rename";
|
||||||
|
|
||||||
@@ -4082,6 +4113,7 @@ public class AccountManagerService
|
|||||||
// who called.
|
// who called.
|
||||||
private static String ACTION_CALLED_ACCOUNT_ADD = "action_called_account_add";
|
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_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
|
//This action doesn't add account to accountdb. Account is only
|
||||||
// added in finishSession which may be in a different user profile.
|
// 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,
|
* 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.
|
* it also performs migration to the new CE database.
|
||||||
|
|||||||
Reference in New Issue
Block a user