summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/accounts/AccountsDb.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java341
2 files changed, 344 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java
index 1adcf34fc326..cb594f674b37 100644
--- a/services/core/java/com/android/server/accounts/AccountsDb.java
+++ b/services/core/java/com/android/server/accounts/AccountsDb.java
@@ -913,6 +913,9 @@ class AccountsDb implements AutoCloseable {
) > 0;
}
+ /**
+ * Returns list of all grants as {@link Pair pairs} of account name and UID.
+ */
List<Pair<String, Integer>> findAllAccountGrants() {
SQLiteDatabase db = mDeDatabase.getReadableDatabase();
try (Cursor cursor = db.rawQuery(ACCOUNT_ACCESS_GRANTS, null)) {
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
new file mode 100644
index 000000000000..5b565a7e3455
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
@@ -0,0 +1,341 @@
+
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.accounts;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.database.Cursor;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Pair;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Tests for {@link AccountsDb}.
+ * <p>Run with:<pre>
+ * m FrameworksServicesTests &&
+ * adb install \
+ * -r out/target/product/marlin/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
+ * adb shell am instrument -e class com.android.server.accounts.AccountsDbTest \
+ * -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ * </pre>
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class AccountsDbTest {
+ private static final String PREN_DB = "pren.db";
+ private static final String DE_DB = "de.db";
+ private static final String CE_DB = "ce.db";
+
+ private AccountsDb mAccountsDb;
+ private File preNDb;
+ private File deDb;
+ private File ceDb;
+
+ @Before
+ public void setUp() {
+ Context context = InstrumentationRegistry.getContext();
+ preNDb = new File(context.getCacheDir(), PREN_DB);
+ ceDb = new File(context.getCacheDir(), CE_DB);
+ deDb = new File(context.getCacheDir(), DE_DB);
+ deleteDbFiles();
+ mAccountsDb = AccountsDb.create(context, 0, preNDb, deDb);
+ }
+
+ @After
+ public void tearDown() {
+ deleteDbFiles();
+ }
+
+ private void deleteDbFiles() {
+ AccountsDb.deleteDbFileWarnIfFailed(preNDb);
+ AccountsDb.deleteDbFileWarnIfFailed(ceDb);
+ AccountsDb.deleteDbFileWarnIfFailed(deDb);
+ }
+
+ @Test
+ public void testCeNotAvailableInitially() {
+ Account account = new Account("name", "example.com");
+ long id = mAccountsDb.insertCeAccount(account, "");
+ assertEquals("Insert into CE should fail until CE database is attached", -1, id);
+ }
+
+ @Test
+ public void testDeAccountInsertFindDelete() {
+ Account account = new Account("name", "example.com");
+ long accId = 1;
+ mAccountsDb.insertDeAccount(account, accId);
+ long actualId = mAccountsDb.findDeAccountId(account);
+ assertEquals(accId, actualId);
+ // Delete and verify that account no longer exists
+ mAccountsDb.deleteDeAccount(accId);
+ actualId = mAccountsDb.findDeAccountId(account);
+ assertEquals(-1, actualId);
+ }
+
+ @Test
+ public void testCeAccountInsertFindDelete() {
+ mAccountsDb.attachCeDatabase(ceDb);
+ Account account = new Account("name", "example.com");
+ long accId = mAccountsDb.insertCeAccount(account, "password");
+ long actualId = mAccountsDb.findCeAccountId(account);
+ assertEquals(accId, actualId);
+ // Delete and verify that account no longer exists
+ mAccountsDb.deleteCeAccount(accId);
+ actualId = mAccountsDb.findCeAccountId(account);
+ assertEquals(-1, actualId);
+ }
+
+ @Test
+ public void testAuthTokenInsertFindDelete() {
+ mAccountsDb.attachCeDatabase(ceDb);
+ Account account = new Account("name", "example.com");
+ long accId = mAccountsDb.insertCeAccount(account, "password");
+ mAccountsDb.insertDeAccount(account, accId);
+ long authTokenId = mAccountsDb.insertAuthToken(accId, "type", "token");
+ Map<String, String> authTokensByAccount = mAccountsDb.findAuthTokensByAccount(account);
+ assertEquals(1, authTokensByAccount.size());
+ try (Cursor cursor = mAccountsDb.findAuthtokenForAllAccounts(account.type, "token")) {
+ assertTrue(cursor.moveToNext());
+ }
+ try (Cursor cursor = mAccountsDb.findAuthtokenForAllAccounts(account.type, "nosuchtoken")) {
+ assertFalse(cursor.moveToNext());
+ }
+ mAccountsDb.deleteAuthToken(String.valueOf(authTokenId));
+ // Verify that token no longer exists
+ authTokensByAccount = mAccountsDb.findAuthTokensByAccount(account);
+ assertEquals(0, authTokensByAccount.size());
+ }
+
+ @Test
+ public void testAuthTokenDeletes() {
+ mAccountsDb.attachCeDatabase(ceDb);
+ // 1st account
+ Account account = new Account("name", "example.com");
+ long accId = mAccountsDb.insertCeAccount(account, "password");
+ mAccountsDb.insertDeAccount(account, accId);
+ mAccountsDb.insertAuthToken(accId, "type", "token");
+ mAccountsDb.insertAuthToken(accId, "type2", "token2");
+ // 2nd account
+ Account account2 = new Account("name", "example2.com");
+ long accId2 = mAccountsDb.insertCeAccount(account2, "password");
+ mAccountsDb.insertDeAccount(account2, accId);
+ mAccountsDb.insertAuthToken(accId2, "type", "token");
+
+ mAccountsDb.deleteAuthTokensByAccountId(accId2);
+ Map<String, String> authTokensByAccount = mAccountsDb.findAuthTokensByAccount(account2);
+ assertEquals(0, authTokensByAccount.size());
+ // Authtokens from account 1 are still there
+ authTokensByAccount = mAccountsDb.findAuthTokensByAccount(account);
+ assertEquals(2, authTokensByAccount.size());
+
+ // Delete authtokens from account 1 and verify
+ mAccountsDb.deleteAuthtokensByAccountIdAndType(accId, "type");
+ authTokensByAccount = mAccountsDb.findAuthTokensByAccount(account);
+ assertEquals(1, authTokensByAccount.size());
+ mAccountsDb.deleteAuthtokensByAccountIdAndType(accId, "type2");
+ authTokensByAccount = mAccountsDb.findAuthTokensByAccount(account);
+ assertEquals(0, authTokensByAccount.size());
+ }
+
+ @Test
+ public void testExtrasInsertFindDelete() {
+ mAccountsDb.attachCeDatabase(ceDb);
+ Account account = new Account("name", "example.com");
+ long accId = mAccountsDb.insertCeAccount(account, "password");
+ mAccountsDb.insertDeAccount(account, accId);
+ String extraKey = "extra_key";
+ String extraValue = "extra_value";
+ long extraId = mAccountsDb.insertExtra(accId, extraKey, extraValue);
+ // Test find methods
+ long actualExtraId = mAccountsDb.findExtrasIdByAccountId(accId, extraKey);
+ assertEquals(extraId, actualExtraId);
+ Map<String, String> extras = mAccountsDb.findUserExtrasForAccount(account);
+ assertEquals(1, extras.size());
+ assertEquals(extraValue, extras.get(extraKey));
+ // Test update
+ String newExtraValue = "extra_value2";
+ mAccountsDb.updateExtra(extraId, newExtraValue);
+ String newValue = mAccountsDb.findUserExtrasForAccount(account).get(extraKey);
+ assertEquals(newExtraValue, newValue);
+
+ // Delete account and verify that extras cascade removed
+ mAccountsDb.deleteCeAccount(accId);
+ actualExtraId = mAccountsDb.findExtrasIdByAccountId(accId, extraKey);
+ assertEquals(-1, actualExtraId);
+ }
+
+ @Test
+ public void testGrantsInsertFindDelete() {
+ mAccountsDb.attachCeDatabase(ceDb);
+ Account account = new Account("name", "example.com");
+ long accId = mAccountsDb.insertCeAccount(account, "password");
+ mAccountsDb.insertDeAccount(account, accId);
+ int testUid = 100500;
+ long grantId = mAccountsDb.insertGrant(accId, "tokenType", testUid);
+ assertTrue(grantId > 0);
+ List<Integer> allUidGrants = mAccountsDb.findAllUidGrants();
+ List<Integer> expectedUids = Arrays.asList(testUid);
+ assertEquals(expectedUids, allUidGrants);
+
+ long matchingGrantsCount = mAccountsDb.findMatchingGrantsCount(
+ testUid, "tokenType", account);
+ assertEquals(1, matchingGrantsCount);
+ // Test nonexistent type
+ matchingGrantsCount = mAccountsDb.findMatchingGrantsCount(
+ testUid, "noSuchType", account);
+ assertEquals(0, matchingGrantsCount);
+
+ matchingGrantsCount = mAccountsDb.findMatchingGrantsCountAnyToken(testUid, account);
+ assertEquals(1, matchingGrantsCount);
+
+ List<Pair<String, Integer>> allAccountGrants = mAccountsDb.findAllAccountGrants();
+ assertEquals(1, allAccountGrants.size());
+ assertEquals(account.name, allAccountGrants.get(0).first);
+ assertEquals(testUid, (int)allAccountGrants.get(0).second);
+
+ mAccountsDb.deleteGrantsByUid(testUid);
+ allUidGrants = mAccountsDb.findAllUidGrants();
+ assertTrue("Test grants should be removed", allUidGrants.isEmpty());
+ }
+
+ @Test
+ public void testSharedAccountsInsertFindDelete() {
+ Account account = new Account("name", "example.com");
+ long accId = 0;
+ mAccountsDb.insertDeAccount(account, accId);
+ long sharedAccId = mAccountsDb.insertSharedAccount(account);
+ long foundSharedAccountId = mAccountsDb.findSharedAccountId(account);
+ assertEquals(sharedAccId, foundSharedAccountId);
+ List<Account> sharedAccounts = mAccountsDb.getSharedAccounts();
+ List<Account> expectedList = Arrays.asList(account);
+ assertEquals(expectedList, sharedAccounts);
+
+ // Delete and verify
+ mAccountsDb.deleteSharedAccount(account);
+ foundSharedAccountId = mAccountsDb.findSharedAccountId(account);
+ assertEquals(-1, foundSharedAccountId);
+ }
+
+ @Test
+ public void testMetaInsertFindDelete() {
+ int testUid = 100500;
+ String authenticatorType = "authType";
+ mAccountsDb.insertOrReplaceMetaAuthTypeAndUid(authenticatorType, testUid);
+ Map<String, Integer> metaAuthUid = mAccountsDb.findMetaAuthUid();
+ assertEquals(1, metaAuthUid.size());
+ assertEquals(testUid, (int)metaAuthUid.get(authenticatorType));
+
+ // Delete and verify
+ boolean deleteResult = mAccountsDb.deleteMetaByAuthTypeAndUid(authenticatorType, testUid);
+ assertTrue(deleteResult);
+ metaAuthUid = mAccountsDb.findMetaAuthUid();
+ assertEquals(0, metaAuthUid.size());
+ }
+
+ @Test
+ public void testUpdateDeAccountLastAuthenticatedTime() {
+ Account account = new Account("name", "example.com");
+ long accId = 1;
+ mAccountsDb.insertDeAccount(account, accId);
+ long now = System.currentTimeMillis();
+ mAccountsDb.updateAccountLastAuthenticatedTime(account);
+ long time = mAccountsDb.findAccountLastAuthenticatedTime(account);
+ assertTrue("LastAuthenticatedTime should be current", time >= now);
+ }
+
+ @Test
+ public void testRenameAccount() {
+ mAccountsDb.attachCeDatabase(ceDb);
+ Account account = new Account("name", "example.com");
+ long accId = mAccountsDb.insertCeAccount(account, "password");
+ mAccountsDb.insertDeAccount(account, accId);
+ mAccountsDb.renameDeAccount(accId, "newName", "name");
+ Account newAccount = mAccountsDb.findAllDeAccounts().get(accId);
+ assertEquals("newName", newAccount.name);
+
+ String prevName = mAccountsDb.findDeAccountPreviousName(newAccount);
+ assertEquals("name", prevName);
+ mAccountsDb.renameCeAccount(accId, "newName");
+ long foundAccId = mAccountsDb.findCeAccountId(account);
+ assertEquals("Account shouldn't be found under the old name", -1, foundAccId);
+ foundAccId = mAccountsDb.findCeAccountId(newAccount);
+ assertEquals(accId, foundAccId);
+ }
+
+ @Test
+ public void testUpdateCeAccountPassword() {
+ mAccountsDb.attachCeDatabase(ceDb);
+ Account account = new Account("name", "example.com");
+ long accId = mAccountsDb.insertCeAccount(account, "password");
+ String newPassword = "newPassword";
+ mAccountsDb.updateCeAccountPassword(accId, newPassword);
+ String actualPassword = mAccountsDb
+ .findAccountPasswordByNameAndType(account.name, account.type);
+ assertEquals(newPassword, actualPassword);
+ }
+
+ @Test
+ public void testFindCeAccountsNotInDe() {
+ mAccountsDb.attachCeDatabase(ceDb);
+ Account account = new Account("name", "example.com");
+ long accId = mAccountsDb.insertCeAccount(account, "password");
+ mAccountsDb.insertDeAccount(account, accId);
+
+ Account accountNotInDe = new Account("name2", "example.com");
+ mAccountsDb.insertCeAccount(accountNotInDe, "password");
+
+ List<Account> ceAccounts = mAccountsDb.findCeAccountsNotInDe();
+ List<Account> expectedList = Arrays.asList(accountNotInDe);
+ assertEquals(expectedList, ceAccounts);
+ }
+
+ @Test
+ public void testCrossDbTransactions() {
+ mAccountsDb.attachCeDatabase(ceDb);
+ mAccountsDb.beginTransaction();
+ Account account = new Account("name", "example.com");
+ long accId;
+ accId = mAccountsDb.insertCeAccount(account, "password");
+ accId = mAccountsDb.insertDeAccount(account, accId);
+ long actualId = mAccountsDb.findCeAccountId(account);
+ assertEquals(accId, actualId);
+ actualId = mAccountsDb.findDeAccountId(account);
+ assertEquals(accId, actualId);
+ mAccountsDb.endTransaction();
+ // Verify that records were removed
+ actualId = mAccountsDb.findCeAccountId(account);
+ assertEquals(-1, actualId);
+ actualId = mAccountsDb.findDeAccountId(account);
+ assertEquals(-1, actualId);
+ }
+}