summaryrefslogtreecommitdiffstats
path: root/androidTest/src/com/android/contacts
diff options
context:
space:
mode:
Diffstat (limited to 'androidTest/src/com/android/contacts')
-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
4 files changed, 958 insertions, 0 deletions
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;
+ }
+}