diff --git a/tests/Android.mk b/tests/Android.mk
index ef11c5e..241ff5e 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_CERTIFICATE := shared
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_STATIC_JAVA_LIBRARIES := com.android.contacts.common.test
 
 # Include all test java files.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index d80a35d..a3dacbe 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -76,16 +76,6 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".calllog.FillCallLogTestActivity"
-            android:label="@string/fillCallLogTest"
-            >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-
         <activity android:name=".streamitems.StreamItemPopulatorActivity"
             android:label="@string/streamItemPopulator"
             >
@@ -139,9 +129,4 @@
         android:label="Contacts launch performance">
     </instrumentation>
 
-    <instrumentation android:name="com.android.contacts.DialerLaunchPerformance"
-        android:targetPackage="com.android.contacts"
-        android:label="Dialer launch performance">
-    </instrumentation>
-
 </manifest>
diff --git a/tests/src/com/android/contacts/CallDetailActivityTest.java b/tests/src/com/android/contacts/CallDetailActivityTest.java
deleted file mode 100644
index ae28929..0000000
--- a/tests/src/com/android/contacts/CallDetailActivityTest.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.contacts;
-
-import static com.android.contacts.CallDetailActivity.Tasks.UPDATE_PHONE_CALL_DETAILS;
-import static com.android.contacts.voicemail.VoicemailPlaybackPresenter.Tasks.CHECK_FOR_CONTENT;
-import static com.android.contacts.voicemail.VoicemailPlaybackPresenter.Tasks.PREPARE_MEDIA_PLAYER;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Intent;
-import android.content.res.AssetManager;
-import android.net.Uri;
-import android.provider.CallLog;
-import android.provider.VoicemailContract;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
-import android.view.Menu;
-import android.widget.TextView;
-
-import com.android.contacts.util.AsyncTaskExecutors;
-import com.android.contacts.util.FakeAsyncTaskExecutor;
-import com.android.contacts.util.IntegrationTestUtils;
-import com.android.contacts.util.LocaleTestUtils;
-import com.android.internal.view.menu.ContextMenuBuilder;
-import com.google.common.io.Closeables;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Unit tests for the {@link CallDetailActivity}.
- */
-@LargeTest
-public class CallDetailActivityTest extends ActivityInstrumentationTestCase2<CallDetailActivity> {
-    private static final String TEST_ASSET_NAME = "quick_test_recording.mp3";
-    private static final String MIME_TYPE = "audio/mp3";
-    private static final String CONTACT_NUMBER = "+1412555555";
-    private static final String VOICEMAIL_FILE_LOCATION = "/sdcard/sadlfj893w4j23o9sfu.mp3";
-
-    private Uri mCallLogUri;
-    private Uri mVoicemailUri;
-    private IntegrationTestUtils mTestUtils;
-    private LocaleTestUtils mLocaleTestUtils;
-    private FakeAsyncTaskExecutor mFakeAsyncTaskExecutor;
-    private CallDetailActivity mActivityUnderTest;
-
-    public CallDetailActivityTest() {
-        super(CallDetailActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mFakeAsyncTaskExecutor = new FakeAsyncTaskExecutor(getInstrumentation());
-        AsyncTaskExecutors.setFactoryForTest(mFakeAsyncTaskExecutor.getFactory());
-        // I don't like the default of focus-mode for tests, the green focus border makes the
-        // screenshots look weak.
-        setActivityInitialTouchMode(true);
-        mTestUtils = new IntegrationTestUtils(getInstrumentation());
-        // Some of the tests rely on the text that appears on screen - safest to force a
-        // specific locale.
-        mLocaleTestUtils = new LocaleTestUtils(getInstrumentation().getTargetContext());
-        mLocaleTestUtils.setLocale(Locale.US);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mLocaleTestUtils.restoreLocale();
-        mLocaleTestUtils = null;
-        cleanUpUri();
-        mTestUtils = null;
-        AsyncTaskExecutors.setFactoryForTest(null);
-        super.tearDown();
-    }
-
-    public void testInitialActivityStartsWithFetchingVoicemail() throws Throwable {
-        setActivityIntentForTestVoicemailEntry();
-        startActivityUnderTest();
-        // When the activity first starts, we will show "Fetching voicemail" on the screen.
-        // The duration should not be visible.
-        assertHasOneTextViewContaining("Fetching voicemail");
-        assertZeroTextViewsContaining("00:00");
-    }
-
-    public void testWhenCheckForContentCompletes_UiShowsBuffering() throws Throwable {
-        setActivityIntentForTestVoicemailEntry();
-        startActivityUnderTest();
-        // There is a background check that is testing to see if we have the content available.
-        // Once that task completes, we shouldn't be showing the fetching message, we should
-        // be showing "Buffering".
-        mFakeAsyncTaskExecutor.runTask(CHECK_FOR_CONTENT);
-        assertHasOneTextViewContaining("Buffering");
-        assertZeroTextViewsContaining("Fetching voicemail");
-    }
-
-    public void testInvalidVoicemailShowsErrorMessage() throws Throwable {
-        setActivityIntentForTestVoicemailEntry();
-        startActivityUnderTest();
-        mFakeAsyncTaskExecutor.runTask(CHECK_FOR_CONTENT);
-        // There should be exactly one background task ready to prepare the media player.
-        // Preparing the media player will have thrown an IOException since the file doesn't exist.
-        // This should have put a failed to play message on screen, buffering is gone.
-        mFakeAsyncTaskExecutor.runTask(PREPARE_MEDIA_PLAYER);
-        assertHasOneTextViewContaining("Couldn't play voicemail");
-        assertZeroTextViewsContaining("Buffering");
-    }
-
-    public void testOnResumeDoesNotCreateManyFragments() throws Throwable {
-        // There was a bug where every time the activity was resumed, a new fragment was created.
-        // Before the fix, this was failing reproducibly with at least 3 "Buffering" views.
-        setActivityIntentForTestVoicemailEntry();
-        startActivityUnderTest();
-        mFakeAsyncTaskExecutor.runTask(CHECK_FOR_CONTENT);
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                getInstrumentation().callActivityOnPause(mActivityUnderTest);
-                getInstrumentation().callActivityOnResume(mActivityUnderTest);
-                getInstrumentation().callActivityOnPause(mActivityUnderTest);
-                getInstrumentation().callActivityOnResume(mActivityUnderTest);
-            }
-        });
-        assertHasOneTextViewContaining("Buffering");
-    }
-
-    /**
-     * Test for bug where increase rate button with invalid voicemail causes a crash.
-     * <p>
-     * The repro steps for this crash were to open a voicemail that does not have an attachment,
-     * then click the play button (which just reported an error), then after that try to adjust the
-     * rate.  See http://b/5047879.
-     */
-    public void testClickIncreaseRateButtonWithInvalidVoicemailDoesNotCrash() throws Throwable {
-        setActivityIntentForTestVoicemailEntry();
-        startActivityUnderTest();
-        mTestUtils.clickButton(mActivityUnderTest, R.id.playback_start_stop);
-        mTestUtils.clickButton(mActivityUnderTest, R.id.rate_increase_button);
-    }
-
-    /** Test for bug where missing Extras on intent used to start Activity causes NPE. */
-    public void testCallLogUriWithMissingExtrasShouldNotCauseNPE() throws Throwable {
-        setActivityIntentForTestCallEntry();
-        startActivityUnderTest();
-    }
-
-    /**
-     * Test for bug where voicemails should not have remove-from-call-log entry.
-     * <p>
-     * See http://b/5054103.
-     */
-    public void testVoicemailDoesNotHaveRemoveFromCallLog() throws Throwable {
-        setActivityIntentForTestVoicemailEntry();
-        startActivityUnderTest();
-        Menu menu = new ContextMenuBuilder(mActivityUnderTest);
-        mActivityUnderTest.onCreateOptionsMenu(menu);
-        mActivityUnderTest.onPrepareOptionsMenu(menu);
-        assertFalse(menu.findItem(R.id.menu_remove_from_call_log).isVisible());
-    }
-
-    /** Test to check that I haven't broken the remove-from-call-log entry from regular calls. */
-    public void testRegularCallDoesHaveRemoveFromCallLog() throws Throwable {
-        setActivityIntentForTestCallEntry();
-        startActivityUnderTest();
-        Menu menu = new ContextMenuBuilder(mActivityUnderTest);
-        mActivityUnderTest.onCreateOptionsMenu(menu);
-        mActivityUnderTest.onPrepareOptionsMenu(menu);
-        assertTrue(menu.findItem(R.id.menu_remove_from_call_log).isVisible());
-    }
-
-    /**
-     * Test to show that we are correctly displaying playback rate on the ui.
-     * <p>
-     * See bug http://b/5044075.
-     */
-    @Suppress
-    public void testVoicemailPlaybackRateDisplayedOnUi() throws Throwable {
-        setActivityIntentForTestVoicemailEntry();
-        startActivityUnderTest();
-        // Find the TextView containing the duration.  It should be initially displaying "00:00".
-        List<TextView> views = mTestUtils.getTextViewsWithString(mActivityUnderTest, "00:00");
-        assertEquals(1, views.size());
-        TextView timeDisplay = views.get(0);
-        // Hit the plus button.  At this point we should be displaying "fast speed".
-        mTestUtils.clickButton(mActivityUnderTest, R.id.rate_increase_button);
-        assertEquals("fast speed", mTestUtils.getText(timeDisplay));
-        // Hit the minus button.  We should be back to "normal" speed.
-        mTestUtils.clickButton(mActivityUnderTest, R.id.rate_decrease_button);
-        assertEquals("normal speed", mTestUtils.getText(timeDisplay));
-        // Wait for one and a half seconds.  The timer will be back.
-        Thread.sleep(1500);
-        assertEquals("00:00", mTestUtils.getText(timeDisplay));
-    }
-
-    @Suppress
-    public void testClickingCallStopsPlayback() throws Throwable {
-        setActivityIntentForRealFileVoicemailEntry();
-        startActivityUnderTest();
-        mFakeAsyncTaskExecutor.runTask(CHECK_FOR_CONTENT);
-        mFakeAsyncTaskExecutor.runTask(PREPARE_MEDIA_PLAYER);
-        mTestUtils.clickButton(mActivityUnderTest, R.id.playback_speakerphone);
-        mTestUtils.clickButton(mActivityUnderTest, R.id.playback_start_stop);
-        mTestUtils.clickButton(mActivityUnderTest, R.id.call_and_sms_main_action);
-        Thread.sleep(2000);
-        // TODO: Suppressed the test for now, because I'm looking for an easy way to say "the audio
-        // is not playing at this point", and I can't find it without doing dirty things.
-    }
-
-    private void setActivityIntentForTestCallEntry() {
-        assertNull(mCallLogUri);
-        ContentResolver contentResolver = getContentResolver();
-        ContentValues values = new ContentValues();
-        values.put(CallLog.Calls.NUMBER, CONTACT_NUMBER);
-        values.put(CallLog.Calls.TYPE, CallLog.Calls.INCOMING_TYPE);
-        mCallLogUri = contentResolver.insert(CallLog.Calls.CONTENT_URI, values);
-        setActivityIntent(new Intent(Intent.ACTION_VIEW, mCallLogUri));
-    }
-
-    private void setActivityIntentForTestVoicemailEntry() {
-        assertNull(mVoicemailUri);
-        ContentResolver contentResolver = getContentResolver();
-        ContentValues values = new ContentValues();
-        values.put(VoicemailContract.Voicemails.NUMBER, CONTACT_NUMBER);
-        values.put(VoicemailContract.Voicemails.HAS_CONTENT, 1);
-        values.put(VoicemailContract.Voicemails._DATA, VOICEMAIL_FILE_LOCATION);
-        mVoicemailUri = contentResolver.insert(VoicemailContract.Voicemails.CONTENT_URI, values);
-        Uri callLogUri = ContentUris.withAppendedId(CallLog.Calls.CONTENT_URI_WITH_VOICEMAIL,
-                ContentUris.parseId(mVoicemailUri));
-        Intent intent = new Intent(Intent.ACTION_VIEW, callLogUri);
-        intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI, mVoicemailUri);
-        setActivityIntent(intent);
-    }
-
-    private void setActivityIntentForRealFileVoicemailEntry() throws IOException {
-        assertNull(mVoicemailUri);
-        ContentValues values = new ContentValues();
-        values.put(VoicemailContract.Voicemails.DATE, String.valueOf(System.currentTimeMillis()));
-        values.put(VoicemailContract.Voicemails.NUMBER, CONTACT_NUMBER);
-        values.put(VoicemailContract.Voicemails.MIME_TYPE, MIME_TYPE);
-        values.put(VoicemailContract.Voicemails.HAS_CONTENT, 1);
-        String packageName = getInstrumentation().getTargetContext().getPackageName();
-        mVoicemailUri = getContentResolver().insert(
-                VoicemailContract.Voicemails.buildSourceUri(packageName), values);
-        AssetManager assets = getAssets();
-        OutputStream outputStream = null;
-        InputStream inputStream = null;
-        try {
-            inputStream = assets.open(TEST_ASSET_NAME);
-            outputStream = getContentResolver().openOutputStream(mVoicemailUri);
-            copyBetweenStreams(inputStream, outputStream);
-        } finally {
-            Closeables.closeQuietly(outputStream);
-            Closeables.closeQuietly(inputStream);
-        }
-        Uri callLogUri = ContentUris.withAppendedId(CallLog.Calls.CONTENT_URI_WITH_VOICEMAIL,
-                ContentUris.parseId(mVoicemailUri));
-        Intent intent = new Intent(Intent.ACTION_VIEW, callLogUri);
-        intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI, mVoicemailUri);
-        setActivityIntent(intent);
-    }
-
-    public void copyBetweenStreams(InputStream in, OutputStream out) throws IOException {
-        byte[] buffer = new byte[1024];
-        int bytesRead;
-        int total = 0;
-        while ((bytesRead = in.read(buffer)) != -1) {
-            total += bytesRead;
-            out.write(buffer, 0, bytesRead);
-        }
-    }
-
-    private void cleanUpUri() {
-        if (mVoicemailUri != null) {
-            getContentResolver().delete(VoicemailContract.Voicemails.CONTENT_URI,
-                    "_ID = ?", new String[] { String.valueOf(ContentUris.parseId(mVoicemailUri)) });
-            mVoicemailUri = null;
-        }
-        if (mCallLogUri != null) {
-            getContentResolver().delete(CallLog.Calls.CONTENT_URI_WITH_VOICEMAIL,
-                    "_ID = ?", new String[] { String.valueOf(ContentUris.parseId(mCallLogUri)) });
-            mCallLogUri = null;
-        }
-    }
-
-    private ContentResolver getContentResolver() {
-        return getInstrumentation().getTargetContext().getContentResolver();
-    }
-
-    private TextView assertHasOneTextViewContaining(String text) throws Throwable {
-        assertNotNull(mActivityUnderTest);
-        List<TextView> views = mTestUtils.getTextViewsWithString(mActivityUnderTest, text);
-        assertEquals("There should have been one TextView with text '" + text + "' but found "
-                + views, 1, views.size());
-        return views.get(0);
-    }
-
-    private void assertZeroTextViewsContaining(String text) throws Throwable {
-        assertNotNull(mActivityUnderTest);
-        List<TextView> views = mTestUtils.getTextViewsWithString(mActivityUnderTest, text);
-        assertEquals("There should have been no TextViews with text '" + text + "' but found "
-                + views, 0,  views.size());
-    }
-
-    private void startActivityUnderTest() throws Throwable {
-        assertNull(mActivityUnderTest);
-        mActivityUnderTest = getActivity();
-        assertNotNull("activity should not be null", mActivityUnderTest);
-        // We have to run all tasks, not just one.
-        // This is because it seems that we can have onResume, onPause, onResume during the course
-        // of a single unit test.
-        mFakeAsyncTaskExecutor.runAllTasks(UPDATE_PHONE_CALL_DETAILS);
-    }
-
-    private AssetManager getAssets() {
-        return getInstrumentation().getContext().getAssets();
-    }
-}
diff --git a/tests/src/com/android/contacts/DialerLaunchPerformance.java b/tests/src/com/android/contacts/DialerLaunchPerformance.java
deleted file mode 100644
index 0803c6b..0000000
--- a/tests/src/com/android/contacts/DialerLaunchPerformance.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2007 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.
- */
-
-package com.android.contacts;
-
-import android.app.Activity;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.os.Bundle;
-import android.test.LaunchPerformanceBase;
-
-/**
- * Instrumentation class for Address Book launch performance testing.
- */
-public class DialerLaunchPerformance extends LaunchPerformanceBase {
-
-    @Override
-    public void onCreate(Bundle arguments) {
-        mIntent.setAction(Intent.ACTION_MAIN);
-        mIntent.addCategory(Intent.CATEGORY_LAUNCHER);
-        mIntent.setComponent(new ComponentName("com.android.contacts",
-                "com.android.contacts.activities.DialtactsActivity"));
-
-        start();
-    }
-
-    /**
-     * Calls LaunchApp and finish.
-     */
-    @Override
-    public void onStart() {
-        super.onStart();
-        LaunchApp();
-        finish(Activity.RESULT_OK, mResults);
-    }
-}
diff --git a/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java b/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
deleted file mode 100644
index b852b58..0000000
--- a/tests/src/com/android/contacts/PhoneCallDetailsHelperTest.java
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Copyright (C) 2010 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.
- */
-
-package com.android.contacts;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.provider.CallLog.Calls;
-import android.test.AndroidTestCase;
-import android.text.Html;
-import android.text.Spanned;
-import android.view.View;
-import android.widget.TextView;
-
-import com.android.contacts.calllog.CallTypeHelper;
-import com.android.contacts.calllog.PhoneNumberHelper;
-import com.android.contacts.calllog.TestPhoneNumberHelper;
-import com.android.contacts.util.LocaleTestUtils;
-import com.android.internal.telephony.CallerInfo;
-
-import java.util.GregorianCalendar;
-import java.util.Locale;
-
-/**
- * Unit tests for {@link PhoneCallDetailsHelper}.
- */
-public class PhoneCallDetailsHelperTest extends AndroidTestCase {
-    /** The number to be used to access the voicemail. */
-    private static final String TEST_VOICEMAIL_NUMBER = "125";
-    /** The date of the call log entry. */
-    private static final long TEST_DATE =
-        new GregorianCalendar(2011, 5, 3, 13, 0, 0).getTimeInMillis();
-    /** A test duration value for phone calls. */
-    private static final long TEST_DURATION = 62300;
-    /** The number of the caller/callee in the log entry. */
-    private static final String TEST_NUMBER = "14125555555";
-    /** The formatted version of {@link #TEST_NUMBER}. */
-    private static final String TEST_FORMATTED_NUMBER = "1-412-255-5555";
-    /** The country ISO name used in the tests. */
-    private static final String TEST_COUNTRY_ISO = "US";
-    /** The geocoded location used in the tests. */
-    private static final String TEST_GEOCODE = "United States";
-
-    /** The object under test. */
-    private PhoneCallDetailsHelper mHelper;
-    /** The views to fill. */
-    private PhoneCallDetailsViews mViews;
-    private TextView mNameView;
-    private PhoneNumberHelper mPhoneNumberHelper;
-    private LocaleTestUtils mLocaleTestUtils;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        Context context = getContext();
-        Resources resources = context.getResources();
-        CallTypeHelper callTypeHelper = new CallTypeHelper(resources);
-        mPhoneNumberHelper = new TestPhoneNumberHelper(resources, TEST_VOICEMAIL_NUMBER);
-        mHelper = new PhoneCallDetailsHelper(resources, callTypeHelper, mPhoneNumberHelper);
-        mHelper.setCurrentTimeForTest(
-                new GregorianCalendar(2011, 5, 4, 13, 0, 0).getTimeInMillis());
-        mViews = PhoneCallDetailsViews.createForTest(context);
-        mNameView = new TextView(context);
-        mLocaleTestUtils = new LocaleTestUtils(getContext());
-        mLocaleTestUtils.setLocale(Locale.US);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mLocaleTestUtils.restoreLocale();
-        mNameView = null;
-        mViews = null;
-        mHelper = null;
-        mPhoneNumberHelper = null;
-        super.tearDown();
-    }
-
-    public void testSetPhoneCallDetails_Unknown() {
-        setPhoneCallDetailsWithNumber(CallerInfo.UNKNOWN_NUMBER, CallerInfo.UNKNOWN_NUMBER);
-        assertNameEqualsResource(R.string.unknown);
-    }
-
-    public void testSetPhoneCallDetails_Private() {
-        setPhoneCallDetailsWithNumber(CallerInfo.PRIVATE_NUMBER, CallerInfo.PRIVATE_NUMBER);
-        assertNameEqualsResource(R.string.private_num);
-    }
-
-    public void testSetPhoneCallDetails_Payphone() {
-        setPhoneCallDetailsWithNumber(CallerInfo.PAYPHONE_NUMBER, CallerInfo.PAYPHONE_NUMBER);
-        assertNameEqualsResource(R.string.payphone);
-    }
-
-    public void testSetPhoneCallDetails_Voicemail() {
-        setPhoneCallDetailsWithNumber(TEST_VOICEMAIL_NUMBER, TEST_VOICEMAIL_NUMBER);
-        assertNameEqualsResource(R.string.voicemail);
-    }
-
-    public void testSetPhoneCallDetails_Normal() {
-        setPhoneCallDetailsWithNumber("14125551212", "1-412-555-1212");
-        assertEquals("yesterday", mViews.callTypeAndDate.getText().toString());
-        assertEqualsHtml("<font color='#33b5e5'><b>yesterday</b></font>",
-                mViews.callTypeAndDate.getText());
-    }
-
-    /** Asserts that a char sequence is actually a Spanned corresponding to the expected HTML. */
-    private void assertEqualsHtml(String expectedHtml, CharSequence actualText) {
-        // In order to contain HTML, the text should actually be a Spanned.
-        assertTrue(actualText instanceof Spanned);
-        Spanned actualSpanned = (Spanned) actualText;
-        // Convert from and to HTML to take care of alternative formatting of HTML.
-        assertEquals(Html.toHtml(Html.fromHtml(expectedHtml)), Html.toHtml(actualSpanned));
-
-    }
-
-    public void testSetPhoneCallDetails_Date() {
-        mHelper.setCurrentTimeForTest(
-                new GregorianCalendar(2011, 5, 3, 13, 0, 0).getTimeInMillis());
-
-        setPhoneCallDetailsWithDate(
-                new GregorianCalendar(2011, 5, 3, 13, 0, 0).getTimeInMillis());
-        assertDateEquals("0 mins ago");
-
-        setPhoneCallDetailsWithDate(
-                new GregorianCalendar(2011, 5, 3, 12, 0, 0).getTimeInMillis());
-        assertDateEquals("1 hour ago");
-
-        setPhoneCallDetailsWithDate(
-                new GregorianCalendar(2011, 5, 2, 13, 0, 0).getTimeInMillis());
-        assertDateEquals("yesterday");
-
-        setPhoneCallDetailsWithDate(
-                new GregorianCalendar(2011, 5, 1, 13, 0, 0).getTimeInMillis());
-        assertDateEquals("2 days ago");
-    }
-
-    public void testSetPhoneCallDetails_CallTypeIcons() {
-        setPhoneCallDetailsWithCallTypeIcons(Calls.INCOMING_TYPE);
-        assertCallTypeIconsEquals(Calls.INCOMING_TYPE);
-
-        setPhoneCallDetailsWithCallTypeIcons(Calls.OUTGOING_TYPE);
-        assertCallTypeIconsEquals(Calls.OUTGOING_TYPE);
-
-        setPhoneCallDetailsWithCallTypeIcons(Calls.MISSED_TYPE);
-        assertCallTypeIconsEquals(Calls.MISSED_TYPE);
-
-        setPhoneCallDetailsWithCallTypeIcons(Calls.VOICEMAIL_TYPE);
-        assertCallTypeIconsEquals(Calls.VOICEMAIL_TYPE);
-    }
-
-    public void testSetPhoneCallDetails_MultipleCallTypeIcons() {
-        setPhoneCallDetailsWithCallTypeIcons(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
-        assertCallTypeIconsEquals(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
-
-        setPhoneCallDetailsWithCallTypeIcons(Calls.MISSED_TYPE, Calls.MISSED_TYPE);
-        assertCallTypeIconsEquals(Calls.MISSED_TYPE, Calls.MISSED_TYPE);
-    }
-
-    public void testSetPhoneCallDetails_MultipleCallTypeIconsLastOneDropped() {
-        setPhoneCallDetailsWithCallTypeIcons(Calls.MISSED_TYPE, Calls.MISSED_TYPE,
-                Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
-        assertCallTypeIconsEqualsPlusOverflow("(4)",
-                Calls.MISSED_TYPE, Calls.MISSED_TYPE, Calls.INCOMING_TYPE);
-    }
-
-    public void testSetPhoneCallDetails_Geocode() {
-        setPhoneCallDetailsWithNumberAndGeocode("+14125555555", "1-412-555-5555", "Pennsylvania");
-        assertNameEquals("1-412-555-5555");  // The phone number is shown as the name.
-        assertNumberEquals("Pennsylvania");  // The geocode is shown as the number.
-    }
-
-    public void testSetPhoneCallDetails_NoGeocode() {
-        setPhoneCallDetailsWithNumberAndGeocode("+14125555555", "1-412-555-5555", null);
-        assertNameEquals("1-412-555-5555");  // The phone number is shown as the name.
-        assertNumberEquals("-");  // The empty geocode is shown as the number.
-    }
-
-    public void testSetPhoneCallDetails_EmptyGeocode() {
-        setPhoneCallDetailsWithNumberAndGeocode("+14125555555", "1-412-555-5555", "");
-        assertNameEquals("1-412-555-5555");  // The phone number is shown as the name.
-        assertNumberEquals("-");  // The empty geocode is shown as the number.
-    }
-
-    public void testSetPhoneCallDetails_NoGeocodeForVoicemail() {
-        setPhoneCallDetailsWithNumberAndGeocode(TEST_VOICEMAIL_NUMBER, "", "United States");
-        assertNumberEquals("-");  // The empty geocode is shown as the number.
-    }
-
-    public void testSetPhoneCallDetails_Highlighted() {
-        setPhoneCallDetailsWithNumber(TEST_VOICEMAIL_NUMBER, "");
-    }
-
-    public void testSetCallDetailsHeader_NumberOnly() {
-        setCallDetailsHeaderWithNumberOnly(TEST_NUMBER);
-        assertEquals(View.VISIBLE, mNameView.getVisibility());
-        assertEquals("Add to contacts", mNameView.getText().toString());
-    }
-
-    public void testSetCallDetailsHeader_UnknownNumber() {
-        setCallDetailsHeaderWithNumberOnly(CallerInfo.UNKNOWN_NUMBER);
-        assertEquals(View.VISIBLE, mNameView.getVisibility());
-        assertEquals("Unknown", mNameView.getText().toString());
-    }
-
-    public void testSetCallDetailsHeader_PrivateNumber() {
-        setCallDetailsHeaderWithNumberOnly(CallerInfo.PRIVATE_NUMBER);
-        assertEquals(View.VISIBLE, mNameView.getVisibility());
-        assertEquals("Private number", mNameView.getText().toString());
-    }
-
-    public void testSetCallDetailsHeader_PayphoneNumber() {
-        setCallDetailsHeaderWithNumberOnly(CallerInfo.PAYPHONE_NUMBER);
-        assertEquals(View.VISIBLE, mNameView.getVisibility());
-        assertEquals("Pay phone", mNameView.getText().toString());
-    }
-
-    public void testSetCallDetailsHeader_VoicemailNumber() {
-        setCallDetailsHeaderWithNumberOnly(TEST_VOICEMAIL_NUMBER);
-        assertEquals(View.VISIBLE, mNameView.getVisibility());
-        assertEquals("Voicemail", mNameView.getText().toString());
-    }
-
-    public void testSetCallDetailsHeader() {
-        setCallDetailsHeader("John Doe");
-        assertEquals(View.VISIBLE, mNameView.getVisibility());
-        assertEquals("John Doe", mNameView.getText().toString());
-    }
-
-    /** Asserts that the name text field contains the value of the given string resource. */
-    private void assertNameEqualsResource(int resId) {
-        assertNameEquals(getContext().getString(resId));
-    }
-
-    /** Asserts that the name text field contains the given string value. */
-    private void assertNameEquals(String text) {
-        assertEquals(text, mViews.nameView.getText().toString());
-    }
-
-    /** Asserts that the number text field contains the given string value. */
-    private void assertNumberEquals(String text) {
-        assertEquals(text, mViews.numberView.getText().toString());
-    }
-
-    /** Asserts that the date text field contains the given string value. */
-    private void assertDateEquals(String text) {
-        assertEquals(text, mViews.callTypeAndDate.getText().toString());
-    }
-
-    /** Asserts that the call type contains the images with the given drawables. */
-    private void assertCallTypeIconsEquals(int... ids) {
-        assertEquals(ids.length, mViews.callTypeIcons.getCount());
-        for (int index = 0; index < ids.length; ++index) {
-            int id = ids[index];
-            assertEquals(id, mViews.callTypeIcons.getCallType(index));
-        }
-        assertEquals(View.VISIBLE, mViews.callTypeIcons.getVisibility());
-        assertEquals("yesterday", mViews.callTypeAndDate.getText().toString());
-    }
-
-    /**
-     * Asserts that the call type contains the images with the given drawables and shows the given
-     * text next to the icons.
-     */
-    private void assertCallTypeIconsEqualsPlusOverflow(String overflowText, int... ids) {
-        assertEquals(ids.length, mViews.callTypeIcons.getCount());
-        for (int index = 0; index < ids.length; ++index) {
-            int id = ids[index];
-            assertEquals(id, mViews.callTypeIcons.getCallType(index));
-        }
-        assertEquals(View.VISIBLE, mViews.callTypeIcons.getVisibility());
-        assertEquals(overflowText + " yesterday", mViews.callTypeAndDate.getText().toString());
-    }
-
-    /** Sets the phone call details with default values and the given number. */
-    private void setPhoneCallDetailsWithNumber(String number, String formattedNumber) {
-        setPhoneCallDetailsWithNumberAndGeocode(number, formattedNumber, TEST_GEOCODE);
-    }
-
-    /** Sets the phone call details with default values and the given number. */
-    private void setPhoneCallDetailsWithNumberAndGeocode(String number, String formattedNumber,
-            String geocodedLocation) {
-        mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(number, formattedNumber, TEST_COUNTRY_ISO, geocodedLocation,
-                        new int[]{ Calls.VOICEMAIL_TYPE }, TEST_DATE, TEST_DURATION),
-                true);
-    }
-
-    /** Sets the phone call details with default values and the given date. */
-    private void setPhoneCallDetailsWithDate(long date) {
-        mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
-                        TEST_GEOCODE, new int[]{ Calls.INCOMING_TYPE }, date, TEST_DURATION),
-                false);
-    }
-
-    /** Sets the phone call details with default values and the given call types using icons. */
-    private void setPhoneCallDetailsWithCallTypeIcons(int... callTypes) {
-        mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
-                        TEST_GEOCODE, callTypes, TEST_DATE, TEST_DURATION),
-                false);
-    }
-
-    private void setCallDetailsHeaderWithNumberOnly(String number) {
-        mHelper.setCallDetailsHeader(mNameView,
-                new PhoneCallDetails(number, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
-                        TEST_GEOCODE, new int[]{ Calls.INCOMING_TYPE }, TEST_DATE, TEST_DURATION));
-    }
-
-    private void setCallDetailsHeader(String name) {
-        mHelper.setCallDetailsHeader(mNameView,
-                new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
-                        TEST_GEOCODE, new int[]{ Calls.INCOMING_TYPE }, TEST_DATE, TEST_DURATION,
-                        name, 0, "", null, null));
-    }
-}
diff --git a/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java b/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java
deleted file mode 100644
index 5bc31f9..0000000
--- a/tests/src/com/android/contacts/calllog/CallLogAdapterTest.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.contacts.calllog;
-
-import android.content.Context;
-import android.database.MatrixCursor;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.view.View;
-
-import com.google.common.collect.Lists;
-
-import java.util.List;
-
-/**
- * Unit tests for {@link CallLogAdapter}.
- */
-@SmallTest
-public class CallLogAdapterTest extends AndroidTestCase {
-    private static final String TEST_NUMBER = "12345678";
-    private static final String TEST_NAME = "name";
-    private static final String TEST_NUMBER_LABEL = "label";
-    private static final int TEST_NUMBER_TYPE = 1;
-    private static final String TEST_COUNTRY_ISO = "US";
-
-    /** The object under test. */
-    private TestCallLogAdapter mAdapter;
-
-    private MatrixCursor mCursor;
-    private View mView;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // Use a call fetcher that does not do anything.
-        CallLogAdapter.CallFetcher fakeCallFetcher = new CallLogAdapter.CallFetcher() {
-            @Override
-            public void fetchCalls() {}
-        };
-
-        ContactInfoHelper fakeContactInfoHelper =
-                new ContactInfoHelper(getContext(), TEST_COUNTRY_ISO) {
-                    @Override
-                    public ContactInfo lookupNumber(String number, String countryIso) {
-                        ContactInfo info = new ContactInfo();
-                        info.number = number;
-                        info.formattedNumber = number;
-                        return info;
-                    }
-                };
-
-        mAdapter = new TestCallLogAdapter(getContext(), fakeCallFetcher, fakeContactInfoHelper);
-        // The cursor used in the tests to store the entries to display.
-        mCursor = new MatrixCursor(CallLogQuery.EXTENDED_PROJECTION);
-        mCursor.moveToFirst();
-        // The views into which to store the data.
-        mView = new View(getContext());
-        mView.setTag(CallLogListItemViews.createForTest(getContext()));
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mAdapter = null;
-        mCursor = null;
-        mView = null;
-        super.tearDown();
-    }
-
-    public void testBindView_NoCallLogCacheNorMemoryCache_EnqueueRequest() {
-        mCursor.addRow(createCallLogEntry());
-
-        // Bind the views of a single row.
-        mAdapter.bindStandAloneView(mView, getContext(), mCursor);
-
-        // There is one request for contact details.
-        assertEquals(1, mAdapter.requests.size());
-
-        TestCallLogAdapter.Request request = mAdapter.requests.get(0);
-        // It is for the number we need to show.
-        assertEquals(TEST_NUMBER, request.number);
-        // It has the right country.
-        assertEquals(TEST_COUNTRY_ISO, request.countryIso);
-        // Since there is nothing in the cache, it is an immediate request.
-        assertTrue("should be immediate", request.immediate);
-    }
-
-    public void testBindView_CallLogCacheButNoMemoryCache_EnqueueRequest() {
-        mCursor.addRow(createCallLogEntryWithCachedValues());
-
-        // Bind the views of a single row.
-        mAdapter.bindStandAloneView(mView, getContext(), mCursor);
-
-        // There is one request for contact details.
-        assertEquals(1, mAdapter.requests.size());
-
-        TestCallLogAdapter.Request request = mAdapter.requests.get(0);
-        // The values passed to the request, match the ones in the call log cache.
-        assertEquals(TEST_NAME, request.callLogInfo.name);
-        assertEquals(1, request.callLogInfo.type);
-        assertEquals(TEST_NUMBER_LABEL, request.callLogInfo.label);
-    }
-
-
-    public void testBindView_NoCallLogButMemoryCache_EnqueueRequest() {
-        mCursor.addRow(createCallLogEntry());
-        mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, createContactInfo());
-
-        // Bind the views of a single row.
-        mAdapter.bindStandAloneView(mView, getContext(), mCursor);
-
-        // There is one request for contact details.
-        assertEquals(1, mAdapter.requests.size());
-
-        TestCallLogAdapter.Request request = mAdapter.requests.get(0);
-        // Since there is something in the cache, it is not an immediate request.
-        assertFalse("should not be immediate", request.immediate);
-    }
-
-    public void testBindView_BothCallLogAndMemoryCache_NoEnqueueRequest() {
-        mCursor.addRow(createCallLogEntryWithCachedValues());
-        mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, createContactInfo());
-
-        // Bind the views of a single row.
-        mAdapter.bindStandAloneView(mView, getContext(), mCursor);
-
-        // Cache and call log are up-to-date: no need to request update.
-        assertEquals(0, mAdapter.requests.size());
-    }
-
-    public void testBindView_MismatchBetwenCallLogAndMemoryCache_EnqueueRequest() {
-        mCursor.addRow(createCallLogEntryWithCachedValues());
-
-        // Contact info contains a different name.
-        ContactInfo info = createContactInfo();
-        info.name = "new name";
-        mAdapter.injectContactInfoForTest(TEST_NUMBER, TEST_COUNTRY_ISO, info);
-
-        // Bind the views of a single row.
-        mAdapter.bindStandAloneView(mView, getContext(), mCursor);
-
-        // There is one request for contact details.
-        assertEquals(1, mAdapter.requests.size());
-
-        TestCallLogAdapter.Request request = mAdapter.requests.get(0);
-        // Since there is something in the cache, it is not an immediate request.
-        assertFalse("should not be immediate", request.immediate);
-    }
-
-    /** Returns a contact info with default values. */
-    private ContactInfo createContactInfo() {
-        ContactInfo info = new ContactInfo();
-        info.number = TEST_NUMBER;
-        info.name = TEST_NAME;
-        info.type = TEST_NUMBER_TYPE;
-        info.label = TEST_NUMBER_LABEL;
-        return info;
-    }
-
-    /** Returns a call log entry without cached values. */
-    private Object[] createCallLogEntry() {
-        Object[] values = CallLogQueryTestUtils.createTestExtendedValues();
-        values[CallLogQuery.NUMBER] = TEST_NUMBER;
-        values[CallLogQuery.COUNTRY_ISO] = TEST_COUNTRY_ISO;
-        return values;
-    }
-
-    /** Returns a call log entry with a cached values. */
-    private Object[] createCallLogEntryWithCachedValues() {
-        Object[] values = createCallLogEntry();
-        values[CallLogQuery.CACHED_NAME] = TEST_NAME;
-        values[CallLogQuery.CACHED_NUMBER_TYPE] = TEST_NUMBER_TYPE;
-        values[CallLogQuery.CACHED_NUMBER_LABEL] = TEST_NUMBER_LABEL;
-        return values;
-    }
-
-    /**
-     * Subclass of {@link CallLogAdapter} used in tests to intercept certain calls.
-     */
-    // TODO: This would be better done by splitting the contact lookup into a collaborator class
-    // instead.
-    private static final class TestCallLogAdapter extends CallLogAdapter {
-        public static class Request {
-            public final String number;
-            public final String countryIso;
-            public final ContactInfo callLogInfo;
-            public final boolean immediate;
-
-            public Request(String number, String countryIso, ContactInfo callLogInfo,
-                    boolean immediate) {
-                this.number = number;
-                this.countryIso = countryIso;
-                this.callLogInfo = callLogInfo;
-                this.immediate = immediate;
-            }
-        }
-
-        public final List<Request> requests = Lists.newArrayList();
-
-        public TestCallLogAdapter(Context context, CallFetcher callFetcher,
-                ContactInfoHelper contactInfoHelper) {
-            super(context, callFetcher, contactInfoHelper);
-        }
-
-        @Override
-        void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo,
-                boolean immediate) {
-            requests.add(new Request(number, countryIso, callLogInfo, immediate));
-        }
-    }
-}
diff --git a/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java b/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
deleted file mode 100644
index 0eaca60..0000000
--- a/tests/src/com/android/contacts/calllog/CallLogFragmentTest.java
+++ /dev/null
@@ -1,632 +0,0 @@
-/*
- * Copyright (C) 2009 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.
- */
-
-package com.android.contacts.calllog;
-
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.ComponentName;
-import android.content.ContentUris;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.MatrixCursor;
-import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
-import android.net.Uri;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.VoicemailContract;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import com.android.contacts.CallDetailActivity;
-import com.android.contacts.R;
-import com.android.contacts.test.FragmentTestActivity;
-import com.android.internal.telephony.CallerInfo;
-
-import java.util.Date;
-import java.util.Formatter;
-import java.util.HashMap;
-import java.util.Random;
-
-/**
- * Tests for the contact call list activity.
- *
- * Running all tests:
- *
- *   runtest contacts
- * or
- *   adb shell am instrument \
- *     -w com.android.contacts.tests/android.test.InstrumentationTestRunner
- */
-@LargeTest
-public class CallLogFragmentTest extends ActivityInstrumentationTestCase2<FragmentTestActivity> {
-    private static final int RAND_DURATION = -1;
-    private static final long NOW = -1L;
-
-    /** A test value for the URI of a contact. */
-    private static final Uri TEST_LOOKUP_URI = Uri.parse("content://contacts/2");
-    /** A test value for the country ISO of the phone number in the call log. */
-    private static final String TEST_COUNTRY_ISO = "US";
-    /** A phone number to be used in tests. */
-    private static final String TEST_NUMBER = "12125551000";
-    /** The formatted version of {@link #TEST_NUMBER}. */
-    private static final String TEST_FORMATTED_NUMBER = "1 212-555-1000";
-
-    /** The activity in which we are hosting the fragment. */
-    private FragmentTestActivity mActivity;
-    private CallLogFragment mFragment;
-    private FrameLayout mParentView;
-    /**
-     * The adapter used by the fragment to build the rows in the call log. We use it with our own in
-     * memory database.
-     */
-    private CallLogAdapter mAdapter;
-    private String mVoicemail;
-
-    // In memory array to hold the rows corresponding to the 'calls' table.
-    private MatrixCursor mCursor;
-    private int mIndex;  // Of the next row.
-
-    private Random mRnd;
-
-    // References to the icons bitmaps used to build the list are stored in a
-    // map mIcons. The keys to retrieve the icons are:
-    // Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE and Calls.MISSED_TYPE.
-    private HashMap<Integer, Bitmap> mCallTypeIcons;
-
-    // An item in the call list. All the methods performing checks use it.
-    private CallLogListItemViews mItem;
-    // The list of views representing the data in the DB. View are in
-    // reverse order compare to the DB.
-    private View[] mList;
-
-    public CallLogFragmentTest() {
-        super("com.android.contacts", FragmentTestActivity.class);
-        mIndex = 1;
-        mRnd = new Random();
-    }
-
-    @Override
-    public void setUp() {
-        mActivity = getActivity();
-        // Needed by the CallLogFragment.
-        mActivity.setTheme(R.style.DialtactsTheme);
-
-        // Create the fragment and load it into the activity.
-        mFragment = new CallLogFragment();
-        FragmentManager fragmentManager = mActivity.getFragmentManager();
-        FragmentTransaction transaction = fragmentManager.beginTransaction();
-        transaction.add(R.id.fragment, mFragment);
-        transaction.commit();
-        // Wait for the fragment to be loaded.
-        getInstrumentation().waitForIdleSync();
-
-        mVoicemail = TelephonyManager.getDefault().getVoiceMailNumber();
-        mAdapter = mFragment.getAdapter();
-        // Do not process requests for details during tests. This would start a background thread,
-        // which makes the tests flaky.
-        mAdapter.disableRequestProcessingForTest();
-        mAdapter.stopRequestProcessing();
-        mParentView = new FrameLayout(mActivity);
-        mCursor = new MatrixCursor(CallLogQuery.EXTENDED_PROJECTION);
-        buildIconMap();
-    }
-
-    /**
-     * Checks that the call icon is not visible for private and
-     * unknown numbers.
-     * Use 2 passes, one where new views are created and one where
-     * half of the total views are updated and the other half created.
-     */
-    @MediumTest
-    public void testCallViewIsNotVisibleForPrivateAndUnknownNumbers() {
-        final int SIZE = 100;
-        mList = new View[SIZE];
-
-        // Insert the first batch of entries.
-        mCursor.moveToFirst();
-        insertRandomEntries(SIZE / 2);
-        int startOfSecondBatch = mCursor.getPosition();
-
-        buildViewListFromDb();
-        checkCallStatus();
-
-        // Append the rest of the entries. We keep the first set of
-        // views around so they get updated and not built from
-        // scratch, this exposes some bugs that are not there when the
-        // call log is launched for the 1st time but show up when the
-        // call log gets updated afterwards.
-        mCursor.move(startOfSecondBatch);
-        insertRandomEntries(SIZE / 2);
-
-        buildViewListFromDb();
-        checkCallStatus();
-    }
-
-    @MediumTest
-    public void testCallAndGroupViews_GroupView() {
-        mCursor.moveToFirst();
-        insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
-        insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
-        insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
-        View view = mAdapter.newGroupView(getActivity(), mParentView);
-        mAdapter.bindGroupView(view, getActivity(), mCursor, 3, false);
-        assertNotNull(view.findViewById(R.id.secondary_action_icon));
-    }
-
-    @MediumTest
-    public void testCallAndGroupViews_StandAloneView() {
-        mCursor.moveToFirst();
-        insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
-        View view = mAdapter.newStandAloneView(getActivity(), mParentView);
-        mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-        assertNotNull(view.findViewById(R.id.secondary_action_icon));
-    }
-
-    @MediumTest
-    public void testCallAndGroupViews_ChildView() {
-        mCursor.moveToFirst();
-        insert(CallerInfo.PRIVATE_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
-        View view = mAdapter.newChildView(getActivity(), mParentView);
-        mAdapter.bindChildView(view, getActivity(), mCursor);
-        assertNotNull(view.findViewById(R.id.secondary_action_icon));
-    }
-
-    @MediumTest
-    public void testBindView_NumberOnlyNoCache() {
-        mCursor.moveToFirst();
-        insert(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
-        View view = mAdapter.newStandAloneView(getActivity(), mParentView);
-        mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
-        CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        assertNameIs(views, TEST_NUMBER);
-    }
-
-    @MediumTest
-    public void testBindView_NumberOnlyDbCachedFormattedNumber() {
-        mCursor.moveToFirst();
-        Object[] values = getValuesToInsert(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
-        values[CallLogQuery.CACHED_FORMATTED_NUMBER] = TEST_FORMATTED_NUMBER;
-        insertValues(values);
-        View view = mAdapter.newStandAloneView(getActivity(), mParentView);
-        mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
-        CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        assertNameIs(views, TEST_FORMATTED_NUMBER);
-    }
-
-    @MediumTest
-    public void testBindView_WithCachedName() {
-        mCursor.moveToFirst();
-        insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
-                "John Doe", Phone.TYPE_HOME, "");
-        View view = mAdapter.newStandAloneView(getActivity(), mParentView);
-        mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
-        CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        assertNameIs(views, "John Doe");
-        assertNumberAndLabelAre(views, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_HOME));
-    }
-
-    @MediumTest
-    public void testBindView_UriNumber() {
-        mCursor.moveToFirst();
-        insertWithCachedValues("sip:johndoe@gmail.com", NOW, 0, Calls.INCOMING_TYPE,
-                "John Doe", Phone.TYPE_HOME, "");
-        View view = mAdapter.newStandAloneView(getActivity(), mParentView);
-        mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
-        CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        assertNameIs(views, "John Doe");
-        assertNumberAndLabelAre(views, "sip:johndoe@gmail.com", null);
-    }
-
-    @MediumTest
-    public void testBindView_HomeLabel() {
-        mCursor.moveToFirst();
-        insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
-                "John Doe", Phone.TYPE_HOME, "");
-        View view = mAdapter.newStandAloneView(getActivity(), mParentView);
-        mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
-        CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        assertNameIs(views, "John Doe");
-        assertNumberAndLabelAre(views, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_HOME));
-    }
-
-    @MediumTest
-    public void testBindView_WorkLabel() {
-        mCursor.moveToFirst();
-        insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
-                "John Doe", Phone.TYPE_WORK, "");
-        View view = mAdapter.newStandAloneView(getActivity(), mParentView);
-        mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
-        CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        assertNameIs(views, "John Doe");
-        assertNumberAndLabelAre(views, TEST_FORMATTED_NUMBER, getTypeLabel(Phone.TYPE_WORK));
-    }
-
-    @MediumTest
-    public void testBindView_CustomLabel() {
-        mCursor.moveToFirst();
-        String numberLabel = "My label";
-        insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
-                "John Doe", Phone.TYPE_CUSTOM, numberLabel);
-        View view = mAdapter.newStandAloneView(getActivity(), mParentView);
-        mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
-        CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        assertNameIs(views, "John Doe");
-        assertNumberAndLabelAre(views, TEST_FORMATTED_NUMBER, numberLabel);
-    }
-
-    @MediumTest
-    public void testBindView_WithQuickContactBadge() {
-        mCursor.moveToFirst();
-        insertWithCachedValues(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE,
-                "John Doe", Phone.TYPE_HOME, "");
-        View view = mAdapter.newStandAloneView(getActivity(), mParentView);
-        mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
-        CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        assertTrue(views.quickContactView.isEnabled());
-    }
-
-    @MediumTest
-    public void testBindView_WithoutQuickContactBadge() {
-        mCursor.moveToFirst();
-        insert(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
-        View view = mAdapter.newStandAloneView(getActivity(), mParentView);
-        mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
-        CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        assertFalse(views.quickContactView.isEnabled());
-    }
-
-    @MediumTest
-    public void testBindView_CallButton() {
-        mCursor.moveToFirst();
-        insert(TEST_NUMBER, NOW, 0, Calls.INCOMING_TYPE);
-        View view = mAdapter.newStandAloneView(getActivity(), mParentView);
-        mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
-        CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        IntentProvider intentProvider = (IntentProvider) views.secondaryActionView.getTag();
-        Intent intent = intentProvider.getIntent(mActivity);
-        // Starts a call.
-        assertEquals(Intent.ACTION_CALL_PRIVILEGED, intent.getAction());
-        // To the entry's number.
-        assertEquals(Uri.parse("tel:" + TEST_NUMBER), intent.getData());
-    }
-
-    @MediumTest
-    public void testBindView_PlayButton() {
-        mCursor.moveToFirst();
-        insertVoicemail(TEST_NUMBER, NOW, 0);
-        View view = mAdapter.newStandAloneView(getActivity(), mParentView);
-        mAdapter.bindStandAloneView(view, getActivity(), mCursor);
-
-        CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        IntentProvider intentProvider = (IntentProvider) views.secondaryActionView.getTag();
-        Intent intent = intentProvider.getIntent(mActivity);
-        // Starts the call detail activity.
-        assertEquals(new ComponentName(mActivity, CallDetailActivity.class),
-                intent.getComponent());
-        // With the given entry.
-        assertEquals(ContentUris.withAppendedId(Calls.CONTENT_URI_WITH_VOICEMAIL, 1),
-                intent.getData());
-        // With the URI of the voicemail.
-        assertEquals(
-                ContentUris.withAppendedId(VoicemailContract.Voicemails.CONTENT_URI, 1),
-                intent.getParcelableExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI));
-        // And starts playback.
-        assertTrue(
-                intent.getBooleanExtra(CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK, false));
-    }
-
-    /** Returns the label associated with a given phone type. */
-    private CharSequence getTypeLabel(int phoneType) {
-        return Phone.getTypeLabel(getActivity().getResources(), phoneType, "");
-    }
-
-    //
-    // HELPERS to check conditions on the DB/views
-    //
-    /**
-     * Go over all the views in the list and check that the Call
-     * icon's visibility matches the nature of the number.
-     */
-    private void checkCallStatus() {
-        for (int i = 0; i < mList.length; i++) {
-            if (null == mList[i]) {
-                break;
-            }
-            mItem = (CallLogListItemViews) mList[i].getTag();
-            String number = getPhoneNumberForListEntry(i);
-            if (CallerInfo.PRIVATE_NUMBER.equals(number) ||
-                CallerInfo.UNKNOWN_NUMBER.equals(number)) {
-                assertFalse(View.VISIBLE == mItem.secondaryActionView.getVisibility());
-            } else {
-                assertEquals(View.VISIBLE, mItem.secondaryActionView.getVisibility());
-            }
-        }
-    }
-
-
-    //
-    // HELPERS to setup the tests.
-    //
-
-    /**
-     * Get the Bitmap from the icons in the contacts package.
-     */
-    private Bitmap getBitmap(String resName) {
-        Resources r = mActivity.getResources();
-        int resid = r.getIdentifier(resName, "drawable", "com.android.contacts");
-        BitmapDrawable d = (BitmapDrawable) r.getDrawable(resid);
-        assertNotNull(d);
-        return d.getBitmap();
-    }
-
-    /**
-     * Fetch all the icons we need in tests from the contacts app and store them in a map.
-     */
-    private void buildIconMap() {
-        mCallTypeIcons = new HashMap<Integer, Bitmap>(3);
-
-        mCallTypeIcons.put(Calls.INCOMING_TYPE, getBitmap("ic_call_incoming_holo_dark"));
-        mCallTypeIcons.put(Calls.MISSED_TYPE, getBitmap("ic_call_missed_holo_dark"));
-        mCallTypeIcons.put(Calls.OUTGOING_TYPE, getBitmap("ic_call_outgoing_holo_dark"));
-    }
-
-    //
-    // HELPERS to build/update the call entries (views) from the DB.
-    //
-
-    /**
-     * Read the DB and foreach call either update the existing view if
-     * one exists already otherwise create one.
-     * The list is build from a DESC view of the DB (last inserted entry is first).
-     */
-    private void buildViewListFromDb() {
-        int i = 0;
-        mCursor.moveToLast();
-        while(!mCursor.isBeforeFirst()) {
-            if (null == mList[i]) {
-                mList[i] = mAdapter.newStandAloneView(mActivity, mParentView);
-            }
-            mAdapter.bindStandAloneView(mList[i], mActivity, mCursor);
-            mCursor.moveToPrevious();
-            i++;
-        }
-    }
-
-    /** Returns the number associated with the given entry in {{@link #mList}. */
-    private String getPhoneNumberForListEntry(int index) {
-        // The entries are added backward, so count from the end of the cursor.
-        mCursor.moveToPosition(mCursor.getCount() - index - 1);
-        return mCursor.getString(CallLogQuery.NUMBER);
-    }
-
-    //
-    // HELPERS to insert numbers in the call log DB.
-    //
-
-    /**
-     * Insert a certain number of random numbers in the DB. Makes sure
-     * there is at least one private and one unknown number in the DB.
-     * @param num Of entries to be inserted.
-     */
-    private void insertRandomEntries(int num) {
-        if (num < 10) {
-            throw new IllegalArgumentException("num should be >= 10");
-        }
-        boolean privateOrUnknownOrVm[];
-        privateOrUnknownOrVm = insertRandomRange(0, num - 2);
-
-        if (privateOrUnknownOrVm[0] && privateOrUnknownOrVm[1]) {
-            insertRandomRange(num - 2, num);
-        } else {
-            insertPrivate(NOW, RAND_DURATION);
-            insertUnknown(NOW, RAND_DURATION);
-        }
-    }
-
-    /**
-     * Insert a new call entry in the test DB.
-     *
-     * It includes the values for the cached contact associated with the number.
-     *
-     * @param number The phone number. For unknown and private numbers,
-     *               use CallerInfo.UNKNOWN_NUMBER or CallerInfo.PRIVATE_NUMBER.
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE.
-     * @param cachedName the name of the contact with this number
-     * @param cachedNumberType the type of the number, from the contact with this number
-     * @param cachedNumberLabel the label of the number, from the contact with this number
-     */
-    private void insertWithCachedValues(String number, long date, int duration, int type,
-            String cachedName, int cachedNumberType, String cachedNumberLabel) {
-        insert(number, date, duration, type);
-        ContactInfo contactInfo = new ContactInfo();
-        contactInfo.lookupUri = TEST_LOOKUP_URI;
-        contactInfo.name = cachedName;
-        contactInfo.type = cachedNumberType;
-        contactInfo.label = cachedNumberLabel;
-        String formattedNumber = PhoneNumberUtils.formatNumber(number, TEST_COUNTRY_ISO);
-        if (formattedNumber == null) {
-            formattedNumber = number;
-        }
-        contactInfo.formattedNumber = formattedNumber;
-        contactInfo.normalizedNumber = number;
-        contactInfo.photoId = 0;
-        mAdapter.injectContactInfoForTest(number, TEST_COUNTRY_ISO, contactInfo);
-    }
-
-    /**
-     * Insert a new call entry in the test DB.
-     * @param number The phone number. For unknown and private numbers,
-     *               use CallerInfo.UNKNOWN_NUMBER or CallerInfo.PRIVATE_NUMBER.
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE.
-     */
-    private void insert(String number, long date, int duration, int type) {
-        insertValues(getValuesToInsert(number, date, duration, type));
-    }
-
-    /** Inserts the given values in the cursor. */
-    private void insertValues(Object[] values) {
-        mCursor.addRow(values);
-        ++mIndex;
-    }
-
-    /**
-     * Returns the values for a new call entry.
-     *
-     * @param number The phone number. For unknown and private numbers,
-     *               use CallerInfo.UNKNOWN_NUMBER or CallerInfo.PRIVATE_NUMBER.
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     * @param type Either Call.OUTGOING_TYPE or Call.INCOMING_TYPE or Call.MISSED_TYPE.
-     */
-    private Object[] getValuesToInsert(String number, long date, int duration, int type) {
-        Object[] values = CallLogQueryTestUtils.createTestExtendedValues();
-        values[CallLogQuery.ID] = mIndex;
-        values[CallLogQuery.NUMBER] = number;
-        values[CallLogQuery.DATE] = date == NOW ? new Date().getTime() : date;
-        values[CallLogQuery.DURATION] = duration < 0 ? mRnd.nextInt(10 * 60) : duration;
-        if (mVoicemail != null && mVoicemail.equals(number)) {
-            assertEquals(Calls.OUTGOING_TYPE, type);
-        }
-        values[CallLogQuery.CALL_TYPE] = type;
-        values[CallLogQuery.COUNTRY_ISO] = TEST_COUNTRY_ISO;
-        values[CallLogQuery.SECTION] = CallLogQuery.SECTION_OLD_ITEM;
-        return values;
-    }
-
-    /**
-     * Insert a new voicemail entry in the test DB.
-     * @param number The phone number. For unknown and private numbers,
-     *               use CallerInfo.UNKNOWN_NUMBER or CallerInfo.PRIVATE_NUMBER.
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     */
-    private void insertVoicemail(String number, long date, int duration) {
-        Object[] values = getValuesToInsert(number, date, duration, Calls.VOICEMAIL_TYPE);
-        // Must have the same index as the row.
-        values[CallLogQuery.VOICEMAIL_URI] =
-                ContentUris.withAppendedId(VoicemailContract.Voicemails.CONTENT_URI, mIndex);
-        insertValues(values);
-    }
-
-    /**
-     * Insert a new private call entry in the test DB.
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     */
-    private void insertPrivate(long date, int duration) {
-        insert(CallerInfo.PRIVATE_NUMBER, date, duration, Calls.INCOMING_TYPE);
-    }
-
-    /**
-     * Insert a new unknown call entry in the test DB.
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     */
-    private void insertUnknown(long date, int duration) {
-        insert(CallerInfo.UNKNOWN_NUMBER, date, duration, Calls.INCOMING_TYPE);
-    }
-
-    /**
-     * Insert a new call to voicemail entry in the test DB.
-     * @param date In millisec since epoch. Use NOW to use the current time.
-     * @param duration In seconds of the call. Use RAND_DURATION to pick a random one.
-     */
-    private void insertCalltoVoicemail(long date, int duration) {
-        // mVoicemail may be null
-        if (mVoicemail != null) {
-            insert(mVoicemail, date, duration, Calls.OUTGOING_TYPE);
-        }
-    }
-
-    /**
-     * Insert a range [start, end) of random numbers in the DB. For
-     * each row, there is a 1/10 probability that the number will be
-     * marked as PRIVATE or UNKNOWN or VOICEMAIL. For regular numbers, a number is
-     * inserted, its last 4 digits will be the number of the iteration
-     * in the range.
-     * @param start Of the range.
-     * @param end Of the range (excluded).
-     * @return An array with 2 booleans [0 = private number, 1 =
-     * unknown number, 2 = voicemail] to indicate if at least one
-     * private or unknown or voicemail number has been inserted. Since
-     * the numbers are random some tests may want to enforce the
-     * insertion of such numbers.
-     */
-    // TODO: Should insert numbers with contact entries too.
-    private boolean[] insertRandomRange(int start, int end) {
-        boolean[] privateOrUnknownOrVm = new boolean[] {false, false, false};
-
-        for (int i = start; i < end; i++ ) {
-            int type = mRnd.nextInt(10);
-
-            if (0 == type) {
-                insertPrivate(NOW, RAND_DURATION);
-                privateOrUnknownOrVm[0] = true;
-            } else if (1 == type) {
-                insertUnknown(NOW, RAND_DURATION);
-                privateOrUnknownOrVm[1] = true;
-            } else if (2 == type) {
-                insertCalltoVoicemail(NOW, RAND_DURATION);
-                privateOrUnknownOrVm[2] = true;
-            } else {
-                int inout = mRnd.nextBoolean() ? Calls.OUTGOING_TYPE :  Calls.INCOMING_TYPE;
-                String number = new Formatter().format("1800123%04d", i).toString();
-                insert(number, NOW, RAND_DURATION, inout);
-            }
-        }
-        return privateOrUnknownOrVm;
-    }
-
-    /** Asserts that the name text view is shown and contains the given text. */
-    private void assertNameIs(CallLogListItemViews views, String name) {
-        assertEquals(View.VISIBLE, views.phoneCallDetailsViews.nameView.getVisibility());
-        assertEquals(name, views.phoneCallDetailsViews.nameView.getText());
-    }
-
-    /** Asserts that the number and label text view contains the given text. */
-    private void assertNumberAndLabelAre(CallLogListItemViews views, CharSequence number,
-            CharSequence label) {
-        assertEquals(View.VISIBLE, views.phoneCallDetailsViews.numberView.getVisibility());
-        assertEquals(number, views.phoneCallDetailsViews.numberView.getText().toString());
-
-        assertEquals(label == null ? View.GONE : View.VISIBLE,
-                views.phoneCallDetailsViews.labelView.getVisibility());
-        if (label != null) {
-            assertEquals(label, views.phoneCallDetailsViews.labelView.getText().toString());
-        }
-    }
-}
diff --git a/tests/src/com/android/contacts/calllog/CallLogGroupBuilderTest.java b/tests/src/com/android/contacts/calllog/CallLogGroupBuilderTest.java
deleted file mode 100644
index 1fced0b..0000000
--- a/tests/src/com/android/contacts/calllog/CallLogGroupBuilderTest.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.contacts.calllog;
-
-import static com.google.common.collect.Lists.newArrayList;
-
-import android.database.MatrixCursor;
-import android.provider.CallLog.Calls;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import java.util.List;
-
-/**
- * Unit tests for {@link CallLogGroupBuilder}
- */
-@SmallTest
-public class CallLogGroupBuilderTest extends AndroidTestCase {
-    /** A phone number for testing. */
-    private static final String TEST_NUMBER1 = "14125551234";
-    /** A phone number for testing. */
-    private static final String TEST_NUMBER2 = "14125555555";
-
-    /** The object under test. */
-    private CallLogGroupBuilder mBuilder;
-    /** Records the created groups. */
-    private FakeGroupCreator mFakeGroupCreator;
-    /** Cursor to store the values. */
-    private MatrixCursor mCursor;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mFakeGroupCreator = new FakeGroupCreator();
-        mBuilder = new CallLogGroupBuilder(mFakeGroupCreator);
-        createCursor();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mCursor = null;
-        mBuilder = null;
-        mFakeGroupCreator = null;
-        super.tearDown();
-    }
-
-    public void testAddGroups_NoCalls() {
-        mBuilder.addGroups(mCursor);
-        assertEquals(0, mFakeGroupCreator.groups.size());
-    }
-
-    public void testAddGroups_OneCall() {
-        addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
-        mBuilder.addGroups(mCursor);
-        assertEquals(0, mFakeGroupCreator.groups.size());
-    }
-
-    public void testAddGroups_TwoCallsNotMatching() {
-        addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
-        addOldCallLogEntry(TEST_NUMBER2, Calls.INCOMING_TYPE);
-        mBuilder.addGroups(mCursor);
-        assertEquals(0, mFakeGroupCreator.groups.size());
-    }
-
-    public void testAddGroups_ThreeCallsMatching() {
-        addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
-        addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
-        addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
-        mBuilder.addGroups(mCursor);
-        assertEquals(1, mFakeGroupCreator.groups.size());
-        assertGroupIs(0, 3, false, mFakeGroupCreator.groups.get(0));
-    }
-
-    public void testAddGroups_MatchingIncomingAndOutgoing() {
-        addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
-        addOldCallLogEntry(TEST_NUMBER1, Calls.OUTGOING_TYPE);
-        addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
-        mBuilder.addGroups(mCursor);
-        assertEquals(1, mFakeGroupCreator.groups.size());
-        assertGroupIs(0, 3, false, mFakeGroupCreator.groups.get(0));
-    }
-
-    public void testAddGroups_HeaderSplitsGroups() {
-        addNewCallLogHeader();
-        addNewCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
-        addNewCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
-        addOldCallLogHeader();
-        addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
-        addOldCallLogEntry(TEST_NUMBER1, Calls.INCOMING_TYPE);
-        mBuilder.addGroups(mCursor);
-        assertEquals(2, mFakeGroupCreator.groups.size());
-        assertGroupIs(1, 2, false, mFakeGroupCreator.groups.get(0));
-        assertGroupIs(4, 2, false, mFakeGroupCreator.groups.get(1));
-    }
-
-    public void testAddGroups_Voicemail() {
-        // Does not group with other types of calls, include voicemail themselves.
-        assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE);
-        //assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.MISSED_TYPE, Calls.MISSED_TYPE);
-        assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.VOICEMAIL_TYPE);
-        assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.INCOMING_TYPE);
-        assertCallsAreNotGrouped(Calls.VOICEMAIL_TYPE, Calls.OUTGOING_TYPE);
-    }
-
-    public void testAddGroups_Missed() {
-        // Groups with one or more missed calls.
-        assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.MISSED_TYPE);
-        assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.MISSED_TYPE, Calls.MISSED_TYPE);
-        // Does not group with other types of calls.
-        assertCallsAreNotGrouped(Calls.MISSED_TYPE, Calls.VOICEMAIL_TYPE);
-        assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.INCOMING_TYPE);
-        assertCallsAreGrouped(Calls.MISSED_TYPE, Calls.OUTGOING_TYPE);
-    }
-
-    public void testAddGroups_Incoming() {
-        // Groups with one or more incoming or outgoing.
-        assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.INCOMING_TYPE);
-        assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
-        assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
-        assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE);
-        assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.MISSED_TYPE);
-        // Does not group with voicemail and missed calls.
-        assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.VOICEMAIL_TYPE);
-    }
-
-    public void testAddGroups_Outgoing() {
-        // Groups with one or more incoming or outgoing.
-        assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE);
-        assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE);
-        assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE);
-        assertCallsAreGrouped(Calls.OUTGOING_TYPE, Calls.OUTGOING_TYPE, Calls.INCOMING_TYPE);
-        assertCallsAreGrouped(Calls.INCOMING_TYPE, Calls.MISSED_TYPE);
-        // Does not group with voicemail and missed calls.
-        assertCallsAreNotGrouped(Calls.INCOMING_TYPE, Calls.VOICEMAIL_TYPE);
-    }
-
-    public void testAddGroups_Mixed() {
-        addMultipleOldCallLogEntries(TEST_NUMBER1,
-                Calls.VOICEMAIL_TYPE,  // Stand-alone
-                Calls.INCOMING_TYPE,  // Group 1: 1-4
-                Calls.OUTGOING_TYPE,
-                Calls.MISSED_TYPE,
-                Calls.MISSED_TYPE,
-                Calls.VOICEMAIL_TYPE,  // Stand-alone
-                Calls.INCOMING_TYPE,  // Stand-alone
-                Calls.VOICEMAIL_TYPE,  // Stand-alone
-                Calls.MISSED_TYPE, // Group 2: 8-10
-                Calls.MISSED_TYPE,
-                Calls.OUTGOING_TYPE);
-        mBuilder.addGroups(mCursor);
-        assertEquals(2, mFakeGroupCreator.groups.size());
-        assertGroupIs(1, 4, false, mFakeGroupCreator.groups.get(0));
-        assertGroupIs(8, 3, false, mFakeGroupCreator.groups.get(1));
-    }
-
-    public void testEqualPhoneNumbers() {
-        // Identical.
-        assertTrue(mBuilder.equalNumbers("6505555555", "6505555555"));
-        assertTrue(mBuilder.equalNumbers("650 555 5555", "650 555 5555"));
-        // Formatting.
-        assertTrue(mBuilder.equalNumbers("6505555555", "650 555 5555"));
-        assertTrue(mBuilder.equalNumbers("6505555555", "(650) 555-5555"));
-        assertTrue(mBuilder.equalNumbers("650 555 5555", "(650) 555-5555"));
-        // Short codes.
-        assertTrue(mBuilder.equalNumbers("55555", "55555"));
-        assertTrue(mBuilder.equalNumbers("55555", "555 55"));
-        // Different numbers.
-        assertFalse(mBuilder.equalNumbers("6505555555", "650555555"));
-        assertFalse(mBuilder.equalNumbers("6505555555", "6505555551"));
-        assertFalse(mBuilder.equalNumbers("650 555 5555", "650 555 555"));
-        assertFalse(mBuilder.equalNumbers("650 555 5555", "650 555 5551"));
-        assertFalse(mBuilder.equalNumbers("55555", "5555"));
-        assertFalse(mBuilder.equalNumbers("55555", "55551"));
-        // SIP addresses.
-        assertTrue(mBuilder.equalNumbers("6505555555@host.com", "6505555555@host.com"));
-        assertTrue(mBuilder.equalNumbers("6505555555@host.com", "6505555555@HOST.COM"));
-        assertTrue(mBuilder.equalNumbers("user@host.com", "user@host.com"));
-        assertTrue(mBuilder.equalNumbers("user@host.com", "user@HOST.COM"));
-        assertFalse(mBuilder.equalNumbers("USER@host.com", "user@host.com"));
-        assertFalse(mBuilder.equalNumbers("user@host.com", "user@host1.com"));
-        // SIP address vs phone number.
-        assertFalse(mBuilder.equalNumbers("6505555555@host.com", "6505555555"));
-        assertFalse(mBuilder.equalNumbers("6505555555", "6505555555@host.com"));
-        assertFalse(mBuilder.equalNumbers("user@host.com", "6505555555"));
-        assertFalse(mBuilder.equalNumbers("6505555555", "user@host.com"));
-        // Nulls.
-        assertTrue(mBuilder.equalNumbers(null, null));
-        assertFalse(mBuilder.equalNumbers(null, "6505555555"));
-        assertFalse(mBuilder.equalNumbers("6505555555", null));
-        assertFalse(mBuilder.equalNumbers(null, "6505555555@host.com"));
-        assertFalse(mBuilder.equalNumbers("6505555555@host.com", null));
-    }
-
-    public void testCompareSipAddresses() {
-        // Identical.
-        assertTrue(mBuilder.compareSipAddresses("6505555555@host.com", "6505555555@host.com"));
-        assertTrue(mBuilder.compareSipAddresses("user@host.com", "user@host.com"));
-        // Host is case insensitive.
-        assertTrue(mBuilder.compareSipAddresses("6505555555@host.com", "6505555555@HOST.COM"));
-        assertTrue(mBuilder.compareSipAddresses("user@host.com", "user@HOST.COM"));
-        // Userinfo is case sensitive.
-        assertFalse(mBuilder.compareSipAddresses("USER@host.com", "user@host.com"));
-        // Different hosts.
-        assertFalse(mBuilder.compareSipAddresses("user@host.com", "user@host1.com"));
-        // Different users.
-        assertFalse(mBuilder.compareSipAddresses("user1@host.com", "user@host.com"));
-        // Nulls.
-        assertTrue(mBuilder.compareSipAddresses(null, null));
-        assertFalse(mBuilder.compareSipAddresses(null, "6505555555@host.com"));
-        assertFalse(mBuilder.compareSipAddresses("6505555555@host.com", null));
-    }
-
-    /** Creates (or recreates) the cursor used to store the call log content for the tests. */
-    private void createCursor() {
-        mCursor = new MatrixCursor(CallLogQuery.EXTENDED_PROJECTION);
-    }
-
-    /** Clears the content of the {@link FakeGroupCreator} used in the tests. */
-    private void clearFakeGroupCreator() {
-        mFakeGroupCreator.groups.clear();
-    }
-
-    /** Asserts that calls of the given types are grouped together into a single group. */
-    private void assertCallsAreGrouped(int... types) {
-        createCursor();
-        clearFakeGroupCreator();
-        addMultipleOldCallLogEntries(TEST_NUMBER1, types);
-        mBuilder.addGroups(mCursor);
-        assertEquals(1, mFakeGroupCreator.groups.size());
-        assertGroupIs(0, types.length, false, mFakeGroupCreator.groups.get(0));
-
-    }
-
-    /** Asserts that calls of the given types are not grouped together at all. */
-    private void assertCallsAreNotGrouped(int... types) {
-        createCursor();
-        clearFakeGroupCreator();
-        addMultipleOldCallLogEntries(TEST_NUMBER1, types);
-        mBuilder.addGroups(mCursor);
-        assertEquals(0, mFakeGroupCreator.groups.size());
-    }
-
-    /** Adds a set of calls with the given types, all from the same number, in the old section. */
-    private void addMultipleOldCallLogEntries(String number, int... types) {
-        for (int type : types) {
-            addOldCallLogEntry(number, type);
-        }
-    }
-
-    /** Adds a call with the given number and type to the old section of the call log. */
-    private void addOldCallLogEntry(String number, int type) {
-        addCallLogEntry(number, type, CallLogQuery.SECTION_OLD_ITEM);
-    }
-
-    /** Adds a call with the given number and type to the new section of the call log. */
-    private void addNewCallLogEntry(String number, int type) {
-        addCallLogEntry(number, type, CallLogQuery.SECTION_NEW_ITEM);
-    }
-
-    /** Adds a call log entry with the given number and type to the cursor. */
-    private void addCallLogEntry(String number, int type, int section) {
-        if (section != CallLogQuery.SECTION_NEW_ITEM
-                && section != CallLogQuery.SECTION_OLD_ITEM) {
-            throw new IllegalArgumentException("not an item section: " + section);
-        }
-        mCursor.moveToNext();
-        Object[] values = CallLogQueryTestUtils.createTestExtendedValues();
-        values[CallLogQuery.ID] = mCursor.getPosition();
-        values[CallLogQuery.NUMBER] = number;
-        values[CallLogQuery.CALL_TYPE] = type;
-        values[CallLogQuery.SECTION] = section;
-        mCursor.addRow(values);
-    }
-
-    /** Adds the old section header to the call log. */
-    private void addOldCallLogHeader() {
-        addCallLogHeader(CallLogQuery.SECTION_OLD_HEADER);
-    }
-
-    /** Adds the new section header to the call log. */
-    private void addNewCallLogHeader() {
-        addCallLogHeader(CallLogQuery.SECTION_NEW_HEADER);
-    }
-
-    /** Adds a call log entry with a header to the cursor. */
-    private void addCallLogHeader(int section) {
-        if (section != CallLogQuery.SECTION_NEW_HEADER
-                && section != CallLogQuery.SECTION_OLD_HEADER) {
-            throw new IllegalArgumentException("not a header section: " + section);
-        }
-        mCursor.moveToNext();
-        Object[] values = CallLogQueryTestUtils.createTestExtendedValues();
-        values[CallLogQuery.ID] = mCursor.getPosition();
-        values[CallLogQuery.SECTION] = section;
-        mCursor.addRow(values);
-    }
-
-    /** Asserts that the group matches the given values. */
-    private void assertGroupIs(int cursorPosition, int size, boolean expanded, GroupSpec group) {
-        assertEquals(cursorPosition, group.cursorPosition);
-        assertEquals(size, group.size);
-        assertEquals(expanded, group.expanded);
-    }
-
-    /** Defines an added group. Used by the {@link FakeGroupCreator}. */
-    private static class GroupSpec {
-        /** The starting position of the group. */
-        public final int cursorPosition;
-        /** The number of elements in the group. */
-        public final int size;
-        /** Whether the group should be initially expanded. */
-        public final boolean expanded;
-
-        public GroupSpec(int cursorPosition, int size, boolean expanded) {
-            this.cursorPosition = cursorPosition;
-            this.size = size;
-            this.expanded = expanded;
-        }
-    }
-
-    /** Fake implementation of a GroupCreator which stores the created groups in a member field. */
-    private static class FakeGroupCreator implements CallLogGroupBuilder.GroupCreator {
-        /** The list of created groups. */
-        public final List<GroupSpec> groups = newArrayList();
-
-        @Override
-        public void addGroup(int cursorPosition, int size, boolean expanded) {
-            groups.add(new GroupSpec(cursorPosition, size, expanded));
-        }
-    }
-}
diff --git a/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java b/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java
deleted file mode 100644
index a184f75..0000000
--- a/tests/src/com/android/contacts/calllog/CallLogListItemHelperTest.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.contacts.calllog;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.provider.CallLog.Calls;
-import android.test.AndroidTestCase;
-import android.view.View;
-
-import com.android.contacts.PhoneCallDetails;
-import com.android.contacts.PhoneCallDetailsHelper;
-import com.android.internal.telephony.CallerInfo;
-
-/**
- * Unit tests for {@link CallLogListItemHelper}.
- */
-public class CallLogListItemHelperTest extends AndroidTestCase {
-    /** A test phone number for phone calls. */
-    private static final String TEST_NUMBER = "14125555555";
-    /** The formatted version of {@link #TEST_NUMBER}. */
-    private static final String TEST_FORMATTED_NUMBER = "1-412-255-5555";
-    /** A test date value for phone calls. */
-    private static final long TEST_DATE = 1300000000;
-    /** A test duration value for phone calls. */
-    private static final long TEST_DURATION = 62300;
-    /** A test voicemail number. */
-    private static final String TEST_VOICEMAIL_NUMBER = "123";
-    /** The country ISO name used in the tests. */
-    private static final String TEST_COUNTRY_ISO = "US";
-    /** The geocoded location used in the tests. */
-    private static final String TEST_GEOCODE = "United States";
-
-    /** The object under test. */
-    private CallLogListItemHelper mHelper;
-
-    /** The views used in the tests. */
-    private CallLogListItemViews mViews;
-    private PhoneNumberHelper mPhoneNumberHelper;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        Context context = getContext();
-        Resources resources = context.getResources();
-        CallTypeHelper callTypeHelper = new CallTypeHelper(resources);
-        mPhoneNumberHelper = new TestPhoneNumberHelper(resources, TEST_VOICEMAIL_NUMBER);
-        PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
-                resources, callTypeHelper, mPhoneNumberHelper);
-        mHelper = new CallLogListItemHelper(phoneCallDetailsHelper, mPhoneNumberHelper, resources);
-        mViews = CallLogListItemViews.createForTest(context);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mHelper = null;
-        mViews = null;
-        super.tearDown();
-    }
-
-    public void testSetPhoneCallDetails() {
-        setPhoneCallDetailsWithNumber("12125551234", "1-212-555-1234");
-        assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
-    }
-
-    public void testSetPhoneCallDetails_Unknown() {
-        setPhoneCallDetailsWithNumber(CallerInfo.UNKNOWN_NUMBER, CallerInfo.UNKNOWN_NUMBER);
-        assertNoCallButton();
-    }
-
-    public void testSetPhoneCallDetails_Private() {
-        setPhoneCallDetailsWithNumber(CallerInfo.PRIVATE_NUMBER, CallerInfo.PRIVATE_NUMBER);
-        assertNoCallButton();
-    }
-
-    public void testSetPhoneCallDetails_Payphone() {
-        setPhoneCallDetailsWithNumber(CallerInfo.PAYPHONE_NUMBER, CallerInfo.PAYPHONE_NUMBER);
-        assertNoCallButton();
-    }
-
-    public void testSetPhoneCallDetails_VoicemailNumber() {
-        setPhoneCallDetailsWithNumber(TEST_VOICEMAIL_NUMBER, TEST_VOICEMAIL_NUMBER);
-        assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
-    }
-
-    public void testSetPhoneCallDetails_ReadVoicemail() {
-        setPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
-        assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
-    }
-
-    public void testSetPhoneCallDetails_UnreadVoicemail() {
-        setUnreadPhoneCallDetailsWithTypes(Calls.VOICEMAIL_TYPE);
-        assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
-    }
-
-    public void testSetPhoneCallDetails_VoicemailFromUnknown() {
-        setPhoneCallDetailsWithNumberAndType(CallerInfo.UNKNOWN_NUMBER, CallerInfo.UNKNOWN_NUMBER,
-                Calls.VOICEMAIL_TYPE);
-        assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
-    }
-
-    /** Asserts that the whole call area is gone. */
-    private void assertNoCallButton() {
-        assertEquals(View.GONE, mViews.secondaryActionView.getVisibility());
-        assertEquals(View.GONE, mViews.dividerView.getVisibility());
-    }
-
-    /** Sets the details of a phone call using the specified phone number. */
-    private void setPhoneCallDetailsWithNumber(String number, String formattedNumber) {
-        setPhoneCallDetailsWithNumberAndType(number, formattedNumber, Calls.INCOMING_TYPE);
-    }
-
-    /** Sets the details of a phone call using the specified phone number. */
-    private void setPhoneCallDetailsWithNumberAndType(String number, String formattedNumber,
-            int callType) {
-        mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(number, formattedNumber, TEST_COUNTRY_ISO, TEST_GEOCODE,
-                        new int[]{ callType }, TEST_DATE, TEST_DURATION),
-                false);
-    }
-
-    /** Sets the details of a phone call using the specified call type. */
-    private void setPhoneCallDetailsWithTypes(int... types) {
-        mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
-                        TEST_GEOCODE, types, TEST_DATE, TEST_DURATION),
-                false);
-    }
-
-    /** Sets the details of a phone call using the specified call type. */
-    private void setUnreadPhoneCallDetailsWithTypes(int... types) {
-        mHelper.setPhoneCallDetails(mViews,
-                new PhoneCallDetails(TEST_NUMBER, TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO,
-                        TEST_GEOCODE, types, TEST_DATE, TEST_DURATION),
-                true);
-    }
-}
diff --git a/tests/src/com/android/contacts/calllog/CallLogQueryTestUtils.java b/tests/src/com/android/contacts/calllog/CallLogQueryTestUtils.java
deleted file mode 100644
index a88bf4f..0000000
--- a/tests/src/com/android/contacts/calllog/CallLogQueryTestUtils.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.contacts.calllog;
-
-import static junit.framework.Assert.assertEquals;
-
-import android.provider.CallLog.Calls;
-
-import junit.framework.Assert;
-
-/**
- * Helper class to create test values for {@link CallLogQuery}.
- */
-public class CallLogQueryTestUtils {
-    public static Object[] createTestValues() {
-        Object[] values = new Object[]{
-                0L, "", 0L, 0L, Calls.INCOMING_TYPE, "", "", "", null, 0, null, null, null, null,
-                0L, null, 0,
-        };
-        assertEquals(CallLogQuery._PROJECTION.length, values.length);
-        return values;
-    }
-
-    public static Object[] createTestExtendedValues() {
-        Object[] values = new Object[]{
-                0L, "", 0L, 0L, Calls.INCOMING_TYPE, "", "", "", null, 0, null, null, null, null,
-                0L, null, 1, CallLogQuery.SECTION_OLD_ITEM
-        };
-        Assert.assertEquals(CallLogQuery.EXTENDED_PROJECTION.length, values.length);
-        return values;
-    }
-}
diff --git a/tests/src/com/android/contacts/calllog/TestPhoneNumberHelper.java b/tests/src/com/android/contacts/calllog/TestPhoneNumberHelper.java
deleted file mode 100644
index 2bbd978..0000000
--- a/tests/src/com/android/contacts/calllog/TestPhoneNumberHelper.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.contacts.calllog;
-
-import android.content.res.Resources;
-
-/**
- * Modified version of {@link PhoneNumberHelper} to be used in tests that allows injecting the
- * voicemail number.
- */
-public final class TestPhoneNumberHelper extends PhoneNumberHelper {
-    private CharSequence mVoicemailNumber;
-
-    public TestPhoneNumberHelper(Resources resources, CharSequence voicemailNumber) {
-        super(resources);
-        mVoicemailNumber = voicemailNumber;
-    }
-
-    @Override
-    public boolean isVoicemailNumber(CharSequence number) {
-        return mVoicemailNumber.equals(number);
-    }
-}
\ No newline at end of file
diff --git a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
index fcbd83d..3b856ea 100644
--- a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
@@ -29,13 +29,13 @@
 import com.android.contacts.model.AccountTypeManager;
 import com.android.contacts.model.account.AccountType;
 import com.android.contacts.model.account.BaseAccountType;
