summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java956
1 files changed, 539 insertions, 417 deletions
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index acab1afb6a58..31f14e7a77ba 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -110,7 +110,6 @@ import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
@@ -279,11 +278,9 @@ public class AccountManagerService
private final HashMap<String, Account[]> accountCache =
new LinkedHashMap<String, Account[]>();
/** protected by the {@link #cacheLock} */
- private final HashMap<Account, HashMap<String, String>> userDataCache =
- new HashMap<Account, HashMap<String, String>>();
+ private final Map<Account, Map<String, String>> userDataCache = new HashMap<>();
/** protected by the {@link #cacheLock} */
- private final HashMap<Account, HashMap<String, String>> authTokenCache =
- new HashMap<Account, HashMap<String, String>>();
+ private final Map<Account, Map<String, String>> authTokenCache = new HashMap<>();
/** protected by the {@link #cacheLock} */
private final TokenCache accountTokenCaches = new TokenCache();
@@ -978,106 +975,74 @@ public class AccountManagerService
final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
boolean accountDeleted = false;
- // Get a list of stored authenticator type and UID
- Cursor metaCursor = db.query(
- TABLE_META,
- new String[] {META_KEY, META_VALUE},
- SELECTION_META_BY_AUTHENTICATOR_TYPE,
- new String[] {META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + "%"},
- null /* groupBy */,
- null /* having */,
- META_KEY);
+ // Get a map of stored authenticator types to UID
+ Map<String, Integer> metaAuthUid = AccountsDbUtils.findMetaAuthUid(db);
// Create a list of authenticator type whose previous uid no longer exists
HashSet<String> obsoleteAuthType = Sets.newHashSet();
- try {
- SparseBooleanArray knownUids = null;
- while (metaCursor.moveToNext()) {
- String type = TextUtils.split(metaCursor.getString(0), META_KEY_DELIMITER)[1];
- String uid = metaCursor.getString(1);
- if (TextUtils.isEmpty(type) || TextUtils.isEmpty(uid)) {
- // Should never happen.
- Slog.e(TAG, "Auth type empty: " + TextUtils.isEmpty(type)
- + ", uid empty: " + TextUtils.isEmpty(uid));
- continue;
+ SparseBooleanArray knownUids = null;
+ for (Entry<String, Integer> authToUidEntry : metaAuthUid.entrySet()) {
+ String type = authToUidEntry.getKey();
+ int uid = authToUidEntry.getValue();
+ Integer knownUid = knownAuth.get(type);
+ if (knownUid != null && uid == knownUid) {
+ // Remove it from the knownAuth list if it's unchanged.
+ knownAuth.remove(type);
+ } else {
+ /*
+ * The authenticator is presently not cached and should only be triggered
+ * when we think an authenticator has been removed (or is being updated).
+ * But we still want to check if any data with the associated uid is
+ * around. This is an (imperfect) signal that the package may be updating.
+ *
+ * A side effect of this is that an authenticator sharing a uid with
+ * multiple apps won't get its credentials wiped as long as some app with
+ * that uid is still on the device. But I suspect that this is a rare case.
+ * And it isn't clear to me how an attacker could really exploit that
+ * feature.
+ *
+ * The upshot is that we don't have to worry about accounts getting
+ * uninstalled while the authenticator's package is being updated.
+ *
+ */
+ if (knownUids == null) {
+ knownUids = getUidsOfInstalledOrUpdatedPackagesAsUser(accounts.userId);
}
- Integer knownUid = knownAuth.get(type);
- if (knownUid != null && uid.equals(knownUid.toString())) {
- // Remove it from the knownAuth list if it's unchanged.
- knownAuth.remove(type);
- } else {
- /*
- * The authenticator is presently not cached and should only be triggered
- * when we think an authenticator has been removed (or is being updated).
- * But we still want to check if any data with the associated uid is
- * around. This is an (imperfect) signal that the package may be updating.
- *
- * A side effect of this is that an authenticator sharing a uid with
- * multiple apps won't get its credentials wiped as long as some app with
- * that uid is still on the device. But I suspect that this is a rare case.
- * And it isn't clear to me how an attacker could really exploit that
- * feature.
- *
- * The upshot is that we don't have to worry about accounts getting
- * uninstalled while the authenticator's package is being updated.
- *
- */
- if (knownUids == null) {
- knownUids = getUidsOfInstalledOrUpdatedPackagesAsUser(accounts.userId);
- }
- if (!knownUids.get(Integer.parseInt(uid))) {
- // The authenticator is not presently available to the cache. And the
- // package no longer has a data directory (so we surmise it isn't updating).
- // So purge its data from the account databases.
- obsoleteAuthType.add(type);
- // And delete it from the TABLE_META
- db.delete(
- TABLE_META,
- META_KEY + "=? AND " + META_VALUE + "=?",
- new String[] {
- META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + type,
- uid}
- );
- }
+ if (!knownUids.get(uid)) {
+ // The authenticator is not presently available to the cache. And the
+ // package no longer has a data directory (so we surmise it isn't updating).
+ // So purge its data from the account databases.
+ obsoleteAuthType.add(type);
+ // And delete it from the TABLE_META
+ AccountsDbUtils.deleteMetaByAuthTypeAndUid(db, type, uid);
}
}
- } finally {
- metaCursor.close();
}
// Add the newly registered authenticator to TABLE_META. If old authenticators have
- // been renabled (after being updated for example), then we just overwrite the old
+ // been re-enabled (after being updated for example), then we just overwrite the old
// values.
- Iterator<Entry<String, Integer>> iterator = knownAuth.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry<String, Integer> entry = iterator.next();
- ContentValues values = new ContentValues();
- values.put(META_KEY,
- META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + entry.getKey());
- values.put(META_VALUE, entry.getValue());
- db.insertWithOnConflict(TABLE_META, null, values, SQLiteDatabase.CONFLICT_REPLACE);
+ for (Entry<String, Integer> entry : knownAuth.entrySet()) {
+ AccountsDbUtils.insertOrReplaceMetaAuthTypeAndUid(db, entry.getKey(),
+ entry.getValue());
}
- Cursor cursor = db.query(TABLE_ACCOUNTS,
- new String[]{ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME},
- null, null, null, null, ACCOUNTS_ID);
+ final Map<Long, Account> accountsMap = AccountsDbUtils.findAllAccounts(db);
try {
accounts.accountCache.clear();
final HashMap<String, ArrayList<String>> accountNamesByType = new LinkedHashMap<>();
- while (cursor.moveToNext()) {
- final long accountId = cursor.getLong(0);
- final String accountType = cursor.getString(1);
- final String accountName = cursor.getString(2);
-
- if (obsoleteAuthType.contains(accountType)) {
- Slog.w(TAG, "deleting account " + accountName + " because type "
- + accountType + "'s registered authenticator no longer exist.");
+ for (Entry<Long, Account> accountEntry : accountsMap.entrySet()) {
+ final long accountId = accountEntry.getKey();
+ final Account account = accountEntry.getValue();
+ if (obsoleteAuthType.contains(account.type)) {
+ Slog.w(TAG, "deleting account " + account.name + " because type "
+ + account.type + "'s registered authenticator no longer exist.");
db.beginTransaction();
try {
- db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null);
+ AccountsDbUtils.deleteAccount(db, accountId);
// Also delete from CE table if user is unlocked; if user is currently
// locked the account will be removed later by syncDeCeAccountsLocked
if (userUnlocked) {
- db.delete(CE_TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null);
+ AccountsDbUtils.deleteCeAccount(db, accountId);
}
db.setTransactionSuccessful();
} finally {
@@ -1088,17 +1053,16 @@ public class AccountManagerService
logRecord(db, DebugDbHelper.ACTION_AUTHENTICATOR_REMOVE, TABLE_ACCOUNTS,
accountId, accounts);
- final Account account = new Account(accountName, accountType);
accounts.userDataCache.remove(account);
accounts.authTokenCache.remove(account);
accounts.accountTokenCaches.remove(account);
} else {
- ArrayList<String> accountNames = accountNamesByType.get(accountType);
+ ArrayList<String> accountNames = accountNamesByType.get(account.type);
if (accountNames == null) {
accountNames = new ArrayList<>();
- accountNamesByType.put(accountType, accountNames);
+ accountNamesByType.put(account.type, accountNames);
}
- accountNames.add(accountName);
+ accountNames.add(account.name);
}
}
for (Map.Entry<String, ArrayList<String>> cur : accountNamesByType.entrySet()) {
@@ -1111,7 +1075,6 @@ public class AccountManagerService
accounts.accountCache.put(accountType, accountsForType);
}
} finally {
- cursor.close();
if (accountDeleted) {
sendAccountsChangedBroadcast(accounts.userId);
}
@@ -1192,7 +1155,7 @@ 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);
+ List<Account> accountsToRemove = AccountsDbUtils.findCeAccountsNotInDe(db);
if (!accountsToRemove.isEmpty()) {
Slog.i(TAG, "Accounts " + accountsToRemove + " were previously deleted while user "
+ accounts.userId + " was locked. Removing accounts from CE tables");
@@ -1215,23 +1178,15 @@ public class AccountManagerService
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)});
+ List<Integer> uids = AccountsDbUtils.findAllUidGrants(db);
+ for (int uid : uids) {
+ final boolean packageExists = mPackageManager.getPackagesForUid(uid) != null;
+ if (packageExists) {
+ continue;
}
- } finally {
- cursor.close();
+ Log.d(TAG, "deleting grants for UID " + uid
+ + " because its package is no longer installed");
+ AccountsDbUtils.deleteGrantsByUid(db, uid);
}
}
}
@@ -1350,7 +1305,7 @@ public class AccountManagerService
synchronized (accounts.cacheLock) {
final SQLiteDatabase db = accounts.openHelper.getReadableDatabaseUserIsUnlocked();
- return CeDatabaseHelper.findAccountPasswordByNameAndType(db, account.name,
+ return AccountsDbUtils.findAccountPasswordByNameAndType(db, account.name,
account.type);
}
}
@@ -1381,26 +1336,10 @@ public class AccountManagerService
AtomicReference<String> previousNameRef = accounts.previousNameCache.get(account);
if (previousNameRef == null) {
final SQLiteDatabase db = accounts.openHelper.getReadableDatabase();
- Cursor cursor = db.query(
- TABLE_ACCOUNTS,
- new String[]{ ACCOUNTS_PREVIOUS_NAME },
- ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[] { account.name, account.type },
- null,
- null,
- null);
- try {
- if (cursor.moveToNext()) {
- String previousName = cursor.getString(0);
- previousNameRef = new AtomicReference<>(previousName);
- accounts.previousNameCache.put(account, previousNameRef);
- return previousName;
- } else {
- return null;
- }
- } finally {
- cursor.close();
- }
+ String previousName = AccountsDbUtils.findAccountPreviousName(db, account);
+ previousNameRef = new AtomicReference<>(previousName);
+ accounts.previousNameCache.put(account, previousNameRef);
+ return previousName;
} else {
return previousNameRef.get();
}
@@ -1753,7 +1692,7 @@ public class AccountManagerService
if (extras != null) {
for (String key : extras.keySet()) {
final String value = extras.getString(key);
- if (insertExtraLocked(db, accountId, key, value) < 0) {
+ if (AccountsDbUtils.insertExtra(db, accountId, key, value) < 0) {
Log.w(TAG, "insertAccountIntoDatabase: " + account
+ ", skipping since insertExtra failed for key " + key);
return false;
@@ -1804,14 +1743,6 @@ public class AccountManagerService
}
}
- private long insertExtraLocked(SQLiteDatabase db, long accountId, String key, String value) {
- ContentValues values = new ContentValues();
- values.put(EXTRAS_KEY, key);
- values.put(EXTRAS_ACCOUNTS_ID, accountId);
- values.put(EXTRAS_VALUE, value);
- return db.insert(CE_TABLE_EXTRAS, EXTRAS_KEY, values);
- }
-
@Override
public void hasFeatures(IAccountManagerResponse response,
Account account, String[] features, String opPackageName) {
@@ -1960,7 +1891,7 @@ public class AccountManagerService
db.beginTransaction();
Account renamedAccount = new Account(newName, accountToRename.type);
try {
- final long accountId = getAccountIdLocked(db, accountToRename);
+ final long accountId = AccountsDbUtils.findAccountId(db, accountToRename);
if (accountId >= 0) {
final ContentValues values = new ContentValues();
values.put(ACCOUNTS_NAME, newName);
@@ -1986,8 +1917,8 @@ public class AccountManagerService
* old account to preserve the user data associated with
* the account.
*/
- HashMap<String, String> tmpData = accounts.userDataCache.get(accountToRename);
- HashMap<String, String> tmpTokens = accounts.authTokenCache.get(accountToRename);
+ Map<String, String> tmpData = accounts.userDataCache.get(accountToRename);
+ Map<String, String> tmpTokens = accounts.authTokenCache.get(accountToRename);
removeAccountFromCacheLocked(accounts, accountToRename);
/*
* Update the cached data associated with the renamed
@@ -1997,7 +1928,7 @@ public class AccountManagerService
accounts.authTokenCache.put(renamedAccount, tmpTokens);
accounts.previousNameCache.put(
renamedAccount,
- new AtomicReference<String>(accountToRename.name));
+ new AtomicReference<>(accountToRename.name));
resultAccount = renamedAccount;
int parentUserId = accounts.userId;
@@ -2098,7 +2029,7 @@ public class AccountManagerService
}
}
SQLiteDatabase db = accounts.openHelper.getReadableDatabase();
- final long accountId = getAccountIdLocked(db, account);
+ final long accountId = AccountsDbUtils.findAccountId(db, account);
logRecord(
db,
DebugDbHelper.ACTION_CALLED_ACCOUNT_REMOVE,
@@ -2139,7 +2070,7 @@ public class AccountManagerService
removeVisibleListFunctionality(account, getUserAccounts(UserHandle.getUserId(callingUid)));
UserAccounts accounts = getUserAccountsForCaller();
SQLiteDatabase db = accounts.openHelper.getReadableDatabase();
- final long accountId = getAccountIdLocked(db, account);
+ final long accountId = AccountsDbUtils.findAccountId(db, account);
logRecord(
db,
DebugDbHelper.ACTION_CALLED_ACCOUNT_REMOVE,
@@ -2225,18 +2156,12 @@ public class AccountManagerService
// transaction succeeds.
long accountId = -1;
try {
- accountId = getAccountIdLocked(db, account);
+ accountId = AccountsDbUtils.findAccountId(db, account);
if (accountId >= 0) {
- db.delete(
- TABLE_ACCOUNTS,
- ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
- new String[]{ account.name, account.type });
+ AccountsDbUtils.deleteAccount(db, accountId);
if (userUnlocked) {
// Delete from CE table
- db.delete(
- CE_TABLE_ACCOUNTS,
- ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
- new String[]{ account.name, account.type });
+ AccountsDbUtils.deleteCeAccount(db, accountId);
}
db.setTransactionSuccessful();
isChanged = true;
@@ -2317,23 +2242,13 @@ public class AccountManagerService
if (authToken == null || accountType == null) {
return;
}
- Cursor cursor = db.rawQuery(
- "SELECT " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID
- + ", " + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_NAME
- + ", " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_TYPE
- + " FROM " + CE_TABLE_ACCOUNTS
- + " JOIN " + CE_TABLE_AUTHTOKENS
- + " ON " + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_ID
- + " = " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_ACCOUNTS_ID
- + " WHERE " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_AUTHTOKEN
- + " = ? AND " + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + " = ?",
- new String[]{authToken, accountType});
+ Cursor cursor = AccountsDbUtils.findAuthtokenForAllAccounts(db, accountType, authToken);
try {
while (cursor.moveToNext()) {
- long authTokenId = cursor.getLong(0);
+ String authTokenId = cursor.getString(0);
String accountName = cursor.getString(1);
String authTokenType = cursor.getString(2);
- db.delete(CE_TABLE_AUTHTOKENS, AUTHTOKENS_ID + "=" + authTokenId, null);
+ AccountsDbUtils.deleteAuthToken(db, authTokenId);
writeAuthTokenIntoCacheLocked(
accounts,
db,
@@ -2377,18 +2292,12 @@ public class AccountManagerService
final SQLiteDatabase db = accounts.openHelper.getWritableDatabaseUserIsUnlocked();
db.beginTransaction();
try {
- long accountId = getAccountIdLocked(db, account);
+ long accountId = AccountsDbUtils.findAccountId(db, account);
if (accountId < 0) {
return false;
}
- db.delete(CE_TABLE_AUTHTOKENS,
- AUTHTOKENS_ACCOUNTS_ID + "=" + accountId + " AND " + AUTHTOKENS_TYPE + "=?",
- new String[]{type});
- ContentValues values = new ContentValues();
- values.put(AUTHTOKENS_ACCOUNTS_ID, accountId);
- values.put(AUTHTOKENS_TYPE, type);
- values.put(AUTHTOKENS_AUTHTOKEN, authToken);
- if (db.insert(CE_TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values) >= 0) {
+ AccountsDbUtils.deleteAuthtokensByAccountIdAndType(db, accountId, type);
+ if (AccountsDbUtils.insertAuthToken(db, accountId, type, authToken) >= 0) {
db.setTransactionSuccessful();
writeAuthTokenIntoCacheLocked(accounts, db, account, type, authToken);
return true;
@@ -2497,15 +2406,10 @@ public class AccountManagerService
final SQLiteDatabase db = accounts.openHelper.getWritableDatabaseUserIsUnlocked();
db.beginTransaction();
try {
- final ContentValues values = new ContentValues();
- values.put(ACCOUNTS_PASSWORD, password);
- final long accountId = getAccountIdLocked(db, account);
+ final long accountId = AccountsDbUtils.findAccountId(db, account);
if (accountId >= 0) {
- final String[] argsAccountId = {String.valueOf(accountId)};
- db.update(
- CE_TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId);
- db.delete(
- CE_TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId);
+ AccountsDbUtils.updateAccountPassword(db, accountId, password);
+ AccountsDbUtils.deleteAuthTokensByAccountId(db, accountId);
accounts.authTokenCache.remove(account);
accounts.accountTokenCaches.remove(account);
db.setTransactionSuccessful();
@@ -2612,22 +2516,18 @@ public class AccountManagerService
final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
db.beginTransaction();
try {
- long accountId = getAccountIdLocked(db, account);
+ long accountId = AccountsDbUtils.findAccountId(db, account);
if (accountId < 0) {
return;
}
- long extrasId = getExtrasIdLocked(db, accountId, key);
+ long extrasId = AccountsDbUtils.findExtrasIdByAccountId(db, accountId, key);
if (extrasId < 0) {
- extrasId = insertExtraLocked(db, accountId, key, value);
+ extrasId = AccountsDbUtils.insertExtra(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 if (!AccountsDbUtils.updateExtra(db, extrasId, value)) {
+ return;
}
writeUserDataIntoCacheLocked(accounts, db, account, key, value);
db.setTransactionSuccessful();
@@ -2963,7 +2863,7 @@ public class AccountManagerService
title = titleAndSubtitle.substring(0, index);
subtitle = titleAndSubtitle.substring(index + 1);
}
- UserHandle user = new UserHandle(userId);
+ UserHandle user = UserHandle.of(userId);
Context contextForUser = getContextForUser(user);
Notification n = new Notification.Builder(contextForUser)
.setSmallIcon(android.R.drawable.stat_sys_warning)
@@ -4125,12 +4025,8 @@ public class AccountManagerService
userId = handleIncomingUser(userId);
UserAccounts accounts = getUserAccounts(userId);
SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
- ContentValues values = new ContentValues();
- values.put(ACCOUNTS_NAME, account.name);
- values.put(ACCOUNTS_TYPE, account.type);
- db.delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[] {account.name, account.type});
- long accountId = db.insert(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME, values);
+ AccountsDbUtils.deleteSharedAccount(db, account);
+ long accountId = AccountsDbUtils.insertSharedAccount(db, account);
if (accountId < 0) {
Log.w(TAG, "insertAccountIntoDatabase: " + account
+ ", skipping the DB insert failed");
@@ -4145,14 +4041,8 @@ public class AccountManagerService
userId = handleIncomingUser(userId);
UserAccounts accounts = getUserAccounts(userId);
SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
- long sharedTableAccountId = getAccountIdFromSharedTable(db, account);
- final ContentValues values = new ContentValues();
- values.put(ACCOUNTS_NAME, newName);
- int r = db.update(
- TABLE_SHARED_ACCOUNTS,
- values,
- ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[] { account.name, account.type });
+ long sharedTableAccountId = AccountsDbUtils.findSharedAccountId(db, account);
+ int r = AccountsDbUtils.renameSharedAccount(db, account, newName);
if (r > 0) {
int callingUid = getCallingUid();
logRecord(db, DebugDbHelper.ACTION_ACCOUNT_RENAME, TABLE_SHARED_ACCOUNTS,
@@ -4172,40 +4062,21 @@ public class AccountManagerService
userId = handleIncomingUser(userId);
UserAccounts accounts = getUserAccounts(userId);
SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
- long sharedTableAccountId = getAccountIdFromSharedTable(db, account);
- int r = db.delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
- new String[] {account.name, account.type});
- if (r > 0) {
+ long sharedTableAccountId = AccountsDbUtils.findSharedAccountId(db, account);
+ boolean deleted = AccountsDbUtils.deleteSharedAccount(db, account);
+ if (deleted) {
logRecord(db, DebugDbHelper.ACTION_ACCOUNT_REMOVE, TABLE_SHARED_ACCOUNTS,
sharedTableAccountId, accounts, callingUid);
removeAccountInternal(accounts, account, callingUid);
}
- return r > 0;
+ return deleted;
}
@Override
public Account[] getSharedAccountsAsUser(int userId) {
userId = handleIncomingUser(userId);
- UserAccounts accounts = getUserAccounts(userId);
- ArrayList<Account> accountList = new ArrayList<>();
- Cursor cursor = null;
- try {
- cursor = accounts.openHelper.getReadableDatabase()
- .query(TABLE_SHARED_ACCOUNTS, new String[]{ACCOUNTS_NAME, ACCOUNTS_TYPE},
- null, null, null, null, null);
- if (cursor != null && cursor.moveToFirst()) {
- int nameIndex = cursor.getColumnIndex(ACCOUNTS_NAME);
- int typeIndex = cursor.getColumnIndex(ACCOUNTS_TYPE);
- do {
- accountList.add(new Account(cursor.getString(nameIndex),
- cursor.getString(typeIndex)));
- } while (cursor.moveToNext());
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
+ SQLiteDatabase db = getUserAccounts(userId).openHelper.getReadableDatabase();
+ List<Account> accountList = AccountsDbUtils.getSharedAccounts(db);
Account[] accountArray = new Account[accountList.size()];
accountList.toArray(accountArray);
return accountArray;
@@ -4301,46 +4172,6 @@ public class AccountManagerService
}
}
- private long getAccountIdFromSharedTable(SQLiteDatabase db, Account account) {
- Cursor cursor = db.query(TABLE_SHARED_ACCOUNTS, new String[]{ACCOUNTS_ID},
- "name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
- try {
- if (cursor.moveToNext()) {
- return cursor.getLong(0);
- }
- return -1;
- } finally {
- cursor.close();
- }
- }
-
- private long getAccountIdLocked(SQLiteDatabase db, Account account) {
- Cursor cursor = db.query(TABLE_ACCOUNTS, new String[]{ACCOUNTS_ID},
- "name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
- try {
- if (cursor.moveToNext()) {
- return cursor.getLong(0);
- }
- return -1;
- } finally {
- cursor.close();
- }
- }
-
- private long getExtrasIdLocked(SQLiteDatabase db, long accountId, String key) {
- Cursor cursor = db.query(CE_TABLE_EXTRAS, new String[]{EXTRAS_ID},
- EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?",
- new String[]{key}, null, null, null);
- try {
- if (cursor.moveToNext()) {
- return cursor.getLong(0);
- }
- return -1;
- } finally {
- cursor.close();
- }
- }
-
private abstract class Session extends IAccountAuthenticatorResponse.Stub
implements IBinder.DeathRecipient, ServiceConnection {
IAccountManagerResponse mResponse;
@@ -5013,17 +4844,10 @@ public class AccountManagerService
+ "," + GRANTS_GRANTEE_UID + "))");
}
- private void populateMetaTableWithAuthTypeAndUID(
- SQLiteDatabase db,
+ private void populateMetaTableWithAuthTypeAndUID(SQLiteDatabase db,
Map<String, Integer> authTypeAndUIDMap) {
- Iterator<Entry<String, Integer>> iterator = authTypeAndUIDMap.entrySet().iterator();
- while (iterator.hasNext()) {
- Entry<String, Integer> entry = iterator.next();
- ContentValues values = new ContentValues();
- values.put(META_KEY,
- META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + entry.getKey());
- values.put(META_VALUE, entry.getValue());
- db.insert(TABLE_META, null, values);
+ for (Entry<String, Integer> entry : authTypeAndUIDMap.entrySet()) {
+ AccountsDbUtils.insertMetaAuthTypeAndUid(db, entry.getKey(), entry.getValue());
}
}
@@ -5076,7 +4900,7 @@ public class AccountManagerService
if (oldVersion == 8) {
populateMetaTableWithAuthTypeAndUID(
db,
- AccountManagerService.getAuthenticatorTypeAndUIDForUser(mContext, mUserId));
+ getAuthenticatorTypeAndUIDForUser(mContext, mUserId));
oldVersion++;
}
@@ -5336,42 +5160,6 @@ public class AccountManagerService
if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "opened database " + CE_DATABASE_NAME);
}
- static String findAccountPasswordByNameAndType(SQLiteDatabase db, String name,
- String type) {
- Cursor cursor = db.query(CE_TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD},
- ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
- new String[]{name, type}, null, null, null);
- try {
- if (cursor.moveToNext()) {
- return cursor.getString(0);
- }
- return null;
- } finally {
- cursor.close();
- }
- }
-
- 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,
@@ -5470,18 +5258,7 @@ public class AccountManagerService
if (isCheckinRequest) {
// This is a checkin request. *Only* upload the account types and the count of each.
- Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION,
- null, null, ACCOUNTS_TYPE, null, null);
- try {
- while (cursor.moveToNext()) {
- // print type,count
- fout.println(cursor.getString(0) + "," + cursor.getString(1));
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
+ AccountsDbUtils.dumpAccountsTable(db, fout);
} else {
Account[] accounts = getAccountsFromCacheLocked(userAccounts, null /* type */,
Process.myUid(), null);
@@ -5492,21 +5269,7 @@ public class AccountManagerService
// Add debug information.
fout.println();
- Cursor cursor = db.query(DebugDbHelper.TABLE_DEBUG, null,
- null, null, null, null, DebugDbHelper.TIMESTAMP);
- fout.println("AccountId, Action_Type, timestamp, UID, TableName, Key");
- fout.println("Accounts History");
- try {
- while (cursor.moveToNext()) {
- // print type,count
- fout.println(cursor.getString(0) + "," + cursor.getString(1) + "," +
- cursor.getString(2) + "," + cursor.getString(3) + ","
- + cursor.getString(4) + "," + cursor.getString(5));
- }
- } finally {
- cursor.close();
- }
-
+ AccountsDbUtils.dumpDebugTable(db, fout);
fout.println();
synchronized (mSessions) {
final long now = SystemClock.elapsedRealtime();
@@ -5733,10 +5496,8 @@ public class AccountManagerService
UserAccounts accounts = getUserAccountsForCaller();
synchronized (accounts.cacheLock) {
final SQLiteDatabase db = accounts.openHelper.getReadableDatabase();
- String[] args = { String.valueOf(callerUid), authTokenType,
- account.name, account.type};
- final boolean permissionGranted =
- DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args) != 0;
+ final boolean permissionGranted = AccountsDbUtils.findMatchingGrantsCount(db, callerUid,
+ authTokenType, account) != 0;
if (!permissionGranted && ActivityManager.isRunningInTestHarness()) {
// TODO: Skip this check when running automated tests. Replace this
// with a more general solution.
@@ -5861,19 +5622,9 @@ public class AccountManagerService
UserAccounts accounts = getUserAccounts(UserHandle.getUserId(uid));
synchronized (accounts.cacheLock) {
final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- long accountId = getAccountIdLocked(db, account);
- if (accountId >= 0) {
- ContentValues values = new ContentValues();
- values.put(GRANTS_ACCOUNTS_ID, accountId);
- values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType);
- values.put(GRANTS_GRANTEE_UID, uid);
- db.insert(TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values);
- db.setTransactionSuccessful();
- }
- } finally {
- db.endTransaction();
+ long accountId = AccountsDbUtils.findAccountId(db, account);
+ if (accountId >= 0) {
+ AccountsDbUtils.insertGrant(db, accountId, authTokenType, uid);
}
cancelNotification(getCredentialPermissionNotificationId(account, authTokenType, uid),
UserHandle.of(accounts.userId));
@@ -5898,13 +5649,10 @@ public class AccountManagerService
final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
db.beginTransaction();
try {
- long accountId = getAccountIdLocked(db, account);
+ long accountId = AccountsDbUtils.findAccountId(db, account);
if (accountId >= 0) {
- db.delete(TABLE_GRANTS,
- GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND "
- + GRANTS_GRANTEE_UID + "=?",
- new String[]{String.valueOf(accountId), authTokenType,
- String.valueOf(uid)});
+ AccountsDbUtils.deleteGrantsByAccountIdAuthTokenTypeAndUid(
+ db, accountId, authTokenType, uid);
db.setTransactionSuccessful();
}
} finally {
@@ -6057,9 +5805,9 @@ public class AccountManagerService
protected void writeUserDataIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db,
Account account, String key, String value) {
- HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account);
+ Map<String, String> userDataForAccount = accounts.userDataCache.get(account);
if (userDataForAccount == null) {
- userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account);
+ userDataForAccount = AccountsDbUtils.findUserExtrasForAccount(db, account);
accounts.userDataCache.put(account, userDataForAccount);
}
if (value == null) {
@@ -6083,9 +5831,9 @@ public class AccountManagerService
protected void writeAuthTokenIntoCacheLocked(UserAccounts accounts, final SQLiteDatabase db,
Account account, String key, String value) {
- HashMap<String, String> authTokensForAccount = accounts.authTokenCache.get(account);
+ Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account);
if (authTokensForAccount == null) {
- authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account);
+ authTokensForAccount = AccountsDbUtils.findAuthTokensByAccount(db, account);
accounts.authTokenCache.put(account, authTokensForAccount);
}
if (value == null) {
@@ -6098,11 +5846,12 @@ public class AccountManagerService
protected String readAuthTokenInternal(UserAccounts accounts, Account account,
String authTokenType) {
synchronized (accounts.cacheLock) {
- HashMap<String, String> authTokensForAccount = accounts.authTokenCache.get(account);
+ Map<String, String> authTokensForAccount = accounts.authTokenCache.get(account);
if (authTokensForAccount == null) {
// need to populate the cache for this account
final SQLiteDatabase db = accounts.openHelper.getReadableDatabaseUserIsUnlocked();
- authTokensForAccount = readAuthTokensForAccountFromDatabaseLocked(db, account);
+ authTokensForAccount = AccountsDbUtils
+ .findAuthTokensByAccount(db, account);
accounts.authTokenCache.put(account, authTokensForAccount);
}
return authTokensForAccount.get(authTokenType);
@@ -6111,56 +5860,16 @@ public class AccountManagerService
protected String readUserDataInternalLocked(
UserAccounts accounts, Account account, String key) {
- HashMap<String, String> userDataForAccount = accounts.userDataCache.get(account);
+ Map<String, String> userDataForAccount = accounts.userDataCache.get(account);
if (userDataForAccount == null) {
// need to populate the cache for this account
final SQLiteDatabase db = accounts.openHelper.getReadableDatabaseUserIsUnlocked();
- userDataForAccount = readUserDataForAccountFromDatabaseLocked(db, account);
+ userDataForAccount = AccountsDbUtils.findUserExtrasForAccount(db, account);
accounts.userDataCache.put(account, userDataForAccount);
}
return userDataForAccount.get(key);
}
- protected HashMap<String, String> readUserDataForAccountFromDatabaseLocked(
- final SQLiteDatabase db, Account account) {
- HashMap<String, String> userDataForAccount = new HashMap<>();
- Cursor cursor = db.query(CE_TABLE_EXTRAS,
- COLUMNS_EXTRAS_KEY_AND_VALUE,
- SELECTION_USERDATA_BY_ACCOUNT,
- new String[]{account.name, account.type},
- null, null, null);
- try {
- while (cursor.moveToNext()) {
- final String tmpkey = cursor.getString(0);
- final String value = cursor.getString(1);
- userDataForAccount.put(tmpkey, value);
- }
- } finally {
- cursor.close();
- }
- return userDataForAccount;
- }
-
- protected HashMap<String, String> readAuthTokensForAccountFromDatabaseLocked(
- final SQLiteDatabase db, Account account) {
- HashMap<String, String> authTokensForAccount = new HashMap<>();
- Cursor cursor = db.query(CE_TABLE_AUTHTOKENS,
- COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN,
- SELECTION_AUTHTOKENS_BY_ACCOUNT,
- new String[]{account.name, account.type},
- null, null, null);
- try {
- while (cursor.moveToNext()) {
- final String type = cursor.getString(0);
- final String authToken = cursor.getString(1);
- authTokensForAccount.put(type, authToken);
- }
- } finally {
- cursor.close();
- }
- return authTokensForAccount;
- }
-
private Context getContextForUser(UserHandle user) {
try {
return mContext.createPackageContextAsUser(mContext.getPackageName(), 0, user);
@@ -6194,4 +5903,417 @@ public class AccountManagerService
}
}
}
+
+ static class AccountsDbUtils {
+
+ static String findAccountPasswordByNameAndType(SQLiteDatabase db, String name,
+ String type) {
+ Cursor cursor = db.query(CE_TABLE_ACCOUNTS, new String[]{ACCOUNTS_PASSWORD},
+ ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
+ new String[]{name, type}, null, null, null);
+ try {
+ if (cursor.moveToNext()) {
+ return cursor.getString(0);
+ }
+ return null;
+ } finally {
+ cursor.close();
+ }
+ }
+
+ static Map<Long, Account> findAllAccounts(SQLiteDatabase db) {
+ LinkedHashMap<Long, Account> map = new LinkedHashMap<>();
+ Cursor cursor = db.query(TABLE_ACCOUNTS,
+ new String[] {ACCOUNTS_ID, ACCOUNTS_TYPE, ACCOUNTS_NAME},
+ null, null, null, null, ACCOUNTS_ID);
+ try {
+ while (cursor.moveToNext()) {
+ final long accountId = cursor.getLong(0);
+ final String accountType = cursor.getString(1);
+ final String accountName = cursor.getString(2);
+
+ final Account account = new Account(accountName, accountType);
+ map.put(accountId, account);
+ }
+ } finally {
+ cursor.close();
+ }
+ return map;
+ }
+
+ static String findAccountPreviousName(SQLiteDatabase db, Account account) {
+ Cursor cursor = db.query(
+ TABLE_ACCOUNTS,
+ new String[]{ ACCOUNTS_PREVIOUS_NAME },
+ ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+ new String[] { account.name, account.type },
+ null,
+ null,
+ null);
+ try {
+ if (cursor.moveToNext()) {
+ return cursor.getString(0);
+ }
+ } finally {
+ cursor.close();
+ }
+ return null;
+ }
+
+ 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();
+ }
+ }
+
+ static boolean deleteAccount(SQLiteDatabase db, long accountId) {
+ return db.delete(TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null) > 0;
+ }
+
+ static boolean deleteCeAccount(SQLiteDatabase db, long accountId) {
+ return db.delete(CE_TABLE_ACCOUNTS, ACCOUNTS_ID + "=" + accountId, null) > 0;
+ }
+
+ /**
+ * Returns information about auth tokens and their account for the specified query parameters.
+ * Output is in the format:
+ * <pre><code> | AUTHTOKEN_ID | ACCOUNT_NAME | AUTH_TOKEN_TYPE |</code></pre>
+ */
+ static Cursor findAuthtokenForAllAccounts(SQLiteDatabase db, String accountType,
+ String authToken) {
+ return db.rawQuery(
+ "SELECT " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_ID
+ + ", " + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_NAME
+ + ", " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_TYPE
+ + " FROM " + CE_TABLE_ACCOUNTS
+ + " JOIN " + CE_TABLE_AUTHTOKENS
+ + " ON " + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_ID
+ + " = " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_ACCOUNTS_ID
+ + " WHERE " + CE_TABLE_AUTHTOKENS + "." + AUTHTOKENS_AUTHTOKEN
+ + " = ? AND " + CE_TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE + " = ?",
+ new String[]{authToken, accountType});
+ }
+
+ static boolean deleteAuthtokensByAccountIdAndType(SQLiteDatabase db, long accountId,
+ String authtokenType) {
+ return db.delete(CE_TABLE_AUTHTOKENS,
+ AUTHTOKENS_ACCOUNTS_ID + "=?" + accountId + " AND " + AUTHTOKENS_TYPE + "=?",
+ new String[] {String.valueOf(accountId), authtokenType}) > 0;
+ }
+
+ static boolean deleteAuthToken(SQLiteDatabase db, String authTokenId) {
+ return db.delete(CE_TABLE_AUTHTOKENS, AUTHTOKENS_ID + "= ?",
+ new String[] {authTokenId}) > 0;
+ }
+
+ static long insertAuthToken(SQLiteDatabase db, long accountId, String authTokenType,
+ String authToken) {
+ ContentValues values = new ContentValues();
+ values.put(AUTHTOKENS_ACCOUNTS_ID, accountId);
+ values.put(AUTHTOKENS_TYPE, authTokenType);
+ values.put(AUTHTOKENS_AUTHTOKEN, authToken);
+ return db.insert(CE_TABLE_AUTHTOKENS, AUTHTOKENS_AUTHTOKEN, values);
+ }
+
+ static Map<String, String> findAuthTokensByAccount(final SQLiteDatabase db, Account account) {
+ HashMap<String, String> authTokensForAccount = new HashMap<>();
+ Cursor cursor = db.query(CE_TABLE_AUTHTOKENS,
+ COLUMNS_AUTHTOKENS_TYPE_AND_AUTHTOKEN,
+ SELECTION_AUTHTOKENS_BY_ACCOUNT,
+ new String[]{account.name, account.type},
+ null, null, null);
+ try {
+ while (cursor.moveToNext()) {
+ final String type = cursor.getString(0);
+ final String authToken = cursor.getString(1);
+ authTokensForAccount.put(type, authToken);
+ }
+ } finally {
+ cursor.close();
+ }
+ return authTokensForAccount;
+ }
+
+ static int updateAccountPassword(SQLiteDatabase db, long accountId, String password) {
+ final ContentValues values = new ContentValues();
+ values.put(ACCOUNTS_PASSWORD, password);
+ return db.update(CE_TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?",
+ new String[] {String.valueOf(accountId)});
+ }
+
+ static boolean deleteAuthTokensByAccountId(SQLiteDatabase db, long accountId) {
+ return db.delete(CE_TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?",
+ new String[] {String.valueOf(accountId)}) > 0;
+ }
+
+ static long insertSharedAccount(SQLiteDatabase db, Account account) {
+ ContentValues values = new ContentValues();
+ values.put(ACCOUNTS_NAME, account.name);
+ values.put(ACCOUNTS_TYPE, account.type);
+ return db.insert(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME, values);
+ }
+
+ static boolean deleteSharedAccount(SQLiteDatabase db, Account account) {
+ return db.delete(TABLE_SHARED_ACCOUNTS, ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE + "=?",
+ new String[] {account.name, account.type}) > 0;
+ }
+
+ static int renameSharedAccount(SQLiteDatabase db, Account account, String newName) {
+ final ContentValues values = new ContentValues();
+ values.put(ACCOUNTS_NAME, newName);
+ return db.update(TABLE_SHARED_ACCOUNTS,
+ values,
+ ACCOUNTS_NAME + "=? AND " + ACCOUNTS_TYPE+ "=?",
+ new String[] { account.name, account.type });
+ }
+
+ static List<Account> getSharedAccounts(SQLiteDatabase db) {
+ ArrayList<Account> accountList = new ArrayList<>();
+ Cursor cursor = null;
+ try {
+ cursor = db.query(TABLE_SHARED_ACCOUNTS, new String[] {ACCOUNTS_NAME, ACCOUNTS_TYPE},
+ null, null, null, null, null);
+ if (cursor != null && cursor.moveToFirst()) {
+ int nameIndex = cursor.getColumnIndex(ACCOUNTS_NAME);
+ int typeIndex = cursor.getColumnIndex(ACCOUNTS_TYPE);
+ do {
+ accountList.add(new Account(cursor.getString(nameIndex),
+ cursor.getString(typeIndex)));
+ } while (cursor.moveToNext());
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ return accountList;
+ }
+
+ static long findSharedAccountId(SQLiteDatabase db, Account account) {
+ Cursor cursor = db.query(TABLE_SHARED_ACCOUNTS, new String[]{ACCOUNTS_ID},
+ "name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
+ try {
+ if (cursor.moveToNext()) {
+ return cursor.getLong(0);
+ }
+ return -1;
+ } finally {
+ cursor.close();
+ }
+ }
+
+ static long findAccountId(SQLiteDatabase db, Account account) {
+ Cursor cursor = db.query(
+ TABLE_ACCOUNTS, new String[] {ACCOUNTS_ID},
+ "name=? AND type=?", new String[]{account.name, account.type}, null, null, null);
+ try {
+ if (cursor.moveToNext()) {
+ return cursor.getLong(0);
+ }
+ return -1;
+ } finally {
+ cursor.close();
+ }
+ }
+
+ static long findExtrasIdByAccountId(SQLiteDatabase db, long accountId, String key) {
+ Cursor cursor = db.query(
+ CE_TABLE_EXTRAS, new String[] {EXTRAS_ID},
+ EXTRAS_ACCOUNTS_ID + "=" + accountId + " AND " + EXTRAS_KEY + "=?",
+ new String[]{key}, null, null, null);
+ try {
+ if (cursor.moveToNext()) {
+ return cursor.getLong(0);
+ }
+ return -1;
+ } finally {
+ cursor.close();
+ }
+ }
+
+ static boolean updateExtra(SQLiteDatabase db, long extrasId, String value) {
+ ContentValues values = new ContentValues();
+ values.put(EXTRAS_VALUE, value);
+ int rows = db.update(TABLE_EXTRAS, values, EXTRAS_ID + "=?",
+ new String[]{String.valueOf(extrasId)});
+ return rows == 1;
+ }
+
+ static long insertExtra(SQLiteDatabase db, long accountId, String key, String value) {
+ ContentValues values = new ContentValues();
+ values.put(EXTRAS_KEY, key);
+ values.put(EXTRAS_ACCOUNTS_ID, accountId);
+ values.put(EXTRAS_VALUE, value);
+ return db.insert(CE_TABLE_EXTRAS, EXTRAS_KEY, values);
+ }
+
+ static Map<String, String> findUserExtrasForAccount(SQLiteDatabase db, Account account) {
+ Map<String, String> userExtrasForAccount = new HashMap<>();
+ Cursor cursor = db.query(CE_TABLE_EXTRAS,
+ COLUMNS_EXTRAS_KEY_AND_VALUE,
+ SELECTION_USERDATA_BY_ACCOUNT,
+ new String[] {account.name, account.type},
+ null, null, null);
+ try {
+ while (cursor.moveToNext()) {
+ final String tmpkey = cursor.getString(0);
+ final String value = cursor.getString(1);
+ userExtrasForAccount.put(tmpkey, value);
+ }
+ } finally {
+ cursor.close();
+ }
+ return userExtrasForAccount;
+ }
+
+ static long insertGrant(SQLiteDatabase db, long accountId, String authTokenType, int uid) {
+ ContentValues values = new ContentValues();
+ values.put(GRANTS_ACCOUNTS_ID, accountId);
+ values.put(GRANTS_AUTH_TOKEN_TYPE, authTokenType);
+ values.put(GRANTS_GRANTEE_UID, uid);
+ return db.insert(TABLE_GRANTS, GRANTS_ACCOUNTS_ID, values);
+ }
+
+ static boolean deleteGrantsByUid(SQLiteDatabase db, int uid) {
+ return db.delete(TABLE_GRANTS, GRANTS_GRANTEE_UID + "=?",
+ new String[] {Integer.toString(uid)}) > 0;
+ }
+
+ static boolean deleteGrantsByAccountIdAuthTokenTypeAndUid(SQLiteDatabase db, long accountId, String authTokenType, long uid) {
+ return db.delete(TABLE_GRANTS,
+ GRANTS_ACCOUNTS_ID + "=? AND " + GRANTS_AUTH_TOKEN_TYPE + "=? AND "
+ + GRANTS_GRANTEE_UID + "=?",
+ new String[] {String.valueOf(accountId), authTokenType, String.valueOf(uid)}) > 0;
+ }
+
+ static List<Integer> findAllUidGrants(SQLiteDatabase db) {
+ List<Integer> result = new ArrayList<>();
+ 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);
+ result.add(uid);
+ }
+ } finally {
+ cursor.close();
+ }
+ return result;
+ }
+
+ static long findMatchingGrantsCount(SQLiteDatabase db,
+ int uid, String authTokenType, Account account) {
+ String[] args = { String.valueOf(uid), authTokenType,
+ account.name, account.type};
+ return DatabaseUtils.longForQuery(db, COUNT_OF_MATCHING_GRANTS, args);
+ }
+
+ static long insertMetaAuthTypeAndUid(SQLiteDatabase db, String authenticatorType, int uid) {
+ ContentValues values = new ContentValues();
+ values.put(META_KEY,
+ META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + authenticatorType);
+ values.put(META_VALUE, uid);
+ return db.insert(TABLE_META, null, values);
+ }
+
+ static long insertOrReplaceMetaAuthTypeAndUid(SQLiteDatabase db, String authenticatorType,
+ int uid) {
+ ContentValues values = new ContentValues();
+ values.put(META_KEY,
+ META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + authenticatorType);
+ values.put(META_VALUE, uid);
+ return db.insertWithOnConflict(TABLE_META, null, values,
+ SQLiteDatabase.CONFLICT_REPLACE);
+ }
+
+
+ static Map<String, Integer> findMetaAuthUid(SQLiteDatabase db) {
+ Cursor metaCursor = db.query(
+ TABLE_META,
+ new String[] {META_KEY, META_VALUE},
+ SELECTION_META_BY_AUTHENTICATOR_TYPE,
+ new String[] {META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + "%"},
+ null /* groupBy */,
+ null /* having */,
+ META_KEY);
+ Map<String, Integer> map = new LinkedHashMap<>();
+ try {
+ while (metaCursor.moveToNext()) {
+ String type = TextUtils.split(metaCursor.getString(0), META_KEY_DELIMITER)[1];
+ String uidStr = metaCursor.getString(1);
+ if (TextUtils.isEmpty(type) || TextUtils.isEmpty(uidStr)) {
+ // Should never happen.
+ Slog.e(TAG, "Auth type empty: " + TextUtils.isEmpty(type)
+ + ", uid empty: " + TextUtils.isEmpty(uidStr));
+ continue;
+ }
+ int uid = Integer.parseInt(metaCursor.getString(1));
+ map.put(type, uid);
+ }
+ } finally {
+ metaCursor.close();
+ }
+ return map;
+ }
+
+ static boolean deleteMetaByAuthTypeAndUid(SQLiteDatabase db, String type, int uid) {
+ return db.delete(
+ TABLE_META,
+ META_KEY + "=? AND " + META_VALUE + "=?",
+ new String[] {
+ META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + type,
+ String.valueOf(uid)}
+ ) > 0;
+ }
+
+ static void dumpAccountsTable(SQLiteDatabase db, PrintWriter pw) {
+ Cursor cursor = db.query(TABLE_ACCOUNTS, ACCOUNT_TYPE_COUNT_PROJECTION,
+ null, null, ACCOUNTS_TYPE, null, null);
+ try {
+ while (cursor.moveToNext()) {
+ // print type,count
+ pw.println(cursor.getString(0) + "," + cursor.getString(1));
+ }
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ }
+
+ static void dumpDebugTable(SQLiteDatabase db, PrintWriter pw) {
+ Cursor cursor = db.query(DebugDbHelper.TABLE_DEBUG, null,
+ null, null, null, null, DebugDbHelper.TIMESTAMP);
+ pw.println("AccountId, Action_Type, timestamp, UID, TableName, Key");
+ pw.println("Accounts History");
+ try {
+ while (cursor.moveToNext()) {
+ // print type,count
+ pw.println(cursor.getString(0) + "," + cursor.getString(1) + "," +
+ cursor.getString(2) + "," + cursor.getString(3) + ","
+ + cursor.getString(4) + "," + cursor.getString(5));
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+
+ }
}