Add basic ContactsDataKind to ContactsTest (1/2)
* Use the same icons for the test app as the
regular app so that custom QuickContacts
actions have it.
* Make a copy of the fallback xml and add
a ContactsDataKind to it
* Update the TestSyncAdapter to add
the custom mimetype data row for null
contacts that it sweeps up.
Test: Add null contacts, add test accounts, grant
contacts permission to test account, toggle
contacts sync for test account
Bug: 31549157
Change-Id: I59f0798c286e7043e0b40ca02f4336533534fae7
diff --git a/tests/Android.mk b/tests/Android.mk
index 48a00f4..b895035 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -8,7 +8,9 @@
LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, res)
+
+res_dirs := res ../res-icons
+LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs))
LOCAL_PACKAGE_NAME := ContactsTests
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 87f9a8a..65be28a 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -36,6 +36,8 @@
<uses-permission android:name="android.permission.READ_SOCIAL_STREAM" />
<application
+ android:icon="@mipmap/ic_contacts_launcher_square"
+ android:roundIcon="@mipmap/ic_contacts_launcher"
android:label="@string/applicationLabel">
<uses-library android:name="android.test.runner" />
@@ -49,7 +51,13 @@
</intent-filter>
</activity>
- <activity android:name=".allintents.ResultActivity"/>
+ <activity android:name=".allintents.ResultActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.VIEW" />
+ <category android:name="android.intent.category.DEFAULT" />
+ <data android:mimeType="vnd.android.cursor.item/vnd.contactstest.profile" />
+ </intent-filter>
+ </activity>
<activity android:name=".quickcontact.QuickContactTestsActivity"/>
@@ -78,7 +86,7 @@
android:resource="@xml/test_basic_syncadapter" />
<meta-data
android:name="android.provider.CONTACTS_STRUCTURE"
- android:resource="@xml/contacts_fallback" />
+ android:resource="@xml/contacts_contactsdatakind" />
</service>
<service android:name=".QueryService" />
diff --git a/tests/res/xml/contacts_contactsdatakind.xml b/tests/res/xml/contacts_contactsdatakind.xml
new file mode 100644
index 0000000..c289e6e
--- /dev/null
+++ b/tests/res/xml/contacts_contactsdatakind.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+
+<!--
+ contacts.xml to build a "fallback account type" equivalent with
+ an additional test ContactsDataKind
+-->
+
+<ContactsAccountType
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ accountType="com.android.contacts.tests.testauth.basic"
+ accountTypeLabel="@string/applicationLabel"
+ accountTypeIcon="@mipmap/ic_contacts_launcher_square"
+ >
+ <EditSchema
+ >
+ <DataKind kind="name"
+ maxOccurs="1"
+ supportsDisplayName="true"
+ supportsPrefix="true"
+ supportsMiddleName="true"
+ supportsSuffix="true"
+ supportsPhoneticFamilyName="true"
+ supportsPhoneticMiddleName="true"
+ supportsPhoneticGivenName="true"
+ >
+ </DataKind>
+ <DataKind kind="photo" maxOccurs="1" />
+ <DataKind kind="phone" >
+ <Type type="mobile" />
+ <Type type="home" />
+ <Type type="work" />
+ <Type type="fax_work" />
+ <Type type="fax_home" />
+ <Type type="pager" />
+ <Type type="other" />
+ <Type type="custom"/>
+ <Type type="callback" />
+ <Type type="car" />
+ <Type type="company_main" />
+ <Type type="isdn" />
+ <Type type="main" />
+ <Type type="other_fax" />
+ <Type type="radio" />
+ <Type type="telex" />
+ <Type type="tty_tdd" />
+ <Type type="work_mobile"/>
+ <Type type="work_pager" />
+ <Type type="assistant" />
+ <Type type="mms" />
+ </DataKind>
+ <DataKind kind="email" >
+ <Type type="home" />
+ <Type type="work" />
+ <Type type="other" />
+ <Type type="mobile" />
+ <Type type="custom" />
+ </DataKind>
+ <DataKind kind="nickname" maxOccurs="1" />
+ <DataKind kind="im" >
+ <Type type="aim" />
+ <Type type="msn" />
+ <Type type="yahoo" />
+ <Type type="skype" />
+ <Type type="qq" />
+ <Type type="google_talk" />
+ <Type type="icq" />
+ <Type type="jabber" />
+ <Type type="custom" />
+ </DataKind>
+ <DataKind kind="postal" needsStructured="false" >
+ <Type type="home" />
+ <Type type="work" />
+ <Type type="other" />
+ <Type type="custom" />
+ </DataKind>
+ <DataKind kind="organization" maxOccurs="1" />
+ <DataKind kind="website" />
+ <DataKind kind="sip_address" maxOccurs="1" />
+ <DataKind kind="note" maxOccurs="1" />
+ <DataKind kind="group_membership" maxOccurs="1" />
+ </EditSchema>
+
+ <ContactsDataKind
+ android:mimeType="vnd.android.cursor.item/vnd.contactstest.profile"
+ android:icon="@mipmap/ic_contacts_launcher_square"
+ android:summaryColumn="data2"
+ android:detailColumn="data3" />
+
+</ContactsAccountType>
diff --git a/tests/res/xml/test_basic_authenticator.xml b/tests/res/xml/test_basic_authenticator.xml
index efcdadf..83bd135 100644
--- a/tests/res/xml/test_basic_authenticator.xml
+++ b/tests/res/xml/test_basic_authenticator.xml
@@ -19,5 +19,7 @@
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.android.contacts.tests.testauth.basic"
+ android:icon="@mipmap/ic_contacts_launcher_square"
+ android:smallIcon="@mipmap/ic_contacts_launcher_square"
android:label="@string/applicationLabel"
/>
diff --git a/tests/src/com/android/contacts/tests/testauth/TestSyncAdapter.java b/tests/src/com/android/contacts/tests/testauth/TestSyncAdapter.java
index feef8ec..076baea 100644
--- a/tests/src/com/android/contacts/tests/testauth/TestSyncAdapter.java
+++ b/tests/src/com/android/contacts/tests/testauth/TestSyncAdapter.java
@@ -18,20 +18,29 @@
import android.accounts.Account;
import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient;
+import android.content.ContentProviderOperation;
import android.content.ContentResolver;
-import android.content.ContentValues;
import android.content.Context;
import android.content.SyncResult;
+import android.database.Cursor;
+import android.net.Uri;
import android.os.Bundle;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.util.Log;
+import java.util.ArrayList;
+
/**
* Simple (minimal) sync adapter.
*
*/
public class TestSyncAdapter extends AbstractThreadedSyncAdapter {
+ private static final String TEXT_CONTENT_ITEM_TYPE =
+ "vnd.android.cursor.item/vnd.contactstest.profile";
+
private final Context mContext;
public TestSyncAdapter(Context context, boolean autoInitialize) {
@@ -47,19 +56,51 @@
ContentProviderClient provider, SyncResult syncResult) {
Log.v(TestauthConstants.LOG_TAG, "TestSyncAdapter.onPerformSync() account=" + account);
- // First, claim all local-only contacts, if any.
- ContentResolver cr = mContext.getContentResolver();
- ContentValues values = new ContentValues();
- values.put(RawContacts.ACCOUNT_NAME, account.name);
- values.put(RawContacts.ACCOUNT_TYPE, account.type);
- final int count = cr.update(RawContacts.CONTENT_URI, values,
+ final ArrayList<ContentProviderOperation> ops = new ArrayList<>();
+
+ final ContentResolver contentResolver = mContext.getContentResolver();
+ final Cursor cursor = contentResolver.query(RawContacts.CONTENT_URI,
+ new String[] { RawContacts._ID },
RawContacts.ACCOUNT_NAME + " IS NULL AND " + RawContacts.ACCOUNT_TYPE + " IS NULL",
- null);
- if (count > 0) {
- Log.v(TestauthConstants.LOG_TAG, "Claimed " + count + " local raw contacts");
+ null, null);
+ try {
+ while (cursor.moveToNext()) {
+ final String rawContactId = Long.toString(cursor.getLong(0));
+
+ // Claim all local-only contacts for the test account
+ ops.add(ContentProviderOperation.newUpdate(RawContacts.CONTENT_URI)
+ .withValue(RawContacts.ACCOUNT_NAME, account.name)
+ .withValue(RawContacts.ACCOUNT_TYPE, account.type)
+ .withSelection(RawContacts._ID+"=?", new String[] { rawContactId })
+ .build());
+
+ // Create custom QuickContact action data rows
+ final Uri dataUri = Data.CONTENT_URI.buildUpon()
+ .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
+ .build();
+ ops.add(ContentProviderOperation.newInsert(dataUri)
+ .withValue(Data.RAW_CONTACT_ID, rawContactId)
+ .withValue(Data.MIMETYPE, TEXT_CONTENT_ITEM_TYPE)
+ .withValue(Data.DATA3, "Contacts test action")
+ .withValue(Data.DATA5, "view")
+ .build());
+ }
+ } finally {
+ cursor.close();
}
+ if (ops.isEmpty()) return;
// TODO: Clear isDirty flag
// TODO: Remove isDeleted raw contacts
+
+ Log.v(TestauthConstants.LOG_TAG, "Claiming " + ops.size() + " local raw contacts");
+ for (ContentProviderOperation op : ops) {
+ Log.v(TestauthConstants.LOG_TAG, op.toString());
+ }
+ try {
+ contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+ } catch (Exception e ) {
+ Log.e(TestauthConstants.LOG_TAG, "Failed to claim local raw contacts", e);
+ }
}
}