-import com.android.contacts.test.FragmentTestActivity;
+import com.android.contacts.common.test.FragmentTestActivity;
 import com.android.contacts.test.InjectedServices;
 import com.android.contacts.tests.mocks.ContactsMockContext;
 import com.android.contacts.tests.mocks.MockAccountTypeManager;
 import com.android.contacts.tests.mocks.MockContentProvider;
 import com.android.contacts.tests.mocks.MockContentProvider.Query;
-import com.android.contacts.util.IntegrationTestUtils;
+import com.android.contacts.common.test.IntegrationTestUtils;
 
 /**
  * Tests for {@link ContactDeletionInteraction}.
diff --git a/tests/src/com/android/contacts/list/ContactListItemViewTest.java b/tests/src/com/android/contacts/list/ContactListItemViewTest.java
index 748876f..d05e8cf 100644
--- a/tests/src/com/android/contacts/list/ContactListItemViewTest.java
+++ b/tests/src/com/android/contacts/list/ContactListItemViewTest.java
@@ -25,7 +25,7 @@
 
 import com.android.contacts.activities.PeopleActivity;
 import com.android.contacts.format.SpannedTestUtils;
-import com.android.contacts.util.IntegrationTestUtils;
+import com.android.contacts.common.test.IntegrationTestUtils;
 
 /**
  * Unit tests for {@link ContactListItemView}.
diff --git a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
index 519dc5c..d7ea5bf 100644
--- a/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
+++ b/tests/src/com/android/contacts/tests/allintents/AllIntentsActivity.java
@@ -512,7 +512,7 @@
                 }
                 final Intent intent = new Intent("android.intent.action.VIEW");
                 intent.setData(uri);
-                bindIntentToClass(intent, "com.android.contacts.CallDetailActivity");
+                bindIntentToClass(intent, "com.android.dialer.CallDetailActivity");
                 startActivity(intent);
                 break;
             }
diff --git a/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java b/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java
deleted file mode 100644
index d04d978..0000000
--- a/tests/src/com/android/contacts/tests/calllog/FillCallLogTestActivity.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.contacts.tests.calllog;
-
-import android.app.Activity;
-import android.app.LoaderManager;
-import android.content.ContentProviderClient;
-import android.content.ContentValues;
-import android.content.CursorLoader;
-import android.content.Loader;
-import android.database.Cursor;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.provider.CallLog.Calls;
-import android.util.Log;
-import android.view.View;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.contacts.tests.R;
-
-import java.util.Random;
-
-/**
- * Activity to add entries to the call log for testing.
- */
-public class FillCallLogTestActivity extends Activity {
-    private static final String TAG = "FillCallLogTestActivity";
-    /** Identifier of the loader for querying the call log. */
-    private static final int CALLLOG_LOADER_ID = 1;
-
-    private static final Random RNG = new Random();
-    private static final int[] CALL_TYPES = new int[] {
-        Calls.INCOMING_TYPE, Calls.OUTGOING_TYPE, Calls.MISSED_TYPE,
-    };
-
-    private TextView mNumberTextView;
-    private Button mAddButton;
-    private ProgressBar mProgressBar;
-    private CheckBox mUseRandomNumbers;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.fill_call_log_test);
-        mNumberTextView = (TextView) findViewById(R.id.number);
-        mAddButton = (Button) findViewById(R.id.add);
-        mProgressBar = (ProgressBar) findViewById(R.id.progress);
-        mUseRandomNumbers = (CheckBox) findViewById(R.id.use_random_numbers);
-
-        mAddButton.setOnClickListener(new View.OnClickListener(){
-            @Override
-            public void onClick(View v) {
-                int count;
-                try {
-                    count = Integer.parseInt(mNumberTextView.getText().toString());
-                    if (count > 100) {
-                        throw new RuntimeException("Number too large.  Max=100");
-                    }
-                } catch (RuntimeException e) {
-                    Toast.makeText(FillCallLogTestActivity.this, e.toString(), Toast.LENGTH_LONG)
-                            .show();
-                    return;
-                }
-                addEntriesToCallLog(count, mUseRandomNumbers.isChecked());
-                mNumberTextView.setEnabled(false);
-                mAddButton.setEnabled(false);
-                mProgressBar.setProgress(0);
-                mProgressBar.setMax(count);
-                mProgressBar.setVisibility(View.VISIBLE);
-            }
-        });
-    }
-
-    /**
-     * Adds a number of entries to the call log. The content of the entries is based on existing
-     * entries.
-     *
-     * @param count the number of entries to add
-     */
-    private void addEntriesToCallLog(final int count, boolean useRandomNumbers) {
-        if (useRandomNumbers) {
-            addRandomNumbers(count);
-        } else {
-            getLoaderManager().initLoader(CALLLOG_LOADER_ID, null,
-                    new CallLogLoaderListener(count));
-        }
-    }
-
-    /**
-     * Calls when the insertion has completed.
-     *
-     * @param message the message to show in a toast to the user
-     */
-    private void insertCompleted(String message) {
-        // Hide the progress bar.
-        mProgressBar.setVisibility(View.GONE);
-        // Re-enable the add button.
-        mNumberTextView.setEnabled(true);
-        mAddButton.setEnabled(true);
-        mNumberTextView.setText("");
-        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
-    }
-
-
-    /**
-     * Creates a {@link ContentValues} object containing values corresponding to the given cursor.
-     *
-     * @param cursor the cursor from which to get the values
-     * @return a newly created content values object
-     */
-    private ContentValues createContentValuesFromCursor(Cursor cursor) {
-        ContentValues values = new ContentValues();
-        for (int column = 0; column < cursor.getColumnCount();
-                ++column) {
-            String name = cursor.getColumnName(column);
-            switch (cursor.getType(column)) {
-                case Cursor.FIELD_TYPE_STRING:
-                    values.put(name, cursor.getString(column));
-                    break;
-                case Cursor.FIELD_TYPE_INTEGER:
-                    values.put(name, cursor.getLong(column));
-                    break;
-                case Cursor.FIELD_TYPE_FLOAT:
-                    values.put(name, cursor.getDouble(column));
-                    break;
-                case Cursor.FIELD_TYPE_BLOB:
-                    values.put(name, cursor.getBlob(column));
-                    break;
-                case Cursor.FIELD_TYPE_NULL:
-                    values.putNull(name);
-                    break;
-                default:
-                    Log.d(TAG, "Invalid value in cursor: " + cursor.getType(column));
-                    break;
-            }
-        }
-        return values;
-    }
-
-    private void addRandomNumbers(int count) {
-        ContentValues[] values = new ContentValues[count];
-        for (int i = 0; i < count; i++) {
-            values[i] = new ContentValues();
-            values[i].put(Calls.NUMBER, generateRandomNumber());
-            values[i].put(Calls.DATE, System.currentTimeMillis()); // Will be randomized later
-            values[i].put(Calls.DURATION, 1); // Will be overwritten later
-        }
-        new AsyncCallLogInserter(values).execute(new Void[0]);
-    }
-
-    private static String generateRandomNumber() {
-        return String.format("5%09d", RNG.nextInt(1000000000));
-    }
-
-    /** Invokes {@link AsyncCallLogInserter} when the call log has loaded. */
-    private final class CallLogLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
-        /** The number of items to insert when done. */
-        private final int mCount;
-
-        private CallLogLoaderListener(int count) {
-            mCount = count;
-        }
-
-        @Override
-        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
-            Log.d(TAG, "onCreateLoader");
-            return new CursorLoader(FillCallLogTestActivity.this, Calls.CONTENT_URI,
-                    null, null, null, null);
-        }
-
-        @Override
-        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
-            try {
-                Log.d(TAG, "onLoadFinished");
-
-                if (data.getCount() == 0) {
-                    // If there are no entries in the call log, we cannot generate new ones.
-                    insertCompleted(getString(R.string.noLogEntriesToast));
-                    return;
-                }
-
-                data.moveToPosition(-1);
-
-                ContentValues[] values = new ContentValues[mCount];
-                for (int index = 0; index < mCount; ++index) {
-                    if (!data.moveToNext()) {
-                        data.moveToFirst();
-                    }
-                    values[index] = createContentValuesFromCursor(data);
-                }
-                new AsyncCallLogInserter(values).execute(new Void[0]);
-            } finally {
-                // This is a one shot loader.
-                getLoaderManager().destroyLoader(CALLLOG_LOADER_ID);
-            }
-        }
-
-        @Override
-        public void onLoaderReset(Loader<Cursor> loader) {}
-    }
-
-    /** Inserts a given number of entries in the call log based on the values given. */
-    private final class AsyncCallLogInserter extends AsyncTask<Void, Integer, Integer> {
-        /** The number of items to insert. */
-        private final ContentValues[] mValues;
-
-        public AsyncCallLogInserter(ContentValues[] values) {
-            mValues = values;
-        }
-
-        @Override
-        protected Integer doInBackground(Void... params) {
-            Log.d(TAG, "doInBackground");
-            return insertIntoCallLog();
-        }
-
-        @Override
-        protected void onProgressUpdate(Integer... values) {
-            Log.d(TAG, "onProgressUpdate");
-            updateCount(values[0]);
-        }
-
-        @Override
-        protected void onPostExecute(Integer count) {
-            Log.d(TAG, "onPostExecute");
-            insertCompleted(getString(R.string.addedLogEntriesToast, count));
-        }
-
-        /**
-         * Inserts a number of entries in the call log based on the given templates.
-         *
-         * @return the number of inserted entries
-         */
-        private Integer insertIntoCallLog() {
-            int inserted = 0;
-
-            for (int index = 0; index < mValues.length; ++index) {
-                ContentValues values = mValues[index];
-                // These should not be set.
-                values.putNull(Calls._ID);
-                // Add some randomness to the date. For each new entry being added, add an extra
-                // day to the maximum possible offset from the original.
-                values.put(Calls.DATE,
-                        values.getAsLong(Calls.DATE)
-                        - RNG.nextInt(24 * 60 * 60 * (index + 1)) * 1000L);
-                // Add some randomness to the duration.
-                if (values.getAsLong(Calls.DURATION) > 0) {
-                    values.put(Calls.DURATION, RNG.nextInt(30 * 60 * 60 * 1000));
-                }
-
-                // Overwrite type.
-                values.put(Calls.TYPE, CALL_TYPES[RNG.nextInt(CALL_TYPES.length)]);
-
-                // Clear cached columns.
-                values.putNull(Calls.CACHED_FORMATTED_NUMBER);
-                values.putNull(Calls.CACHED_LOOKUP_URI);
-                values.putNull(Calls.CACHED_MATCHED_NUMBER);
-                values.putNull(Calls.CACHED_NAME);
-                values.putNull(Calls.CACHED_NORMALIZED_NUMBER);
-                values.putNull(Calls.CACHED_NUMBER_LABEL);
-                values.putNull(Calls.CACHED_NUMBER_TYPE);
-                values.putNull(Calls.CACHED_PHOTO_ID);
-
-                // Insert into the call log the newly generated entry.
-                ContentProviderClient contentProvider =
-                        getContentResolver().acquireContentProviderClient(
-                                Calls.CONTENT_URI);
-                try {
-                    Log.d(TAG, "adding entry to call log");
-                    contentProvider.insert(Calls.CONTENT_URI, values);
-                    ++inserted;
-                    this.publishProgress(inserted);
-                } catch (RemoteException e) {
-                    Log.d(TAG, "insert failed", e);
-                }
-            }
-            return inserted;
-        }
-    }
-
-    /**
-     * Updates the count shown to the user corresponding to the number of entries added.
-     *
-     * @param count the number of entries inserted so far
-     */
-    public void updateCount(Integer count) {
-        mProgressBar.setProgress(count);
-    }
-}
diff --git a/tests/src/com/android/contacts/util/ExpirableCacheTest.java b/tests/src/com/android/contacts/util/ExpirableCacheTest.java
deleted file mode 100644
index 33e176e..0000000
--- a/tests/src/com/android/contacts/util/ExpirableCacheTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.contacts.util;
-
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.LruCache;
-
-import com.android.contacts.util.ExpirableCache.CachedValue;
-
-/**
- * Unit tests for {@link ExpirableCache}.
- */
-@SmallTest
-public class ExpirableCacheTest extends AndroidTestCase {
-    /** The object under test. */
-    private ExpirableCache<String, Integer> mCache;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        LruCache<String, CachedValue<Integer>> lruCache =
-            new LruCache<String, ExpirableCache.CachedValue<Integer>>(20);
-        mCache = ExpirableCache.create(lruCache);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mCache = null;
-        super.tearDown();
-    }
-
-    public void testPut() {
-        mCache.put("a", 1);
-        mCache.put("b", 2);
-        assertEquals(1, mCache.getPossiblyExpired("a").intValue());
-        assertEquals(2, mCache.getPossiblyExpired("b").intValue());
-        mCache.put("a", 3);
-        assertEquals(3, mCache.getPossiblyExpired("a").intValue());
-    }
-
-    public void testGet_NotExisting() {
-        assertNull(mCache.getPossiblyExpired("a"));
-        mCache.put("b", 1);
-        assertNull(mCache.getPossiblyExpired("a"));
-    }
-
-    public void testGet_Expired() {
-        mCache.put("a", 1);
-        assertEquals(1, mCache.getPossiblyExpired("a").intValue());
-        mCache.expireAll();
-        assertEquals(1, mCache.getPossiblyExpired("a").intValue());
-    }
-
-    public void testGetNotExpired_NotExisting() {
-        assertNull(mCache.get("a"));
-        mCache.put("b", 1);
-        assertNull(mCache.get("a"));
-    }
-
-    public void testGetNotExpired_Expired() {
-        mCache.put("a", 1);
-        assertEquals(1, mCache.get("a").intValue());
-        mCache.expireAll();
-        assertNull(mCache.get("a"));
-    }
-
-    public void testGetCachedValue_NotExisting() {
-        assertNull(mCache.getCachedValue("a"));
-        mCache.put("b", 1);
-        assertNull(mCache.getCachedValue("a"));
-    }
-
-    public void testGetCachedValue_Expired() {
-        mCache.put("a", 1);
-        assertFalse("Should not be expired", mCache.getCachedValue("a").isExpired());
-        mCache.expireAll();
-        assertTrue("Should be expired", mCache.getCachedValue("a").isExpired());
-    }
-
-    public void testGetChangedValue_PutAfterExpired() {
-        mCache.put("a", 1);
-        mCache.expireAll();
-        mCache.put("a", 1);
-        assertFalse("Should not be expired", mCache.getCachedValue("a").isExpired());
-    }
-
-    public void testComputingCache() {
-        // Creates a cache in which all unknown values default to zero.
-        mCache = ExpirableCache.create(
-                new LruCache<String, ExpirableCache.CachedValue<Integer>>(10) {
-                    @Override
-                    protected CachedValue<Integer> create(String key) {
-                        return mCache.newCachedValue(0);
-                    }
-                });
-
-        // The first time we request a new value, we add it to the cache.
-        CachedValue<Integer> cachedValue = mCache.getCachedValue("a");
-        assertNotNull("Should have been created implicitly", cachedValue);
-        assertEquals(0, cachedValue.getValue().intValue());
-        assertFalse("Should not be expired", cachedValue.isExpired());
-
-        // If we expire all the values, the implicitly created value will also be marked as expired.
-        mCache.expireAll();
-        CachedValue<Integer> expiredCachedValue = mCache.getCachedValue("a");
-        assertNotNull("Should have been created implicitly", expiredCachedValue);
-        assertEquals(0, expiredCachedValue.getValue().intValue());
-        assertTrue("Should be expired", expiredCachedValue.isExpired());
-    }
-}
diff --git a/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java b/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java
deleted file mode 100644
index 8c97f21..0000000
--- a/tests/src/com/android/contacts/util/FakeAsyncTaskExecutor.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.contacts.util;
-
-import android.app.Instrumentation;
-import android.os.AsyncTask;
-
-import com.google.common.collect.Lists;
-
-import junit.framework.Assert;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * Test implementation of AsyncTaskExecutor.
- * <p>
- * This class is thread-safe. As per the contract of the AsyncTaskExecutor, the submit methods must
- * be called from the main ui thread, however the other public methods may be called from any thread
- * (most commonly the test thread).
- * <p>
- * Tasks submitted to this executor will not be run immediately. Rather they will be stored in a
- * list of submitted tasks, where they can be examined. They can also be run on-demand using the run
- * methods, so that different ordering of AsyncTask execution can be simulated.
- * <p>
- * The onPreExecute method of the submitted AsyncTask will be called synchronously during the
- * call to {@link #submit(Object, AsyncTask, Object...)}.
- */
-@ThreadSafe
-public class FakeAsyncTaskExecutor implements AsyncTaskExecutor {
-    private static final long DEFAULT_TIMEOUT_MS = 10000;
-
-    /** The maximum length of time in ms to wait for tasks to execute during tests. */
-    private final long mTimeoutMs = DEFAULT_TIMEOUT_MS;
-
-    private final Object mLock = new Object();
-    @GuardedBy("mLock") private final List<SubmittedTask> mSubmittedTasks = Lists.newArrayList();
-
-    private final DelayedExecutor mBlockingExecutor = new DelayedExecutor();
-    private final Instrumentation mInstrumentation;
-
-    /** Create a fake AsyncTaskExecutor for use in unit tests. */
-    public FakeAsyncTaskExecutor(Instrumentation instrumentation) {
-        Assert.assertNotNull(instrumentation);
-        mInstrumentation = instrumentation;
-    }
-
-    /** Encapsulates an async task with the params and identifier it was submitted with. */
-    public interface SubmittedTask {
-        Runnable getRunnable();
-        Object getIdentifier();
-        AsyncTask<?, ?, ?> getAsyncTask();
-    }
-
-    private static final class SubmittedTaskImpl implements SubmittedTask {
-        private final Object mIdentifier;
-        private final Runnable mRunnable;
-        private final AsyncTask<?, ?, ?> mAsyncTask;
-
-        public SubmittedTaskImpl(Object identifier, Runnable runnable,
-                AsyncTask<?, ?, ?> asyncTask) {
-            mIdentifier = identifier;
-            mRunnable = runnable;
-            mAsyncTask = asyncTask;
-        }
-
-        @Override
-        public Object getIdentifier() {
-            return mIdentifier;
-        }
-
-        @Override
-        public Runnable getRunnable() {
-            return mRunnable;
-        }
-
-        @Override
-        public AsyncTask<?, ?, ?> getAsyncTask() {
-            return mAsyncTask;
-        }
-
-        @Override
-        public String toString() {
-            return "SubmittedTaskImpl [mIdentifier=" + mIdentifier + "]";
-        }
-    }
-
-    private class DelayedExecutor implements Executor {
-        private final Object mNextLock = new Object();
-        @GuardedBy("mNextLock") private Object mNextIdentifier;
-        @GuardedBy("mNextLock") private AsyncTask<?, ?, ?> mNextTask;
-
-        @Override
-        public void execute(Runnable command) {
-            synchronized (mNextLock) {
-                Assert.assertNotNull(mNextTask);
-                mSubmittedTasks.add(new SubmittedTaskImpl(mNextIdentifier,
-                        command, mNextTask));
-                mNextIdentifier = null;
-                mNextTask = null;
-            }
-        }
-
-        public <T> AsyncTask<T, ?, ?> submit(Object identifier,
-                AsyncTask<T, ?, ?> task, T... params) {
-            synchronized (mNextLock) {
-                Assert.assertNull(mNextIdentifier);
-                Assert.assertNull(mNextTask);
-                mNextIdentifier = identifier;
-                Assert.assertNotNull("Already had a valid task.\n"
-                        + "Are you calling AsyncTaskExecutor.submit(...) from within the "
-                        + "onPreExecute() method of another task being submitted?\n"
-                        + "Sorry!  Not that's not supported.", task);
-                mNextTask = task;
-            }
-            return task.executeOnExecutor(this, params);
-        }
-    }
-
-    @Override
-    public <T> AsyncTask<T, ?, ?> submit(Object identifier, AsyncTask<T, ?, ?> task, T... params) {
-        AsyncTaskExecutors.checkCalledFromUiThread();
-        return mBlockingExecutor.submit(identifier, task, params);
-    }
-
-    /**
-     * Runs a single task matching the given identifier.
-     * <p>
-     * Removes the matching task from the list of submitted tasks, then runs it. The executor used
-     * to execute this async task will be a same-thread executor.
-     * <p>
-     * Fails if there was not exactly one task matching the given identifier.
-     * <p>
-     * This method blocks until the AsyncTask has completely finished executing.
-     */
-    public void runTask(Object identifier) throws InterruptedException {
-        List<SubmittedTask> tasks = getSubmittedTasksByIdentifier(identifier, true);
-        Assert.assertEquals("Expected one task " + identifier + ", got " + tasks, 1, tasks.size());
-        runTask(tasks.get(0));
-    }
-
-    /**
-     * Runs all tasks whose identifier matches the given identifier.
-     * <p>
-     * Removes all matching tasks from the list of submitted tasks, and runs them. The executor used
-     * to execute these async tasks will be a same-thread executor.
-     * <p>
-     * Fails if there were no tasks matching the given identifier.
-     * <p>
-     * This method blocks until the AsyncTask objects have completely finished executing.
-     */
-    public void runAllTasks(Object identifier) throws InterruptedException {
-        List<SubmittedTask> tasks = getSubmittedTasksByIdentifier(identifier, true);
-        Assert.assertTrue("There were no tasks with identifier " + identifier, tasks.size() > 0);
-        for (SubmittedTask task : tasks) {
-            runTask(task);
-        }
-    }
-
-    /**
-     * Executes a single {@link SubmittedTask}.
-     * <p>
-     * Blocks until the task has completed running.
-     */
-    private <T> void runTask(final SubmittedTask submittedTask) throws InterruptedException {
-        submittedTask.getRunnable().run();
-        // Block until the onPostExecute or onCancelled has finished.
-        // Unfortunately we can't be sure when the AsyncTask will have posted its result handling
-        // code to the main ui thread, the best we can do is wait for the Status to be FINISHED.
-        final CountDownLatch latch = new CountDownLatch(1);
-        class AsyncTaskHasFinishedRunnable implements Runnable {
-            @Override
-            public void run() {
-                if (submittedTask.getAsyncTask().getStatus() == AsyncTask.Status.FINISHED) {
-                    latch.countDown();
-                } else {
-                    mInstrumentation.waitForIdle(this);
-                }
-            }
-        }
-        mInstrumentation.waitForIdle(new AsyncTaskHasFinishedRunnable());
-        Assert.assertTrue(latch.await(mTimeoutMs, TimeUnit.MILLISECONDS));
-    }
-
-    private List<SubmittedTask> getSubmittedTasksByIdentifier(
-            Object identifier, boolean remove) {
-        Assert.assertNotNull(identifier);
-        List<SubmittedTask> results = Lists.newArrayList();
-        synchronized (mLock) {
-            Iterator<SubmittedTask> iter = mSubmittedTasks.iterator();
-            while (iter.hasNext()) {
-                SubmittedTask task = iter.next();
-                if (identifier.equals(task.getIdentifier())) {
-                    results.add(task);
-                    iter.remove();
-                }
-            }
-        }
-        return results;
-    }
-
-    /** Get a factory that will return this instance - useful for testing. */
-    public AsyncTaskExecutors.AsyncTaskExecutorFactory getFactory() {
-        return new AsyncTaskExecutors.AsyncTaskExecutorFactory() {
-            @Override
-            public AsyncTaskExecutor createAsyncTaskExeuctor() {
-                return FakeAsyncTaskExecutor.this;
-            }
-        };
-    }
-}
diff --git a/tests/src/com/android/contacts/util/IntegrationTestUtils.java b/tests/src/com/android/contacts/util/IntegrationTestUtils.java
deleted file mode 100644
index 8c9dd6c..0000000
--- a/tests/src/com/android/contacts/util/IntegrationTestUtils.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.contacts.util;
-
-import static android.os.PowerManager.ACQUIRE_CAUSES_WAKEUP;
-import static android.os.PowerManager.FULL_WAKE_LOCK;
-import static android.os.PowerManager.ON_AFTER_RELEASE;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.content.Context;
-import android.os.PowerManager;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.google.common.base.Preconditions;
-
-import junit.framework.Assert;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
-
-/** Some utility methods for making integration testing smoother. */
-@ThreadSafe
-public class IntegrationTestUtils {
-    private static final String TAG = "IntegrationTestUtils";
-
-    private final Instrumentation mInstrumentation;
-    private final Object mLock = new Object();
-    @GuardedBy("mLock") private PowerManager.WakeLock mWakeLock;
-
-    public IntegrationTestUtils(Instrumentation instrumentation) {
-        mInstrumentation = instrumentation;
-    }
-
-    /**
-     * Find a view by a given resource id, from the given activity, and click it, iff it is
-     * enabled according to {@link View#isEnabled()}.
-     */
-    public void clickButton(final Activity activity, final int buttonResourceId) throws Throwable {
-        runOnUiThreadAndGetTheResult(new Callable<Void>() {
-            @Override
-            public Void call() throws Exception {
-                View view = activity.findViewById(buttonResourceId);
-                Assert.assertNotNull(view);
-                if (view.isEnabled()) {
-                    view.performClick();
-                }
-                return null;
-            }
-        });
-    }
-
-    /** Returns the result of running {@link TextView#getText()} on the ui thread. */
-    public CharSequence getText(final TextView view) throws Throwable {
-        return runOnUiThreadAndGetTheResult(new Callable<CharSequence>() {
-            @Override
-            public CharSequence call() {
-                return view.getText();
-            }
-        });
-    }
-
-    // TODO: Move this class and the appropriate documentation into a test library, having checked
-    // first to see if exactly this code already exists or not.
-    /**
-     * Execute a callable on the ui thread, returning its result synchronously.
-     * <p>
-     * Waits for an idle sync on the main thread (see {@link Instrumentation#waitForIdle(Runnable)})
-     * before executing this callable.
-     */
-    public <T> T runOnUiThreadAndGetTheResult(Callable<T> callable) throws Throwable {
-        FutureTask<T> future = new FutureTask<T>(callable);
-        mInstrumentation.waitForIdle(future);
-        try {
-            return future.get();
-        } catch (ExecutionException e) {
-            // Unwrap the cause of the exception and re-throw it.
-            throw e.getCause();
-        }
-    }
-
-    /**
-     * Wake up the screen, useful in tests that want or need the screen to be on.
-     * <p>
-     * This is usually called from setUp() for tests that require it.  After calling this method,
-     * {@link #releaseScreenWakeLock()} must be called, this is usually done from tearDown().
-     */
-    public void acquireScreenWakeLock(Context context) {
-        synchronized (mLock) {
-            Preconditions.checkState(mWakeLock == null, "mWakeLock was already held");
-            mWakeLock = ((PowerManager) context.getSystemService(Context.POWER_SERVICE))
-                    .newWakeLock(ACQUIRE_CAUSES_WAKEUP | ON_AFTER_RELEASE | FULL_WAKE_LOCK, TAG);
-            mWakeLock.acquire();
-        }
-    }
-
-    /** Release the wake lock previously acquired with {@link #acquireScreenWakeLock(Context)}. */
-    public void releaseScreenWakeLock() {
-        synchronized (mLock) {
-            // We don't use Preconditions to force you to have acquired before release.
-            // This is because we don't want unnecessary exceptions in tearDown() since they'll
-            // typically mask the actual exception that happened during the test.
-            // The other reason is that this method is most likely to be called from tearDown(),
-            // which is invoked within a finally block, so it's not infrequently the case that
-            // the setUp() method fails before getting the lock, at which point we don't want
-            // to fail in tearDown().
-            if (mWakeLock != null) {
-                mWakeLock.release();
-                mWakeLock = null;
-            }
-        }
-    }
-
-    /**
-     * Gets all {@link TextView} objects whose {@link TextView#getText()} contains the given text as
-     * a substring.
-     */
-    public List<TextView> getTextViewsWithString(final Activity activity, final String text)
-            throws Throwable {
-        return runOnUiThreadAndGetTheResult(new Callable<List<TextView>>() {
-            @Override
-            public List<TextView> call() throws Exception {
-                List<TextView> matchingViews = new ArrayList<TextView>();
-                for (TextView textView : getAllViews(TextView.class, getRootView(activity))) {
-                    if (textView.getText().toString().contains(text)) {
-                        matchingViews.add(textView);
-                    }
-                }
-                return matchingViews;
-            }
-        });
-    }
-
-    /** Find the root view for a given activity. */
-    public static View getRootView(Activity activity) {
-        return activity.findViewById(android.R.id.content).getRootView();
-    }
-
-    /**
-     * Gets a list of all views of a given type, rooted at the given parent.
-     * <p>
-     * This method will recurse down through all {@link ViewGroup} instances looking for
-     * {@link View} instances of the supplied class type. Specifically it will use the
-     * {@link Class#isAssignableFrom(Class)} method as the test for which views to add to the list,
-     * so if you provide {@code View.class} as your type, you will get every view. The parent itself
-     * will be included also, should it be of the right type.
-     * <p>
-     * This call manipulates the ui, and as such should only be called from the application's main
-     * thread.
-     */
-    private static <T extends View> List<T> getAllViews(final Class<T> clazz, final View parent) {
-        List<T> results = new ArrayList<T>();
-        if (parent.getClass().equals(clazz)) {
-            results.add(clazz.cast(parent));
-        }
-        if (parent instanceof ViewGroup) {
-            ViewGroup viewGroup = (ViewGroup) parent;
-            for (int i = 0; i < viewGroup.getChildCount(); ++i) {
-                results.addAll(getAllViews(clazz, viewGroup.getChildAt(i)));
-            }
-        }
-        return results;
-    }
-}
diff --git a/tests/src/com/android/contacts/util/LocaleTestUtils.java b/tests/src/com/android/contacts/util/LocaleTestUtils.java
deleted file mode 100644
index e0a8670..0000000
--- a/tests/src/com/android/contacts/util/LocaleTestUtils.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.contacts.util;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-
-import java.util.Locale;
-
-/**
- * Utility class to save and restore the locale of the system.
- * <p>
- * This can be used for tests that assume to be run in a certain locale, e.g., because they
- * check against strings in a particular language or require an assumption on how the system
- * will behave in a specific locale.
- * <p>
- * In your test, you can change the locale with the following code:
- * <pre>
- * public class CanadaFrenchTest extends AndroidTestCase {
- *     private LocaleTestUtils mLocaleTestUtils;
- *
- *     &#64;Override
- *     public void setUp() throws Exception {
- *         super.setUp();
- *         mLocaleTestUtils = new LocaleTestUtils(getContext());
- *         mLocaleTestUtils.setLocale(Locale.CANADA_FRENCH);
- *     }
- *
- *     &#64;Override
- *     public void tearDown() throws Exception {
- *         mLocaleTestUtils.restoreLocale();
- *         mLocaleTestUtils = null;
- *         super.tearDown();
- *     }
- *
- *     ...
- * }
- * </pre>
- * Note that one should not call {@link #setLocale(Locale)} more than once without calling
- * {@link #restoreLocale()} first.
- * <p>
- * This class is not thread-safe. Usually its methods should be invoked only from the test thread.
- */
-public class LocaleTestUtils {
-    private final Context mContext;
-    private boolean mSaved;
-    private Locale mSavedContextLocale;
-    private Locale mSavedSystemLocale;
-
-    /**
-     * Create a new instance that can be used to set and reset the locale for the given context.
-     *
-     * @param context the context on which to alter the locale
-     */
-    public LocaleTestUtils(Context context) {
-        mContext = context;
-        mSaved = false;
-    }
-
-    /**
-     * Set the locale to the given value and saves the previous value.
-     *
-     * @param locale the value to which the locale should be set
-     * @throws IllegalStateException if the locale was already set
-     */
-    public void setLocale(Locale locale) {
-        if (mSaved) {
-            throw new IllegalStateException(
-                    "call restoreLocale() before calling setLocale() again");
-        }
-        mSavedContextLocale = setResourcesLocale(mContext.getResources(), locale);
-        mSavedSystemLocale = setResourcesLocale(Resources.getSystem(), locale);
-        mSaved = true;
-    }
-
-    /**
-     * Restores the previously set locale.
-     *
-     * @throws IllegalStateException if the locale was not set using {@link #setLocale(Locale)}
-     */
-    public void restoreLocale() {
-        if (!mSaved) {
-            throw new IllegalStateException("call setLocale() before calling restoreLocale()");
-        }
-        setResourcesLocale(mContext.getResources(), mSavedContextLocale);
-        setResourcesLocale(Resources.getSystem(), mSavedSystemLocale);
-        mSaved = false;
-    }
-
-    /**
-     * Sets the locale for the given resources and returns the previous locale.
-     *
-     * @param resources the resources on which to set the locale
-     * @param locale the value to which to set the locale
-     * @return the previous value of the locale for the resources
-     */
-    private Locale setResourcesLocale(Resources resources, Locale locale) {
-        Configuration contextConfiguration = new Configuration(resources.getConfiguration());
-        Locale savedLocale = contextConfiguration.locale;
-        contextConfiguration.locale = locale;
-        resources.updateConfiguration(contextConfiguration, null);
-        return savedLocale;
-    }
-}
\ No newline at end of file
diff --git a/tests/src/com/android/contacts/voicemail/VoicemailStatusHelperImplTest.java b/tests/src/com/android/contacts/voicemail/VoicemailStatusHelperImplTest.java
deleted file mode 100644
index 801c162..0000000
--- a/tests/src/com/android/contacts/voicemail/VoicemailStatusHelperImplTest.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * Copyright (C) 2011 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.
- */
-
-package com.android.contacts.voicemail;
-
-import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE;
-import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE_CAN_BE_CONFIGURED;
-import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE_NOT_CONFIGURED;
-import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE;
-import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE_NO_CONNECTION;
-import static android.provider.VoicemailContract.Status.DATA_CHANNEL_STATE_OK;
-import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE;
-import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING;
-import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_NO_CONNECTION;
-import static android.provider.VoicemailContract.Status.NOTIFICATION_CHANNEL_STATE_OK;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.VoicemailContract.Status;
-import android.test.AndroidTestCase;
-
-import com.android.contacts.R;
-import com.android.contacts.voicemail.VoicemailStatusHelper.StatusMessage;
-
-import java.util.List;
-
-/**
- * Unit tests for {@link VoicemailStatusHelperImpl}.
- */
-public class VoicemailStatusHelperImplTest extends AndroidTestCase {
-    private static final String[] TEST_PACKAGES = new String[] {
-        "com.test.package1",
-        "com.test.package2"
-    };
-
-    private static final Uri TEST_SETTINGS_URI = Uri.parse("http://www.visual.voicemail.setup");
-    private static final Uri TEST_VOICEMAIL_URI = Uri.parse("tel:901");
-
-    private static final int ACTION_MSG_CALL_VOICEMAIL =
-            R.string.voicemail_status_action_call_server;
-    private static final int ACTION_MSG_CONFIGURE = R.string.voicemail_status_action_configure;
-
-    private static final int STATUS_MSG_NONE = -1;
-    private static final int STATUS_MSG_VOICEMAIL_NOT_AVAILABLE =
-            R.string.voicemail_status_voicemail_not_available;
-    private static final int STATUS_MSG_AUDIO_NOT_AVAIALABLE =
-            R.string.voicemail_status_audio_not_available;
-    private static final int STATUS_MSG_MESSAGE_WAITING = R.string.voicemail_status_messages_waiting;
-    private static final int STATUS_MSG_INVITE_FOR_CONFIGURATION =
-            R.string.voicemail_status_configure_voicemail;
-
-    // Object under test.
-    private VoicemailStatusHelper mStatusHelper;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mStatusHelper = new VoicemailStatusHelperImpl();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        for (String sourcePackage : TEST_PACKAGES) {
-            deleteEntryForPackage(sourcePackage);
-        }
-        // Set member variables to null so that they are garbage collected across different runs
-        // of the tests.
-        mStatusHelper = null;
-        super.tearDown();
-    }
-
-
-    public void testNoStatusEntries() {
-        assertEquals(0, getStatusMessages().size());
-    }
-
-    public void testAllOK() {
-        insertEntryForPackage(TEST_PACKAGES[0], getAllOkStatusValues());
-        insertEntryForPackage(TEST_PACKAGES[1], getAllOkStatusValues());
-        assertEquals(0, getStatusMessages().size());
-    }
-
-    public void testNotAllOKForOnePackage() {
-        insertEntryForPackage(TEST_PACKAGES[0], getAllOkStatusValues());
-        insertEntryForPackage(TEST_PACKAGES[1], getAllOkStatusValues());
-
-        ContentValues values = new ContentValues();
-        // Good data channel + no notification
-        // action: call voicemail
-        // msg: voicemail not available in call log page & none in call details page.
-        values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
-        values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_OK);
-        updateEntryForPackage(TEST_PACKAGES[1], values);
-        checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_VOICEMAIL_NOT_AVAILABLE,
-                STATUS_MSG_NONE, ACTION_MSG_CALL_VOICEMAIL);
-
-        // Message waiting + good data channel - no action.
-        values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING);
-        values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_OK);
-        updateEntryForPackage(TEST_PACKAGES[1], values);
-        checkNoMessages(TEST_PACKAGES[1], values);
-
-        // No data channel + no notification
-        // action: call voicemail
-        // msg: voicemail not available in call log page & audio not available in call details page.
-        values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_OK);
-        values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_NO_CONNECTION);
-        updateEntryForPackage(TEST_PACKAGES[1], values);
-        checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_VOICEMAIL_NOT_AVAILABLE,
-                STATUS_MSG_AUDIO_NOT_AVAIALABLE, ACTION_MSG_CALL_VOICEMAIL);
-
-        // No data channel + Notification OK
-        // action: call voicemail
-        // msg: voicemail not available in call log page & audio not available in call details page.
-        values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
-        values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_NO_CONNECTION);
-        updateEntryForPackage(TEST_PACKAGES[1], values);
-        checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_VOICEMAIL_NOT_AVAILABLE,
-                STATUS_MSG_AUDIO_NOT_AVAIALABLE, ACTION_MSG_CALL_VOICEMAIL);
-
-        // No data channel + Notification OK
-        // action: call voicemail
-        // msg: message waiting in call log page & audio not available in call details page.
-        values.put(NOTIFICATION_CHANNEL_STATE, NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING);
-        values.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_NO_CONNECTION);
-        updateEntryForPackage(TEST_PACKAGES[1], values);
-        checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_MESSAGE_WAITING,
-                STATUS_MSG_AUDIO_NOT_AVAIALABLE, ACTION_MSG_CALL_VOICEMAIL);
-
-        // Not configured. No user action, so no message.
-        values.put(CONFIGURATION_STATE, CONFIGURATION_STATE_NOT_CONFIGURED);
-        updateEntryForPackage(TEST_PACKAGES[1], values);
-        checkNoMessages(TEST_PACKAGES[1], values);
-
-        // Can be configured - invite user for configure voicemail.
-        values.put(CONFIGURATION_STATE, CONFIGURATION_STATE_CAN_BE_CONFIGURED);
-        updateEntryForPackage(TEST_PACKAGES[1], values);
-        checkExpectedMessage(TEST_PACKAGES[1], values, STATUS_MSG_INVITE_FOR_CONFIGURATION,
-                STATUS_MSG_NONE, ACTION_MSG_CONFIGURE, TEST_SETTINGS_URI);
-    }
-
-    // Test that priority of messages are handled well.
-    public void testMessageOrdering() {
-        insertEntryForPackage(TEST_PACKAGES[0], getAllOkStatusValues());
-        insertEntryForPackage(TEST_PACKAGES[1], getAllOkStatusValues());
-
-        final ContentValues valuesNoNotificationGoodDataChannel = new ContentValues();
-        valuesNoNotificationGoodDataChannel.put(NOTIFICATION_CHANNEL_STATE,
-                NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
-        valuesNoNotificationGoodDataChannel.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_OK);
-
-        final ContentValues valuesNoNotificationNoDataChannel = new ContentValues();
-        valuesNoNotificationNoDataChannel.put(NOTIFICATION_CHANNEL_STATE,
-                NOTIFICATION_CHANNEL_STATE_NO_CONNECTION);
-        valuesNoNotificationNoDataChannel.put(DATA_CHANNEL_STATE, DATA_CHANNEL_STATE_NO_CONNECTION);
-
-        // Package1 with valuesNoNotificationGoodDataChannel and
-        // package2 with  valuesNoNotificationNoDataChannel. Package2 should be above.
-        updateEntryForPackage(TEST_PACKAGES[0], valuesNoNotificationGoodDataChannel);
-        updateEntryForPackage(TEST_PACKAGES[1], valuesNoNotificationNoDataChannel);
-        List<StatusMessage> messages = getStatusMessages();
-        assertEquals(2, messages.size());
-        assertEquals(TEST_PACKAGES[0], messages.get(1).sourcePackage);
-        assertEquals(TEST_PACKAGES[1], messages.get(0).sourcePackage);
-
-        // Now reverse the values - ordering should be reversed as well.
-        updateEntryForPackage(TEST_PACKAGES[0], valuesNoNotificationNoDataChannel);
-        updateEntryForPackage(TEST_PACKAGES[1], valuesNoNotificationGoodDataChannel);
-        messages = getStatusMessages();
-        assertEquals(2, messages.size());
-        assertEquals(TEST_PACKAGES[0], messages.get(0).sourcePackage);
-        assertEquals(TEST_PACKAGES[1], messages.get(1).sourcePackage);
-    }
-
-    /** Checks that the expected source status message is returned by VoicemailStatusHelper. */
-    private void checkExpectedMessage(String sourcePackage, ContentValues values,
-            int expectedCallLogMsg, int expectedCallDetailsMsg, int expectedActionMsg,
-            Uri expectedUri) {
-        List<StatusMessage> messages = getStatusMessages();
-        assertEquals(1, messages.size());
-        checkMessageMatches(messages.get(0), sourcePackage, expectedCallLogMsg,
-                expectedCallDetailsMsg, expectedActionMsg, expectedUri);
-    }
-
-    private void checkExpectedMessage(String sourcePackage, ContentValues values,
-            int expectedCallLogMsg, int expectedCallDetailsMessage, int expectedActionMsg) {
-        checkExpectedMessage(sourcePackage, values, expectedCallLogMsg, expectedCallDetailsMessage,
-                expectedActionMsg, TEST_VOICEMAIL_URI);
-    }
-
-    private void checkMessageMatches(StatusMessage message, String expectedSourcePackage,
-            int expectedCallLogMsg, int expectedCallDetailsMsg, int expectedActionMsg,
-            Uri expectedUri) {
-        assertEquals(expectedSourcePackage, message.sourcePackage);
-        assertEquals(expectedCallLogMsg, message.callLogMessageId);
-        assertEquals(expectedCallDetailsMsg, message.callDetailsMessageId);
-        assertEquals(expectedActionMsg, message.actionMessageId);
-        if (expectedUri == null) {
-            assertNull(message.actionUri);
-        } else {
-            assertEquals(expectedUri, message.actionUri);
-        }
-    }
-
-    private void checkNoMessages(String sourcePackage, ContentValues values) {
-        assertEquals(1, updateEntryForPackage(sourcePackage, values));
-        List<StatusMessage> messages = getStatusMessages();
-        assertEquals(0, messages.size());
-    }
-
-    private ContentValues getAllOkStatusValues() {
-        ContentValues values = new ContentValues();
-        values.put(Status.SETTINGS_URI, TEST_SETTINGS_URI.toString());
-        values.put(Status.VOICEMAIL_ACCESS_URI, TEST_VOICEMAIL_URI.toString());
-        values.put(Status.CONFIGURATION_STATE, Status.CONFIGURATION_STATE_OK);
-        values.put(Status.DATA_CHANNEL_STATE, Status.DATA_CHANNEL_STATE_OK);
-        values.put(Status.NOTIFICATION_CHANNEL_STATE, Status.NOTIFICATION_CHANNEL_STATE_OK);
-        return values;
-    }
-
-    private void insertEntryForPackage(String sourcePackage, ContentValues values) {
-        // If insertion fails then try update as the record might already exist.
-        if (getContentResolver().insert(Status.buildSourceUri(sourcePackage), values) == null) {
-            updateEntryForPackage(sourcePackage, values);
-        }
-    }
-
-    private void deleteEntryForPackage(String sourcePackage) {
-        getContentResolver().delete(Status.buildSourceUri(sourcePackage), null, null);
-    }
-
-    private int updateEntryForPackage(String sourcePackage, ContentValues values) {
-        return getContentResolver().update(
-                Status.buildSourceUri(sourcePackage), values, null, null);
-    }
-
-    private List<StatusMessage> getStatusMessages() {
-        // Restrict the cursor to only the the test packages to eliminate any side effects if there
-        // are other status messages already stored on the device.
-        Cursor cursor = getContentResolver().query(Status.CONTENT_URI,
-                VoicemailStatusHelperImpl.PROJECTION, getTestPackageSelection(), null, null);
-        return mStatusHelper.getStatusMessages(cursor);
-    }
-
-    private String getTestPackageSelection() {
-        StringBuilder sb = new StringBuilder();
-        for (String sourcePackage : TEST_PACKAGES) {
-            if (sb.length() > 0) {
-                sb.append(" OR ");
-            }
-            sb.append(String.format("(source_package='%s')", sourcePackage));
-        }
-        return sb.toString();
-    }
-
-    private ContentResolver getContentResolver() {
-        return getContext().getContentResolver();
-    }
-}
