Set/get default account to/from CP2 DB.
Test: unit tests.
Bug: 188347310
Change-Id: I9c5f487699662d08f8ff6137ceda08375bd7227c
diff --git a/src/com/android/providers/contacts/ContactsDatabaseHelper.java b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
index c20330d..7bc7935 100644
--- a/src/com/android/providers/contacts/ContactsDatabaseHelper.java
+++ b/src/com/android/providers/contacts/ContactsDatabaseHelper.java
@@ -16,6 +16,7 @@
package com.android.providers.contacts;
+import android.accounts.Account;
import android.app.ActivityManager;
import android.content.ContentResolver;
import android.content.ContentValues;
@@ -4138,6 +4139,50 @@
}
/**
+ * Set is_default column for the given account name and account type.
+ *
+ * @param accountName The account name to be set to default.
+ * @param accountType The account type to be set to default.
+ */
+ public void setDefaultAccount(String accountName, String accountType) {
+ SQLiteDatabase db = getWritableDatabase();
+ db.execSQL(
+ "UPDATE " + Tables.ACCOUNTS +
+ " SET " + AccountsColumns.IS_DEFAULT + "=0" +
+ " WHERE " + AccountsColumns.IS_DEFAULT + "=1");
+
+ ContentValues values = new ContentValues();
+ if (!TextUtils.isEmpty(accountName)) {
+ values.put(AccountsColumns.ACCOUNT_NAME, accountName);
+ }
+ if (!TextUtils.isEmpty(accountType)) {
+ values.put(AccountsColumns.ACCOUNT_TYPE, accountType);
+ }
+ values.put(AccountsColumns.IS_DEFAULT, 1);
+ db.insertWithOnConflict(Tables.ACCOUNTS, null, values, SQLiteDatabase.CONFLICT_REPLACE);
+ }
+
+ /**
+ * Return the default account from Accounts table.
+ */
+ public Account getDefaultAccount() {
+ Account defaultAccount = null;
+ try (Cursor c = getReadableDatabase().rawQuery(
+ "SELECT " + AccountsColumns.ACCOUNT_NAME + ","
+ + AccountsColumns.ACCOUNT_TYPE + " FROM " + Tables.ACCOUNTS + " WHERE "
+ + AccountsColumns.IS_DEFAULT + " = 1", null)) {
+ while (c.moveToNext()) {
+ String accountName = c.getString(0);
+ String accountType = c.getString(1);
+ if (!TextUtils.isEmpty(accountName) && !TextUtils.isEmpty(accountType)) {
+ defaultAccount = new Account(accountName, accountType);
+ }
+ }
+ }
+ return defaultAccount;
+ }
+
+ /**
* Update {@link Contacts#IN_VISIBLE_GROUP} for all contacts.
*/
public void updateAllVisible() {
diff --git a/src/com/android/providers/contacts/ContactsProvider2.java b/src/com/android/providers/contacts/ContactsProvider2.java
index 7171240..737b4b5 100644
--- a/src/com/android/providers/contacts/ContactsProvider2.java
+++ b/src/com/android/providers/contacts/ContactsProvider2.java
@@ -219,6 +219,8 @@
private static final String WRITE_PERMISSION = "android.permission.WRITE_CONTACTS";
private static final String MANAGE_SIM_ACCOUNTS_PERMISSION =
"android.contacts.permission.MANAGE_SIM_ACCOUNTS";
+ private static final String SET_DEFAULT_ACCOUNT_PERMISSION =
+ "android.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS";
/* package */ static final String PHONEBOOK_COLLATOR_NAME = "PHONEBOOK";
@@ -2389,6 +2391,40 @@
response.putParcelableList(SimContacts.KEY_SIM_ACCOUNTS, simAccounts);
return response;
+ } else if (Settings.QUERY_DEFAULT_ACCOUNT_METHOD.equals(method)) {
+ ContactsPermissions.enforceCallingOrSelfPermission(getContext(), READ_PERMISSION);
+ final Bundle response = new Bundle();
+
+ final Account defaultAccount = mDbHelper.get().getDefaultAccount();
+ response.putParcelable(Settings.KEY_DEFAULT_ACCOUNT, defaultAccount);
+
+ return response;
+ } else if (Settings.SET_DEFAULT_ACCOUNT_METHOD.equals(method)) {
+ ContactsPermissions.enforceCallingOrSelfPermission(getContext(),
+ SET_DEFAULT_ACCOUNT_PERMISSION);
+ final String accountName = extras.getString(Settings.ACCOUNT_NAME);
+ final String accountType = extras.getString(Settings.ACCOUNT_TYPE);
+ final String dataSet = extras.getString(Settings.DATA_SET);
+
+ if (TextUtils.isEmpty(accountName) ^ TextUtils.isEmpty(accountType)) {
+ throw new IllegalArgumentException(
+ "Must specify both or neither of ACCOUNT_NAME and ACCOUNT_TYPE");
+ }
+ if (!TextUtils.isEmpty(dataSet)) {
+ throw new IllegalArgumentException(
+ "Cannot set default account with non-null data set.");
+ }
+
+ final Bundle response = new Bundle();
+ final SQLiteDatabase db = mDbHelper.get().getWritableDatabase();
+ db.beginTransaction();
+ try {
+ mDbHelper.get().setDefaultAccount(accountName, accountType);
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ }
+ return response;
}
return null;
}
diff --git a/tests/src/com/android/providers/contacts/ContactsDatabaseHelperTest.java b/tests/src/com/android/providers/contacts/ContactsDatabaseHelperTest.java
index a9867c5..8c060cb 100644
--- a/tests/src/com/android/providers/contacts/ContactsDatabaseHelperTest.java
+++ b/tests/src/com/android/providers/contacts/ContactsDatabaseHelperTest.java
@@ -18,6 +18,7 @@
import android.content.ContentValues;
import android.database.ContentObserver;
+import android.accounts.Account;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
@@ -508,4 +509,28 @@
assertEquals(creationTime, dbHelper2.getDatabaseCreationTime());
}
+
+ public void testGetAndSetDefaultAccount() {
+ Account account = mDbHelper.getDefaultAccount();
+ assertNull(account);
+
+ mDbHelper.setDefaultAccount("a", "b");
+ account = mDbHelper.getDefaultAccount();
+ assertEquals("a", account.name);
+ assertEquals("b", account.type);
+
+ mDbHelper.setDefaultAccount("c", "d");
+ account = mDbHelper.getDefaultAccount();
+ assertEquals("c", account.name);
+ assertEquals("d", account.type);
+
+ mDbHelper.setDefaultAccount(null, null);
+ account = mDbHelper.getDefaultAccount();
+ assertNull(account);
+
+ // invalid account name does nothing.
+ mDbHelper.setDefaultAccount(")--", null);
+ account = mDbHelper.getDefaultAccount();
+ assertNull(account);
+ }
}
diff --git a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
index 0bcab46..dd582d0 100644
--- a/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
+++ b/tests/src/com/android/providers/contacts/ContactsProvider2Test.java
@@ -9124,6 +9124,67 @@
);
}
+ public void testDefaultAccountSet_throwException() {
+ try {
+ mResolver.call(ContactsContract.AUTHORITY_URI, Settings.SET_DEFAULT_ACCOUNT_METHOD,
+ null, null);
+ fail();
+ } catch (SecurityException expected) {
+ }
+
+ mActor.addPermissions("android.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS");
+ try {
+ Bundle bundle = new Bundle();
+ bundle.putString(Settings.ACCOUNT_NAME, "a"); // no account type specified
+ mResolver.call(ContactsContract.AUTHORITY_URI, Settings.SET_DEFAULT_ACCOUNT_METHOD,
+ null, bundle);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ Bundle bundle = new Bundle();
+ bundle.putString(Settings.ACCOUNT_NAME, "a");
+ bundle.putString(Settings.ACCOUNT_TYPE, "b");
+ bundle.putString(Settings.DATA_SET, "c");
+ mResolver.call(ContactsContract.AUTHORITY_URI, Settings.SET_DEFAULT_ACCOUNT_METHOD,
+ null, bundle);
+ fail();
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ public void testDefaultAccountSetAndQuery() {
+ Bundle response = mResolver.call(ContactsContract.AUTHORITY_URI,
+ Settings.QUERY_DEFAULT_ACCOUNT_METHOD, null, null);
+ Account account = response.getParcelable(Settings.KEY_DEFAULT_ACCOUNT);
+ assertNull(account);
+
+ mActor.addPermissions("android.permission.SET_DEFAULT_ACCOUNT_FOR_CONTACTS");
+ // Set (a, b) account as the default account.
+ Bundle bundle = new Bundle();
+ bundle.putString(Settings.ACCOUNT_NAME, "a");
+ bundle.putString(Settings.ACCOUNT_TYPE, "b");
+ mResolver.call(ContactsContract.AUTHORITY_URI, Settings.SET_DEFAULT_ACCOUNT_METHOD,
+ null, bundle);
+
+ response = mResolver.call(ContactsContract.AUTHORITY_URI,
+ Settings.QUERY_DEFAULT_ACCOUNT_METHOD, null, null);
+ account = response.getParcelable(Settings.KEY_DEFAULT_ACCOUNT);
+ assertEquals("a", account.name);
+ assertEquals("b", account.type);
+
+ // Set NULL account as default account.
+ bundle = new Bundle();
+ mResolver.call(ContactsContract.AUTHORITY_URI, Settings.SET_DEFAULT_ACCOUNT_METHOD,
+ null, bundle);
+
+ response = mResolver.call(ContactsContract.AUTHORITY_URI,
+ Settings.QUERY_DEFAULT_ACCOUNT_METHOD, null, null);
+ account = response.getParcelable(Settings.KEY_DEFAULT_ACCOUNT);
+ assertNull(account);
+ }
+
public void testPinnedPositionsDemoteIllegalArguments() {
try {
mResolver.call(ContactsContract.AUTHORITY_URI, PinnedPositions.UNDEMOTE_METHOD,