summaryrefslogtreecommitdiffstats
path: root/androidTest
diff options
context:
space:
mode:
authorErica Chang <echang@cyngn.com>2016-04-14 12:19:08 -0700
committerGerrit Code Review <gerrit@cyanogenmod.org>2016-05-13 11:11:32 -0700
commitd90403ff078159f161bdc0e12860e2615852322e (patch)
treeb1892655891b4faa7d9a696fcace1e1536dadda8 /androidTest
parenta721e708019f773af31680d0a9a4d4343f1fa7ef (diff)
downloadpackages_apps_Contacts-d90403ff078159f161bdc0e12860e2615852322e.tar.gz
packages_apps_Contacts-d90403ff078159f161bdc0e12860e2615852322e.tar.bz2
packages_apps_Contacts-d90403ff078159f161bdc0e12860e2615852322e.zip
Contacts InCall metrics test
-added espresso & uiautomator for UI automation -added test cases for metrics -INAPP_NUDGE_CONTACTS_TAB_LOGIN -DIRECTORY_SEARCH (from contacts tab) -CONTACTS_MANUAL_MERGED -CONTACTS_AUTO_MERGED -INVITES_SENT -DIRECTORY_SEARCH -INAPP_NUDGE_CONTACTS_LOGIN -INAPP_NUDGE_CONTACTS_INSTALL Change-Id: I86e5827b19ed4f313d55902198d5f3ccb25b20e8
Diffstat (limited to 'androidTest')
-rw-r--r--androidTest/.gitignore2
-rw-r--r--androidTest/Android.mk49
-rw-r--r--androidTest/AndroidManifest.xml22
-rwxr-xr-xandroidTest/README.md36
-rw-r--r--androidTest/res/drawable-hdpi/ic_launcher.pngbin0 -> 4811 bytes
-rw-r--r--androidTest/res/drawable-mdpi/ic_launcher.pngbin0 -> 3033 bytes
-rw-r--r--androidTest/res/drawable-xhdpi/ic_launcher.pngbin0 -> 6887 bytes
-rw-r--r--androidTest/res/values/strings.xml19
-rw-r--r--androidTest/src/com/android/contacts/androidtest/InCallMetricsContactTest.java460
-rw-r--r--androidTest/src/com/android/contacts/androidtest/InCallMetricsSendTest.java131
-rw-r--r--androidTest/src/com/android/contacts/androidtest/InCallMetricsTestDbUtils.java103
-rw-r--r--androidTest/src/com/android/contacts/androidtest/InCallMetricsTestUtils.java264
12 files changed, 1086 insertions, 0 deletions
diff --git a/androidTest/.gitignore b/androidTest/.gitignore
new file mode 100644
index 000000000..abba8972d
--- /dev/null
+++ b/androidTest/.gitignore
@@ -0,0 +1,2 @@
+/gen
+/*.iml
diff --git a/androidTest/Android.mk b/androidTest/Android.mk
new file mode 100644
index 000000000..973ef102d
--- /dev/null
+++ b/androidTest/Android.mk
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2016 The CyanogenMod 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_STATIC_JAVA_LIBRARIES := espresso \
+ contacts-ub-uiautomator
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Notice that we don't have to include the src files of Contacts because, by
+# running the tests using an instrumentation targeting Contacts, we
+# automatically get all of its classes loaded into our environment.
+
+LOCAL_PACKAGE_NAME := ContactsAndroidTests
+
+LOCAL_INSTRUMENTATION_FOR := Contacts
+
+LOCAL_CERTIFICATE := shared
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
+ espresso:../../../../prebuilts/misc/common/android-support-test/espresso-core.jar \
+ contacts-ub-uiautomator:../../../../prebuilts/misc/common/ub-uiautomator/ub-uiautomator.jar
+
+include $(BUILD_MULTI_PREBUILT)
diff --git a/androidTest/AndroidManifest.xml b/androidTest/AndroidManifest.xml
new file mode 100644
index 000000000..a9304831e
--- /dev/null
+++ b/androidTest/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.contacts.androidtest">
+
+ <original-package android:name="com.android.contacts.androidtest"/>
+
+ <uses-sdk
+ android:minSdkVersion="23"
+ android:targetSdkVersion="23"/>
+
+
+ <instrumentation
+ android:name="android.support.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.contacts"/>
+
+ <application
+ android:icon="@drawable/ic_launcher"
+ android:label="@string/app_name">
+ <uses-library android:name="android.test.runner"/>
+ </application>
+
+</manifest>
diff --git a/androidTest/README.md b/androidTest/README.md
new file mode 100755
index 000000000..e2902df7d
--- /dev/null
+++ b/androidTest/README.md
@@ -0,0 +1,36 @@
+To run the espresso tests:
+
+# Test setup
+## 1) Build the binary first
+packages/apps/Contacts/androidtest/mm
+## 2) Install the test apk on target device
+adb install -r $OUT/target/product/[device]/data/app/ContactsAndroidTests/ContactsAndroidTests.apk
+## 3) Install an InCall plugin, its dependency app and sign in. It is
+ recommended to use a test version of InCall plugin that supports the
+ ACTION "com.android.contacts.androidtest.AUTH_STATE" to help with
+ the plugin state automation. test1 ~ test6 uses this ACTION to
+ automate the plugin authentication state
+
+# Execute InCallMetricsContactTest (all Contact UI related) tests
+* test1: CONTACTS_MANUAL_MERGED
+* test2: CONTACTS_AUTO_MERGED
+* test3: INVITES_SENT
+* test4: DIRECTORY_SEARCH (from Contacts card)
+* test5: INAPP_NUDGE_CONTACTS_LOGIN
+* test6: DIRECTORY_SEARCH (from Contacts plugin tab)
+* test7: INAPP_NUDGE_CONTACTS_TAB_LOGIN (precondition: hard signed out)
+* test8: INAPP_NUDGE_CONTACTS_INSTALL (precondition: uninstall dependency)
+adb shell am instrument -w -e class com.android.contacts.androidtest.InCallMetricsContactTest \
+com.android.contacts.androidtest/android.support.test.runner.AndroidJUnitRunner
+
+## Note. It's best to run test cases individually since they have
+preconditions such as the auth state needs to be signed in/signed
+out, or plugin state needs to be ENABLED or HIDDEN (eg. test1 in InCallMetricsContactTest)
+adb shell am instrument -w -e class com.android.contacts.androidtest.InCallMetricsContactTest#test1 \
+com.android.contacts.androidtest/android.support.test.runner.AndroidJUnitRunner
+
+# Execute InCallMetricsSendTest (auto generate metrics and send) tests
+adb shell am instrument -w -e class com.android.contacts.androidtest.InCallMetricsSendTest \
+com.android.contacts.androidtest/android.support.test.runner.AndroidJUnitRunner
+
+
diff --git a/androidTest/res/drawable-hdpi/ic_launcher.png b/androidTest/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 000000000..6705a79da
--- /dev/null
+++ b/androidTest/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/androidTest/res/drawable-mdpi/ic_launcher.png b/androidTest/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 000000000..7d7c4881a
--- /dev/null
+++ b/androidTest/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/androidTest/res/drawable-xhdpi/ic_launcher.png b/androidTest/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..51e4604bd
--- /dev/null
+++ b/androidTest/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/androidTest/res/values/strings.xml b/androidTest/res/values/strings.xml
new file mode 100644
index 000000000..9f5465f5f
--- /dev/null
+++ b/androidTest/res/values/strings.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ** Copyright (C) 2015 The CyanogenMod 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.
+-->
+<resources>
+ <string name="app_name">Contacts InCall Metrics Test</string>
+</resources>
diff --git a/androidTest/src/com/android/contacts/androidtest/InCallMetricsContactTest.java b/androidTest/src/com/android/contacts/androidtest/InCallMetricsContactTest.java
new file mode 100644
index 000000000..26bd36010
--- /dev/null
+++ b/androidTest/src/com/android/contacts/androidtest/InCallMetricsContactTest.java
@@ -0,0 +1,460 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod 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.contacts.androidtest;
+
+import static android.support.test.espresso.action.ViewActions.click;
+import static android.support.test.espresso.action.ViewActions.swipeLeft;
+import static android.support.test.espresso.action.ViewActions.swipeRight;
+import static android.support.test.espresso.Espresso.onView;
+import static android.support.test.espresso.matcher.ViewMatchers.withId;
+
+import android.content.Context;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.support.test.espresso.NoMatchingViewException;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiSelector;
+import android.support.test.uiautomator.UiObjectNotFoundException;
+
+import android.net.Uri;
+import android.support.test.rules.ActivityTestRule;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
+
+import com.android.contacts.activities.PeopleActivity;
+import com.android.contacts.ContactSaveService;
+import com.android.contacts.incall.InCallMetricsDbHelper;
+import com.android.contacts.incall.InCallMetricsHelper;
+import com.android.contacts.R;
+
+import com.android.phone.common.incall.CallMethodInfo;
+import com.android.phone.common.incall.ContactsDataSubscription;
+import com.android.phone.common.incall.utils.CallMethodFilters;
+
+import org.hamcrest.Matcher;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class InCallMetricsContactTest {
+ private static final String TAG = InCallMetricsContactTest.class.getSimpleName();
+ private Context mContext;
+ private PeopleActivity mActivity;
+ private CallMethodInfo mCm;
+ private UiDevice mDevice;
+
+ private static final String TESTER1_NAME = "Tester1";
+ private static final String TESTER2_NAME = "Tester2";
+ private static final String TESTER1_PHONE = "777-777-7777";
+ private static final String TESTER2_PHONE = "123-456-7890";
+ private static final String MENU_MERGE = "Merge";
+ private static final String SIGN_IN = "Sign in";
+ private static final String GET = "Get";
+
+ @Rule
+ public ActivityTestRule<PeopleActivity> mActivityRule
+ = new ActivityTestRule<PeopleActivity>(PeopleActivity.class);
+
+ @Before
+ public void setUp() {
+ // get Activity handle under test
+ mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ // get CallMethodInfo under test
+ //InCallMetricsTestUtils.waitFor(500);
+ HashMap<ComponentName, CallMethodInfo> cmMap =
+ CallMethodFilters.getAllEnabledAndHiddenCallMethods(
+ ContactsDataSubscription.get(mContext));
+ Assert.assertNotNull(cmMap);
+ Set<ComponentName> cmKeySet = cmMap.keySet();
+ if (cmKeySet.size() == 0) {
+ Log.d(TAG, "No InCall plugin installed");
+ return;
+ }
+ // test the first plugin only
+ ComponentName cn = cmKeySet.iterator().next();
+ mCm = cmMap.get(cn);
+ Assert.assertNotNull(mCm);
+
+ // Initialize UiDevice instance
+ mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ }
+
+ /*
+ * test metrics: CONTACTS_MANUAL_MERGED
+ * precondition : signed in
+ */
+ @Test
+ public void test1() {
+ mActivity = (PeopleActivity) mActivityRule.getActivity();
+ String testName = InCallMetricsHelper.Events.CONTACTS_MANUAL_MERGED.value();
+ Log.d(TAG, "-----test1 start -----" + testName);
+ InCallMetricsTestUtils.setInCallPluginAuthState(mContext, true);
+ InCallMetricsTestUtils.waitFor(100);
+
+ // clear out db
+ Assert.assertTrue(InCallMetricsTestDbUtils.clearAllEntries(mActivity));
+ // check current impression count
+ // show contacts tab login 2x
+ // select InCall plugin tab
+ ContentResolver cr = mActivity.getContentResolver();
+ Uri contactUri1 =
+ InCallMetricsTestUtils.createContact(null, TESTER1_NAME, TESTER1_PHONE, cr);
+ Uri contactUri2 =
+ InCallMetricsTestUtils.createContact(null, TESTER2_NAME, TESTER2_PHONE, cr);
+
+ InCallMetricsTestUtils.openContactCard(mActivity, contactUri1);
+ InCallMetricsTestUtils.waitFor(1000);
+
+ // Click on edit
+ UiObject editButton = mDevice.findObject(new UiSelector()
+ .resourceId("com.android.contacts:id/menu_edit"));
+ try {
+ if (editButton.exists()) {
+ editButton.click();
+ InCallMetricsTestUtils.waitFor(1000);
+ // Open menu
+ mDevice.pressMenu();
+ InCallMetricsTestUtils.waitFor(1000);
+ // Click on merge
+ UiObject mergeMenu = mDevice.findObject(new UiSelector()
+ .text(MENU_MERGE));
+ if (mergeMenu.exists()) {
+ mergeMenu.click();
+ InCallMetricsTestUtils.waitFor(1000);
+ // Select the merge target contact
+ UiObject mergeContact = mDevice.findObject(new UiSelector()
+ .text(TESTER2_NAME));
+ if (mergeContact.exists()) {
+ mergeContact.click();
+ } else {
+ Log.d(TAG, "ERROR: mergeCount does not exist");
+ }
+ }
+ } else {
+ Log.d(TAG, "ERROR: edit button not found");
+ }
+ InCallMetricsTestUtils.waitFor(100);
+ ContentValues entry = InCallMetricsTestDbUtils.getEntry(mActivity,
+ InCallMetricsDbHelper.Tables.USER_ACTIONS_TABLE,
+ InCallMetricsHelper.Events.CONTACTS_MANUAL_MERGED);
+ InCallMetricsTestUtils.verifyUserActionsMetrics(testName, entry, 1);
+ } catch (UiObjectNotFoundException e) {
+ Log.d(TAG, "ERROR: No matching view");
+ }
+ // get uri and return uri
+ Uri mergedUri = InCallMetricsTestUtils.findContactUriByDisplayName(TESTER1_NAME, cr);
+
+ // clean up contact
+ mActivity.startService(ContactSaveService.createDeleteContactIntent(mActivity, mergedUri));
+ Log.d(TAG, "-----test1 finish -----");
+ }
+
+ /*
+ * test metrics: CONTACTS_AUTO_MERGED
+ * precondition : signed in
+ */
+ @Test
+ public void test2() {
+ mActivity = (PeopleActivity) mActivityRule.getActivity();
+ String testName = InCallMetricsHelper.Events.CONTACTS_AUTO_MERGED.value();
+ Log.d(TAG, "-----test2 start -----" + testName);
+ InCallMetricsTestUtils.setInCallPluginAuthState(mActivity, true);
+ InCallMetricsTestUtils.waitFor(100);
+ // clear out db
+ Assert.assertTrue(InCallMetricsTestDbUtils.clearAllEntries(mActivity));
+
+ // query
+ ContentResolver cr = mActivity.getContentResolver();
+ Uri matchUri = InCallMetricsTestUtils.createContact(null, TESTER1_NAME, TESTER1_PHONE, cr);
+ Uri contactUri =
+ InCallMetricsTestUtils.createContact(null, TESTER1_NAME, TESTER1_PHONE, cr);
+
+ InCallMetricsTestUtils.waitFor(500);
+
+ // check count
+ ContentValues entry = InCallMetricsTestDbUtils.getEntry(mActivity,
+ InCallMetricsDbHelper.Tables.USER_ACTIONS_TABLE,
+ InCallMetricsHelper.Events.CONTACTS_AUTO_MERGED);
+ InCallMetricsTestUtils.verifyUserActionsMetrics(testName, entry, 1);
+
+ // clean up contact
+ InCallMetricsTestUtils.deleteContact(contactUri, cr);
+ InCallMetricsTestUtils.deleteContact(matchUri, cr);
+ Log.d(TAG, "-----test2 finish -----");
+ }
+
+ /*
+ * test metrics: INVITES_SENT
+ * precondition : signed in
+ */
+ @Test
+ public void test3() {
+ mActivity = (PeopleActivity) mActivityRule.getActivity();
+ String testName = InCallMetricsHelper.Events.INVITES_SENT.value();
+ Log.d(TAG, "-----test3 start -----" + testName);
+ // precondition signed in
+ InCallMetricsTestUtils.setInCallPluginAuthState(mActivity, true);
+ InCallMetricsTestUtils.waitFor(100);
+ // clear out db
+ Assert.assertTrue(InCallMetricsTestDbUtils.clearAllEntries(mActivity));
+
+ // launch activity
+ ContentResolver cr = mActivity.getContentResolver();
+ Uri contactUri =
+ InCallMetricsTestUtils.createContact(null, TESTER1_NAME, TESTER1_PHONE, cr);
+ InCallMetricsTestUtils.openContactCard(mActivity, contactUri);
+ InCallMetricsTestUtils.waitFor(1000);
+ try {
+ UiObject inviteButton = mDevice.findObject(new UiSelector().text(
+ mActivity.getResources()
+ .getString(R.string.incall_plugin_invite)));
+ if (inviteButton.exists()) {
+ inviteButton.click();
+ InCallMetricsTestUtils.waitFor(100);
+ // check count
+ ContentValues entry = InCallMetricsTestDbUtils.getEntry(mActivity,
+ InCallMetricsDbHelper.Tables.USER_ACTIONS_TABLE,
+ InCallMetricsHelper.Events.INVITES_SENT);
+ InCallMetricsTestUtils.verifyUserActionsMetrics(testName, entry, 1);
+ } else {
+ Log.d(TAG, "ERROR: No matching view");
+ }
+ } catch (UiObjectNotFoundException e) {
+ Log.d(TAG, "ERROR: invite not found");
+ }
+ // clean up contact
+ InCallMetricsTestUtils.deleteContact(contactUri, cr);
+ Log.d(TAG, "-----test3 finish -----");
+ }
+
+ /*
+ * test metrics: DIRECTORY_SEARCH
+ * precondition : signed in
+ */
+ @Test
+ public void test4() {
+ mActivity = (PeopleActivity) mActivityRule.getActivity();
+ String testName = InCallMetricsHelper.Events.DIRECTORY_SEARCH.value();
+ Log.d(TAG, "-----test4 start -----" + testName);
+ // precondition: signed in
+ InCallMetricsTestUtils.setInCallPluginAuthState(mActivity, true);
+ InCallMetricsTestUtils.waitFor(100);
+
+ Assert.assertTrue(InCallMetricsTestDbUtils.clearAllEntries(mActivity));
+ ContentResolver cr = mActivity.getContentResolver();
+ Uri contactUri =
+ InCallMetricsTestUtils.createContact(null, TESTER1_NAME, TESTER1_PHONE, cr);
+ InCallMetricsTestUtils.openContactCard(mActivity, contactUri);
+ InCallMetricsTestUtils.waitFor(1000);
+ try {
+ UiObject searchButton = mDevice.findObject(new UiSelector().text(
+ mActivity.getResources()
+ .getString(R.string.incall_plugin_directory_search, mCm.mName)));
+ if (searchButton.exists()) {
+ searchButton.click();
+ InCallMetricsTestUtils.waitFor(100);
+ // check count
+ ContentValues entry = InCallMetricsTestDbUtils.getEntry(mActivity,
+ InCallMetricsDbHelper.Tables.USER_ACTIONS_TABLE,
+ InCallMetricsHelper.Events.DIRECTORY_SEARCH);
+ InCallMetricsTestUtils.verifyUserActionsMetrics(testName, entry, 1);
+ } else {
+ Log.d(TAG, "ERROR: search not found");
+ }
+ } catch (UiObjectNotFoundException e) {
+ Log.d(TAG, "ERROR: No matching view");
+ }
+ // clean up contact
+ InCallMetricsTestUtils.deleteContact(contactUri, cr);
+ Log.d(TAG, "-----test4 finish -----");
+ }
+ /*
+ * test metrics: INAPP_NUDGE_CONTACTS_LOGIN
+ * precondition : signed out
+ */
+ @Test
+ public void test5() {
+ mActivity = (PeopleActivity) mActivityRule.getActivity();
+ String testName = InCallMetricsHelper.Events.INAPP_NUDGE_CONTACTS_LOGIN.value();
+ Log.d(TAG, "-----test5 start -----" + testName);
+
+ // sign out
+ InCallMetricsTestUtils.setInCallPluginAuthState(mActivity, false);
+ InCallMetricsTestUtils.waitFor(100);
+
+ ContentResolver cr = mActivity.getContentResolver();
+ Assert.assertTrue(InCallMetricsTestDbUtils.clearAllEntries(mActivity));
+ Uri contactUri =
+ InCallMetricsTestUtils.createContact(null, TESTER1_NAME, TESTER1_PHONE, cr);
+ InCallMetricsTestUtils.openContactCard(mActivity, contactUri);
+ InCallMetricsTestUtils.waitFor(1000);
+ try {
+ UiObject signinButton = mDevice.findObject(new UiSelector().text(SIGN_IN));
+ if (signinButton.exists()) {
+ signinButton.click();
+ InCallMetricsTestUtils.waitFor(100);
+ // check count
+ ContentValues entry = InCallMetricsTestDbUtils.getEntry(mActivity,
+ InCallMetricsDbHelper.Tables.INAPP_TABLE,
+ InCallMetricsHelper.Events.INAPP_NUDGE_CONTACTS_LOGIN);
+ InCallMetricsTestUtils.verifyUserActionsMetrics(testName, entry, 1);
+ } else {
+ Log.d(TAG, "ERROR: " + SIGN_IN + " not found");
+ }
+ } catch (UiObjectNotFoundException e) {
+ Log.d(TAG, "ERROR: No matching view");
+ }
+ // clean up contact
+ InCallMetricsTestUtils.deleteContact(contactUri, cr);
+
+ Log.d(TAG, "-----test5 finish -----");
+ }
+
+ /*
+ * test metrics: DIRECTORY_SEARCH (from contacts plugin tab)
+ * precondition : signed in
+ */
+ @Test
+ public void test6() {
+ mActivity = (PeopleActivity) mActivityRule.getActivity();
+ String testName = InCallMetricsHelper.Events.DIRECTORY_SEARCH.value();
+ Log.d(TAG, "-----test6 start -----" + testName);
+ // clear out db
+ Assert.assertTrue(InCallMetricsTestDbUtils.clearAllEntries(mActivity));
+ InCallMetricsTestUtils.setInCallPluginAuthState(mActivity, true);
+ InCallMetricsTestUtils.waitFor(100);
+ try {
+ // focus on plugin tab
+ onView(withId(R.id.tab_pager)).perform(swipeLeft());
+
+ // click on directory search button
+ onView(withId(R.id.floating_action_button)).perform(click());
+ InCallMetricsTestUtils.waitFor(100);
+ ContentValues entry = InCallMetricsTestDbUtils.getEntry(mActivity,
+ InCallMetricsDbHelper.Tables.USER_ACTIONS_TABLE,
+ InCallMetricsHelper.Events.DIRECTORY_SEARCH);
+ InCallMetricsTestUtils.verifyUserActionsMetrics(testName, entry, 1);
+ } catch (NoMatchingViewException e) {
+ Log.d(TAG, "ERROR: No matching view");
+ }
+ Log.d(TAG, "-----test6 finish -----");
+ }
+
+ /*
+ * test metrics: INAPP_NUDGE_CONTACTS_TAB_LOGIN
+ * precondition : hard signed out
+ */
+ @Test
+ public void test7() {
+ mActivity = (PeopleActivity) mActivityRule.getActivity();
+ String testName = InCallMetricsHelper.Events.INAPP_NUDGE_CONTACTS_TAB_LOGIN.value();
+ Log.d(TAG, "-----test7 start -----" + testName);
+ Log.d(TAG, "Please hard sign out...");
+ // clear out db
+ Assert.assertTrue(InCallMetricsTestDbUtils.clearAllEntries(mActivity));
+ InCallMetricsTestUtils.setInCallPluginAuthState(mActivity, false);
+ InCallMetricsTestUtils.waitFor(100);
+ Log.d(TAG, "inAppNudgeContactsTabLogin cm:" + mCm.mName);
+
+ // check current impression count
+ // show contacts tab login 2x
+ // select InCall plugin tab
+ try {
+ onView(withId(R.id.tab_pager)).perform(swipeLeft());
+ InCallMetricsTestUtils.waitFor(1000);
+ // swipe away
+ onView(withId(R.id.tab_pager)).perform(swipeRight());
+ // select InCall plugin tab again
+ onView(withId(R.id.tab_pager)).perform(swipeLeft());
+ InCallMetricsTestUtils.waitFor(1000);
+
+ long currentTime = System.currentTimeMillis();
+
+ onView(withId(R.id.plugin_login_button)).perform(click());
+ InCallMetricsTestUtils.waitFor(100);
+ ContentValues entry = InCallMetricsTestDbUtils.getEntry(mActivity,
+ InCallMetricsDbHelper.Tables.INAPP_TABLE,
+ InCallMetricsHelper.Events.INAPP_NUDGE_CONTACTS_TAB_LOGIN);
+ InCallMetricsTestUtils.verifyInAppMetrics(testName, entry, 2, currentTime);
+
+ } catch (NoMatchingViewException e) {
+ Log.d(TAG, "ERROR: No matching view");
+ }
+ Log.d(TAG, "-----test7 finish -----");
+ }
+ /*
+ * test metrics: INAPP_NUDGE_CONTACTS_INSTALL
+ * precondition : plugin hidden (uninstall dependency)
+ */
+ @Test
+ public void test8() {
+ mActivity = (PeopleActivity) mActivityRule.getActivity();
+ String testName = InCallMetricsHelper.Events.INAPP_NUDGE_CONTACTS_INSTALL.value();
+ Log.d(TAG, "-----test8 start -----" + testName);
+ Log.d(TAG, "Please uninsatll InCall plugin dependency package...(waiting 10 seconds)");
+ InCallMetricsTestUtils.setInCallPluginAuthState(mActivity, true);
+ InCallMetricsTestUtils.waitFor(100);
+
+ ContentResolver cr = mActivity.getContentResolver();
+ InCallMetricsTestDbUtils.clearAllEntries(mActivity);
+ Uri contactUri =
+ InCallMetricsTestUtils.createContact(null, TESTER1_NAME, TESTER1_PHONE, cr);
+ InCallMetricsTestUtils.openContactCard(mActivity, contactUri);
+ InCallMetricsTestUtils.waitFor(1000);
+ try {
+ UiObject button = mDevice.findObject(new UiSelector().text(GET));
+ if (button.exists()) {
+ button.click();
+ InCallMetricsTestUtils.waitFor(100);
+ // check count
+ ContentValues entry = InCallMetricsTestDbUtils.getEntry(mActivity,
+ InCallMetricsDbHelper.Tables.INAPP_TABLE,
+ InCallMetricsHelper.Events.INAPP_NUDGE_CONTACTS_INSTALL);
+ InCallMetricsTestUtils.verifyUserActionsMetrics(testName, entry, 1);
+ } else {
+ Log.d(TAG, "ERROR: " + GET + " not found");
+ }
+ } catch (UiObjectNotFoundException e) {
+ Log.d(TAG, "ERROR: No matching View");
+ }
+ // clean up contact
+ InCallMetricsTestUtils.deleteContact(contactUri, cr);
+
+ Log.d(TAG, "-----test8 finish -----");
+ }
+
+ @After
+ public void cleanup() {
+ // change plugin auth state back to signed in
+ InCallMetricsTestUtils.setInCallPluginAuthState(mActivity, true);
+ // clear out db metrics entries
+ InCallMetricsTestDbUtils.clearAllEntries(mActivity);
+ }
+}
+
diff --git a/androidTest/src/com/android/contacts/androidtest/InCallMetricsSendTest.java b/androidTest/src/com/android/contacts/androidtest/InCallMetricsSendTest.java
new file mode 100644
index 000000000..aea748cdf
--- /dev/null
+++ b/androidTest/src/com/android/contacts/androidtest/InCallMetricsSendTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod 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.contacts.androidtest;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.rules.ActivityTestRule;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
+
+import com.android.contacts.activities.PeopleActivity;
+import com.android.contacts.incall.InCallMetricsDbHelper;
+import com.android.contacts.incall.InCallMetricsHelper;
+import com.android.phone.common.incall.CallMethodInfo;
+import com.android.phone.common.incall.ContactsDataSubscription;
+import com.android.phone.common.incall.utils.CallMethodFilters;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.HashMap;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class InCallMetricsSendTest {
+ private static final String TAG = InCallMetricsSendTest.class.getSimpleName();
+
+ private Context mContext;
+ private CallMethodInfo mCm;
+
+ @Rule
+ public ActivityTestRule<PeopleActivity> mActivityTestRule = new
+ ActivityTestRule<PeopleActivity>(PeopleActivity.class);
+
+ @Before
+ public void setUp() {
+ mContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ // Query plugins
+ HashMap<ComponentName, CallMethodInfo> cmMap =
+ CallMethodFilters.getAllEnabledAndHiddenCallMethods(
+ ContactsDataSubscription.get(mContext));
+ Assert.assertNotNull(cmMap);
+ Set<ComponentName> cmKeySet = cmMap.keySet();
+ if (cmKeySet.size() == 0) {
+ Log.d(TAG, "No InCall plugin installed");
+ return;
+ }
+ // test the first one
+ ComponentName cn = cmKeySet.iterator().next();
+ mCm = cmMap.get(cn);
+ Assert.assertNotNull(mCm);
+ }
+
+ @Test
+ public void sendTest() {
+ populateMetricsInDb();
+ InCallMetricsTestUtils.waitFor(500);
+ InCallMetricsHelper.prepareAndSend(mContext);
+ }
+
+ private void populateMetricsInDb() {
+ // Category: USER_ACTIONS
+ // CONTACTS_MANUAL_MERGED
+ InCallMetricsDbHelper.getInstance(mContext).incrementUserActionsParam(
+ mCm.mComponent.flattenToString(),
+ "",
+ InCallMetricsHelper.Events.CONTACTS_MANUAL_MERGED.value(),
+ InCallMetricsHelper.Categories.USER_ACTIONS.value(),
+ InCallMetricsHelper.Parameters.COUNT.toCol());
+ // CONTACTS_AUTO_MERGED
+ InCallMetricsDbHelper.getInstance(mContext).incrementUserActionsParam(
+ mCm.mComponent.flattenToString(),
+ "",
+ InCallMetricsHelper.Events.CONTACTS_AUTO_MERGED.value(),
+ InCallMetricsHelper.Categories.USER_ACTIONS.value(),
+ InCallMetricsHelper.Parameters.COUNT.toCol());
+ // INVITES_SENT
+ InCallMetricsHelper.increaseCount(mContext, InCallMetricsHelper.Events.INVITES_SENT,
+ mCm.mComponent.flattenToString());
+ // DIRECTORY_SEARCH
+ InCallMetricsHelper.increaseCount(mContext, InCallMetricsHelper.Events.DIRECTORY_SEARCH,
+ mCm.mComponent.flattenToString());
+ // Category: In App Nudges
+ // INAPP_NUDGE_CONTACTS_TAB_LOGIN
+ InCallMetricsHelper.setValue(
+ mContext,
+ mCm.mComponent,
+ InCallMetricsHelper.Categories.INAPP_NUDGES,
+ InCallMetricsHelper.Events.INAPP_NUDGE_CONTACTS_TAB_LOGIN,
+ InCallMetricsHelper.Parameters.EVENT_ACCEPTANCE,
+ InCallMetricsHelper.EVENT_ACCEPT,
+ InCallMetricsHelper.generateNudgeId(mCm.mLoginSubtitle));
+ // INAPP_NUDGE_CONTACTS_LOGIN
+ InCallMetricsHelper.setValue(
+ mContext,
+ mCm.mComponent,
+ InCallMetricsHelper.Categories.INAPP_NUDGES,
+ InCallMetricsHelper.Events.INAPP_NUDGE_CONTACTS_LOGIN,
+ InCallMetricsHelper.Parameters.EVENT_ACCEPTANCE,
+ InCallMetricsHelper.EVENT_ACCEPT,
+ InCallMetricsHelper.generateNudgeId(mCm.mLoginNudgeSubtitle));
+ // INAPP_NUDGE_CONTACTS_INSTALL
+ InCallMetricsHelper.setValue(
+ mContext,
+ mCm.mComponent,
+ InCallMetricsHelper.Categories.INAPP_NUDGES,
+ InCallMetricsHelper.Events.INAPP_NUDGE_CONTACTS_INSTALL,
+ InCallMetricsHelper.Parameters.EVENT_ACCEPTANCE,
+ InCallMetricsHelper.EVENT_DISMISS,
+ InCallMetricsHelper.generateNudgeId(mCm.mInstallNudgeSubtitle));
+ }
+}
diff --git a/androidTest/src/com/android/contacts/androidtest/InCallMetricsTestDbUtils.java b/androidTest/src/com/android/contacts/androidtest/InCallMetricsTestDbUtils.java
new file mode 100644
index 000000000..820868255
--- /dev/null
+++ b/androidTest/src/com/android/contacts/androidtest/InCallMetricsTestDbUtils.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod 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.contacts.androidtest;
+
+import com.android.contacts.incall.InCallMetricsDbHelper;
+import com.android.contacts.incall.InCallMetricsHelper;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDatabase;
+import android.util.Log;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class InCallMetricsTestDbUtils {
+ private static final String TAG = InCallMetricsTestDbUtils.class.getSimpleName();
+
+ private static final String[] INAPP_PROJECTION = new String[] {
+ InCallMetricsDbHelper.InAppColumns._ID,
+ InCallMetricsDbHelper.InAppColumns.CATEGORY,
+ InCallMetricsDbHelper.InAppColumns.EVENT_NAME,
+ InCallMetricsDbHelper.InAppColumns.COUNT,
+ InCallMetricsDbHelper.InAppColumns.NUDGE_ID,
+ InCallMetricsDbHelper.InAppColumns.EVENT_ACCEPTANCE,
+ InCallMetricsDbHelper.InAppColumns.EVENT_ACCEPTANCE_TIME,
+ InCallMetricsDbHelper.InAppColumns.PROVIDER_NAME
+ };
+ private static final String[] USER_ACTIONS_PROJECTION = new String[] {
+ InCallMetricsDbHelper.UserActionsColumns._ID,
+ InCallMetricsDbHelper.UserActionsColumns.CATEGORY,
+ InCallMetricsDbHelper.UserActionsColumns.EVENT_NAME,
+ InCallMetricsDbHelper.UserActionsColumns.COUNT,
+ InCallMetricsDbHelper.UserActionsColumns.PROVIDER_NAME,
+ InCallMetricsDbHelper.UserActionsColumns.RAW_ID
+ };
+ private static final String SELECT_EVENT =
+ InCallMetricsDbHelper.UserActionsColumns.EVENT_NAME + " ==?";
+
+ public static boolean clearAllEntries(Context context) {
+ List<ContentValues> list = new LinkedList<ContentValues>();
+ SQLiteDatabase db = InCallMetricsDbHelper.getInstance(context).getWritableDatabase();
+ if (db == null) {
+ Log.d(TAG, "No valid db");
+ return false;
+ }
+ db.delete(InCallMetricsDbHelper.Tables.USER_ACTIONS_TABLE, null, null);
+ db.delete(InCallMetricsDbHelper.Tables.INAPP_TABLE, null, null);
+ return true;
+ }
+
+ public static ContentValues getEntry(Context context, String table,
+ InCallMetricsHelper.Events event) {
+ InCallMetricsDbHelper dbHelper = InCallMetricsDbHelper.getInstance(context);
+ SQLiteDatabase db = dbHelper.getWritableDatabase();
+ String[] projection = new String[] {};
+ if (table.equals(InCallMetricsDbHelper.Tables.USER_ACTIONS_TABLE)) {
+ projection = USER_ACTIONS_PROJECTION;
+ } else if (table.equals(InCallMetricsDbHelper.Tables.INAPP_TABLE)) {
+ projection = INAPP_PROJECTION;
+ }
+ Cursor cursor = db.query(
+ table,
+ projection,
+ SELECT_EVENT,
+ new String[]{event.value()},
+ null,
+ null,
+ null);
+ ContentValues cv = getContentValues(cursor);
+ if (cursor != null) {
+ cursor.close();
+ }
+ return cv;
+ }
+
+ private static ContentValues getContentValues(Cursor cursor) {
+ ContentValues map = new ContentValues();;
+ if (cursor != null && cursor.moveToFirst()) {
+ if (cursor.moveToFirst()) {
+ DatabaseUtils.cursorRowToContentValues(cursor, map);
+ Log.d(TAG, "getContentValues:" + map);
+ }
+ }
+ return map;
+ }
+}
diff --git a/androidTest/src/com/android/contacts/androidtest/InCallMetricsTestUtils.java b/androidTest/src/com/android/contacts/androidtest/InCallMetricsTestUtils.java
new file mode 100644
index 000000000..23c2ecf92
--- /dev/null
+++ b/androidTest/src/com/android/contacts/androidtest/InCallMetricsTestUtils.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2016 The CyanogenMod 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.contacts.androidtest;
+
+import android.app.Activity;
+import android.content.ContentProviderOperation;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.util.Log;
+
+import com.android.contacts.common.util.ImplicitIntentsUtil;
+import com.android.contacts.incall.InCallMetricsDbHelper;
+import com.android.contacts.incall.InCallMetricsHelper;
+import com.android.contacts.quickcontact.QuickContactActivity;
+import org.junit.Assert;
+
+import java.util.ArrayList;
+
+public class InCallMetricsTestUtils {
+ private static final String TAG = InCallMetricsTestUtils.class.getSimpleName();
+
+ // threshold for user interaction (click) and current timestamp difference, ensure
+ // the metric timestamp is corret
+ public static final double TIMESTAMP_THRESHOLD = 10000;
+
+ public static void waitFor(long millis) {
+ try {
+ Thread.sleep(millis);
+ } catch (InterruptedException e) {
+
+ }
+ }
+
+ public static void setInCallPluginAuthState(Context context, boolean state) {
+ Intent intent = new Intent("com.android.contacts.androidtest.AUTH_STATE");
+ intent.putExtra("state", state);
+ context.sendBroadcast(intent);
+
+ }
+
+ public static Intent getContactCardIntent(Uri uri) {
+ final Intent intent = new Intent(ContactsContract.QuickContact.ACTION_QUICK_CONTACT);
+ intent.setData(uri);
+ intent.putExtra(ContactsContract.QuickContact.EXTRA_MODE,
+ QuickContactActivity.MODE_FULLY_EXPANDED);
+ // Make sure not to show QuickContacts on top of another QuickContacts.
+ intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ return intent;
+ }
+
+ public static Uri createContact(Uri matchUri, String displayName, String phone, ContentResolver
+ contentResolver) {
+ String name = displayName;
+ int phoneType = ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE;
+ if (matchUri != null) {
+ // look up matchUri
+ String selection = ContactsContract.Data.MIMETYPE + " =? OR " +
+ ContactsContract.Data.MIMETYPE + " =?";
+ Cursor cursor = contentResolver.query(
+ Uri.withAppendedPath(matchUri, ContactsContract.Contacts.Entity
+ .CONTENT_DIRECTORY),
+ null,
+ selection,
+ new String[] {
+ ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE,
+ ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE},
+ null);
+ boolean foundName = false;
+ boolean foundPhone = false;
+ while (cursor.moveToNext()) {
+ Log.d(TAG, "found matchUri");
+ if (cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE))
+ .equals(ContactsContract.CommonDataKinds.StructuredName
+ .CONTENT_ITEM_TYPE)) {
+ name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts
+ .DISPLAY_NAME));
+ foundPhone = true;
+ }
+ if (cursor.getString(cursor.getColumnIndex(ContactsContract.Data.MIMETYPE))
+ .equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
+ phone = cursor.getString(cursor.getColumnIndex(ContactsContract
+ .CommonDataKinds.Phone.NUMBER));
+ phoneType = cursor.getInt(cursor.getColumnIndex(ContactsContract
+ .CommonDataKinds.Phone.TYPE));
+ foundPhone = true;
+ }
+ if (foundName && foundPhone) {
+ Log.d(TAG, "found matchUri name:" + name + " phone:"+phone);
+ break;
+ }
+ }
+ cursor.close();
+ }
+
+ ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+ ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
+ .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, "com.android.localphone")
+ .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, "PHONE")
+ .build());
+ ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
+ .withValue(ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
+ .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
+ .build());
+ ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
+ .withValue(ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
+ .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
+ .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType)
+ .build());
+
+
+ // Ask the Contact provider to create a new contact
+ Log.i(TAG,"Creating contact: " + name);
+ try {
+ contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
+ } catch (Exception e) {
+ // Display warning
+ Log.e(TAG, "Exceptoin encoutered while inserting contact: " + e);
+ }
+
+ // get uri and return uri
+ Uri contactUri = null;
+ String[] projection = {
+ ContactsContract.Contacts._ID,
+ ContactsContract.Contacts.LOOKUP_KEY};
+ String selection = ContactsContract.Contacts.DISPLAY_NAME + " =?";
+ Cursor cursor = contentResolver.query(
+ ContactsContract.Contacts.CONTENT_URI,
+ projection,
+ selection,
+ new String[] {name},
+ null);
+ if (cursor != null && cursor.moveToFirst()) {
+ contactUri = ContactsContract.Contacts.getLookupUri(
+ cursor.getLong(0), cursor.getString(1));
+ }
+ cursor.close();
+ return contactUri;
+ }
+
+ public static void deleteContact(Uri contactUri, ContentResolver contentResolver) {
+ //ContentProviderOperation.newDelete(contactUri).build();
+ contentResolver.delete(contactUri, null, null);
+ }
+
+ public static Uri findFirstContactWithPhoneNumber(String accountType,
+ ContentResolver contentResolver) {
+ Uri contactUri = null;
+ Log.d(TAG, "RawContact accountType:" + accountType);
+ String selection = ContactsContract.RawContacts.ACCOUNT_TYPE + " =?";
+ Cursor cursor = contentResolver.query(
+ ContactsContract.RawContacts.CONTENT_URI,
+ null,
+ selection,
+ new String[] {accountType},
+ null);
+
+ while (cursor.moveToNext()) {
+ int rawId = cursor.getInt(cursor.getColumnIndex(ContactsContract.RawContacts._ID));
+ int contactId = cursor.getInt(cursor.getColumnIndex(ContactsContract.RawContacts
+ .CONTACT_ID));
+ Log.d(TAG, "RawContact rawId " + rawId + " contactId:" + contactId);
+ Cursor dataCursor = contentResolver.query(
+ ContactsContract.Data.CONTENT_URI,
+ null,
+ ContactsContract.Data.RAW_CONTACT_ID + " =? AND " + ContactsContract.Data
+ .MIMETYPE + " =?",
+ new String[] {String.valueOf(rawId), ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE},
+ null);
+ while (dataCursor.moveToNext()) {
+ Log.d(TAG, "dataCursor found" + dataCursor.getInt(0));
+ contactUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI,
+ String.valueOf(contactId));
+ cursor.close();
+ dataCursor.close();
+ return contactUri;
+ }
+ dataCursor.close();
+ }
+ cursor.close();
+ return contactUri;
+ }
+
+ public static void openContactCard(Activity activity, Uri contactUri) {
+ final Intent cardIntent = ImplicitIntentsUtil.composeQuickContactIntent(
+ contactUri, QuickContactActivity.MODE_FULLY_EXPANDED);
+ ImplicitIntentsUtil.startActivityInApp(activity, cardIntent);
+ }
+
+ public static void verifyInAppMetrics(String testName, ContentValues entry, int expectedCount,
+ long currentTime) {
+ int newCount = entry.containsKey(InCallMetricsDbHelper.InAppColumns.COUNT) ?
+ entry.getAsInteger(InCallMetricsDbHelper.InAppColumns.COUNT) : 0;
+ boolean eventAccept =
+ entry.containsKey(InCallMetricsDbHelper.InAppColumns.EVENT_ACCEPTANCE)
+ ? entry.getAsBoolean(
+ InCallMetricsDbHelper.InAppColumns.EVENT_ACCEPTANCE) : false;
+ int timestamp =
+ entry.containsKey(InCallMetricsDbHelper.InAppColumns.EVENT_ACCEPTANCE_TIME)
+ ? entry.getAsInteger(
+ InCallMetricsDbHelper.InAppColumns.EVENT_ACCEPTANCE_TIME) : -1;
+
+ Log.d(TAG, testName + " newCount:" + newCount);
+
+ // check count
+ Assert.assertEquals(expectedCount, newCount);
+ // check accept value
+ Assert.assertTrue(eventAccept);
+ // check user accept timestamp is within threshold
+ Assert.assertTrue(
+ (timestamp - currentTime) < InCallMetricsTestUtils.TIMESTAMP_THRESHOLD);
+ }
+
+ public static void verifyUserActionsMetrics(String testName, ContentValues entry, int
+ expectedCount) {
+ int newCount = entry.containsKey(InCallMetricsDbHelper.UserActionsColumns.COUNT) ?
+ entry.getAsInteger(InCallMetricsDbHelper.UserActionsColumns.COUNT) : 0;
+ Log.d(TAG, testName + " newCount:" + newCount);
+ Assert.assertEquals(expectedCount, newCount);
+ }
+
+ public static Uri findContactUriByDisplayName(String displayName, ContentResolver cr) {
+ Uri contactUri = null;
+ String[] projection = {
+ ContactsContract.Contacts._ID,
+ ContactsContract.Contacts.LOOKUP_KEY};
+ String selection = ContactsContract.Contacts.DISPLAY_NAME + " =?";
+ Cursor cursor = cr.query(
+ ContactsContract.Contacts.CONTENT_URI,
+ projection,
+ selection,
+ new String[] {displayName},
+ null);
+ if (cursor != null && cursor.moveToFirst()) {
+ contactUri = ContactsContract.Contacts.getLookupUri(
+ cursor.getLong(0), cursor.getString(1));
+ }
+ cursor.close();
+ return contactUri;
+ }
+}