Loading tests/Android.mk +3 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,9 @@ LOCAL_CERTIFICATE := shared 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 Loading tests/AndroidManifest.xml +10 −2 Original line number Diff line number Diff line Loading @@ -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" /> Loading @@ -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"/> Loading Loading @@ -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" /> Loading tests/res/xml/contacts_contactsdatakind.xml 0 → 100644 +104 −0 Original line number Diff line number Diff line <?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> tests/res/xml/test_basic_authenticator.xml +2 −0 Original line number Diff line number Diff line Loading @@ -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" /> tests/src/com/android/contacts/tests/testauth/TestSyncAdapter.java +51 −10 Original line number Diff line number Diff line Loading @@ -18,20 +18,29 @@ package com.android.contacts.tests.testauth; 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) { Loading @@ -47,19 +56,51 @@ public class TestSyncAdapter extends AbstractThreadedSyncAdapter { 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); } } } Loading
tests/Android.mk +3 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,9 @@ LOCAL_CERTIFICATE := shared 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 Loading
tests/AndroidManifest.xml +10 −2 Original line number Diff line number Diff line Loading @@ -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" /> Loading @@ -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"/> Loading Loading @@ -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" /> Loading
tests/res/xml/contacts_contactsdatakind.xml 0 → 100644 +104 −0 Original line number Diff line number Diff line <?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>
tests/res/xml/test_basic_authenticator.xml +2 −0 Original line number Diff line number Diff line Loading @@ -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" />
tests/src/com/android/contacts/tests/testauth/TestSyncAdapter.java +51 −10 Original line number Diff line number Diff line Loading @@ -18,20 +18,29 @@ package com.android.contacts.tests.testauth; 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) { Loading @@ -47,19 +56,51 @@ public class TestSyncAdapter extends AbstractThreadedSyncAdapter { 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); } } }