diff --git a/Android.mk b/Android.mk
index 67859bd..c29c90d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -8,6 +8,7 @@
 LOCAL_JAVA_LIBRARIES := telephony-common
 LOCAL_STATIC_JAVA_LIBRARIES := \
     com.android.phone.common \
+    com.android.phone.shared \
     com.android.vcard \
     android-common \
     guava \
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index babd439..4c527aa 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -60,126 +60,6 @@
         android:hardwareAccelerated="true"
     >
 
-        <!-- Intercept Dialer Intents for devices without a phone.
-        This activity should have the same intent filters as the DialtactsActivity,
-        so that its capturing the same events. Omit android.intent.category.LAUNCHER, because we
-        don't want this to show up in the Launcher. The priorities of the intent-filters
-        are set lower, so that the user does not see a disambig dialog -->
-        <activity
-            android:name=".activities.NonPhoneActivity"
-            android:theme="@style/NonPhoneActivityTheme"
-        >
-            <intent-filter android:priority="-1">
-                <action android:name="android.intent.action.DIAL" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:mimeType="vnd.android.cursor.item/phone" />
-                <data android:mimeType="vnd.android.cursor.item/person" />
-            </intent-filter>
-            <intent-filter android:priority="-1">
-                <action android:name="android.intent.action.DIAL" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:scheme="voicemail" />
-            </intent-filter>
-            <intent-filter android:priority="-1">
-                <action android:name="android.intent.action.DIAL" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-            <intent-filter android:priority="-1">
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-            </intent-filter>
-            <intent-filter android:priority="-1">
-                <action android:name="android.intent.action.VIEW" />
-                <action android:name="android.intent.action.DIAL" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:scheme="tel" />
-            </intent-filter>
-            <intent-filter android:priority="-1">
-                <action android:name="android.intent.action.VIEW" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:mimeType="vnd.android.cursor.dir/calls" />
-            </intent-filter>
-            <intent-filter android:priority="-1">
-                <action android:name="android.intent.action.CALL_BUTTON" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-            </intent-filter>
-        </activity>
-
-        <!-- The entrance point for Phone UI.
-             stateAlwaysHidden is set to suppress keyboard show up on
-             dialpad screen. -->
-        <activity android:name=".activities.DialtactsActivity"
-            android:label="@string/launcherDialer"
-            android:theme="@style/DialtactsTheme"
-            android:uiOptions="splitActionBarWhenNarrow"
-            android:launchMode="singleTask"
-            android:clearTaskOnLaunch="true"
-            android:icon="@mipmap/ic_launcher_phone"
-            android:screenOrientation="nosensor"
-            android:enabled="@*android:bool/config_voice_capable"
-            android:taskAffinity="android.task.contacts.phone"
-            android:windowSoftInputMode="stateAlwaysHidden|adjustNothing">
-            <intent-filter>
-                <action android:name="android.intent.action.DIAL" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:mimeType="vnd.android.cursor.item/phone" />
-                <data android:mimeType="vnd.android.cursor.item/person" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.DIAL" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:scheme="voicemail" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.DIAL" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.LAUNCHER" />
-                <category android:name="android.intent.category.BROWSABLE" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW" />
-                <action android:name="android.intent.action.DIAL" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:scheme="tel" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-                <data android:mimeType="vnd.android.cursor.dir/calls" />
-            </intent-filter>
-            <intent-filter>
-                <action android:name="android.intent.action.CALL_BUTTON" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.BROWSABLE" />
-            </intent-filter>
-            <!-- This was never intended to be public, but is here for backward
-                 compatibility.  Use Intent.ACTION_DIAL instead. -->
-            <intent-filter>
-                <action android:name="com.android.phone.action.TOUCH_DIALER" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.TAB" />
-            </intent-filter>
-            <intent-filter android:label="@string/recentCallsIconLabel">
-                <action android:name="com.android.phone.action.RECENT_CALLS" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.TAB" />
-            </intent-filter>
-        </activity>
-
         <!-- The main Contacts activity with the contact list, favorites, and groups. -->
         <activity android:name=".activities.PeopleActivity"
             android:label="@string/people"
@@ -321,24 +201,6 @@
             android:exported="true"
         />
 
-        <!-- Backwards compatibility: "Phone" from Gingerbread and earlier -->
-        <activity-alias android:name="DialtactsActivity"
-            android:targetActivity=".activities.DialtactsActivity"
-            android:exported="true"
-        />
-
-        <!-- Backwards compatibility: "Call log" from Gingerbread and earlier -->
-        <activity-alias android:name="RecentCallsListActivity"
-            android:targetActivity=".activities.DialtactsActivity"
-            android:exported="true"
-        />
-
-        <!-- Backwards compatibility: "Call log" from ICS -->
-        <activity-alias android:name=".activities.CallLogActivity"
-            android:targetActivity=".activities.DialtactsActivity"
-            android:exported="true"
-        />
-
         <!-- An activity for joining contacts -->
         <activity android:name=".activities.JoinContactActivity"
             android:theme="@style/JoinContactActivityTheme"
@@ -461,20 +323,6 @@
 
         </activity-alias>
 
-        <activity android:name="CallDetailActivity"
-            android:label="@string/callDetailTitle"
-            android:theme="@style/CallDetailActivityTheme"
-            android:screenOrientation="portrait"
-            android:icon="@mipmap/ic_launcher_phone"
-            android:taskAffinity="android.task.contacts.phone"
-        >
-            <intent-filter>
-                <action android:name="android.intent.action.VIEW" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <data android:mimeType="vnd.android.cursor.item/calls" />
-            </intent-filter>
-        </activity>
-
         <!-- Views the details of a single contact -->
         <activity android:name=".activities.ContactDetailActivity"
             android:label="@string/viewContactTitle"
@@ -527,7 +375,7 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".test.FragmentTestActivity">
+        <activity android:name=".common.test.FragmentTestActivity">
             <intent-filter>
                 <category android:name="android.intent.category.TEST" />
             </intent-filter>
@@ -628,21 +476,6 @@
                     android:resource="@xml/social_widget_info" />
         </receiver>
 
-        <receiver android:name=".calllog.CallLogReceiver"
-            android:enabled="@*android:bool/config_voice_capable">
-            <intent-filter>
-                <action android:name="android.intent.action.NEW_VOICEMAIL" />
-                <data
-                    android:scheme="content"
-                    android:host="com.android.voicemail"
-                    android:mimeType="vnd.android.cursor.item/voicemail"
-                />
-            </intent-filter>
-            <intent-filter android:priority="100">
-                 <action android:name="android.intent.action.BOOT_COMPLETED"/>
-            </intent-filter>
-        </receiver>
-
         <activity
             android:name=".socialwidget.SocialWidgetConfigureActivity"
             android:theme="@android:style/Theme.Translucent.NoTitleBar" >
@@ -651,20 +484,5 @@
             </intent-filter>
         </activity>
 
-        <service
-            android:name=".calllog.CallLogNotificationsService"
-            android:exported="false"
-        />
-
-        <!-- Service that is exclusively for the Phone application that sends out a view
-             notification. This service might be removed in future versions of the app  -->
-        <service android:name=".ViewNotificationService"
-            android:permission="android.permission.WRITE_CONTACTS"
-            android:exported="true">
-            <intent-filter>
-                <action android:name="com.android.contacts.VIEW_NOTIFICATION" />
-                <data android:mimeType="vnd.android.cursor.item/contact" />
-            </intent-filter>
-        </service>
     </application>
 </manifest>
diff --git a/res/layout-land/dialpad_fragment.xml b/res/layout-land/dialpad_fragment.xml
deleted file mode 100644
index 63dd369..0000000
--- a/res/layout-land/dialpad_fragment.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/top"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent" >
-
-    <LinearLayout
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="3"
-        android:orientation="vertical" >
-
-        <LinearLayout
-            android:id="@+id/digits_container"
-            android:layout_width="match_parent"
-            android:layout_height="0px"
-            android:layout_weight="@integer/dialpad_layout_weight_digits"
-            android:layout_marginTop="@dimen/dialpad_vertical_margin"
-            android:background="@drawable/dialpad_background"
-            android:gravity="center">
-
-            <com.android.contacts.dialpad.DigitsEditText
-                android:id="@+id/digits"
-                android:layout_width="0dip"
-                android:layout_weight="1"
-                android:layout_height="match_parent"
-                android:gravity="center"
-                android:textAppearance="@style/DialtactsDigitsTextAppearance"
-                android:textColor="?android:attr/textColorPrimary"
-                android:nextFocusRight="@+id/overflow_menu"
-                android:background="@android:color/transparent" />
-
-            <ImageButton
-                android:id="@+id/deleteButton"
-                android:layout_width="56dip"
-                android:layout_height="match_parent"
-                android:layout_gravity="center_vertical"
-                android:gravity="center"
-                android:state_enabled="false"
-                android:background="?android:attr/selectableItemBackground"
-                android:contentDescription="@string/description_delete_button"
-                android:src="@drawable/ic_dial_action_delete" />
-
-
-        </LinearLayout>
-        <!-- "Dialpad chooser" UI, shown only when the user brings up the
-         Dialer while a call is already in progress.
-         When this UI is visible, the other Dialer elements
-         (the textfield and button) are hidden. -->
-        <ListView android:id="@+id/dialpadChooser"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:footerDividersEnabled="true" />
-
-        <!-- Keypad section -->
-        <include layout="@layout/dialpad" />
-    </LinearLayout>
-    <View
-       android:layout_width="@dimen/dialpad_center_margin"
-       android:layout_height="match_parent"
-       android:background="#66000000"/>
-    <RelativeLayout
-        android:id="@+id/dialButtonContainer"
-        android:layout_width="0dp"
-        android:layout_height="match_parent"
-        android:layout_weight="2"
-        android:background="@drawable/dialpad_background">
-        <View
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/dialpad_button_margin"
-            android:layout_above="@id/dialButton"
-            android:background="#33000000" />
-        <ImageButton android:id="@+id/dialButton"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/call_button_height"
-            android:layout_alignParentBottom="true"
-            android:state_enabled="false"
-            android:background="@drawable/btn_call"
-            android:contentDescription="@string/description_dial_button"
-            android:src="@drawable/ic_dial_action_call" />
-    </RelativeLayout>
-</LinearLayout>
diff --git a/res/layout-land/dialtacts_activity.xml b/res/layout-land/dialtacts_activity.xml
deleted file mode 100644
index f43fe5f..0000000
--- a/res/layout-land/dialtacts_activity.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 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.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_marginTop="?android:attr/actionBarSize"
-    android:id="@+id/dialtacts_frame"
-    >
-    <android.support.v4.view.ViewPager
-        android:id="@+id/pager"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" />
-</FrameLayout>
diff --git a/res/layout/call_detail.xml b/res/layout/call_detail.xml
deleted file mode 100644
index 8f38a19..0000000
--- a/res/layout/call_detail.xml
+++ /dev/null
@@ -1,218 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:ex="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/call_detail"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:visibility="gone"
-    android:background="@android:color/black"
->
-    <!--
-      The list view is under everything.
-      It contains a first header element which is hidden under the controls UI.
-      When scrolling, the controls move up until the name bar hits the top.
-      -->
-    <ListView
-        android:id="@+id/history"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-    />
-
-    <!-- All the controls which are part of the pinned header are in this layout. -->
-    <RelativeLayout
-        android:id="@+id/controls"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-    >
-        <FrameLayout
-            android:id="@+id/voicemail_status"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignParentLeft="true"
-            android:layout_alignParentTop="true"
-            android:visibility="gone"
-        >
-            <include layout="@layout/call_log_voicemail_status"/>
-        </FrameLayout>
-
-        <view
-            class="com.android.contacts.widget.ProportionalLayout"
-            android:id="@+id/contact_background_sizer"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_alignParentLeft="true"
-            android:layout_below="@id/voicemail_status"
-            ex:ratio="0.5"
-            ex:direction="widthToHeight"
-        >
-            <ImageView
-                android:id="@+id/contact_background"
-                android:layout_width="match_parent"
-                android:layout_height="0dip"
-                android:adjustViewBounds="true"
-                android:scaleType="centerCrop"
-            />
-        </view>
-        <LinearLayout
-            android:id="@+id/blue_separator"
-            android:layout_width="match_parent"
-            android:layout_height="1dip"
-            android:background="@android:color/holo_blue_light"
-            android:layout_below="@+id/contact_background_sizer"
-        />
-        <View
-            android:id="@+id/photo_text_bar"
-            android:layout_width="match_parent"
-            android:layout_height="42dip"
-            android:background="#7F000000"
-            android:layout_alignParentLeft="true"
-            android:layout_alignBottom="@id/contact_background_sizer"
-        />
-        <ImageView
-            android:id="@+id/main_action"
-            android:layout_width="wrap_content"
-            android:layout_height="0dip"
-            android:scaleType="center"
-            android:layout_alignRight="@id/photo_text_bar"
-            android:layout_alignBottom="@id/photo_text_bar"
-            android:layout_alignTop="@id/photo_text_bar"
-            android:layout_marginRight="@dimen/call_log_outer_margin"
-        />
-        <TextView
-            android:id="@+id/header_text"
-            android:layout_width="wrap_content"
-            android:layout_height="0dip"
-            android:layout_alignLeft="@id/photo_text_bar"
-            android:layout_toLeftOf="@id/main_action"
-            android:layout_alignTop="@id/photo_text_bar"
-            android:layout_alignBottom="@id/photo_text_bar"
-            android:layout_marginRight="@dimen/call_log_inner_margin"
-            android:layout_marginLeft="@dimen/call_detail_contact_name_margin"
-            android:gravity="center_vertical"
-            android:textColor="?attr/call_log_primary_text_color"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:singleLine="true"
-        />
-        <ImageButton
-            android:id="@+id/main_action_push_layer"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_alignLeft="@id/contact_background_sizer"
-            android:layout_alignTop="@id/contact_background_sizer"
-            android:layout_alignRight="@id/contact_background_sizer"
-            android:layout_alignBottom="@id/contact_background_sizer"
-            android:background="?android:attr/selectableItemBackground"
-        />
-        <LinearLayout
-            android:id="@+id/voicemail_container"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingBottom="@dimen/call_detail_button_spacing"
-            android:layout_below="@id/blue_separator"
-        >
-            <!-- The voicemail fragment will be put here. -->
-        </LinearLayout>
-        <FrameLayout
-            android:id="@+id/call_and_sms"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/call_log_list_item_height"
-            android:layout_marginBottom="@dimen/call_detail_button_spacing"
-            android:layout_below="@id/voicemail_container"
-            android:gravity="center_vertical"
-            android:background="@drawable/dialpad_background"
-        >
-            <LinearLayout
-                android:id="@+id/call_and_sms_main_action"
-                android:layout_width="match_parent"
-                android:layout_height="match_parent"
-                android:orientation="horizontal"
-                android:focusable="true"
-                android:background="?android:attr/selectableItemBackground"
-                >
-
-                <LinearLayout
-                    android:layout_width="0dip"
-                    android:layout_height="match_parent"
-                    android:layout_weight="1"
-                    android:paddingLeft="@dimen/call_log_indent_margin"
-                    android:orientation="vertical"
-                    android:gravity="center_vertical"
-                >
-
-                    <TextView android:id="@+id/call_and_sms_text"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:paddingRight="@dimen/call_log_icon_margin"
-                        android:textAppearance="?android:attr/textAppearanceMedium"
-                        android:textColor="?attr/call_log_primary_text_color"
-                        android:singleLine="true"
-                        android:ellipsize="end"
-                    />
-
-                    <TextView android:id="@+id/call_and_sms_label"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:paddingRight="@dimen/call_log_icon_margin"
-                        android:textAppearance="?android:attr/textAppearanceSmall"
-                        android:textColor="?attr/call_log_primary_text_color"
-                        android:textAllCaps="true"
-                        android:singleLine="true"
-                        android:ellipsize="end"
-                    />
-                </LinearLayout>
-
-                <View android:id="@+id/call_and_sms_divider"
-                    android:layout_width="1px"
-                    android:layout_height="32dip"
-                    android:background="@drawable/ic_divider_dashed_holo_dark"
-                    android:layout_gravity="center_vertical"
-                />
-
-                <ImageView android:id="@+id/call_and_sms_icon"
-                    android:layout_width="@color/call_log_voicemail_highlight_color"
-                    android:layout_height="match_parent"
-                    android:paddingLeft="@dimen/call_log_inner_margin"
-                    android:paddingRight="@dimen/call_log_outer_margin"
-                    android:gravity="center"
-                    android:scaleType="centerInside"
-                    android:focusable="true"
-                    android:background="?android:attr/selectableItemBackground"
-                />
-            </LinearLayout>
-        </FrameLayout>
-    </RelativeLayout>
-
-    <!--
-         Used to hide the UI when playing a voicemail and the proximity sensor
-         is detecting something near the screen.
-      -->
-    <View
-        android:id="@+id/blank"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
-        android:background="@android:color/black"
-        android:visibility="gone"
-        android:clickable="true"
-    />
-</RelativeLayout>
diff --git a/res/layout/call_detail_history_header.xml b/res/layout/call_detail_history_header.xml
deleted file mode 100644
index 09047c5..0000000
--- a/res/layout/call_detail_history_header.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<!-- This layout is supposed to match the content of the controls in call_detail.xml  -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:ex="http://schemas.android.com/apk/res-auto"
-    android:orientation="vertical"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content">
-
-    <!-- Contact photo. -->
-    <view
-        class="com.android.contacts.widget.ProportionalLayout"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentLeft="true"
-        android:layout_below="@id/voicemail_status"
-        ex:ratio="0.5"
-        ex:direction="widthToHeight"
-    >
-        <!-- Proportional layout requires a view in it. -->
-        <View
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-        />
-    </view>
-    <!-- Separator line -->
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="1dip"
-    />
-    <!-- Voicemail controls -->
-    <!-- TODO: Make the height be based on a constant. -->
-    <View
-        android:id="@+id/header_voicemail_container"
-        android:layout_width="match_parent"
-        android:layout_height="140dip"
-        android:layout_marginBottom="@dimen/call_detail_button_spacing"
-    />
-    <!-- Call and SMS -->
-    <View
-        android:id="@+id/header_call_and_sms_container"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/call_log_list_item_height"
-    />
-
-</LinearLayout>
diff --git a/res/layout/call_detail_history_item.xml b/res/layout/call_detail_history_item.xml
deleted file mode 100644
index 28a7da0..0000000
--- a/res/layout/call_detail_history_item.xml
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:minHeight="@dimen/call_log_list_item_height"
-    android:paddingTop="@dimen/call_log_inner_margin"
-    android:paddingBottom="@dimen/call_log_inner_margin"
-    android:paddingLeft="@dimen/call_log_indent_margin"
-    android:paddingRight="@dimen/call_log_outer_margin"
-    android:orientation="vertical"
->
-    <LinearLayout
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="horizontal"
-    >
-        <view
-            class="com.android.contacts.calllog.CallTypeIconsView"
-            android:id="@+id/call_type_icon"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-        />
-        <TextView
-            android:id="@+id/call_type_text"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginLeft="@dimen/call_log_icon_margin"
-            android:textAppearance="?android:attr/textAppearanceSmall"
-            android:textColor="@color/secondary_text_color"
-        />
-    </LinearLayout>
-    <TextView
-        android:id="@+id/date"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="@color/secondary_text_color"
-    />
-    <TextView
-        android:id="@+id/duration"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="@color/secondary_text_color"
-    />
-</LinearLayout>
diff --git a/res/layout/call_log_fragment.xml b/res/layout/call_log_fragment.xml
deleted file mode 100644
index 34b4b7f..0000000
--- a/res/layout/call_log_fragment.xml
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<!-- Layout parameters are set programmatically. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/FragmentActionBarPadding"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical"
-    android:divider="?android:attr/dividerHorizontal"
-    android:showDividers="end">
-
-    <FrameLayout
-        android:id="@+id/voicemail_status"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:visibility="gone">
-        <include layout="@layout/call_log_voicemail_status"
-    />
-    </FrameLayout>
-
-    <FrameLayout>
-        <TextView
-            android:id="@+id/filter_status"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingLeft="@dimen/call_log_outer_margin"
-            android:paddingRight="@dimen/call_log_outer_margin"
-            android:paddingTop="@dimen/call_log_inner_margin"
-            android:paddingBottom="@dimen/call_log_inner_margin"
-            android:layout_alignParentLeft="true"
-            android:layout_alignParentBottom="true"
-            android:visibility="gone"
-            />
-        <View
-            android:id="@+id/call_log_divider"
-            android:layout_width="match_parent"
-            android:layout_height="1px"
-            android:layout_marginLeft="@dimen/call_log_outer_margin"
-            android:layout_marginRight="@dimen/call_log_outer_margin"
-            android:layout_gravity="bottom"
-            android:background="#55ffffff"
-            />
-    </FrameLayout>
-    <FrameLayout
-        android:layout_width="match_parent"
-        android:layout_height="match_parent">
-        <ListView android:id="@android:id/list"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:fadingEdge="none"
-            android:scrollbarStyle="outsideOverlay"
-            android:divider="@null"
-        />
-        <TextView android:id="@android:id/empty"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:text="@string/recentCalls_empty"
-            android:gravity="center"
-            android:layout_marginTop="@dimen/empty_message_top_margin"
-            android:textColor="?android:attr/textColorSecondary"
-            android:textAppearance="?android:attr/textAppearanceLarge"
-        />
-    </FrameLayout>
-</LinearLayout>
diff --git a/res/layout/call_log_list_item.xml b/res/layout/call_log_list_item.xml
deleted file mode 100644
index 4040c28..0000000
--- a/res/layout/call_log_list_item.xml
+++ /dev/null
@@ -1,167 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<view
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    class="com.android.contacts.calllog.CallLogListItemView"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical"
->
-    <!--
-        This layout may represent either a call log item or one of the
-        headers in the call log.
-
-        The former will make the @id/call_log_item visible and the
-        @id/call_log_header gone.
-
-        The latter will make the @id/call_log_header visible and the
-        @id/call_log_item gone
-    -->
-
-        <LinearLayout
-            android:id="@+id/primary_action_view"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_centerVertical="true"
-            android:layout_marginLeft="@dimen/call_log_outer_margin"
-            android:layout_marginRight="@dimen/call_log_outer_margin"
-            android:orientation="horizontal"
-            android:gravity="center_vertical"
-            android:background="?android:attr/selectableItemBackground"
-            android:focusable="true"
-            android:nextFocusRight="@+id/secondary_action_icon"
-            android:nextFocusLeft="@+id/quick_contact_photo"
-        >
-            <QuickContactBadge
-                android:id="@+id/quick_contact_photo"
-                android:layout_width="@dimen/call_log_list_contact_photo_size"
-                android:layout_height="@dimen/call_log_list_contact_photo_size"
-                android:nextFocusRight="@id/primary_action_view"
-                android:layout_alignParentLeft="true"
-                android:layout_centerVertical="true"
-                android:focusable="true"
-            />
-            <LinearLayout
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:paddingTop="@dimen/call_log_inner_margin"
-                android:paddingBottom="@dimen/call_log_inner_margin"
-                android:orientation="vertical"
-                android:gravity="center_vertical"
-                android:layout_marginLeft="@dimen/call_log_inner_margin"
-            >
-                <TextView
-                    android:id="@+id/name"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:layout_marginRight="@dimen/call_log_icon_margin"
-                    android:textColor="?attr/call_log_primary_text_color"
-                    android:textSize="18sp"
-                    android:singleLine="true"
-                />
-                <LinearLayout
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:orientation="horizontal"
-                >
-                    <TextView
-                        android:id="@+id/number"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginRight="@dimen/call_log_icon_margin"
-                        android:textColor="?attr/call_log_secondary_text_color"
-                        android:textSize="14sp"
-                        android:singleLine="true"
-                        android:ellipsize="marquee"
-                        />
-                    <TextView
-                        android:id="@+id/label"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginRight="@dimen/call_log_icon_margin"
-                        android:textColor="?attr/call_log_secondary_text_color"
-                        android:textStyle="bold"
-                        android:textSize="14sp"
-                        android:singleLine="true"
-                        android:ellipsize="marquee"
-                        />
-                    </LinearLayout>
-                <LinearLayout
-                    android:id="@+id/call_type"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:orientation="horizontal"
-                >
-                    <view
-                        class="com.android.contacts.calllog.CallTypeIconsView"
-                        android:id="@+id/call_type_icons"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginRight="@dimen/call_log_icon_margin"
-                        android:layout_gravity="center_vertical"
-                    />
-                    <TextView
-                        android:id="@+id/call_count_and_date"
-                        android:layout_width="wrap_content"
-                        android:layout_height="wrap_content"
-                        android:layout_marginRight="@dimen/call_log_icon_margin"
-                        android:layout_gravity="center_vertical"
-                        android:textColor="?attr/call_log_secondary_text_color"
-                        android:textSize="14sp"
-                        android:singleLine="true"
-                    />
-                </LinearLayout>
-            </LinearLayout>
-            <View
-                android:id="@+id/divider"
-                android:layout_width="1px"
-                android:layout_height="@dimen/call_log_call_action_size"
-                android:background="@drawable/ic_divider_dashed_holo_dark"
-                android:layout_gravity="center_vertical"
-            />
-            <ImageButton
-                android:id="@+id/secondary_action_icon"
-                android:layout_width="@dimen/call_log_call_action_width"
-                android:layout_height="match_parent"
-                android:paddingLeft="@dimen/call_log_inner_margin"
-                android:paddingTop="@dimen/call_log_inner_margin"
-                android:paddingBottom="@dimen/call_log_inner_margin"
-                android:paddingRight="@dimen/call_log_inner_margin"
-                android:scaleType="center"
-                android:background="?android:attr/selectableItemBackground"
-                android:nextFocusLeft="@id/primary_action_view"
-            />
-        </LinearLayout>
-
-    <TextView
-        android:id="@+id/call_log_header"
-        style="@style/ContactListSeparatorTextViewStyle"
-        android:layout_marginLeft="@dimen/call_log_outer_margin"
-        android:layout_marginRight="@dimen/call_log_outer_margin"
-        android:paddingTop="@dimen/call_log_inner_margin"
-        android:paddingBottom="@dimen/call_log_inner_margin" />
-
-    <View
-        android:id="@+id/call_log_divider"
-        android:layout_width="match_parent"
-        android:layout_height="1px"
-        android:layout_marginLeft="@dimen/call_log_outer_margin"
-        android:layout_marginRight="@dimen/call_log_outer_margin"
-        android:background="#55ffffff"
-    />
-</view>
diff --git a/res/layout/call_log_voicemail_status.xml b/res/layout/call_log_voicemail_status.xml
deleted file mode 100644
index 191c821..0000000
--- a/res/layout/call_log_voicemail_status.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="?attr/call_log_voicemail_status_height"
-        android:background="?attr/call_log_voicemail_status_background_color"
-    >
-        <TextView
-            android:id="@+id/voicemail_status_message"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:layout_weight="1"
-            android:paddingLeft="@dimen/call_log_outer_margin"
-            android:paddingRight="@dimen/call_log_inner_margin"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textColor="?attr/call_log_voicemail_status_text_color"
-        />
-        <TextView
-            android:id="@+id/voicemail_status_action"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:gravity="center_vertical"
-            android:paddingLeft="@dimen/call_log_inner_margin"
-            android:paddingRight="@dimen/call_log_outer_margin"
-            android:textAppearance="?android:attr/textAppearanceMedium"
-            android:textColor="?attr/call_log_voicemail_status_action_text_color"
-            android:background="?android:attr/selectableItemBackground"
-            android:clickable="true"
-        />
-    </LinearLayout>
-</merge>
diff --git a/res/layout/dialpad.xml b/res/layout/dialpad.xml
deleted file mode 100644
index 54b7955..0000000
--- a/res/layout/dialpad.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 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.
--->
-
-<!-- Dialpad in the Phone app. -->
-<TableLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/dialpad"
-    android:layout_width="match_parent"
-    android:layout_height="0px"
-    android:layout_weight="@integer/dialpad_layout_weight_dialpad"
-    android:layout_gravity="center_horizontal"
-    android:layout_marginTop="@dimen/dialpad_vertical_margin"
-    android:paddingLeft="5dip"
-    android:paddingRight="5dip"
-    android:paddingBottom="10dip"
-    android:background="@drawable/dialpad_background">
-
-    <TableRow
-         android:layout_height="0px"
-         android:layout_weight="1">
-        <com.android.contacts.dialpad.DialpadImageButton
-            android:id="@+id/one" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_1_wht"
-            android:contentDescription="@string/description_image_button_one" />
-        <com.android.contacts.dialpad.DialpadImageButton
-            android:id="@+id/two" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_2_wht"
-            android:contentDescription="@string/description_image_button_two" />
-        <com.android.contacts.dialpad.DialpadImageButton
-            android:id="@+id/three" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_3_wht"
-            android:contentDescription="@string/description_image_button_three" />
-    </TableRow>
-
-    <TableRow
-         android:layout_height="0px"
-         android:layout_weight="1">
-        <com.android.contacts.dialpad.DialpadImageButton
-            android:id="@+id/four" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_4_wht"
-            android:contentDescription="@string/description_image_button_four" />
-        <com.android.contacts.dialpad.DialpadImageButton
-            android:id="@+id/five" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_5_wht"
-            android:contentDescription="@string/description_image_button_five" />
-        <com.android.contacts.dialpad.DialpadImageButton
-            android:id="@+id/six" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_6_wht"
-            android:contentDescription="@string/description_image_button_six" />
-    </TableRow>
-
-    <TableRow
-         android:layout_height="0px"
-         android:layout_weight="1">
-        <com.android.contacts.dialpad.DialpadImageButton
-            android:id="@+id/seven" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_7_wht"
-            android:contentDescription="@string/description_image_button_seven" />
-        <com.android.contacts.dialpad.DialpadImageButton
-            android:id="@+id/eight" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_8_wht"
-            android:contentDescription="@string/description_image_button_eight" />
-        <com.android.contacts.dialpad.DialpadImageButton
-            android:id="@+id/nine" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_9_wht"
-            android:contentDescription="@string/description_image_button_nine" />
-    </TableRow>
-
-    <TableRow
-         android:layout_height="0px"
-         android:layout_weight="1">
-        <com.android.contacts.dialpad.DialpadImageButton
-            android:id="@+id/star" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_star_wht"
-            android:contentDescription="@string/description_image_button_star" />
-        <com.android.contacts.dialpad.DialpadImageButton
-            android:id="@+id/zero" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_0_wht"
-            android:contentDescription="@string/description_image_button_zero" />
-        <com.android.contacts.dialpad.DialpadImageButton
-            android:id="@+id/pound" style="@style/DialtactsDialpadButtonStyle"
-            android:src="@drawable/dial_num_pound_wht"
-            android:contentDescription="@string/description_image_button_pound" />
-    </TableRow>
-</TableLayout>
diff --git a/res/layout/dialpad_chooser_list_item.xml b/res/layout/dialpad_chooser_list_item.xml
deleted file mode 100644
index 853ca47..0000000
--- a/res/layout/dialpad_chooser_list_item.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 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.
--->
-
-<!-- Layout of a single item in the Dialer's "Dialpad chooser" UI. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="horizontal"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent">
-
-    <ImageView android:id="@+id/icon"
-        android:layout_width="64dp"
-        android:layout_height="64dp"
-        android:scaleType="center" />
-
-    <TextView android:id="@+id/text"
-        android:textAppearance="?android:attr/textAppearanceMedium"
-        android:layout_gravity="center_vertical"
-        android:layout_width="0dip"
-        android:layout_weight="1"
-        android:layout_height="wrap_content" />
-
-</LinearLayout>
diff --git a/res/layout/dialpad_fragment.xml b/res/layout/dialpad_fragment.xml
deleted file mode 100644
index 796eb28..0000000
--- a/res/layout/dialpad_fragment.xml
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/top"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical"
-    android:paddingLeft="@dimen/dialpad_horizontal_margin"
-    android:paddingRight="@dimen/dialpad_horizontal_margin">
-
-    <!-- Text field and possibly soft menu button above the keypad where
-         the digits are displayed. -->
-    <LinearLayout
-        android:id="@+id/digits_container"
-        android:layout_width="match_parent"
-        android:layout_height="0px"
-        android:layout_weight="@integer/dialpad_layout_weight_digits"
-        android:layout_marginTop="@dimen/dialpad_vertical_margin"
-        android:gravity="center"
-        android:background="@drawable/dialpad_background" >
-
-        <com.android.contacts.dialpad.DigitsEditText
-            android:id="@+id/digits"
-            android:layout_width="0dip"
-            android:layout_weight="1"
-            android:layout_height="match_parent"
-            android:gravity="center"
-            android:textAppearance="@style/DialtactsDigitsTextAppearance"
-            android:textColor="?android:attr/textColorPrimary"
-            android:nextFocusRight="@+id/overflow_menu"
-            android:background="@android:color/transparent" />
-
-        <ImageButton
-            android:id="@+id/deleteButton"
-            android:layout_width="56dip"
-            android:layout_height="match_parent"
-            android:layout_gravity="center_vertical"
-            android:gravity="center"
-            android:state_enabled="false"
-            android:background="?android:attr/selectableItemBackground"
-            android:contentDescription="@string/description_delete_button"
-            android:src="@drawable/ic_dial_action_delete" />
-    </LinearLayout>
-
-    <!-- Keypad section -->
-    <include layout="@layout/dialpad" />
-
-    <View
-       android:layout_width="match_parent"
-       android:layout_height="@dimen/dialpad_vertical_margin"
-       android:background="#66000000"/>
-
-    <!-- left and right paddings will be modified by the code. See DialpadFragment. -->
-    <FrameLayout
-        android:id="@+id/dialButtonContainer"
-        android:layout_width="match_parent"
-        android:layout_height="0px"
-        android:layout_weight="@integer/dialpad_layout_weight_additional_buttons"
-        android:layout_gravity="center_horizontal"
-        android:background="@drawable/dialpad_background">
-
-        <ImageButton
-            android:id="@+id/dialButton"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_gravity="center"
-            android:state_enabled="false"
-            android:background="@drawable/btn_call"
-            android:contentDescription="@string/description_dial_button"
-            android:src="@drawable/ic_dial_action_call" />
-
-    </FrameLayout>
-
-    <!-- "Dialpad chooser" UI, shown only when the user brings up the
-         Dialer while a call is already in progress.
-         When this UI is visible, the other Dialer elements
-         (the textfield/button and the dialpad) are hidden. -->
-    <ListView android:id="@+id/dialpadChooser"
-        android:layout_width="match_parent"
-        android:layout_height="1dip"
-        android:layout_weight="1"
-    />
-
-</LinearLayout>
diff --git a/res/layout/dialtacts_activity.xml b/res/layout/dialtacts_activity.xml
deleted file mode 100644
index 35fa00f..0000000
--- a/res/layout/dialtacts_activity.xml
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 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.
--->
-
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:layout_marginTop="?android:attr/actionBarSize"
-    android:id="@+id/dialtacts_frame"
-    >
-    <android.support.v4.view.ViewPager
-        android:id="@+id/pager"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" />
-
-    <ImageButton
-         android:id="@+id/searchButton"
-         android:layout_width="wrap_content"
-         android:layout_height="?android:attr/actionBarSize"
-         android:layout_gravity="bottom|left"
-         android:state_enabled="false"
-         android:background="?android:attr/selectableItemBackground"
-         android:contentDescription="@string/description_search_button"
-         android:src="@drawable/ic_dial_action_search"/>
-
-    <ImageButton
-         android:id="@+id/overflow_menu"
-         android:layout_width="wrap_content"
-         android:layout_height="?android:attr/actionBarSize"
-         android:layout_gravity="bottom|right"
-         android:src="@drawable/ic_menu_overflow"
-         android:contentDescription="@string/action_menu_overflow_description"
-         android:nextFocusLeft="@id/digits"
-         android:background="?android:attr/selectableItemBackground"/>
-</FrameLayout>
diff --git a/res/layout/dialtacts_custom_action_bar.xml b/res/layout/dialtacts_custom_action_bar.xml
deleted file mode 100644
index 0af8eaa..0000000
--- a/res/layout/dialtacts_custom_action_bar.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<!-- Dimensions are set at runtime in ActionBarAdapter -->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="0dip"
-    android:layout_height="0dip"
-    android:orientation="horizontal">
-
-    <SearchView
-        android:id="@+id/search_view"
-        android:layout_width="0px"
-        android:layout_height="match_parent"
-        android:layout_weight="1"
-        android:iconifiedByDefault="false"
-        android:inputType="textFilter" />
-
-    <ImageButton
-        android:id="@+id/search_option"
-        android:layout_width="wrap_content"
-        android:paddingLeft="4dip"
-        android:paddingRight="4dip"
-        android:layout_height="match_parent"
-        android:layout_alignParentRight="true"
-        android:src="@drawable/ic_menu_overflow"
-        android:background="?android:attr/selectableItemBackground"
-        android:visibility="gone" />
-
-</LinearLayout>
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
deleted file mode 100644
index 7bb2157..0000000
--- a/src/com/android/contacts/CallDetailActivity.java
+++ /dev/null
@@ -1,936 +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;
-
-import android.app.ActionBar;
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.provider.CallLog;
-import android.provider.CallLog.Calls;
-import android.provider.Contacts.Intents.Insert;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.Contacts;
-import android.provider.VoicemailContract.Voicemails;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.ActionMode;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.contacts.BackScrollManager.ScrollableHeader;
-import com.android.contacts.calllog.CallDetailHistoryAdapter;
-import com.android.contacts.calllog.CallTypeHelper;
-import com.android.contacts.calllog.ContactInfo;
-import com.android.contacts.calllog.ContactInfoHelper;
-import com.android.contacts.calllog.PhoneNumberHelper;
-import com.android.contacts.format.FormatUtils;
-import com.android.contacts.util.AsyncTaskExecutor;
-import com.android.contacts.util.AsyncTaskExecutors;
-import com.android.contacts.util.ClipboardUtils;
-import com.android.contacts.util.Constants;
-import com.android.contacts.voicemail.VoicemailPlaybackFragment;
-import com.android.contacts.voicemail.VoicemailStatusHelper;
-import com.android.contacts.voicemail.VoicemailStatusHelper.StatusMessage;
-import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
-
-import java.util.List;
-
-/**
- * Displays the details of a specific call log entry.
- * <p>
- * This activity can be either started with the URI of a single call log entry, or with the
- * {@link #EXTRA_CALL_LOG_IDS} extra to specify a group of call log entries.
- */
-public class CallDetailActivity extends Activity implements ProximitySensorAware {
-    private static final String TAG = "CallDetail";
-
-    /** The time to wait before enabling the blank the screen due to the proximity sensor. */
-    private static final long PROXIMITY_BLANK_DELAY_MILLIS = 100;
-    /** The time to wait before disabling the blank the screen due to the proximity sensor. */
-    private static final long PROXIMITY_UNBLANK_DELAY_MILLIS = 500;
-
-    /** The enumeration of {@link AsyncTask} objects used in this class. */
-    public enum Tasks {
-        MARK_VOICEMAIL_READ,
-        DELETE_VOICEMAIL_AND_FINISH,
-        REMOVE_FROM_CALL_LOG_AND_FINISH,
-        UPDATE_PHONE_CALL_DETAILS,
-    }
-
-    /** A long array extra containing ids of call log entries to display. */
-    public static final String EXTRA_CALL_LOG_IDS = "EXTRA_CALL_LOG_IDS";
-    /** If we are started with a voicemail, we'll find the uri to play with this extra. */
-    public static final String EXTRA_VOICEMAIL_URI = "EXTRA_VOICEMAIL_URI";
-    /** If we should immediately start playback of the voicemail, this extra will be set to true. */
-    public static final String EXTRA_VOICEMAIL_START_PLAYBACK = "EXTRA_VOICEMAIL_START_PLAYBACK";
-    /** If the activity was triggered from a notification. */
-    public static final String EXTRA_FROM_NOTIFICATION = "EXTRA_FROM_NOTIFICATION";
-
-    private CallTypeHelper mCallTypeHelper;
-    private PhoneNumberHelper mPhoneNumberHelper;
-    private PhoneCallDetailsHelper mPhoneCallDetailsHelper;
-    private TextView mHeaderTextView;
-    private View mHeaderOverlayView;
-    private ImageView mMainActionView;
-    private ImageButton mMainActionPushLayerView;
-    private ImageView mContactBackgroundView;
-    private AsyncTaskExecutor mAsyncTaskExecutor;
-    private ContactInfoHelper mContactInfoHelper;
-
-    private String mNumber = null;
-    private String mDefaultCountryIso;
-
-    /* package */ LayoutInflater mInflater;
-    /* package */ Resources mResources;
-    /** Helper to load contact photos. */
-    private ContactPhotoManager mContactPhotoManager;
-    /** Helper to make async queries to content resolver. */
-    private CallDetailActivityQueryHandler mAsyncQueryHandler;
-    /** Helper to get voicemail status messages. */
-    private VoicemailStatusHelper mVoicemailStatusHelper;
-    // Views related to voicemail status message.
-    private View mStatusMessageView;
-    private TextView mStatusMessageText;
-    private TextView mStatusMessageAction;
-
-    /** Whether we should show "edit number before call" in the options menu. */
-    private boolean mHasEditNumberBeforeCallOption;
-    /** Whether we should show "trash" in the options menu. */
-    private boolean mHasTrashOption;
-    /** Whether we should show "remove from call log" in the options menu. */
-    private boolean mHasRemoveFromCallLogOption;
-
-    private ProximitySensorManager mProximitySensorManager;
-    private final ProximitySensorListener mProximitySensorListener = new ProximitySensorListener();
-
-    /**
-     * The action mode used when the phone number is selected.  This will be non-null only when the
-     * phone number is selected.
-     */
-    private ActionMode mPhoneNumberActionMode;
-
-    private CharSequence mPhoneNumberLabelToCopy;
-    private CharSequence mPhoneNumberToCopy;
-
-    /** Listener to changes in the proximity sensor state. */
-    private class ProximitySensorListener implements ProximitySensorManager.Listener {
-        /** Used to show a blank view and hide the action bar. */
-        private final Runnable mBlankRunnable = new Runnable() {
-            @Override
-            public void run() {
-                View blankView = findViewById(R.id.blank);
-                blankView.setVisibility(View.VISIBLE);
-                getActionBar().hide();
-            }
-        };
-        /** Used to remove the blank view and show the action bar. */
-        private final Runnable mUnblankRunnable = new Runnable() {
-            @Override
-            public void run() {
-                View blankView = findViewById(R.id.blank);
-                blankView.setVisibility(View.GONE);
-                getActionBar().show();
-            }
-        };
-
-        @Override
-        public synchronized void onNear() {
-            clearPendingRequests();
-            postDelayed(mBlankRunnable, PROXIMITY_BLANK_DELAY_MILLIS);
-        }
-
-        @Override
-        public synchronized void onFar() {
-            clearPendingRequests();
-            postDelayed(mUnblankRunnable, PROXIMITY_UNBLANK_DELAY_MILLIS);
-        }
-
-        /** Removed any delayed requests that may be pending. */
-        public synchronized void clearPendingRequests() {
-            View blankView = findViewById(R.id.blank);
-            blankView.removeCallbacks(mBlankRunnable);
-            blankView.removeCallbacks(mUnblankRunnable);
-        }
-
-        /** Post a {@link Runnable} with a delay on the main thread. */
-        private synchronized void postDelayed(Runnable runnable, long delayMillis) {
-            // Post these instead of executing immediately so that:
-            // - They are guaranteed to be executed on the main thread.
-            // - If the sensor values changes rapidly for some time, the UI will not be
-            //   updated immediately.
-            View blankView = findViewById(R.id.blank);
-            blankView.postDelayed(runnable, delayMillis);
-        }
-    }
-
-    static final String[] CALL_LOG_PROJECTION = new String[] {
-        CallLog.Calls.DATE,
-        CallLog.Calls.DURATION,
-        CallLog.Calls.NUMBER,
-        CallLog.Calls.TYPE,
-        CallLog.Calls.COUNTRY_ISO,
-        CallLog.Calls.GEOCODED_LOCATION,
-    };
-
-    static final int DATE_COLUMN_INDEX = 0;
-    static final int DURATION_COLUMN_INDEX = 1;
-    static final int NUMBER_COLUMN_INDEX = 2;
-    static final int CALL_TYPE_COLUMN_INDEX = 3;
-    static final int COUNTRY_ISO_COLUMN_INDEX = 4;
-    static final int GEOCODED_LOCATION_COLUMN_INDEX = 5;
-
-    private final View.OnClickListener mPrimaryActionListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View view) {
-            if (finishPhoneNumerSelectedActionModeIfShown()) {
-                return;
-            }
-            startActivity(((ViewEntry) view.getTag()).primaryIntent);
-        }
-    };
-
-    private final View.OnClickListener mSecondaryActionListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View view) {
-            if (finishPhoneNumerSelectedActionModeIfShown()) {
-                return;
-            }
-            startActivity(((ViewEntry) view.getTag()).secondaryIntent);
-        }
-    };
-
-    private final View.OnLongClickListener mPrimaryLongClickListener =
-            new View.OnLongClickListener() {
-        @Override
-        public boolean onLongClick(View v) {
-            if (finishPhoneNumerSelectedActionModeIfShown()) {
-                return true;
-            }
-            startPhoneNumberSelectedActionMode(v);
-            return true;
-        }
-    };
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        setContentView(R.layout.call_detail);
-
-        mAsyncTaskExecutor = AsyncTaskExecutors.createThreadPoolExecutor();
-        mInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
-        mResources = getResources();
-
-        mCallTypeHelper = new CallTypeHelper(getResources());
-        mPhoneNumberHelper = new PhoneNumberHelper(mResources);
-        mPhoneCallDetailsHelper = new PhoneCallDetailsHelper(mResources, mCallTypeHelper,
-                mPhoneNumberHelper);
-        mVoicemailStatusHelper = new VoicemailStatusHelperImpl();
-        mAsyncQueryHandler = new CallDetailActivityQueryHandler(this);
-        mHeaderTextView = (TextView) findViewById(R.id.header_text);
-        mHeaderOverlayView = findViewById(R.id.photo_text_bar);
-        mStatusMessageView = findViewById(R.id.voicemail_status);
-        mStatusMessageText = (TextView) findViewById(R.id.voicemail_status_message);
-        mStatusMessageAction = (TextView) findViewById(R.id.voicemail_status_action);
-        mMainActionView = (ImageView) findViewById(R.id.main_action);
-        mMainActionPushLayerView = (ImageButton) findViewById(R.id.main_action_push_layer);
-        mContactBackgroundView = (ImageView) findViewById(R.id.contact_background);
-        mDefaultCountryIso = ContactsUtils.getCurrentCountryIso(this);
-        mContactPhotoManager = ContactPhotoManager.getInstance(this);
-        mProximitySensorManager = new ProximitySensorManager(this, mProximitySensorListener);
-        mContactInfoHelper = new ContactInfoHelper(this, ContactsUtils.getCurrentCountryIso(this));
-        configureActionBar();
-        optionallyHandleVoicemail();
-        if (getIntent().getBooleanExtra(EXTRA_FROM_NOTIFICATION, false)) {
-            closeSystemDialogs();
-        }
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        updateData(getCallLogEntryUris());
-    }
-
-    /**
-     * Handle voicemail playback or hide voicemail ui.
-     * <p>
-     * If the Intent used to start this Activity contains the suitable extras, then start voicemail
-     * playback.  If it doesn't, then hide the voicemail ui.
-     */
-    private void optionallyHandleVoicemail() {
-        View voicemailContainer = findViewById(R.id.voicemail_container);
-        if (hasVoicemail()) {
-            // Has voicemail: add the voicemail fragment.  Add suitable arguments to set the uri
-            // to play and optionally start the playback.
-            // Do a query to fetch the voicemail status messages.
-            VoicemailPlaybackFragment playbackFragment = new VoicemailPlaybackFragment();
-            Bundle fragmentArguments = new Bundle();
-            fragmentArguments.putParcelable(EXTRA_VOICEMAIL_URI, getVoicemailUri());
-            if (getIntent().getBooleanExtra(EXTRA_VOICEMAIL_START_PLAYBACK, false)) {
-                fragmentArguments.putBoolean(EXTRA_VOICEMAIL_START_PLAYBACK, true);
-            }
-            playbackFragment.setArguments(fragmentArguments);
-            voicemailContainer.setVisibility(View.VISIBLE);
-            getFragmentManager().beginTransaction()
-                    .add(R.id.voicemail_container, playbackFragment).commitAllowingStateLoss();
-            mAsyncQueryHandler.startVoicemailStatusQuery(getVoicemailUri());
-            markVoicemailAsRead(getVoicemailUri());
-        } else {
-            // No voicemail uri: hide the status view.
-            mStatusMessageView.setVisibility(View.GONE);
-            voicemailContainer.setVisibility(View.GONE);
-        }
-    }
-
-    private boolean hasVoicemail() {
-        return getVoicemailUri() != null;
-    }
-
-    private Uri getVoicemailUri() {
-        return getIntent().getParcelableExtra(EXTRA_VOICEMAIL_URI);
-    }
-
-    private void markVoicemailAsRead(final Uri voicemailUri) {
-        mAsyncTaskExecutor.submit(Tasks.MARK_VOICEMAIL_READ, new AsyncTask<Void, Void, Void>() {
-            @Override
-            public Void doInBackground(Void... params) {
-                ContentValues values = new ContentValues();
-                values.put(Voicemails.IS_READ, true);
-                getContentResolver().update(voicemailUri, values,
-                        Voicemails.IS_READ + " = 0", null);
-                return null;
-            }
-        });
-    }
-
-    /**
-     * Returns the list of URIs to show.
-     * <p>
-     * There are two ways the URIs can be provided to the activity: as the data on the intent, or as
-     * a list of ids in the call log added as an extra on the URI.
-     * <p>
-     * If both are available, the data on the intent takes precedence.
-     */
-    private Uri[] getCallLogEntryUris() {
-        Uri uri = getIntent().getData();
-        if (uri != null) {
-            // If there is a data on the intent, it takes precedence over the extra.
-            return new Uri[]{ uri };
-        }
-        long[] ids = getIntent().getLongArrayExtra(EXTRA_CALL_LOG_IDS);
-        Uri[] uris = new Uri[ids.length];
-        for (int index = 0; index < ids.length; ++index) {
-            uris[index] = ContentUris.withAppendedId(Calls.CONTENT_URI_WITH_VOICEMAIL, ids[index]);
-        }
-        return uris;
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_CALL: {
-                // Make sure phone isn't already busy before starting direct call
-                TelephonyManager tm = (TelephonyManager)
-                        getSystemService(Context.TELEPHONY_SERVICE);
-                if (tm.getCallState() == TelephonyManager.CALL_STATE_IDLE) {
-                    startActivity(ContactsUtils.getCallIntent(
-                            Uri.fromParts(Constants.SCHEME_TEL, mNumber, null)));
-                    return true;
-                }
-            }
-        }
-
-        return super.onKeyDown(keyCode, event);
-    }
-
-    /**
-     * Update user interface with details of given call.
-     *
-     * @param callUris URIs into {@link CallLog.Calls} of the calls to be displayed
-     */
-    private void updateData(final Uri... callUris) {
-        class UpdateContactDetailsTask extends AsyncTask<Void, Void, PhoneCallDetails[]> {
-            @Override
-            public PhoneCallDetails[] doInBackground(Void... params) {
-                // TODO: All phone calls correspond to the same person, so we can make a single
-                // lookup.
-                final int numCalls = callUris.length;
-                PhoneCallDetails[] details = new PhoneCallDetails[numCalls];
-                try {
-                    for (int index = 0; index < numCalls; ++index) {
-                        details[index] = getPhoneCallDetailsForUri(callUris[index]);
-                    }
-                    return details;
-                } catch (IllegalArgumentException e) {
-                    // Something went wrong reading in our primary data.
-                    Log.w(TAG, "invalid URI starting call details", e);
-                    return null;
-                }
-            }
-
-            @Override
-            public void onPostExecute(PhoneCallDetails[] details) {
-                if (details == null) {
-                    // Somewhere went wrong: we're going to bail out and show error to users.
-                    Toast.makeText(CallDetailActivity.this, R.string.toast_call_detail_error,
-                            Toast.LENGTH_SHORT).show();
-                    finish();
-                    return;
-                }
-
-                // We know that all calls are from the same number and the same contact, so pick the
-                // first.
-                PhoneCallDetails firstDetails = details[0];
-                mNumber = firstDetails.number.toString();
-                final Uri contactUri = firstDetails.contactUri;
-                final Uri photoUri = firstDetails.photoUri;
-
-                // Set the details header, based on the first phone call.
-                mPhoneCallDetailsHelper.setCallDetailsHeader(mHeaderTextView, firstDetails);
-
-                // Cache the details about the phone number.
-                final boolean canPlaceCallsTo = mPhoneNumberHelper.canPlaceCallsTo(mNumber);
-                final boolean isVoicemailNumber = mPhoneNumberHelper.isVoicemailNumber(mNumber);
-                final boolean isSipNumber = mPhoneNumberHelper.isSipNumber(mNumber);
-
-                // Let user view contact details if they exist, otherwise add option to create new
-                // contact from this number.
-                final Intent mainActionIntent;
-                final int mainActionIcon;
-                final String mainActionDescription;
-
-                final CharSequence nameOrNumber;
-                if (!TextUtils.isEmpty(firstDetails.name)) {
-                    nameOrNumber = firstDetails.name;
-                } else {
-                    nameOrNumber = firstDetails.number;
-                }
-
-                if (contactUri != null) {
-                    mainActionIntent = new Intent(Intent.ACTION_VIEW, contactUri);
-                    // This will launch People's detail contact screen, so we probably want to
-                    // treat it as a separate People task.
-                    mainActionIntent.setFlags(
-                            Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                    mainActionIcon = R.drawable.ic_contacts_holo_dark;
-                    mainActionDescription =
-                            getString(R.string.description_view_contact, nameOrNumber);
-                } else if (isVoicemailNumber) {
-                    mainActionIntent = null;
-                    mainActionIcon = 0;
-                    mainActionDescription = null;
-                } else if (isSipNumber) {
-                    // TODO: This item is currently disabled for SIP addresses, because
-                    // the Insert.PHONE extra only works correctly for PSTN numbers.
-                    //
-                    // To fix this for SIP addresses, we need to:
-                    // - define ContactsContract.Intents.Insert.SIP_ADDRESS, and use it here if
-                    //   the current number is a SIP address
-                    // - update the contacts UI code to handle Insert.SIP_ADDRESS by
-                    //   updating the SipAddress field
-                    // and then we can remove the "!isSipNumber" check above.
-                    mainActionIntent = null;
-                    mainActionIcon = 0;
-                    mainActionDescription = null;
-                } else if (canPlaceCallsTo) {
-                    mainActionIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
-                    mainActionIntent.setType(Contacts.CONTENT_ITEM_TYPE);
-                    mainActionIntent.putExtra(Insert.PHONE, mNumber);
-                    mainActionIcon = R.drawable.ic_add_contact_holo_dark;
-                    mainActionDescription = getString(R.string.description_add_contact);
-                } else {
-                    // If we cannot call the number, when we probably cannot add it as a contact either.
-                    // This is usually the case of private, unknown, or payphone numbers.
-                    mainActionIntent = null;
-                    mainActionIcon = 0;
-                    mainActionDescription = null;
-                }
-
-                if (mainActionIntent == null) {
-                    mMainActionView.setVisibility(View.INVISIBLE);
-                    mMainActionPushLayerView.setVisibility(View.GONE);
-                    mHeaderTextView.setVisibility(View.INVISIBLE);
-                    mHeaderOverlayView.setVisibility(View.INVISIBLE);
-                } else {
-                    mMainActionView.setVisibility(View.VISIBLE);
-                    mMainActionView.setImageResource(mainActionIcon);
-                    mMainActionPushLayerView.setVisibility(View.VISIBLE);
-                    mMainActionPushLayerView.setOnClickListener(new View.OnClickListener() {
-                        @Override
-                        public void onClick(View v) {
-                            startActivity(mainActionIntent);
-                        }
-                    });
-                    mMainActionPushLayerView.setContentDescription(mainActionDescription);
-                    mHeaderTextView.setVisibility(View.VISIBLE);
-                    mHeaderOverlayView.setVisibility(View.VISIBLE);
-                }
-
-                // This action allows to call the number that places the call.
-                if (canPlaceCallsTo) {
-                    final CharSequence displayNumber =
-                            mPhoneNumberHelper.getDisplayNumber(
-                                    firstDetails.number, firstDetails.formattedNumber);
-
-                    ViewEntry entry = new ViewEntry(
-                            getString(R.string.menu_callNumber,
-                                    FormatUtils.forceLeftToRight(displayNumber)),
-                                    ContactsUtils.getCallIntent(mNumber),
-                                    getString(R.string.description_call, nameOrNumber));
-
-                    // Only show a label if the number is shown and it is not a SIP address.
-                    if (!TextUtils.isEmpty(firstDetails.name)
-                            && !TextUtils.isEmpty(firstDetails.number)
-                            && !PhoneNumberUtils.isUriNumber(firstDetails.number.toString())) {
-                        entry.label = Phone.getTypeLabel(mResources, firstDetails.numberType,
-                                firstDetails.numberLabel);
-                    }
-
-                    // The secondary action allows to send an SMS to the number that placed the
-                    // call.
-                    if (mPhoneNumberHelper.canSendSmsTo(mNumber)) {
-                        entry.setSecondaryAction(
-                                R.drawable.ic_text_holo_dark,
-                                new Intent(Intent.ACTION_SENDTO,
-                                           Uri.fromParts("sms", mNumber, null)),
-                                getString(R.string.description_send_text_message, nameOrNumber));
-                    }
-
-                    configureCallButton(entry);
-                    mPhoneNumberToCopy = displayNumber;
-                    mPhoneNumberLabelToCopy = entry.label;
-                } else {
-                    disableCallButton();
-                    mPhoneNumberToCopy = null;
-                    mPhoneNumberLabelToCopy = null;
-                }
-
-                mHasEditNumberBeforeCallOption =
-                        canPlaceCallsTo && !isSipNumber && !isVoicemailNumber;
-                mHasTrashOption = hasVoicemail();
-                mHasRemoveFromCallLogOption = !hasVoicemail();
-                invalidateOptionsMenu();
-
-                ListView historyList = (ListView) findViewById(R.id.history);
-                historyList.setAdapter(
-                        new CallDetailHistoryAdapter(CallDetailActivity.this, mInflater,
-                                mCallTypeHelper, details, hasVoicemail(), canPlaceCallsTo,
-                                findViewById(R.id.controls)));
-                BackScrollManager.bind(
-                        new ScrollableHeader() {
-                            private View mControls = findViewById(R.id.controls);
-                            private View mPhoto = findViewById(R.id.contact_background_sizer);
-                            private View mHeader = findViewById(R.id.photo_text_bar);
-                            private View mSeparator = findViewById(R.id.blue_separator);
-
-                            @Override
-                            public void setOffset(int offset) {
-                                mControls.setY(-offset);
-                            }
-
-                            @Override
-                            public int getMaximumScrollableHeaderOffset() {
-                                // We can scroll the photo out, but we should keep the header if
-                                // present.
-                                if (mHeader.getVisibility() == View.VISIBLE) {
-                                    return mPhoto.getHeight() - mHeader.getHeight();
-                                } else {
-                                    // If the header is not present, we should also scroll out the
-                                    // separator line.
-                                    return mPhoto.getHeight() + mSeparator.getHeight();
-                                }
-                            }
-                        },
-                        historyList);
-                loadContactPhotos(photoUri);
-                findViewById(R.id.call_detail).setVisibility(View.VISIBLE);
-            }
-        }
-        mAsyncTaskExecutor.submit(Tasks.UPDATE_PHONE_CALL_DETAILS, new UpdateContactDetailsTask());
-    }
-
-    /** Return the phone call details for a given call log URI. */
-    private PhoneCallDetails getPhoneCallDetailsForUri(Uri callUri) {
-        ContentResolver resolver = getContentResolver();
-        Cursor callCursor = resolver.query(callUri, CALL_LOG_PROJECTION, null, null, null);
-        try {
-            if (callCursor == null || !callCursor.moveToFirst()) {
-                throw new IllegalArgumentException("Cannot find content: " + callUri);
-            }
-
-            // Read call log specifics.
-            String number = callCursor.getString(NUMBER_COLUMN_INDEX);
-            long date = callCursor.getLong(DATE_COLUMN_INDEX);
-            long duration = callCursor.getLong(DURATION_COLUMN_INDEX);
-            int callType = callCursor.getInt(CALL_TYPE_COLUMN_INDEX);
-            String countryIso = callCursor.getString(COUNTRY_ISO_COLUMN_INDEX);
-            final String geocode = callCursor.getString(GEOCODED_LOCATION_COLUMN_INDEX);
-
-            if (TextUtils.isEmpty(countryIso)) {
-                countryIso = mDefaultCountryIso;
-            }
-
-            // Formatted phone number.
-            final CharSequence formattedNumber;
-            // Read contact specifics.
-            final CharSequence nameText;
-            final int numberType;
-            final CharSequence numberLabel;
-            final Uri photoUri;
-            final Uri lookupUri;
-            // If this is not a regular number, there is no point in looking it up in the contacts.
-            ContactInfo info =
-                    mPhoneNumberHelper.canPlaceCallsTo(number)
-                    && !mPhoneNumberHelper.isVoicemailNumber(number)
-                            ? mContactInfoHelper.lookupNumber(number, countryIso)
-                            : null;
-            if (info == null) {
-                formattedNumber = mPhoneNumberHelper.getDisplayNumber(number, null);
-                nameText = "";
-                numberType = 0;
-                numberLabel = "";
-                photoUri = null;
-                lookupUri = null;
-            } else {
-                formattedNumber = info.formattedNumber;
-                nameText = info.name;
-                numberType = info.type;
-                numberLabel = info.label;
-                photoUri = info.photoUri;
-                lookupUri = info.lookupUri;
-            }
-            return new PhoneCallDetails(number, formattedNumber, countryIso, geocode,
-                    new int[]{ callType }, date, duration,
-                    nameText, numberType, numberLabel, lookupUri, photoUri);
-        } finally {
-            if (callCursor != null) {
-                callCursor.close();
-            }
-        }
-    }
-
-    /** Load the contact photos and places them in the corresponding views. */
-    private void loadContactPhotos(Uri photoUri) {
-        mContactPhotoManager.loadPhoto(mContactBackgroundView, photoUri,
-                mContactBackgroundView.getWidth(), true);
-    }
-
-    static final class ViewEntry {
-        public final String text;
-        public final Intent primaryIntent;
-        /** The description for accessibility of the primary action. */
-        public final String primaryDescription;
-
-        public CharSequence label = null;
-        /** Icon for the secondary action. */
-        public int secondaryIcon = 0;
-        /** Intent for the secondary action. If not null, an icon must be defined. */
-        public Intent secondaryIntent = null;
-        /** The description for accessibility of the secondary action. */
-        public String secondaryDescription = null;
-
-        public ViewEntry(String text, Intent intent, String description) {
-            this.text = text;
-            primaryIntent = intent;
-            primaryDescription = description;
-        }
-
-        public void setSecondaryAction(int icon, Intent intent, String description) {
-            secondaryIcon = icon;
-            secondaryIntent = intent;
-            secondaryDescription = description;
-        }
-    }
-
-    /** Disables the call button area, e.g., for private numbers. */
-    private void disableCallButton() {
-        findViewById(R.id.call_and_sms).setVisibility(View.GONE);
-    }
-
-    /** Configures the call button area using the given entry. */
-    private void configureCallButton(ViewEntry entry) {
-        View convertView = findViewById(R.id.call_and_sms);
-        convertView.setVisibility(View.VISIBLE);
-
-        ImageView icon = (ImageView) convertView.findViewById(R.id.call_and_sms_icon);
-        View divider = convertView.findViewById(R.id.call_and_sms_divider);
-        TextView text = (TextView) convertView.findViewById(R.id.call_and_sms_text);
-
-        View mainAction = convertView.findViewById(R.id.call_and_sms_main_action);
-        mainAction.setOnClickListener(mPrimaryActionListener);
-        mainAction.setTag(entry);
-        mainAction.setContentDescription(entry.primaryDescription);
-        mainAction.setOnLongClickListener(mPrimaryLongClickListener);
-
-        if (entry.secondaryIntent != null) {
-            icon.setOnClickListener(mSecondaryActionListener);
-            icon.setImageResource(entry.secondaryIcon);
-            icon.setVisibility(View.VISIBLE);
-            icon.setTag(entry);
-            icon.setContentDescription(entry.secondaryDescription);
-            divider.setVisibility(View.VISIBLE);
-        } else {
-            icon.setVisibility(View.GONE);
-            divider.setVisibility(View.GONE);
-        }
-        text.setText(entry.text);
-
-        TextView label = (TextView) convertView.findViewById(R.id.call_and_sms_label);
-        if (TextUtils.isEmpty(entry.label)) {
-            label.setVisibility(View.GONE);
-        } else {
-            label.setText(entry.label);
-            label.setVisibility(View.VISIBLE);
-        }
-    }
-
-    protected void updateVoicemailStatusMessage(Cursor statusCursor) {
-        if (statusCursor == null) {
-            mStatusMessageView.setVisibility(View.GONE);
-            return;
-        }
-        final StatusMessage message = getStatusMessage(statusCursor);
-        if (message == null || !message.showInCallDetails()) {
-            mStatusMessageView.setVisibility(View.GONE);
-            return;
-        }
-
-        mStatusMessageView.setVisibility(View.VISIBLE);
-        mStatusMessageText.setText(message.callDetailsMessageId);
-        if (message.actionMessageId != -1) {
-            mStatusMessageAction.setText(message.actionMessageId);
-        }
-        if (message.actionUri != null) {
-            mStatusMessageAction.setClickable(true);
-            mStatusMessageAction.setOnClickListener(new View.OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    startActivity(new Intent(Intent.ACTION_VIEW, message.actionUri));
-                }
-            });
-        } else {
-            mStatusMessageAction.setClickable(false);
-        }
-    }
-
-    private StatusMessage getStatusMessage(Cursor statusCursor) {
-        List<StatusMessage> messages = mVoicemailStatusHelper.getStatusMessages(statusCursor);
-        if (messages.size() == 0) {
-            return null;
-        }
-        // There can only be a single status message per source package, so num of messages can
-        // at most be 1.
-        if (messages.size() > 1) {
-            Log.w(TAG, String.format("Expected 1, found (%d) num of status messages." +
-                    " Will use the first one.", messages.size()));
-        }
-        return messages.get(0);
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        getMenuInflater().inflate(R.menu.call_details_options, menu);
-        return super.onCreateOptionsMenu(menu);
-    }
-
-    @Override
-    public boolean onPrepareOptionsMenu(Menu menu) {
-        // This action deletes all elements in the group from the call log.
-        // We don't have this action for voicemails, because you can just use the trash button.
-        menu.findItem(R.id.menu_remove_from_call_log).setVisible(mHasRemoveFromCallLogOption);
-        menu.findItem(R.id.menu_edit_number_before_call).setVisible(mHasEditNumberBeforeCallOption);
-        menu.findItem(R.id.menu_trash).setVisible(mHasTrashOption);
-        return super.onPrepareOptionsMenu(menu);
-    }
-
-    @Override
-    public boolean onMenuItemSelected(int featureId, MenuItem item) {
-        switch (item.getItemId()) {
-            case android.R.id.home: {
-                onHomeSelected();
-                return true;
-            }
-
-            // All the options menu items are handled by onMenu... methods.
-            default:
-                throw new IllegalArgumentException();
-        }
-    }
-
-    public void onMenuRemoveFromCallLog(MenuItem menuItem) {
-        final StringBuilder callIds = new StringBuilder();
-        for (Uri callUri : getCallLogEntryUris()) {
-            if (callIds.length() != 0) {
-                callIds.append(",");
-            }
-            callIds.append(ContentUris.parseId(callUri));
-        }
-        mAsyncTaskExecutor.submit(Tasks.REMOVE_FROM_CALL_LOG_AND_FINISH,
-                new AsyncTask<Void, Void, Void>() {
-                    @Override
-                    public Void doInBackground(Void... params) {
-                        getContentResolver().delete(Calls.CONTENT_URI_WITH_VOICEMAIL,
-                                Calls._ID + " IN (" + callIds + ")", null);
-                        return null;
-                    }
-
-                    @Override
-                    public void onPostExecute(Void result) {
-                        finish();
-                    }
-                });
-    }
-
-    public void onMenuEditNumberBeforeCall(MenuItem menuItem) {
-        startActivity(new Intent(Intent.ACTION_DIAL, ContactsUtils.getCallUri(mNumber)));
-    }
-
-    public void onMenuTrashVoicemail(MenuItem menuItem) {
-        final Uri voicemailUri = getVoicemailUri();
-        mAsyncTaskExecutor.submit(Tasks.DELETE_VOICEMAIL_AND_FINISH,
-                new AsyncTask<Void, Void, Void>() {
-                    @Override
-                    public Void doInBackground(Void... params) {
-                        getContentResolver().delete(voicemailUri, null, null);
-                        return null;
-                    }
-                    @Override
-                    public void onPostExecute(Void result) {
-                        finish();
-                    }
-                });
-    }
-
-    private void configureActionBar() {
-        ActionBar actionBar = getActionBar();
-        if (actionBar != null) {
-            actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME);
-        }
-    }
-
-    /** Invoked when the user presses the home button in the action bar. */
-    private void onHomeSelected() {
-        Intent intent = new Intent(Intent.ACTION_VIEW, Calls.CONTENT_URI);
-        // This will open the call log even if the detail view has been opened directly.
-        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        startActivity(intent);
-        finish();
-    }
-
-    @Override
-    protected void onPause() {
-        // Immediately stop the proximity sensor.
-        disableProximitySensor(false);
-        mProximitySensorListener.clearPendingRequests();
-        super.onPause();
-    }
-
-    @Override
-    public void enableProximitySensor() {
-        mProximitySensorManager.enable();
-    }
-
-    @Override
-    public void disableProximitySensor(boolean waitForFarState) {
-        mProximitySensorManager.disable(waitForFarState);
-    }
-
-    /**
-     * If the phone number is selected, unselect it and return {@code true}.
-     * Otherwise, just {@code false}.
-     */
-    private boolean finishPhoneNumerSelectedActionModeIfShown() {
-        if (mPhoneNumberActionMode == null) return false;
-        mPhoneNumberActionMode.finish();
-        return true;
-    }
-
-    private void startPhoneNumberSelectedActionMode(View targetView) {
-        mPhoneNumberActionMode = startActionMode(new PhoneNumberActionModeCallback(targetView));
-    }
-
-    private void closeSystemDialogs() {
-        sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
-    }
-
-    private class PhoneNumberActionModeCallback implements ActionMode.Callback {
-        private final View mTargetView;
-        private final Drawable mOriginalViewBackground;
-
-        public PhoneNumberActionModeCallback(View targetView) {
-            mTargetView = targetView;
-
-            // Highlight the phone number view.  Remember the old background, and put a new one.
-            mOriginalViewBackground = mTargetView.getBackground();
-            mTargetView.setBackgroundColor(getResources().getColor(R.color.item_selected));
-        }
-
-        @Override
-        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
-            if (TextUtils.isEmpty(mPhoneNumberToCopy)) return false;
-
-            getMenuInflater().inflate(R.menu.call_details_cab, menu);
-            return true;
-        }
-
-        @Override
-        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
-            return true;
-        }
-
-        @Override
-        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
-            switch (item.getItemId()) {
-                case R.id.copy_phone_number:
-                    ClipboardUtils.copyText(CallDetailActivity.this, mPhoneNumberLabelToCopy,
-                            mPhoneNumberToCopy, true);
-                    mode.finish(); // Close the CAB
-                    return true;
-            }
-            return false;
-        }
-
-        @Override
-        public void onDestroyActionMode(ActionMode mode) {
-            mPhoneNumberActionMode = null;
-
-            // Restore the view background.
-            mTargetView.setBackground(mOriginalViewBackground);
-        }
-    }
-}
diff --git a/src/com/android/contacts/CallDetailActivityQueryHandler.java b/src/com/android/contacts/CallDetailActivityQueryHandler.java
deleted file mode 100644
index 41cf937..0000000
--- a/src/com/android/contacts/CallDetailActivityQueryHandler.java
+++ /dev/null
@@ -1,104 +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 android.content.AsyncQueryHandler;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.VoicemailContract.Status;
-import android.provider.VoicemailContract.Voicemails;
-import android.util.Log;
-
-import com.android.common.io.MoreCloseables;
-import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
-
-/**
- * Class used by {@link CallDetailActivity} to fire async content resolver queries.
- */
-public class CallDetailActivityQueryHandler extends AsyncQueryHandler {
-    private static final String TAG = "CallDetail";
-    private static final int QUERY_VOICEMAIL_CONTENT_TOKEN = 101;
-    private static final int QUERY_VOICEMAIL_STATUS_TOKEN = 102;
-
-    private final String[] VOICEMAIL_CONTENT_PROJECTION = new String[] {
-        Voicemails.SOURCE_PACKAGE,
-        Voicemails.HAS_CONTENT
-    };
-    private static final int SOURCE_PACKAGE_COLUMN_INDEX = 0;
-    private static final int HAS_CONTENT_COLUMN_INDEX = 1;
-
-    private final CallDetailActivity mCallDetailActivity;
-
-    public CallDetailActivityQueryHandler(CallDetailActivity callDetailActivity) {
-        super(callDetailActivity.getContentResolver());
-        mCallDetailActivity = callDetailActivity;
-    }
-
-    /**
-     * Fires a query to update voicemail status for the given voicemail record. On completion of the
-     * query a call to {@link CallDetailActivity#updateVoicemailStatusMessage(Cursor)} is made.
-     * <p>
-     * if this is a voicemail record then it makes up to two asynchronous content resolver queries.
-     * The first one to fetch voicemail content details and check if the voicemail record has audio.
-     * If the voicemail record does not have an audio yet then it fires the second query to get the
-     * voicemail status of the associated source.
-     */
-    public void startVoicemailStatusQuery(Uri voicemailUri) {
-        startQuery(QUERY_VOICEMAIL_CONTENT_TOKEN, null, voicemailUri, VOICEMAIL_CONTENT_PROJECTION,
-                null, null, null);
-    }
-
-    @Override
-    protected synchronized void onQueryComplete(int token, Object cookie, Cursor cursor) {
-        try {
-            if (token == QUERY_VOICEMAIL_CONTENT_TOKEN) {
-                // Query voicemail status only if this voicemail record does not have audio.
-                if (moveToFirst(cursor) && hasNoAudio(cursor)) {
-                    startQuery(QUERY_VOICEMAIL_STATUS_TOKEN, null,
-                            Status.buildSourceUri(getSourcePackage(cursor)),
-                            VoicemailStatusHelperImpl.PROJECTION, null, null, null);
-                } else {
-                    // nothing to show in status
-                    mCallDetailActivity.updateVoicemailStatusMessage(null);
-                }
-            } else if (token == QUERY_VOICEMAIL_STATUS_TOKEN) {
-                mCallDetailActivity.updateVoicemailStatusMessage(cursor);
-            } else {
-                Log.w(TAG, "Unknown query completed: ignoring: " + token);
-            }
-        } finally {
-            MoreCloseables.closeQuietly(cursor);
-        }
-    }
-
-    /** Check that the cursor is non-null and can be moved to first. */
-    private boolean moveToFirst(Cursor cursor) {
-        if (cursor == null || !cursor.moveToFirst()) {
-            Log.e(TAG, "Cursor not valid, could not move to first");
-            return false;
-        }
-        return true;
-    }
-
-    private boolean hasNoAudio(Cursor voicemailCursor) {
-        return voicemailCursor.getInt(HAS_CONTENT_COLUMN_INDEX) == 0;
-    }
-
-    private String getSourcePackage(Cursor voicemailCursor) {
-        return voicemailCursor.getString(SOURCE_PACKAGE_COLUMN_INDEX);
-    }
-}
diff --git a/src/com/android/contacts/ContactsApplication.java b/src/com/android/contacts/ContactsApplication.java
index 3380553..678e7db 100644
--- a/src/com/android/contacts/ContactsApplication.java
+++ b/src/com/android/contacts/ContactsApplication.java
@@ -104,14 +104,6 @@
             return mContactPhotoManager;
         }
 
-        if (ContactListFilterController.CONTACT_LIST_FILTER_SERVICE.equals(name)) {
-            if (mContactListFilterController == null) {
-                mContactListFilterController =
-                        ContactListFilterController.createContactListFilterController(this);
-            }
-            return mContactListFilterController;
-        }
-
         return super.getSystemService(name);
     }
 
diff --git a/src/com/android/contacts/ContactsUtils.java b/src/com/android/contacts/ContactsUtils.java
index 15b33ab..226061e 100644
--- a/src/com/android/contacts/ContactsUtils.java
+++ b/src/com/android/contacts/ContactsUtils.java
@@ -33,12 +33,12 @@
 import android.view.View;
 import android.widget.TextView;
 
-import com.android.contacts.activities.DialtactsActivity;
 import com.android.contacts.model.AccountTypeManager;
 import com.android.contacts.model.account.AccountType;
 import com.android.contacts.model.account.AccountWithDataSet;
 import com.android.contacts.test.NeededForTesting;
 import com.android.contacts.util.Constants;
+import com.android.phone.common.PhoneConstants;
 
 import java.util.List;
 
@@ -269,7 +269,7 @@
         final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED, uri);
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         if (callOrigin != null) {
-            intent.putExtra(DialtactsActivity.EXTRA_CALL_ORIGIN, callOrigin);
+            intent.putExtra(PhoneConstants.EXTRA_CALL_ORIGIN, callOrigin);
         }
         return intent;
     }
diff --git a/src/com/android/contacts/PhoneCallDetails.java b/src/com/android/contacts/PhoneCallDetails.java
deleted file mode 100644
index 547695c..0000000
--- a/src/com/android/contacts/PhoneCallDetails.java
+++ /dev/null
@@ -1,86 +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 android.net.Uri;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-
-/**
- * The details of a phone call to be shown in the UI.
- */
-public class PhoneCallDetails {
-    /** The number of the other party involved in the call. */
-    public final CharSequence number;
-    /** The formatted version of {@link #number}. */
-    public final CharSequence formattedNumber;
-    /** The country corresponding with the phone number. */
-    public final String countryIso;
-    /** The geocoded location for the phone number. */
-    public final String geocode;
-    /**
-     * The type of calls, as defined in the call log table, e.g., {@link Calls#INCOMING_TYPE}.
-     * <p>
-     * There might be multiple types if this represents a set of entries grouped together.
-     */
-    public final int[] callTypes;
-    /** The date of the call, in milliseconds since the epoch. */
-    public final long date;
-    /** The duration of the call in milliseconds, or 0 for missed calls. */
-    public final long duration;
-    /** The name of the contact, or the empty string. */
-    public final CharSequence name;
-    /** The type of phone, e.g., {@link Phone#TYPE_HOME}, 0 if not available. */
-    public final int numberType;
-    /** The custom label associated with the phone number in the contact, or the empty string. */
-    public final CharSequence numberLabel;
-    /** The URI of the contact associated with this phone call. */
-    public final Uri contactUri;
-    /**
-     * The photo URI of the picture of the contact that is associated with this phone call or
-     * null if there is none.
-     * <p>
-     * This is meant to store the high-res photo only.
-     */
-    public final Uri photoUri;
-
-    /** Create the details for a call with a number not associated with a contact. */
-    public PhoneCallDetails(CharSequence number, CharSequence formattedNumber,
-            String countryIso, String geocode, int[] callTypes, long date, long duration) {
-        this(number, formattedNumber, countryIso, geocode, callTypes, date, duration, "", 0, "",
-                null, null);
-    }
-
-    /** Create the details for a call with a number associated with a contact. */
-    public PhoneCallDetails(CharSequence number, CharSequence formattedNumber,
-            String countryIso, String geocode, int[] callTypes, long date, long duration,
-            CharSequence name, int numberType, CharSequence numberLabel, Uri contactUri,
-            Uri photoUri) {
-        this.number = number;
-        this.formattedNumber = formattedNumber;
-        this.countryIso = countryIso;
-        this.geocode = geocode;
-        this.callTypes = callTypes;
-        this.date = date;
-        this.duration = duration;
-        this.name = name;
-        this.numberType = numberType;
-        this.numberLabel = numberLabel;
-        this.contactUri = contactUri;
-        this.photoUri = photoUri;
-    }
-}
diff --git a/src/com/android/contacts/PhoneCallDetailsHelper.java b/src/com/android/contacts/PhoneCallDetailsHelper.java
deleted file mode 100644
index 8192975..0000000
--- a/src/com/android/contacts/PhoneCallDetailsHelper.java
+++ /dev/null
@@ -1,194 +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 android.content.res.Resources;
-import android.graphics.Typeface;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.telephony.PhoneNumberUtils;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.text.style.ForegroundColorSpan;
-import android.text.style.StyleSpan;
-import android.view.View;
-import android.widget.TextView;
-
-import com.android.contacts.calllog.CallTypeHelper;
-import com.android.contacts.calllog.PhoneNumberHelper;
-import com.android.contacts.test.NeededForTesting;
-
-/**
- * Helper class to fill in the views in {@link PhoneCallDetailsViews}.
- */
-public class PhoneCallDetailsHelper {
-    /** The maximum number of icons will be shown to represent the call types in a group. */
-    private static final int MAX_CALL_TYPE_ICONS = 3;
-
-    private final Resources mResources;
-    /** The injected current time in milliseconds since the epoch. Used only by tests. */
-    private Long mCurrentTimeMillisForTest;
-    // Helper classes.
-    private final CallTypeHelper mCallTypeHelper;
-    private final PhoneNumberHelper mPhoneNumberHelper;
-
-    /**
-     * Creates a new instance of the helper.
-     * <p>
-     * Generally you should have a single instance of this helper in any context.
-     *
-     * @param resources used to look up strings
-     */
-    public PhoneCallDetailsHelper(Resources resources, CallTypeHelper callTypeHelper,
-            PhoneNumberHelper phoneNumberHelper) {
-        mResources = resources;
-        mCallTypeHelper = callTypeHelper;
-        mPhoneNumberHelper = phoneNumberHelper;
-    }
-
-    /** Fills the call details views with content. */
-    public void setPhoneCallDetails(PhoneCallDetailsViews views, PhoneCallDetails details,
-            boolean isHighlighted) {
-        // Display up to a given number of icons.
-        views.callTypeIcons.clear();
-        int count = details.callTypes.length;
-        for (int index = 0; index < count && index < MAX_CALL_TYPE_ICONS; ++index) {
-            views.callTypeIcons.add(details.callTypes[index]);
-        }
-        views.callTypeIcons.setVisibility(View.VISIBLE);
-
-        // Show the total call count only if there are more than the maximum number of icons.
-        final Integer callCount;
-        if (count > MAX_CALL_TYPE_ICONS) {
-            callCount = count;
-        } else {
-            callCount = null;
-        }
-        // The color to highlight the count and date in, if any. This is based on the first call.
-        Integer highlightColor =
-                isHighlighted ? mCallTypeHelper.getHighlightedColor(details.callTypes[0]) : null;
-
-        // The date of this call, relative to the current time.
-        CharSequence dateText =
-            DateUtils.getRelativeTimeSpanString(details.date,
-                    getCurrentTimeMillis(),
-                    DateUtils.MINUTE_IN_MILLIS,
-                    DateUtils.FORMAT_ABBREV_RELATIVE);
-
-        // Set the call count and date.
-        setCallCountAndDate(views, callCount, dateText, highlightColor);
-
-        CharSequence numberFormattedLabel = null;
-        // Only show a label if the number is shown and it is not a SIP address.
-        if (!TextUtils.isEmpty(details.number)
-                && !PhoneNumberUtils.isUriNumber(details.number.toString())) {
-            numberFormattedLabel = Phone.getTypeLabel(mResources, details.numberType,
-                    details.numberLabel);
-        }
-
-        final CharSequence nameText;
-        final CharSequence numberText;
-        final CharSequence labelText;
-        final CharSequence displayNumber =
-            mPhoneNumberHelper.getDisplayNumber(details.number, details.formattedNumber);
-        if (TextUtils.isEmpty(details.name)) {
-            nameText = displayNumber;
-            if (TextUtils.isEmpty(details.geocode)
-                    || mPhoneNumberHelper.isVoicemailNumber(details.number)) {
-                numberText = mResources.getString(R.string.call_log_empty_gecode);
-            } else {
-                numberText = details.geocode;
-            }
-            labelText = null;
-        } else {
-            nameText = details.name;
-            numberText = displayNumber;
-            labelText = numberFormattedLabel;
-        }
-
-        views.nameView.setText(nameText);
-        views.numberView.setText(numberText);
-        views.labelView.setText(labelText);
-        views.labelView.setVisibility(TextUtils.isEmpty(labelText) ? View.GONE : View.VISIBLE);
-    }
-
-    /** Sets the text of the header view for the details page of a phone call. */
-    public void setCallDetailsHeader(TextView nameView, PhoneCallDetails details) {
-        final CharSequence nameText;
-        final CharSequence displayNumber =
-                mPhoneNumberHelper.getDisplayNumber(details.number,
-                        mResources.getString(R.string.recentCalls_addToContact));
-        if (TextUtils.isEmpty(details.name)) {
-            nameText = displayNumber;
-        } else {
-            nameText = details.name;
-        }
-
-        nameView.setText(nameText);
-    }
-
-    @NeededForTesting
-    public void setCurrentTimeForTest(long currentTimeMillis) {
-        mCurrentTimeMillisForTest = currentTimeMillis;
-    }
-
-    /**
-     * Returns the current time in milliseconds since the epoch.
-     * <p>
-     * It can be injected in tests using {@link #setCurrentTimeForTest(long)}.
-     */
-    private long getCurrentTimeMillis() {
-        if (mCurrentTimeMillisForTest == null) {
-            return System.currentTimeMillis();
-        } else {
-            return mCurrentTimeMillisForTest;
-        }
-    }
-
-    /** Sets the call count and date. */
-    private void setCallCountAndDate(PhoneCallDetailsViews views, Integer callCount,
-            CharSequence dateText, Integer highlightColor) {
-        // Combine the count (if present) and the date.
-        final CharSequence text;
-        if (callCount != null) {
-            text = mResources.getString(
-                    R.string.call_log_item_count_and_date, callCount.intValue(), dateText);
-        } else {
-            text = dateText;
-        }
-
-        // Apply the highlight color if present.
-        final CharSequence formattedText;
-        if (highlightColor != null) {
-            formattedText = addBoldAndColor(text, highlightColor);
-        } else {
-            formattedText = text;
-        }
-
-        views.callTypeAndDate.setText(formattedText);
-    }
-
-    /** Creates a SpannableString for the given text which is bold and in the given color. */
-    private CharSequence addBoldAndColor(CharSequence text, int color) {
-        int flags = Spanned.SPAN_INCLUSIVE_INCLUSIVE;
-        SpannableString result = new SpannableString(text);
-        result.setSpan(new StyleSpan(Typeface.BOLD), 0, text.length(), flags);
-        result.setSpan(new ForegroundColorSpan(color), 0, text.length(), flags);
-        return result;
-    }
-}
diff --git a/src/com/android/contacts/PhoneCallDetailsViews.java b/src/com/android/contacts/PhoneCallDetailsViews.java
deleted file mode 100644
index 8be7f0c..0000000
--- a/src/com/android/contacts/PhoneCallDetailsViews.java
+++ /dev/null
@@ -1,72 +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 android.content.Context;
-import android.view.View;
-import android.widget.TextView;
-
-import com.android.contacts.calllog.CallTypeIconsView;
-
-/**
- * Encapsulates the views that are used to display the details of a phone call in the call log.
- */
-public final class PhoneCallDetailsViews {
-    public final TextView nameView;
-    public final View callTypeView;
-    public final CallTypeIconsView callTypeIcons;
-    public final TextView callTypeAndDate;
-    public final TextView numberView;
-    public final TextView labelView;
-
-    private PhoneCallDetailsViews(TextView nameView, View callTypeView,
-            CallTypeIconsView callTypeIcons, TextView callTypeAndDate, TextView numberView,
-            TextView labelView) {
-        this.nameView = nameView;
-        this.callTypeView = callTypeView;
-        this.callTypeIcons = callTypeIcons;
-        this.callTypeAndDate = callTypeAndDate;
-        this.numberView = numberView;
-        this.labelView = labelView;
-    }
-
-    /**
-     * Create a new instance by extracting the elements from the given view.
-     * <p>
-     * The view should contain three text views with identifiers {@code R.id.name},
-     * {@code R.id.date}, and {@code R.id.number}, and a linear layout with identifier
-     * {@code R.id.call_types}.
-     */
-    public static PhoneCallDetailsViews fromView(View view) {
-        return new PhoneCallDetailsViews((TextView) view.findViewById(R.id.name),
-                view.findViewById(R.id.call_type),
-                (CallTypeIconsView) view.findViewById(R.id.call_type_icons),
-                (TextView) view.findViewById(R.id.call_count_and_date),
-                (TextView) view.findViewById(R.id.number),
-                (TextView) view.findViewById(R.id.label));
-    }
-
-    public static PhoneCallDetailsViews createForTest(Context context) {
-        return new PhoneCallDetailsViews(
-                new TextView(context),
-                new View(context),
-                new CallTypeIconsView(context),
-                new TextView(context),
-                new TextView(context),
-                new TextView(context));
-    }
-}
diff --git a/src/com/android/contacts/ViewNotificationService.java b/src/com/android/contacts/ViewNotificationService.java
deleted file mode 100644
index 3bc5ed2..0000000
--- a/src/com/android/contacts/ViewNotificationService.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 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.Service;
-import android.content.Intent;
-import android.content.Loader;
-import android.content.Loader.OnLoadCompleteListener;
-import android.os.IBinder;
-import android.util.Log;
-
-import com.android.contacts.model.Contact;
-import com.android.contacts.model.ContactLoader;
-
-
-/**
- * Service that sends out a view notification for a contact. At the moment, this is only
- * supposed to be used by the Phone app
- */
-public class ViewNotificationService extends Service {
-    private static final String TAG = ViewNotificationService.class.getSimpleName();
-
-    private static final boolean DEBUG = false;
-
-    @Override
-    public int onStartCommand(Intent intent, int flags, final int startId) {
-        if (DEBUG) { Log.d(TAG, "onHandleIntent(). Intent: " + intent); }
-
-        // We simply need to start a Loader here. When its done, it will send out the
-        // View-Notification automatically.
-        final ContactLoader contactLoader = new ContactLoader(this, intent.getData(), true);
-        contactLoader.registerListener(0, new OnLoadCompleteListener<Contact>() {
-            @Override
-            public void onLoadComplete(Loader<Contact> loader, Contact data) {
-                try {
-                    loader.reset();
-                } catch (RuntimeException e) {
-                    Log.e(TAG, "Error reseting loader", e);
-                }
-                try {
-                    // This is not 100% accurate actually. If we get several calls quickly,
-                    // we might be stopping out-of-order, in which case the call with the last
-                    // startId will stop this service. In practice, this shouldn't be a problem,
-                    // as this service is supposed to be called by the Phone app which only sends
-                    // out the notification once per phonecall. And even if there is a problem,
-                    // the worst that should happen is a missing view notification
-                    stopSelfResult(startId);
-                } catch (RuntimeException e) {
-                    Log.e(TAG, "Error stopping service", e);
-                }
-            }
-        });
-        contactLoader.startLoading();
-        return START_REDELIVER_INTENT;
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
-}
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
deleted file mode 100644
index ea68407..0000000
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ /dev/null
@@ -1,1270 +0,0 @@
-/*
- * Copyright (C) 2008 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.activities;
-
-import android.app.ActionBar;
-import android.app.ActionBar.LayoutParams;
-import android.app.ActionBar.Tab;
-import android.app.ActionBar.TabListener;
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.preference.PreferenceManager;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Intents.UI;
-import android.support.v13.app.FragmentPagerAdapter;
-import android.support.v4.view.ViewPager;
-import android.support.v4.view.ViewPager.OnPageChangeListener;
-import android.text.TextUtils;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.MenuItem.OnMenuItemClickListener;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.View.OnFocusChangeListener;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.PopupMenu;
-import android.widget.SearchView;
-import android.widget.SearchView.OnCloseListener;
-import android.widget.SearchView.OnQueryTextListener;
-
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.calllog.CallLogFragment;
-import com.android.contacts.dialpad.DialpadFragment;
-import com.android.contacts.interactions.PhoneNumberInteraction;
-import com.android.contacts.list.ContactListFilterController;
-import com.android.contacts.list.ContactListFilterController.ContactListFilterListener;
-import com.android.contacts.list.ContactListItemView;
-import com.android.contacts.list.OnPhoneNumberPickerActionListener;
-import com.android.contacts.list.PhoneFavoriteFragment;
-import com.android.contacts.list.PhoneNumberPickerFragment;
-import com.android.contacts.util.AccountFilterUtil;
-import com.android.contacts.util.Constants;
-import com.android.internal.telephony.ITelephony;
-
-/**
- * The dialer activity that has one tab with the virtual 12key
- * dialer, a tab with recent calls in it, a tab with the contacts and
- * a tab with the favorite. This is the container and the tabs are
- * embedded using intents.
- * The dialer tab's title is 'phone', a more common name (see strings.xml).
- */
-public class DialtactsActivity extends TransactionSafeActivity
-        implements View.OnClickListener {
-    private static final String TAG = "DialtactsActivity";
-
-    public static final boolean DEBUG = false;
-
-    /** Used to open Call Setting */
-    private static final String PHONE_PACKAGE = "com.android.phone";
-    private static final String CALL_SETTINGS_CLASS_NAME =
-            "com.android.phone.CallFeaturesSetting";
-
-    /**
-     * Copied from PhoneApp. See comments in Phone app for more detail.
-     */
-    public static final String EXTRA_CALL_ORIGIN = "com.android.phone.CALL_ORIGIN";
-    /** @see #getCallOrigin() */
-    private static final String CALL_ORIGIN_DIALTACTS =
-            "com.android.contacts.activities.DialtactsActivity";
-
-    /**
-     * Just for backward compatibility. Should behave as same as {@link Intent#ACTION_DIAL}.
-     */
-    private static final String ACTION_TOUCH_DIALER = "com.android.phone.action.TOUCH_DIALER";
-
-    /** Used both by {@link ActionBar} and {@link ViewPagerAdapter} */
-    private static final int TAB_INDEX_DIALER = 0;
-    private static final int TAB_INDEX_CALL_LOG = 1;
-    private static final int TAB_INDEX_FAVORITES = 2;
-
-    private static final int TAB_INDEX_COUNT = 3;
-
-    private SharedPreferences mPrefs;
-
-    /** Last manually selected tab index */
-    private static final String PREF_LAST_MANUALLY_SELECTED_TAB =
-            "DialtactsActivity_last_manually_selected_tab";
-    private static final int PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT = TAB_INDEX_DIALER;
-
-    private static final int SUBACTIVITY_ACCOUNT_FILTER = 1;
-
-    public class ViewPagerAdapter extends FragmentPagerAdapter {
-        public ViewPagerAdapter(FragmentManager fm) {
-            super(fm);
-        }
-
-        @Override
-        public Fragment getItem(int position) {
-            switch (position) {
-                case TAB_INDEX_DIALER:
-                    return new DialpadFragment();
-                case TAB_INDEX_CALL_LOG:
-                    return new CallLogFragment();
-                case TAB_INDEX_FAVORITES:
-                    return new PhoneFavoriteFragment();
-            }
-            throw new IllegalStateException("No fragment at position " + position);
-        }
-
-        @Override
-        public void setPrimaryItem(ViewGroup container, int position, Object object) {
-            // The parent's setPrimaryItem() also calls setMenuVisibility(), so we want to know
-            // when it happens.
-            if (DEBUG) {
-                Log.d(TAG, "FragmentPagerAdapter#setPrimaryItem(), position: " + position);
-            }
-            super.setPrimaryItem(container, position, object);
-        }
-
-        @Override
-        public int getCount() {
-            return TAB_INDEX_COUNT;
-        }
-    }
-
-    /**
-     * True when the app detects user's drag event. This variable should not become true when
-     * mUserTabClick is true.
-     *
-     * During user's drag or tab click, we shouldn't show fake buttons but just show real
-     * ActionBar at the bottom of the screen, for transition animation.
-     */
-    boolean mDuringSwipe = false;
-    /**
-     * True when the app detects user's tab click (at the top of the screen). This variable should
-     * not become true when mDuringSwipe is true.
-     *
-     * During user's drag or tab click, we shouldn't show fake buttons but just show real
-     * ActionBar at the bottom of the screen, for transition animation.
-     */
-    boolean mUserTabClick = false;
-
-    private class PageChangeListener implements OnPageChangeListener {
-        private int mCurrentPosition = -1;
-        /**
-         * Used during page migration, to remember the next position {@link #onPageSelected(int)}
-         * specified.
-         */
-        private int mNextPosition = -1;
-
-        @Override
-        public void onPageScrolled(
-                int position, float positionOffset, int positionOffsetPixels) {
-        }
-
-        @Override
-        public void onPageSelected(int position) {
-            if (DEBUG) Log.d(TAG, "onPageSelected: position: " + position);
-            final ActionBar actionBar = getActionBar();
-            if (mDialpadFragment != null) {
-                if (mDuringSwipe && position == TAB_INDEX_DIALER) {
-                    // TODO: Figure out if we want this or not. Right now
-                    // - with this call, both fake buttons and real action bar overlap
-                    // - without this call, there's tiny flicker happening to search/menu buttons.
-                    // If we can reduce the flicker without this call, it would be much better.
-                    // updateFakeMenuButtonsVisibility(true);
-                }
-            }
-
-            if (mCurrentPosition == position) {
-                Log.w(TAG, "Previous position and next position became same (" + position + ")");
-            }
-
-            actionBar.selectTab(actionBar.getTabAt(position));
-            mNextPosition = position;
-        }
-
-        public void setCurrentPosition(int position) {
-            mCurrentPosition = position;
-        }
-
-        public int getCurrentPosition() {
-            return mCurrentPosition;
-        }
-
-        @Override
-        public void onPageScrollStateChanged(int state) {
-            switch (state) {
-                case ViewPager.SCROLL_STATE_IDLE: {
-                    if (mNextPosition == -1) {
-                        // This happens when the user drags the screen just after launching the
-                        // application, and settle down the same screen without actually swiping it.
-                        // At that moment mNextPosition is apparently -1 yet, and we expect it
-                        // being updated by onPageSelected(), which is *not* called if the user
-                        // settle down the exact same tab after the dragging.
-                        if (DEBUG) {
-                            Log.d(TAG, "Next position is not specified correctly. Use current tab ("
-                                    + mViewPager.getCurrentItem() + ")");
-                        }
-                        mNextPosition = mViewPager.getCurrentItem();
-                    }
-                    if (DEBUG) {
-                        Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_IDLE. "
-                                + "mCurrentPosition: " + mCurrentPosition
-                                + ", mNextPosition: " + mNextPosition);
-                    }
-                    // Interpret IDLE as the end of migration (both swipe and tab click)
-                    mDuringSwipe = false;
-                    mUserTabClick = false;
-
-                    updateFakeMenuButtonsVisibility(mNextPosition == TAB_INDEX_DIALER);
-                    sendFragmentVisibilityChange(mCurrentPosition, false);
-                    sendFragmentVisibilityChange(mNextPosition, true);
-
-                    invalidateOptionsMenu();
-
-                    mCurrentPosition = mNextPosition;
-                    break;
-                }
-                case ViewPager.SCROLL_STATE_DRAGGING: {
-                    if (DEBUG) Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_DRAGGING");
-                    mDuringSwipe = true;
-                    mUserTabClick = false;
-                    break;
-                }
-                case ViewPager.SCROLL_STATE_SETTLING: {
-                    if (DEBUG) Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_SETTLING");
-                    mDuringSwipe = true;
-                    mUserTabClick = false;
-                    break;
-                }
-                default:
-                    break;
-            }
-        }
-    }
-
-    private String mFilterText;
-
-    /** Enables horizontal swipe between Fragments. */
-    private ViewPager mViewPager;
-    private final PageChangeListener mPageChangeListener = new PageChangeListener();
-    private DialpadFragment mDialpadFragment;
-    private CallLogFragment mCallLogFragment;
-    private PhoneFavoriteFragment mPhoneFavoriteFragment;
-
-    private View mSearchButton;
-    private View mMenuButton;
-
-    private final ContactListFilterListener mContactListFilterListener =
-            new ContactListFilterListener() {
-        @Override
-        public void onContactListFilterChanged() {
-            boolean doInvalidateOptionsMenu = false;
-
-            if (mPhoneFavoriteFragment != null && mPhoneFavoriteFragment.isAdded()) {
-                mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter());
-                doInvalidateOptionsMenu = true;
-            }
-
-            if (mSearchFragment != null && mSearchFragment.isAdded()) {
-                mSearchFragment.setFilter(mContactListFilterController.getFilter());
-                doInvalidateOptionsMenu = true;
-            } else {
-                Log.w(TAG, "Search Fragment isn't available when ContactListFilter is changed");
-            }
-
-            if (doInvalidateOptionsMenu) {
-                invalidateOptionsMenu();
-            }
-        }
-    };
-
-    private final TabListener mTabListener = new TabListener() {
-        @Override
-        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
-            if (DEBUG) Log.d(TAG, "onTabUnselected(). tab: " + tab);
-        }
-
-        @Override
-        public void onTabSelected(Tab tab, FragmentTransaction ft) {
-            if (DEBUG) {
-                Log.d(TAG, "onTabSelected(). tab: " + tab + ", mDuringSwipe: " + mDuringSwipe);
-            }
-            // When the user swipes the screen horizontally, this method will be called after
-            // ViewPager.SCROLL_STATE_DRAGGING and ViewPager.SCROLL_STATE_SETTLING events, while
-            // when the user clicks a tab at the ActionBar at the top, this will be called before
-            // them. This logic interprets the order difference as a difference of the user action.
-            if (!mDuringSwipe) {
-                if (DEBUG) {
-                    Log.d(TAG, "Tab select. from: " + mPageChangeListener.getCurrentPosition()
-                            + ", to: " + tab.getPosition());
-                }
-                if (mDialpadFragment != null) {
-                    updateFakeMenuButtonsVisibility(tab.getPosition() == TAB_INDEX_DIALER);
-                }
-                mUserTabClick = true;
-            }
-
-            if (mViewPager.getCurrentItem() != tab.getPosition()) {
-                mViewPager.setCurrentItem(tab.getPosition(), true);
-            }
-
-            // During the call, we don't remember the tab position.
-            if (!DialpadFragment.phoneIsInUse()) {
-                // Remember this tab index. This function is also called, if the tab is set
-                // automatically in which case the setter (setCurrentTab) has to set this to its old
-                // value afterwards
-                mLastManuallySelectedFragment = tab.getPosition();
-            }
-        }
-
-        @Override
-        public void onTabReselected(Tab tab, FragmentTransaction ft) {
-            if (DEBUG) Log.d(TAG, "onTabReselected");
-        }
-    };
-
-    /**
-     * Fragment for searching phone numbers. Unlike the other Fragments, this doesn't correspond
-     * to tab but is shown by a search action.
-     */
-    private PhoneNumberPickerFragment mSearchFragment;
-    /**
-     * True when this Activity is in its search UI (with a {@link SearchView} and
-     * {@link PhoneNumberPickerFragment}).
-     */
-    private boolean mInSearchUi;
-    private SearchView mSearchView;
-
-    private final OnClickListener mFilterOptionClickListener = new OnClickListener() {
-        @Override
-        public void onClick(View view) {
-            final PopupMenu popupMenu = new PopupMenu(DialtactsActivity.this, view);
-            final Menu menu = popupMenu.getMenu();
-            popupMenu.inflate(R.menu.dialtacts_search_options);
-            final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
-            filterOptionMenuItem.setOnMenuItemClickListener(mFilterOptionsMenuItemClickListener);
-            final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
-            addContactOptionMenuItem.setIntent(
-                    new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
-            popupMenu.show();
-        }
-    };
-
-    /**
-     * The index of the Fragment (or, the tab) that has last been manually selected.
-     * This value does not keep track of programmatically set Tabs (e.g. Call Log after a Call)
-     */
-    private int mLastManuallySelectedFragment;
-
-    private ContactListFilterController mContactListFilterController;
-    private OnMenuItemClickListener mFilterOptionsMenuItemClickListener =
-            new OnMenuItemClickListener() {
-        @Override
-        public boolean onMenuItemClick(MenuItem item) {
-            AccountFilterUtil.startAccountFilterActivityForResult(
-                    DialtactsActivity.this, SUBACTIVITY_ACCOUNT_FILTER,
-                    mContactListFilterController.getFilter());
-            return true;
-        }
-    };
-
-    private OnMenuItemClickListener mSearchMenuItemClickListener =
-            new OnMenuItemClickListener() {
-        @Override
-        public boolean onMenuItemClick(MenuItem item) {
-            enterSearchUi();
-            return true;
-        }
-    };
-
-    /**
-     * Listener used when one of phone numbers in search UI is selected. This will initiate a
-     * phone call using the phone number.
-     */
-    private final OnPhoneNumberPickerActionListener mPhoneNumberPickerActionListener =
-            new OnPhoneNumberPickerActionListener() {
-                @Override
-                public void onPickPhoneNumberAction(Uri dataUri) {
-                    // Specify call-origin so that users will see the previous tab instead of
-                    // CallLog screen (search UI will be automatically exited).
-                    PhoneNumberInteraction.startInteractionForPhoneCall(
-                            DialtactsActivity.this, dataUri, getCallOrigin());
-                }
-
-                @Override
-                public void onShortcutIntentCreated(Intent intent) {
-                    Log.w(TAG, "Unsupported intent has come (" + intent + "). Ignoring.");
-                }
-
-                @Override
-                public void onHomeInActionBarSelected() {
-                    exitSearchUi();
-                }
-    };
-
-    /**
-     * Listener used to send search queries to the phone search fragment.
-     */
-    private final OnQueryTextListener mPhoneSearchQueryTextListener =
-            new OnQueryTextListener() {
-                @Override
-                public boolean onQueryTextSubmit(String query) {
-                    View view = getCurrentFocus();
-                    if (view != null) {
-                        hideInputMethod(view);
-                        view.clearFocus();
-                    }
-                    return true;
-                }
-
-                @Override
-                public boolean onQueryTextChange(String newText) {
-                    // Show search result with non-empty text. Show a bare list otherwise.
-                    if (mSearchFragment != null) {
-                        mSearchFragment.setQueryString(newText, true);
-                    }
-                    return true;
-                }
-    };
-
-    /**
-     * Listener used to handle the "close" button on the right side of {@link SearchView}.
-     * If some text is in the search view, this will clean it up. Otherwise this will exit
-     * the search UI and let users go back to usual Phone UI.
-     *
-     * This does _not_ handle back button.
-     */
-    private final OnCloseListener mPhoneSearchCloseListener =
-            new OnCloseListener() {
-                @Override
-                public boolean onClose() {
-                    if (!TextUtils.isEmpty(mSearchView.getQuery())) {
-                        mSearchView.setQuery(null, true);
-                    }
-                    return true;
-                }
-    };
-
-    private final View.OnLayoutChangeListener mFirstLayoutListener
-            = new View.OnLayoutChangeListener() {
-        @Override
-        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
-                int oldTop, int oldRight, int oldBottom) {
-            v.removeOnLayoutChangeListener(this); // Unregister self.
-            addSearchFragment();
-        }
-    };
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        final Intent intent = getIntent();
-        fixIntent(intent);
-
-        setContentView(R.layout.dialtacts_activity);
-
-        mContactListFilterController = ContactListFilterController.getInstance(this);
-        mContactListFilterController.addListener(mContactListFilterListener);
-
-        findViewById(R.id.dialtacts_frame).addOnLayoutChangeListener(mFirstLayoutListener);
-
-        mViewPager = (ViewPager) findViewById(R.id.pager);
-        mViewPager.setAdapter(new ViewPagerAdapter(getFragmentManager()));
-        mViewPager.setOnPageChangeListener(mPageChangeListener);
-        mViewPager.setOffscreenPageLimit(2);
-
-        // Do same width calculation as ActionBar does
-        DisplayMetrics dm = getResources().getDisplayMetrics();
-        int minCellSize = getResources().getDimensionPixelSize(R.dimen.fake_menu_button_min_width);
-        int cellCount = dm.widthPixels / minCellSize;
-        int fakeMenuItemWidth = dm.widthPixels / cellCount;
-        if (DEBUG) Log.d(TAG, "The size of fake menu buttons (in pixel): " + fakeMenuItemWidth);
-
-        // Soft menu button should appear only when there's no hardware menu button.
-        mMenuButton = findViewById(R.id.overflow_menu);
-        if (mMenuButton != null) {
-            mMenuButton.setMinimumWidth(fakeMenuItemWidth);
-            if (ViewConfiguration.get(this).hasPermanentMenuKey()) {
-                // This is required for dialpad button's layout, so must not use GONE here.
-                mMenuButton.setVisibility(View.INVISIBLE);
-            } else {
-                mMenuButton.setOnClickListener(this);
-            }
-        }
-        mSearchButton = findViewById(R.id.searchButton);
-        if (mSearchButton != null) {
-            mSearchButton.setMinimumWidth(fakeMenuItemWidth);
-            mSearchButton.setOnClickListener(this);
-        }
-
-        // Setup the ActionBar tabs (the order matches the tab-index contants TAB_INDEX_*)
-        setupDialer();
-        setupCallLog();
-        setupFavorites();
-        getActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-        getActionBar().setDisplayShowTitleEnabled(false);
-        getActionBar().setDisplayShowHomeEnabled(false);
-
-        // Load the last manually loaded tab
-        mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
-        mLastManuallySelectedFragment = mPrefs.getInt(PREF_LAST_MANUALLY_SELECTED_TAB,
-                PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT);
-        if (mLastManuallySelectedFragment >= TAB_INDEX_COUNT) {
-            // Stored value may have exceeded the number of current tabs. Reset it.
-            mLastManuallySelectedFragment = PREF_LAST_MANUALLY_SELECTED_TAB_DEFAULT;
-        }
-
-        setCurrentTab(intent);
-
-        if (UI.FILTER_CONTACTS_ACTION.equals(intent.getAction())
-                && icicle == null) {
-            setupFilterText(intent);
-        }
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-        if (mPhoneFavoriteFragment != null) {
-            mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter());
-        }
-        if (mSearchFragment != null) {
-            mSearchFragment.setFilter(mContactListFilterController.getFilter());
-        }
-
-        if (mDuringSwipe || mUserTabClick) {
-            if (DEBUG) Log.d(TAG, "reset buggy flag state..");
-            mDuringSwipe = false;
-            mUserTabClick = false;
-        }
-
-        final int currentPosition = mPageChangeListener.getCurrentPosition();
-        if (DEBUG) {
-            Log.d(TAG, "onStart(). current position: " + mPageChangeListener.getCurrentPosition()
-                    + ". Reset all menu visibility state.");
-        }
-        updateFakeMenuButtonsVisibility(currentPosition == TAB_INDEX_DIALER && !mInSearchUi);
-        for (int i = 0; i < TAB_INDEX_COUNT; i++) {
-            sendFragmentVisibilityChange(i, i == currentPosition);
-        }
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        mContactListFilterController.removeListener(mContactListFilterListener);
-    }
-
-    @Override
-    public void onClick(View view) {
-        switch (view.getId()) {
-            case R.id.searchButton: {
-                enterSearchUi();
-                break;
-            }
-            case R.id.overflow_menu: {
-                if (mDialpadFragment != null) {
-                    PopupMenu popup = mDialpadFragment.constructPopupMenu(view);
-                    if (popup != null) {
-                        popup.show();
-                    }
-                } else {
-                    Log.w(TAG, "DialpadFragment is null during onClick() event for " + view);
-                }
-                break;
-            }
-            default: {
-                Log.wtf(TAG, "Unexpected onClick event from " + view);
-                break;
-            }
-        }
-    }
-
-    /**
-     * Add search fragment.  Note this is called during onLayout, so there's some restrictions,
-     * such as executePendingTransaction can't be used in it.
-     */
-    private void addSearchFragment() {
-        // In order to take full advantage of "fragment deferred start", we need to create the
-        // search fragment after all other fragments are created.
-        // The other fragments are created by the ViewPager on the first onMeasure().
-        // We use the first onLayout call, which is after onMeasure().
-
-        // Just return if the fragment is already created, which happens after configuration
-        // changes.
-        if (mSearchFragment != null) return;
-
-        final FragmentTransaction ft = getFragmentManager().beginTransaction();
-        final Fragment searchFragment = new PhoneNumberPickerFragment();
-
-        searchFragment.setUserVisibleHint(false);
-        ft.add(R.id.dialtacts_frame, searchFragment);
-        ft.hide(searchFragment);
-        ft.commitAllowingStateLoss();
-    }
-
-    private void prepareSearchView() {
-        final View searchViewLayout =
-                getLayoutInflater().inflate(R.layout.dialtacts_custom_action_bar, null);
-        mSearchView = (SearchView) searchViewLayout.findViewById(R.id.search_view);
-        mSearchView.setOnQueryTextListener(mPhoneSearchQueryTextListener);
-        mSearchView.setOnCloseListener(mPhoneSearchCloseListener);
-        // Since we're using a custom layout for showing SearchView instead of letting the
-        // search menu icon do that job, we need to manually configure the View so it looks
-        // "shown via search menu".
-        // - it should be iconified by default
-        // - it should not be iconified at this time
-        // See also comments for onActionViewExpanded()/onActionViewCollapsed()
-        mSearchView.setIconifiedByDefault(true);
-        mSearchView.setQueryHint(getString(R.string.hint_findContacts));
-        mSearchView.setIconified(false);
-        mSearchView.setOnQueryTextFocusChangeListener(new OnFocusChangeListener() {
-            @Override
-            public void onFocusChange(View view, boolean hasFocus) {
-                if (hasFocus) {
-                    showInputMethod(view.findFocus());
-                }
-            }
-        });
-
-        if (!ViewConfiguration.get(this).hasPermanentMenuKey()) {
-            // Filter option menu should be shown on the right side of SearchView.
-            final View filterOptionView = searchViewLayout.findViewById(R.id.search_option);
-            filterOptionView.setVisibility(View.VISIBLE);
-            filterOptionView.setOnClickListener(mFilterOptionClickListener);
-        }
-
-        getActionBar().setCustomView(searchViewLayout,
-                new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
-    }
-
-    @Override
-    public void onAttachFragment(Fragment fragment) {
-        // This method can be called before onCreate(), at which point we cannot rely on ViewPager.
-        // In that case, we will setup the "current position" soon after the ViewPager is ready.
-        final int currentPosition = mViewPager != null ? mViewPager.getCurrentItem() : -1;
-
-        if (fragment instanceof DialpadFragment) {
-            mDialpadFragment = (DialpadFragment) fragment;
-        } else if (fragment instanceof CallLogFragment) {
-            mCallLogFragment = (CallLogFragment) fragment;
-        } else if (fragment instanceof PhoneFavoriteFragment) {
-            mPhoneFavoriteFragment = (PhoneFavoriteFragment) fragment;
-            mPhoneFavoriteFragment.setListener(mPhoneFavoriteListener);
-            if (mContactListFilterController != null
-                    && mContactListFilterController.getFilter() != null) {
-                mPhoneFavoriteFragment.setFilter(mContactListFilterController.getFilter());
-            }
-        } else if (fragment instanceof PhoneNumberPickerFragment) {
-            mSearchFragment = (PhoneNumberPickerFragment) fragment;
-            mSearchFragment.setOnPhoneNumberPickerActionListener(mPhoneNumberPickerActionListener);
-            mSearchFragment.setQuickContactEnabled(true);
-            mSearchFragment.setDarkTheme(true);
-            mSearchFragment.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
-            mSearchFragment.setUseCallableUri(true);
-            if (mContactListFilterController != null
-                    && mContactListFilterController.getFilter() != null) {
-                mSearchFragment.setFilter(mContactListFilterController.getFilter());
-            }
-            // Here we assume that we're not on the search mode, so let's hide the fragment.
-            //
-            // We get here either when the fragment is created (normal case), or after configuration
-            // changes.  In the former case, we're not in search mode because we can only
-            // enter search mode if the fragment is created.  (see enterSearchUi())
-            // In the latter case we're not in search mode either because we don't retain
-            // mInSearchUi -- ideally we should but at this point it's not supported.
-            mSearchFragment.setUserVisibleHint(false);
-            // After configuration changes fragments will forget their "hidden" state, so make
-            // sure to hide it.
-            if (!mSearchFragment.isHidden()) {
-                final FragmentTransaction transaction = getFragmentManager().beginTransaction();
-                transaction.hide(mSearchFragment);
-                transaction.commitAllowingStateLoss();
-            }
-        }
-    }
-
-    @Override
-    protected void onPause() {
-        super.onPause();
-
-        mPrefs.edit().putInt(PREF_LAST_MANUALLY_SELECTED_TAB, mLastManuallySelectedFragment)
-                .apply();
-    }
-
-    private void fixIntent(Intent intent) {
-        // This should be cleaned up: the call key used to send an Intent
-        // that just said to go to the recent calls list.  It now sends this
-        // abstract action, but this class hasn't been rewritten to deal with it.
-        if (Intent.ACTION_CALL_BUTTON.equals(intent.getAction())) {
-            intent.setDataAndType(Calls.CONTENT_URI, Calls.CONTENT_TYPE);
-            intent.putExtra("call_key", true);
-            setIntent(intent);
-        }
-    }
-
-    private void setupDialer() {
-        final Tab tab = getActionBar().newTab();
-        tab.setContentDescription(R.string.dialerIconLabel);
-        tab.setTabListener(mTabListener);
-        tab.setIcon(R.drawable.ic_tab_dialer);
-        getActionBar().addTab(tab);
-    }
-
-    private void setupCallLog() {
-        final Tab tab = getActionBar().newTab();
-        tab.setContentDescription(R.string.recentCallsIconLabel);
-        tab.setIcon(R.drawable.ic_tab_recent);
-        tab.setTabListener(mTabListener);
-        getActionBar().addTab(tab);
-    }
-
-    private void setupFavorites() {
-        final Tab tab = getActionBar().newTab();
-        tab.setContentDescription(R.string.contactsFavoritesLabel);
-        tab.setIcon(R.drawable.ic_tab_all);
-        tab.setTabListener(mTabListener);
-        getActionBar().addTab(tab);
-    }
-
-    /**
-     * Returns true if the intent is due to hitting the green send key (hardware call button:
-     * KEYCODE_CALL) while in a call.
-     *
-     * @param intent the intent that launched this activity
-     * @param recentCallsRequest true if the intent is requesting to view recent calls
-     * @return true if the intent is due to hitting the green send key while in a call
-     */
-    private boolean isSendKeyWhileInCall(final Intent intent,
-            final boolean recentCallsRequest) {
-        // If there is a call in progress go to the call screen
-        if (recentCallsRequest) {
-            final boolean callKey = intent.getBooleanExtra("call_key", false);
-
-            try {
-                ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
-                if (callKey && phone != null && phone.showCallScreen()) {
-                    return true;
-                }
-            } catch (RemoteException e) {
-                Log.e(TAG, "Failed to handle send while in call", e);
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Sets the current tab based on the intent's request type
-     *
-     * @param intent Intent that contains information about which tab should be selected
-     */
-    private void setCurrentTab(Intent intent) {
-        // If we got here by hitting send and we're in call forward along to the in-call activity
-        boolean recentCallsRequest = Calls.CONTENT_TYPE.equals(intent.resolveType(
-            getContentResolver()));
-        if (isSendKeyWhileInCall(intent, recentCallsRequest)) {
-            finish();
-            return;
-        }
-
-        // Remember the old manually selected tab index so that it can be restored if it is
-        // overwritten by one of the programmatic tab selections
-        final int savedTabIndex = mLastManuallySelectedFragment;
-
-        final int tabIndex;
-        if (DialpadFragment.phoneIsInUse() || isDialIntent(intent)) {
-            tabIndex = TAB_INDEX_DIALER;
-        } else if (recentCallsRequest) {
-            tabIndex = TAB_INDEX_CALL_LOG;
-        } else {
-            tabIndex = mLastManuallySelectedFragment;
-        }
-
-        final int previousItemIndex = mViewPager.getCurrentItem();
-        mViewPager.setCurrentItem(tabIndex, false /* smoothScroll */);
-        if (previousItemIndex != tabIndex) {
-            sendFragmentVisibilityChange(previousItemIndex, false /* not visible */ );
-        }
-        mPageChangeListener.setCurrentPosition(tabIndex);
-        sendFragmentVisibilityChange(tabIndex, true /* visible */ );
-
-        // Restore to the previous manual selection
-        mLastManuallySelectedFragment = savedTabIndex;
-        mDuringSwipe = false;
-        mUserTabClick = false;
-    }
-
-    @Override
-    public void onNewIntent(Intent newIntent) {
-        setIntent(newIntent);
-        fixIntent(newIntent);
-        setCurrentTab(newIntent);
-        final String action = newIntent.getAction();
-        if (UI.FILTER_CONTACTS_ACTION.equals(action)) {
-            setupFilterText(newIntent);
-        }
-        if (mInSearchUi || (mSearchFragment != null && mSearchFragment.isVisible())) {
-            exitSearchUi();
-        }
-
-        if (mViewPager.getCurrentItem() == TAB_INDEX_DIALER) {
-            if (mDialpadFragment != null) {
-                mDialpadFragment.configureScreenFromIntent(newIntent);
-            } else {
-                Log.e(TAG, "DialpadFragment isn't ready yet when the tab is already selected.");
-            }
-        } else if (mViewPager.getCurrentItem() == TAB_INDEX_CALL_LOG) {
-            if (mCallLogFragment != null) {
-                mCallLogFragment.configureScreenFromIntent(newIntent);
-            } else {
-                Log.e(TAG, "CallLogFragment isn't ready yet when the tab is already selected.");
-            }
-        }
-        invalidateOptionsMenu();
-    }
-
-    /** Returns true if the given intent contains a phone number to populate the dialer with */
-    private boolean isDialIntent(Intent intent) {
-        final String action = intent.getAction();
-        if (Intent.ACTION_DIAL.equals(action) || ACTION_TOUCH_DIALER.equals(action)) {
-            return true;
-        }
-        if (Intent.ACTION_VIEW.equals(action)) {
-            final Uri data = intent.getData();
-            if (data != null && Constants.SCHEME_TEL.equals(data.getScheme())) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Returns an appropriate call origin for this Activity. May return null when no call origin
-     * should be used (e.g. when some 3rd party application launched the screen. Call origin is
-     * for remembering the tab in which the user made a phone call, so the external app's DIAL
-     * request should not be counted.)
-     */
-    public String getCallOrigin() {
-        return !isDialIntent(getIntent()) ? CALL_ORIGIN_DIALTACTS : null;
-    }
-
-    /**
-     * Retrieves the filter text stored in {@link #setupFilterText(Intent)}.
-     * This text originally came from a FILTER_CONTACTS_ACTION intent received
-     * by this activity. The stored text will then be cleared after after this
-     * method returns.
-     *
-     * @return The stored filter text
-     */
-    public String getAndClearFilterText() {
-        String filterText = mFilterText;
-        mFilterText = null;
-        return filterText;
-    }
-
-    /**
-     * Stores the filter text associated with a FILTER_CONTACTS_ACTION intent.
-     * This is so child activities can check if they are supposed to display a filter.
-     *
-     * @param intent The intent received in {@link #onNewIntent(Intent)}
-     */
-    private void setupFilterText(Intent intent) {
-        // If the intent was relaunched from history, don't apply the filter text.
-        if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
-            return;
-        }
-        String filter = intent.getStringExtra(UI.FILTER_TEXT_EXTRA_KEY);
-        if (filter != null && filter.length() > 0) {
-            mFilterText = filter;
-        }
-    }
-
-    @Override
-    public void onBackPressed() {
-        if (mInSearchUi) {
-            // We should let the user go back to usual screens with tabs.
-            exitSearchUi();
-        } else if (isTaskRoot()) {
-            // Instead of stopping, simply push this to the back of the stack.
-            // This is only done when running at the top of the stack;
-            // otherwise, we have been launched by someone else so need to
-            // allow the user to go back to the caller.
-            moveTaskToBack(false);
-        } else {
-            super.onBackPressed();
-        }
-    }
-
-    private final PhoneFavoriteFragment.Listener mPhoneFavoriteListener =
-            new PhoneFavoriteFragment.Listener() {
-        @Override
-        public void onContactSelected(Uri contactUri) {
-            PhoneNumberInteraction.startInteractionForPhoneCall(
-                    DialtactsActivity.this, contactUri, getCallOrigin());
-        }
-
-        @Override
-        public void onCallNumberDirectly(String phoneNumber) {
-            Intent intent = ContactsUtils.getCallIntent(phoneNumber, getCallOrigin());
-            startActivity(intent);
-        }
-    };
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        MenuInflater inflater = getMenuInflater();
-        inflater.inflate(R.menu.dialtacts_options, menu);
-
-        // set up intents and onClick listeners
-        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
-        final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
-        final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
-        final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
-
-        callSettingsMenuItem.setIntent(DialtactsActivity.getCallSettingsIntent());
-        searchMenuItem.setOnMenuItemClickListener(mSearchMenuItemClickListener);
-        filterOptionMenuItem.setOnMenuItemClickListener(mFilterOptionsMenuItemClickListener);
-        addContactOptionMenuItem.setIntent(
-                new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
-
-        return true;
-    }
-
-    @Override
-    public boolean onPrepareOptionsMenu(Menu menu) {
-        if (mInSearchUi) {
-            prepareOptionsMenuInSearchMode(menu);
-        } else {
-            // get reference to the currently selected tab
-            final Tab tab = getActionBar().getSelectedTab();
-            if (tab != null) {
-                switch(tab.getPosition()) {
-                    case TAB_INDEX_DIALER:
-                        prepareOptionsMenuForDialerTab(menu);
-                        break;
-                    case TAB_INDEX_CALL_LOG:
-                        prepareOptionsMenuForCallLogTab(menu);
-                        break;
-                    case TAB_INDEX_FAVORITES:
-                        prepareOptionsMenuForFavoritesTab(menu);
-                        break;
-                }
-            }
-        }
-        return true;
-    }
-
-    private void prepareOptionsMenuInSearchMode(Menu menu) {
-        // get references to menu items
-        final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
-        final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
-        final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
-        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
-        final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item);
-
-        // prepare the menu items
-        searchMenuItem.setVisible(false);
-        filterOptionMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
-        addContactOptionMenuItem.setVisible(false);
-        callSettingsMenuItem.setVisible(false);
-        emptyRightMenuItem.setVisible(false);
-    }
-
-    private void prepareOptionsMenuForDialerTab(Menu menu) {
-        if (DEBUG) {
-            Log.d(TAG, "onPrepareOptionsMenu(dialer). swipe: " + mDuringSwipe
-                    + ", user tab click: " + mUserTabClick);
-        }
-
-        // get references to menu items
-        final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
-        final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
-        final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
-        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
-        final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item);
-
-        // prepare the menu items
-        filterOptionMenuItem.setVisible(false);
-        addContactOptionMenuItem.setVisible(false);
-        if (mDuringSwipe || mUserTabClick) {
-            // During horizontal movement, the real ActionBar menu items are shown
-            searchMenuItem.setVisible(true);
-            callSettingsMenuItem.setVisible(true);
-            // When there is a permanent menu key, there is no overflow icon on the right of
-            // the action bar which would force the search menu item (if it is visible) to the
-            // left.  This is the purpose of showing the emptyRightMenuItem.
-            emptyRightMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
-        } else {
-            // This is when the user is looking at the dialer pad.  In this case, the real
-            // ActionBar is hidden and fake menu items are shown.
-            // Except in landscape, in which case the real search menu item is shown.
-            searchMenuItem.setVisible(ContactsUtils.isLandscape(this));
-            // If a permanent menu key is available, then we need to show the call settings item
-            // so that the call settings item can be invoked by the permanent menu key.
-            callSettingsMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
-            emptyRightMenuItem.setVisible(false);
-        }
-    }
-
-    private void prepareOptionsMenuForCallLogTab(Menu menu) {
-        // get references to menu items
-        final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
-        final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
-        final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
-        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
-        final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item);
-
-        // prepare the menu items
-        searchMenuItem.setVisible(true);
-        filterOptionMenuItem.setVisible(false);
-        addContactOptionMenuItem.setVisible(false);
-        callSettingsMenuItem.setVisible(true);
-        emptyRightMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
-    }
-
-    private void prepareOptionsMenuForFavoritesTab(Menu menu) {
-        // get references to menu items
-        final MenuItem searchMenuItem = menu.findItem(R.id.search_on_action_bar);
-        final MenuItem filterOptionMenuItem = menu.findItem(R.id.filter_option);
-        final MenuItem addContactOptionMenuItem = menu.findItem(R.id.add_contact);
-        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings);
-        final MenuItem emptyRightMenuItem = menu.findItem(R.id.empty_right_menu_item);
-
-        // prepare the menu items
-        searchMenuItem.setVisible(true);
-        filterOptionMenuItem.setVisible(true);
-        addContactOptionMenuItem.setVisible(true);
-        callSettingsMenuItem.setVisible(true);
-        emptyRightMenuItem.setVisible(false);
-    }
-
-    @Override
-    public void startSearch(String initialQuery, boolean selectInitialQuery,
-            Bundle appSearchData, boolean globalSearch) {
-        if (mSearchFragment != null && mSearchFragment.isAdded() && !globalSearch) {
-            if (mInSearchUi) {
-                if (mSearchView.hasFocus()) {
-                    showInputMethod(mSearchView.findFocus());
-                } else {
-                    mSearchView.requestFocus();
-                }
-            } else {
-                enterSearchUi();
-            }
-        } else {
-            super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
-        }
-    }
-
-    /**
-     * Hides every tab and shows search UI for phone lookup.
-     */
-    private void enterSearchUi() {
-        if (mSearchFragment == null) {
-            // We add the search fragment dynamically in the first onLayoutChange() and
-            // mSearchFragment is set sometime later when the fragment transaction is actually
-            // executed, which means there's a window when users are able to hit the (physical)
-            // search key but mSearchFragment is still null.
-            // It's quite hard to handle this case right, so let's just ignore the search key
-            // in this case.  Users can just hit it again and it will work this time.
-            return;
-        }
-        if (mSearchView == null) {
-            prepareSearchView();
-        }
-
-        final ActionBar actionBar = getActionBar();
-
-        final Tab tab = actionBar.getSelectedTab();
-
-        // User can search during the call, but we don't want to remember the status.
-        if (tab != null && !DialpadFragment.phoneIsInUse()) {
-            mLastManuallySelectedFragment = tab.getPosition();
-        }
-
-        mSearchView.setQuery(null, true);
-
-        actionBar.setDisplayShowCustomEnabled(true);
-        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
-        actionBar.setDisplayShowHomeEnabled(true);
-        actionBar.setDisplayHomeAsUpEnabled(true);
-
-        updateFakeMenuButtonsVisibility(false);
-
-        for (int i = 0; i < TAB_INDEX_COUNT; i++) {
-            sendFragmentVisibilityChange(i, false /* not visible */ );
-        }
-
-        // Show the search fragment and hide everything else.
-        mSearchFragment.setUserVisibleHint(true);
-        final FragmentTransaction transaction = getFragmentManager().beginTransaction();
-        transaction.show(mSearchFragment);
-        transaction.commitAllowingStateLoss();
-        mViewPager.setVisibility(View.GONE);
-
-        // We need to call this and onActionViewCollapsed() manually, since we are using a custom
-        // layout instead of asking the search menu item to take care of SearchView.
-        mSearchView.onActionViewExpanded();
-        mInSearchUi = true;
-    }
-
-    private void showInputMethod(View view) {
-        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
-        if (imm != null) {
-            if (!imm.showSoftInput(view, 0)) {
-                Log.w(TAG, "Failed to show soft input method.");
-            }
-        }
-    }
-
-    private void hideInputMethod(View view) {
-        InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
-        if (imm != null && view != null) {
-            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
-        }
-    }
-
-    /**
-     * Goes back to usual Phone UI with tags. Previously selected Tag and associated Fragment
-     * should be automatically focused again.
-     */
-    private void exitSearchUi() {
-        final ActionBar actionBar = getActionBar();
-
-        // Hide the search fragment, if exists.
-        if (mSearchFragment != null) {
-            mSearchFragment.setUserVisibleHint(false);
-
-            final FragmentTransaction transaction = getFragmentManager().beginTransaction();
-            transaction.hide(mSearchFragment);
-            transaction.commitAllowingStateLoss();
-        }
-
-        // We want to hide SearchView and show Tabs. Also focus on previously selected one.
-        actionBar.setDisplayShowCustomEnabled(false);
-        actionBar.setDisplayShowHomeEnabled(false);
-        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-
-        for (int i = 0; i < TAB_INDEX_COUNT; i++) {
-            sendFragmentVisibilityChange(i, i == mViewPager.getCurrentItem());
-        }
-
-        // Before exiting the search screen, reset swipe state.
-        mDuringSwipe = false;
-        mUserTabClick = false;
-
-        mViewPager.setVisibility(View.VISIBLE);
-
-        hideInputMethod(getCurrentFocus());
-
-        // Request to update option menu.
-        invalidateOptionsMenu();
-
-        // See comments in onActionViewExpanded()
-        mSearchView.onActionViewCollapsed();
-        mInSearchUi = false;
-    }
-
-    private Fragment getFragmentAt(int position) {
-        switch (position) {
-            case TAB_INDEX_DIALER:
-                return mDialpadFragment;
-            case TAB_INDEX_CALL_LOG:
-                return mCallLogFragment;
-            case TAB_INDEX_FAVORITES:
-                return mPhoneFavoriteFragment;
-            default:
-                throw new IllegalStateException("Unknown fragment index: " + position);
-        }
-    }
-
-    private void sendFragmentVisibilityChange(int position, boolean visibility) {
-        if (DEBUG) {
-            Log.d(TAG, "sendFragmentVisibiltyChange(). position: " + position
-                    + ", visibility: " + visibility);
-        }
-        // Position can be -1 initially. See PageChangeListener.
-        if (position >= 0) {
-            final Fragment fragment = getFragmentAt(position);
-            if (fragment != null) {
-                fragment.setMenuVisibility(visibility);
-                fragment.setUserVisibleHint(visibility);
-            }
-        }
-    }
-
-    /**
-     * Update visibility of the search button and menu button at the bottom.
-     * They should be invisible when bottom ActionBar's real items are available, and be visible
-     * otherwise.
-     *
-     * @param visible True when visible.
-     */
-    private void updateFakeMenuButtonsVisibility(boolean visible) {
-        // Note: Landscape mode does not have the fake menu and search buttons.
-        if (DEBUG) {
-            Log.d(TAG, "updateFakeMenuButtonVisibility(" + visible + ")");
-        }
-
-        if (mSearchButton != null) {
-            if (visible) {
-                mSearchButton.setVisibility(View.VISIBLE);
-            } else {
-                mSearchButton.setVisibility(View.INVISIBLE);
-            }
-        }
-        if (mMenuButton != null) {
-            if (visible && !ViewConfiguration.get(this).hasPermanentMenuKey()) {
-                mMenuButton.setVisibility(View.VISIBLE);
-            } else {
-                mMenuButton.setVisibility(View.INVISIBLE);
-            }
-        }
-    }
-
-    /** Returns an Intent to launch Call Settings screen */
-    public static Intent getCallSettingsIntent() {
-        final Intent intent = new Intent(Intent.ACTION_MAIN);
-        intent.setClassName(PHONE_PACKAGE, CALL_SETTINGS_CLASS_NAME);
-        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-        return intent;
-    }
-
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (resultCode != Activity.RESULT_OK) {
-            return;
-        }
-        switch (requestCode) {
-            case SUBACTIVITY_ACCOUNT_FILTER: {
-                AccountFilterUtil.handleAccountFilterResult(
-                        mContactListFilterController, resultCode, data);
-            }
-            break;
-        }
-    }
-}
diff --git a/src/com/android/contacts/activities/NonPhoneActivity.java b/src/com/android/contacts/activities/NonPhoneActivity.java
deleted file mode 100644
index fc22146..0000000
--- a/src/com/android/contacts/activities/NonPhoneActivity.java
+++ /dev/null
@@ -1,109 +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.activities;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.Intents.Insert;
-import android.text.TextUtils;
-
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-import com.android.contacts.util.Constants;
-
-/**
- * Activity that intercepts DIAL and VIEW intents for phone numbers for devices that can not
- * be used as a phone. This allows the user to see the phone number
- */
-public class NonPhoneActivity extends ContactsActivity {
-
-    private static final String PHONE_NUMBER_KEY = "PHONE_NUMBER";
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        final String phoneNumber = getPhoneNumber();
-        if (TextUtils.isEmpty(phoneNumber)) {
-            finish();
-            return;
-        }
-
-        final NonPhoneDialogFragment fragment = new NonPhoneDialogFragment();
-        Bundle bundle = new Bundle();
-        bundle.putString(PHONE_NUMBER_KEY, phoneNumber);
-        fragment.setArguments(bundle);
-        getFragmentManager().beginTransaction().add(fragment, "Fragment").commitAllowingStateLoss();
-    }
-
-    private String getPhoneNumber() {
-        if (getIntent() == null) return null;
-        final Uri data = getIntent().getData();
-        if (data == null) return null;
-        final String scheme = data.getScheme();
-        if (!Constants.SCHEME_TEL.equals(scheme)) return null;
-        return getIntent().getData().getSchemeSpecificPart();
-    }
-
-    public static final class NonPhoneDialogFragment extends DialogFragment
-            implements OnClickListener {
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            final AlertDialog alertDialog;
-            alertDialog = new AlertDialog.Builder(getActivity(), R.style.NonPhoneDialogTheme)
-                    .create();
-            alertDialog.setTitle(R.string.non_phone_caption);
-            alertDialog.setMessage(getArgumentPhoneNumber());
-            alertDialog.setButton(DialogInterface.BUTTON_POSITIVE,
-                    getActivity().getString(R.string.non_phone_add_to_contacts), this);
-            alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
-                    getActivity().getString(R.string.non_phone_close), this);
-            return alertDialog;
-        }
-
-        @Override
-        public void onClick(DialogInterface dialog, int which) {
-            if (which == DialogInterface.BUTTON_POSITIVE) {
-                final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
-                intent.setType(Contacts.CONTENT_ITEM_TYPE);
-                intent.putExtra(Insert.PHONE, getArgumentPhoneNumber());
-                startActivity(intent);
-            }
-            dismiss();
-        }
-
-        private String getArgumentPhoneNumber() {
-            return getArguments().getString(PHONE_NUMBER_KEY);
-        }
-
-        @Override
-        public void onDismiss(DialogInterface dialog) {
-            super.onDismiss(dialog);
-            // During screen rotation, getActivity returns null. In this case we do not
-            // want to close the Activity anyway
-            final Activity activity = getActivity();
-            if (activity != null) activity.finish();
-        }
-    }
-}
diff --git a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java b/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
deleted file mode 100644
index 9183208..0000000
--- a/src/com/android/contacts/calllog/CallDetailHistoryAdapter.java
+++ /dev/null
@@ -1,175 +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.provider.CallLog.Calls;
-import android.text.format.DateUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.TextView;
-
-import com.android.contacts.PhoneCallDetails;
-import com.android.contacts.R;
-
-/**
- * Adapter for a ListView containing history items from the details of a call.
- */
-public class CallDetailHistoryAdapter extends BaseAdapter {
-    /** The top element is a blank header, which is hidden under the rest of the UI. */
-    private static final int VIEW_TYPE_HEADER = 0;
-    /** Each history item shows the detail of a call. */
-    private static final int VIEW_TYPE_HISTORY_ITEM = 1;
-
-    private final Context mContext;
-    private final LayoutInflater mLayoutInflater;
-    private final CallTypeHelper mCallTypeHelper;
-    private final PhoneCallDetails[] mPhoneCallDetails;
-    /** Whether the voicemail controls are shown. */
-    private final boolean mShowVoicemail;
-    /** Whether the call and SMS controls are shown. */
-    private final boolean mShowCallAndSms;
-    /** The controls that are shown on top of the history list. */
-    private final View mControls;
-    /** The listener to changes of focus of the header. */
-    private View.OnFocusChangeListener mHeaderFocusChangeListener =
-            new View.OnFocusChangeListener() {
-        @Override
-        public void onFocusChange(View v, boolean hasFocus) {
-            // When the header is focused, focus the controls above it instead.
-            if (hasFocus) {
-                mControls.requestFocus();
-            }
-        }
-    };
-
-    public CallDetailHistoryAdapter(Context context, LayoutInflater layoutInflater,
-            CallTypeHelper callTypeHelper, PhoneCallDetails[] phoneCallDetails,
-            boolean showVoicemail, boolean showCallAndSms, View controls) {
-        mContext = context;
-        mLayoutInflater = layoutInflater;
-        mCallTypeHelper = callTypeHelper;
-        mPhoneCallDetails = phoneCallDetails;
-        mShowVoicemail = showVoicemail;
-        mShowCallAndSms = showCallAndSms;
-        mControls = controls;
-    }
-
-    @Override
-    public boolean isEnabled(int position) {
-        // None of history will be clickable.
-        return false;
-    }
-
-    @Override
-    public int getCount() {
-        return mPhoneCallDetails.length + 1;
-    }
-
-    @Override
-    public Object getItem(int position) {
-        if (position == 0) {
-            return null;
-        }
-        return mPhoneCallDetails[position - 1];
-    }
-
-    @Override
-    public long getItemId(int position) {
-        if (position == 0) {
-            return -1;
-        }
-        return position - 1;
-    }
-
-    @Override
-    public int getViewTypeCount() {
-        return 2;
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        if (position == 0) {
-            return VIEW_TYPE_HEADER;
-        }
-        return VIEW_TYPE_HISTORY_ITEM;
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        if (position == 0) {
-            final View header = convertView == null
-                    ? mLayoutInflater.inflate(R.layout.call_detail_history_header, parent, false)
-                    : convertView;
-            // Voicemail controls are only shown in the main UI if there is a voicemail.
-            View voicemailContainer = header.findViewById(R.id.header_voicemail_container);
-            voicemailContainer.setVisibility(mShowVoicemail ? View.VISIBLE : View.GONE);
-            // Call and SMS controls are only shown in the main UI if there is a known number.
-            View callAndSmsContainer = header.findViewById(R.id.header_call_and_sms_container);
-            callAndSmsContainer.setVisibility(mShowCallAndSms ? View.VISIBLE : View.GONE);
-            header.setFocusable(true);
-            header.setOnFocusChangeListener(mHeaderFocusChangeListener);
-            return header;
-        }
-
-        // Make sure we have a valid convertView to start with
-        final View result  = convertView == null
-                ? mLayoutInflater.inflate(R.layout.call_detail_history_item, parent, false)
-                : convertView;
-
-        PhoneCallDetails details = mPhoneCallDetails[position - 1];
-        CallTypeIconsView callTypeIconView =
-                (CallTypeIconsView) result.findViewById(R.id.call_type_icon);
-        TextView callTypeTextView = (TextView) result.findViewById(R.id.call_type_text);
-        TextView dateView = (TextView) result.findViewById(R.id.date);
-        TextView durationView = (TextView) result.findViewById(R.id.duration);
-
-        int callType = details.callTypes[0];
-        callTypeIconView.clear();
-        callTypeIconView.add(callType);
-        callTypeTextView.setText(mCallTypeHelper.getCallTypeText(callType));
-        // Set the date.
-        CharSequence dateValue = DateUtils.formatDateRange(mContext, details.date, details.date,
-                DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_DATE |
-                DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_YEAR);
-        dateView.setText(dateValue);
-        // Set the duration
-        if (callType == Calls.MISSED_TYPE || callType == Calls.VOICEMAIL_TYPE) {
-            durationView.setVisibility(View.GONE);
-        } else {
-            durationView.setVisibility(View.VISIBLE);
-            durationView.setText(formatDuration(details.duration));
-        }
-
-        return result;
-    }
-
-    private String formatDuration(long elapsedSeconds) {
-        long minutes = 0;
-        long seconds = 0;
-
-        if (elapsedSeconds >= 60) {
-            minutes = elapsedSeconds / 60;
-            elapsedSeconds -= minutes * 60;
-        }
-        seconds = elapsedSeconds;
-
-        return mContext.getString(R.string.callDetailsDurationFormat, minutes, seconds);
-    }
-}
diff --git a/src/com/android/contacts/calllog/CallLogAdapter.java b/src/com/android/contacts/calllog/CallLogAdapter.java
deleted file mode 100644
index 3688dca..0000000
--- a/src/com/android/contacts/calllog/CallLogAdapter.java
+++ /dev/null
@@ -1,802 +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.ContentValues;
-import android.content.Context;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.PhoneLookup;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
-
-import com.android.common.widget.GroupingListAdapter;
-import com.android.contacts.ContactPhotoManager;
-import com.android.contacts.PhoneCallDetails;
-import com.android.contacts.PhoneCallDetailsHelper;
-import com.android.contacts.R;
-import com.android.contacts.util.ExpirableCache;
-import com.android.contacts.util.UriUtils;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-
-import java.util.LinkedList;
-
-/**
- * Adapter class to fill in data for the Call Log.
- */
-/*package*/ class CallLogAdapter extends GroupingListAdapter
-        implements ViewTreeObserver.OnPreDrawListener, CallLogGroupBuilder.GroupCreator {
-    /** Interface used to initiate a refresh of the content. */
-    public interface CallFetcher {
-        public void fetchCalls();
-    }
-
-    /**
-     * Stores a phone number of a call with the country code where it originally occurred.
-     * <p>
-     * Note the country does not necessarily specifies the country of the phone number itself, but
-     * it is the country in which the user was in when the call was placed or received.
-     */
-    private static final class NumberWithCountryIso {
-        public final String number;
-        public final String countryIso;
-
-        public NumberWithCountryIso(String number, String countryIso) {
-            this.number = number;
-            this.countryIso = countryIso;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (o == null) return false;
-            if (!(o instanceof NumberWithCountryIso)) return false;
-            NumberWithCountryIso other = (NumberWithCountryIso) o;
-            return TextUtils.equals(number, other.number)
-                    && TextUtils.equals(countryIso, other.countryIso);
-        }
-
-        @Override
-        public int hashCode() {
-            return (number == null ? 0 : number.hashCode())
-                    ^ (countryIso == null ? 0 : countryIso.hashCode());
-        }
-    }
-
-    /** The time in millis to delay starting the thread processing requests. */
-    private static final int START_PROCESSING_REQUESTS_DELAY_MILLIS = 1000;
-
-    /** The size of the cache of contact info. */
-    private static final int CONTACT_INFO_CACHE_SIZE = 100;
-
-    private final Context mContext;
-    private final ContactInfoHelper mContactInfoHelper;
-    private final CallFetcher mCallFetcher;
-    private ViewTreeObserver mViewTreeObserver = null;
-
-    /**
-     * A cache of the contact details for the phone numbers in the call log.
-     * <p>
-     * The content of the cache is expired (but not purged) whenever the application comes to
-     * the foreground.
-     * <p>
-     * The key is number with the country in which the call was placed or received.
-     */
-    private ExpirableCache<NumberWithCountryIso, ContactInfo> mContactInfoCache;
-
-    /**
-     * A request for contact details for the given number.
-     */
-    private static final class ContactInfoRequest {
-        /** The number to look-up. */
-        public final String number;
-        /** The country in which a call to or from this number was placed or received. */
-        public final String countryIso;
-        /** The cached contact information stored in the call log. */
-        public final ContactInfo callLogInfo;
-
-        public ContactInfoRequest(String number, String countryIso, ContactInfo callLogInfo) {
-            this.number = number;
-            this.countryIso = countryIso;
-            this.callLogInfo = callLogInfo;
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) return true;
-            if (obj == null) return false;
-            if (!(obj instanceof ContactInfoRequest)) return false;
-
-            ContactInfoRequest other = (ContactInfoRequest) obj;
-
-            if (!TextUtils.equals(number, other.number)) return false;
-            if (!TextUtils.equals(countryIso, other.countryIso)) return false;
-            if (!Objects.equal(callLogInfo, other.callLogInfo)) return false;
-
-            return true;
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + ((callLogInfo == null) ? 0 : callLogInfo.hashCode());
-            result = prime * result + ((countryIso == null) ? 0 : countryIso.hashCode());
-            result = prime * result + ((number == null) ? 0 : number.hashCode());
-            return result;
-        }
-    }
-
-    /**
-     * List of requests to update contact details.
-     * <p>
-     * Each request is made of a phone number to look up, and the contact info currently stored in
-     * the call log for this number.
-     * <p>
-     * The requests are added when displaying the contacts and are processed by a background
-     * thread.
-     */
-    private final LinkedList<ContactInfoRequest> mRequests;
-
-    private boolean mLoading = true;
-    private static final int REDRAW = 1;
-    private static final int START_THREAD = 2;
-
-    private QueryThread mCallerIdThread;
-
-    /** Instance of helper class for managing views. */
-    private final CallLogListItemHelper mCallLogViewsHelper;
-
-    /** Helper to set up contact photos. */
-    private final ContactPhotoManager mContactPhotoManager;
-    /** Helper to parse and process phone numbers. */
-    private PhoneNumberHelper mPhoneNumberHelper;
-    /** Helper to group call log entries. */
-    private final CallLogGroupBuilder mCallLogGroupBuilder;
-
-    /** Can be set to true by tests to disable processing of requests. */
-    private volatile boolean mRequestProcessingDisabled = false;
-
-    /** Listener for the primary action in the list, opens the call details. */
-    private final View.OnClickListener mPrimaryActionListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View view) {
-            IntentProvider intentProvider = (IntentProvider) view.getTag();
-            if (intentProvider != null) {
-                mContext.startActivity(intentProvider.getIntent(mContext));
-            }
-        }
-    };
-    /** Listener for the secondary action in the list, either call or play. */
-    private final View.OnClickListener mSecondaryActionListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View view) {
-            IntentProvider intentProvider = (IntentProvider) view.getTag();
-            if (intentProvider != null) {
-                mContext.startActivity(intentProvider.getIntent(mContext));
-            }
-        }
-    };
-
-    @Override
-    public boolean onPreDraw() {
-        // We only wanted to listen for the first draw (and this is it).
-        unregisterPreDrawListener();
-
-        // Only schedule a thread-creation message if the thread hasn't been
-        // created yet. This is purely an optimization, to queue fewer messages.
-        if (mCallerIdThread == null) {
-            mHandler.sendEmptyMessageDelayed(START_THREAD, START_PROCESSING_REQUESTS_DELAY_MILLIS);
-        }
-
-        return true;
-    }
-
-    private Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case REDRAW:
-                    notifyDataSetChanged();
-                    break;
-                case START_THREAD:
-                    startRequestProcessing();
-                    break;
-            }
-        }
-    };
-
-    CallLogAdapter(Context context, CallFetcher callFetcher,
-            ContactInfoHelper contactInfoHelper) {
-        super(context);
-
-        mContext = context;
-        mCallFetcher = callFetcher;
-        mContactInfoHelper = contactInfoHelper;
-
-        mContactInfoCache = ExpirableCache.create(CONTACT_INFO_CACHE_SIZE);
-        mRequests = new LinkedList<ContactInfoRequest>();
-
-        Resources resources = mContext.getResources();
-        CallTypeHelper callTypeHelper = new CallTypeHelper(resources);
-
-        mContactPhotoManager = ContactPhotoManager.getInstance(mContext);
-        mPhoneNumberHelper = new PhoneNumberHelper(resources);
-        PhoneCallDetailsHelper phoneCallDetailsHelper = new PhoneCallDetailsHelper(
-                resources, callTypeHelper, mPhoneNumberHelper);
-        mCallLogViewsHelper =
-                new CallLogListItemHelper(
-                        phoneCallDetailsHelper, mPhoneNumberHelper, resources);
-        mCallLogGroupBuilder = new CallLogGroupBuilder(this);
-    }
-
-    /**
-     * Requery on background thread when {@link Cursor} changes.
-     */
-    @Override
-    protected void onContentChanged() {
-        mCallFetcher.fetchCalls();
-    }
-
-    void setLoading(boolean loading) {
-        mLoading = loading;
-    }
-
-    @Override
-    public boolean isEmpty() {
-        if (mLoading) {
-            // We don't want the empty state to show when loading.
-            return false;
-        } else {
-            return super.isEmpty();
-        }
-    }
-
-    /**
-     * Starts a background thread to process contact-lookup requests, unless one
-     * has already been started.
-     */
-    private synchronized void startRequestProcessing() {
-        // For unit-testing.
-        if (mRequestProcessingDisabled) return;
-
-        // Idempotence... if a thread is already started, don't start another.
-        if (mCallerIdThread != null) return;
-
-        mCallerIdThread = new QueryThread();
-        mCallerIdThread.setPriority(Thread.MIN_PRIORITY);
-        mCallerIdThread.start();
-    }
-
-    /**
-     * Stops the background thread that processes updates and cancels any
-     * pending requests to start it.
-     */
-    public synchronized void stopRequestProcessing() {
-        // Remove any pending requests to start the processing thread.
-        mHandler.removeMessages(START_THREAD);
-        if (mCallerIdThread != null) {
-            // Stop the thread; we are finished with it.
-            mCallerIdThread.stopProcessing();
-            mCallerIdThread.interrupt();
-            mCallerIdThread = null;
-        }
-    }
-
-    /**
-     * Stop receiving onPreDraw() notifications.
-     */
-    private void unregisterPreDrawListener() {
-        if (mViewTreeObserver != null && mViewTreeObserver.isAlive()) {
-            mViewTreeObserver.removeOnPreDrawListener(this);
-        }
-        mViewTreeObserver = null;
-    }
-
-    public void invalidateCache() {
-        mContactInfoCache.expireAll();
-
-        // Restart the request-processing thread after the next draw.
-        stopRequestProcessing();
-        unregisterPreDrawListener();
-    }
-
-    /**
-     * Enqueues a request to look up the contact details for the given phone number.
-     * <p>
-     * It also provides the current contact info stored in the call log for this number.
-     * <p>
-     * If the {@code immediate} parameter is true, it will start immediately the thread that looks
-     * up the contact information (if it has not been already started). Otherwise, it will be
-     * started with a delay. See {@link #START_PROCESSING_REQUESTS_DELAY_MILLIS}.
-     */
-    @VisibleForTesting
-    void enqueueRequest(String number, String countryIso, ContactInfo callLogInfo,
-            boolean immediate) {
-        ContactInfoRequest request = new ContactInfoRequest(number, countryIso, callLogInfo);
-        synchronized (mRequests) {
-            if (!mRequests.contains(request)) {
-                mRequests.add(request);
-                mRequests.notifyAll();
-            }
-        }
-        if (immediate) startRequestProcessing();
-    }
-
-    /**
-     * Queries the appropriate content provider for the contact associated with the number.
-     * <p>
-     * Upon completion it also updates the cache in the call log, if it is different from
-     * {@code callLogInfo}.
-     * <p>
-     * The number might be either a SIP address or a phone number.
-     * <p>
-     * It returns true if it updated the content of the cache and we should therefore tell the
-     * view to update its content.
-     */
-    private boolean queryContactInfo(String number, String countryIso, ContactInfo callLogInfo) {
-        final ContactInfo info = mContactInfoHelper.lookupNumber(number, countryIso);
-
-        if (info == null) {
-            // The lookup failed, just return without requesting to update the view.
-            return false;
-        }
-
-        // Check the existing entry in the cache: only if it has changed we should update the
-        // view.
-        NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
-        ContactInfo existingInfo = mContactInfoCache.getPossiblyExpired(numberCountryIso);
-        boolean updated = (existingInfo != ContactInfo.EMPTY) && !info.equals(existingInfo);
-
-        // Store the data in the cache so that the UI thread can use to display it. Store it
-        // even if it has not changed so that it is marked as not expired.
-        mContactInfoCache.put(numberCountryIso, info);
-        // Update the call log even if the cache it is up-to-date: it is possible that the cache
-        // contains the value from a different call log entry.
-        updateCallLogContactInfoCache(number, countryIso, info, callLogInfo);
-        return updated;
-    }
-
-    /*
-     * Handles requests for contact name and number type.
-     */
-    private class QueryThread extends Thread {
-        private volatile boolean mDone = false;
-
-        public QueryThread() {
-            super("CallLogAdapter.QueryThread");
-        }
-
-        public void stopProcessing() {
-            mDone = true;
-        }
-
-        @Override
-        public void run() {
-            boolean needRedraw = false;
-            while (true) {
-                // Check if thread is finished, and if so return immediately.
-                if (mDone) return;
-
-                // Obtain next request, if any is available.
-                // Keep synchronized section small.
-                ContactInfoRequest req = null;
-                synchronized (mRequests) {
-                    if (!mRequests.isEmpty()) {
-                        req = mRequests.removeFirst();
-                    }
-                }
-
-                if (req != null) {
-                    // Process the request. If the lookup succeeds, schedule a
-                    // redraw.
-                    needRedraw |= queryContactInfo(req.number, req.countryIso, req.callLogInfo);
-                } else {
-                    // Throttle redraw rate by only sending them when there are
-                    // more requests.
-                    if (needRedraw) {
-                        needRedraw = false;
-                        mHandler.sendEmptyMessage(REDRAW);
-                    }
-
-                    // Wait until another request is available, or until this
-                    // thread is no longer needed (as indicated by being
-                    // interrupted).
-                    try {
-                        synchronized (mRequests) {
-                            mRequests.wait(1000);
-                        }
-                    } catch (InterruptedException ie) {
-                        // Ignore, and attempt to continue processing requests.
-                    }
-                }
-            }
-        }
-    }
-
-    @Override
-    protected void addGroups(Cursor cursor) {
-        mCallLogGroupBuilder.addGroups(cursor);
-    }
-
-    @Override
-    protected View newStandAloneView(Context context, ViewGroup parent) {
-        LayoutInflater inflater =
-                (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        View view = inflater.inflate(R.layout.call_log_list_item, parent, false);
-        findAndCacheViews(view);
-        return view;
-    }
-
-    @Override
-    protected void bindStandAloneView(View view, Context context, Cursor cursor) {
-        bindView(view, cursor, 1);
-    }
-
-    @Override
-    protected View newChildView(Context context, ViewGroup parent) {
-        LayoutInflater inflater =
-                (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        View view = inflater.inflate(R.layout.call_log_list_item, parent, false);
-        findAndCacheViews(view);
-        return view;
-    }
-
-    @Override
-    protected void bindChildView(View view, Context context, Cursor cursor) {
-        bindView(view, cursor, 1);
-    }
-
-    @Override
-    protected View newGroupView(Context context, ViewGroup parent) {
-        LayoutInflater inflater =
-                (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        View view = inflater.inflate(R.layout.call_log_list_item, parent, false);
-        findAndCacheViews(view);
-        return view;
-    }
-
-    @Override
-    protected void bindGroupView(View view, Context context, Cursor cursor, int groupSize,
-            boolean expanded) {
-        bindView(view, cursor, groupSize);
-    }
-
-    private void findAndCacheViews(View view) {
-        // Get the views to bind to.
-        CallLogListItemViews views = CallLogListItemViews.fromView(view);
-        views.primaryActionView.setOnClickListener(mPrimaryActionListener);
-        views.secondaryActionView.setOnClickListener(mSecondaryActionListener);
-        view.setTag(views);
-    }
-
-    /**
-     * Binds the views in the entry to the data in the call log.
-     *
-     * @param view the view corresponding to this entry
-     * @param c the cursor pointing to the entry in the call log
-     * @param count the number of entries in the current item, greater than 1 if it is a group
-     */
-    private void bindView(View view, Cursor c, int count) {
-        final CallLogListItemViews views = (CallLogListItemViews) view.getTag();
-        final int section = c.getInt(CallLogQuery.SECTION);
-
-        // This might be a header: check the value of the section column in the cursor.
-        if (section == CallLogQuery.SECTION_NEW_HEADER
-                || section == CallLogQuery.SECTION_OLD_HEADER) {
-            views.primaryActionView.setVisibility(View.GONE);
-            views.bottomDivider.setVisibility(View.GONE);
-            views.listHeaderTextView.setVisibility(View.VISIBLE);
-            views.listHeaderTextView.setText(
-                    section == CallLogQuery.SECTION_NEW_HEADER
-                            ? R.string.call_log_new_header
-                            : R.string.call_log_old_header);
-            // Nothing else to set up for a header.
-            return;
-        }
-        // Default case: an item in the call log.
-        views.primaryActionView.setVisibility(View.VISIBLE);
-        views.bottomDivider.setVisibility(isLastOfSection(c) ? View.GONE : View.VISIBLE);
-        views.listHeaderTextView.setVisibility(View.GONE);
-
-        final String number = c.getString(CallLogQuery.NUMBER);
-        final long date = c.getLong(CallLogQuery.DATE);
-        final long duration = c.getLong(CallLogQuery.DURATION);
-        final int callType = c.getInt(CallLogQuery.CALL_TYPE);
-        final String countryIso = c.getString(CallLogQuery.COUNTRY_ISO);
-
-        final ContactInfo cachedContactInfo = getContactInfoFromCallLog(c);
-
-        views.primaryActionView.setTag(
-                IntentProvider.getCallDetailIntentProvider(
-                        this, c.getPosition(), c.getLong(CallLogQuery.ID), count));
-        // Store away the voicemail information so we can play it directly.
-        if (callType == Calls.VOICEMAIL_TYPE) {
-            String voicemailUri = c.getString(CallLogQuery.VOICEMAIL_URI);
-            final long rowId = c.getLong(CallLogQuery.ID);
-            views.secondaryActionView.setTag(
-                    IntentProvider.getPlayVoicemailIntentProvider(rowId, voicemailUri));
-        } else if (!TextUtils.isEmpty(number)) {
-            // Store away the number so we can call it directly if you click on the call icon.
-            views.secondaryActionView.setTag(
-                    IntentProvider.getReturnCallIntentProvider(number));
-        } else {
-            // No action enabled.
-            views.secondaryActionView.setTag(null);
-        }
-
-        // Lookup contacts with this number
-        NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
-        ExpirableCache.CachedValue<ContactInfo> cachedInfo =
-                mContactInfoCache.getCachedValue(numberCountryIso);
-        ContactInfo info = cachedInfo == null ? null : cachedInfo.getValue();
-        if (!mPhoneNumberHelper.canPlaceCallsTo(number)
-                || mPhoneNumberHelper.isVoicemailNumber(number)) {
-            // If this is a number that cannot be dialed, there is no point in looking up a contact
-            // for it.
-            info = ContactInfo.EMPTY;
-        } else if (cachedInfo == null) {
-            mContactInfoCache.put(numberCountryIso, ContactInfo.EMPTY);
-            // Use the cached contact info from the call log.
-            info = cachedContactInfo;
-            // The db request should happen on a non-UI thread.
-            // Request the contact details immediately since they are currently missing.
-            enqueueRequest(number, countryIso, cachedContactInfo, true);
-            // We will format the phone number when we make the background request.
-        } else {
-            if (cachedInfo.isExpired()) {
-                // The contact info is no longer up to date, we should request it. However, we
-                // do not need to request them immediately.
-                enqueueRequest(number, countryIso, cachedContactInfo, false);
-            } else  if (!callLogInfoMatches(cachedContactInfo, info)) {
-                // The call log information does not match the one we have, look it up again.
-                // We could simply update the call log directly, but that needs to be done in a
-                // background thread, so it is easier to simply request a new lookup, which will, as
-                // a side-effect, update the call log.
-                enqueueRequest(number, countryIso, cachedContactInfo, false);
-            }
-
-            if (info == ContactInfo.EMPTY) {
-                // Use the cached contact info from the call log.
-                info = cachedContactInfo;
-            }
-        }
-
-        final Uri lookupUri = info.lookupUri;
-        final String name = info.name;
-        final int ntype = info.type;
-        final String label = info.label;
-        final long photoId = info.photoId;
-        CharSequence formattedNumber = info.formattedNumber;
-        final int[] callTypes = getCallTypes(c, count);
-        final String geocode = c.getString(CallLogQuery.GEOCODED_LOCATION);
-        final PhoneCallDetails details;
-        if (TextUtils.isEmpty(name)) {
-            details = new PhoneCallDetails(number, formattedNumber, countryIso, geocode,
-                    callTypes, date, duration);
-        } else {
-            // We do not pass a photo id since we do not need the high-res picture.
-            details = new PhoneCallDetails(number, formattedNumber, countryIso, geocode,
-                    callTypes, date, duration, name, ntype, label, lookupUri, null);
-        }
-
-        final boolean isNew = c.getInt(CallLogQuery.IS_READ) == 0;
-        // New items also use the highlighted version of the text.
-        final boolean isHighlighted = isNew;
-        mCallLogViewsHelper.setPhoneCallDetails(views, details, isHighlighted);
-        setPhoto(views, photoId, lookupUri);
-
-        // Listen for the first draw
-        if (mViewTreeObserver == null) {
-            mViewTreeObserver = view.getViewTreeObserver();
-            mViewTreeObserver.addOnPreDrawListener(this);
-        }
-    }
-
-    /** Returns true if this is the last item of a section. */
-    private boolean isLastOfSection(Cursor c) {
-        if (c.isLast()) return true;
-        final int section = c.getInt(CallLogQuery.SECTION);
-        if (!c.moveToNext()) return true;
-        final int nextSection = c.getInt(CallLogQuery.SECTION);
-        c.moveToPrevious();
-        return section != nextSection;
-    }
-
-    /** Checks whether the contact info from the call log matches the one from the contacts db. */
-    private boolean callLogInfoMatches(ContactInfo callLogInfo, ContactInfo info) {
-        // The call log only contains a subset of the fields in the contacts db.
-        // Only check those.
-        return TextUtils.equals(callLogInfo.name, info.name)
-                && callLogInfo.type == info.type
-                && TextUtils.equals(callLogInfo.label, info.label);
-    }
-
-    /** Stores the updated contact info in the call log if it is different from the current one. */
-    private void updateCallLogContactInfoCache(String number, String countryIso,
-            ContactInfo updatedInfo, ContactInfo callLogInfo) {
-        final ContentValues values = new ContentValues();
-        boolean needsUpdate = false;
-
-        if (callLogInfo != null) {
-            if (!TextUtils.equals(updatedInfo.name, callLogInfo.name)) {
-                values.put(Calls.CACHED_NAME, updatedInfo.name);
-                needsUpdate = true;
-            }
-
-            if (updatedInfo.type != callLogInfo.type) {
-                values.put(Calls.CACHED_NUMBER_TYPE, updatedInfo.type);
-                needsUpdate = true;
-            }
-
-            if (!TextUtils.equals(updatedInfo.label, callLogInfo.label)) {
-                values.put(Calls.CACHED_NUMBER_LABEL, updatedInfo.label);
-                needsUpdate = true;
-            }
-            if (!UriUtils.areEqual(updatedInfo.lookupUri, callLogInfo.lookupUri)) {
-                values.put(Calls.CACHED_LOOKUP_URI, UriUtils.uriToString(updatedInfo.lookupUri));
-                needsUpdate = true;
-            }
-            if (!TextUtils.equals(updatedInfo.normalizedNumber, callLogInfo.normalizedNumber)) {
-                values.put(Calls.CACHED_NORMALIZED_NUMBER, updatedInfo.normalizedNumber);
-                needsUpdate = true;
-            }
-            if (!TextUtils.equals(updatedInfo.number, callLogInfo.number)) {
-                values.put(Calls.CACHED_MATCHED_NUMBER, updatedInfo.number);
-                needsUpdate = true;
-            }
-            if (updatedInfo.photoId != callLogInfo.photoId) {
-                values.put(Calls.CACHED_PHOTO_ID, updatedInfo.photoId);
-                needsUpdate = true;
-            }
-            if (!TextUtils.equals(updatedInfo.formattedNumber, callLogInfo.formattedNumber)) {
-                values.put(Calls.CACHED_FORMATTED_NUMBER, updatedInfo.formattedNumber);
-                needsUpdate = true;
-            }
-        } else {
-            // No previous values, store all of them.
-            values.put(Calls.CACHED_NAME, updatedInfo.name);
-            values.put(Calls.CACHED_NUMBER_TYPE, updatedInfo.type);
-            values.put(Calls.CACHED_NUMBER_LABEL, updatedInfo.label);
-            values.put(Calls.CACHED_LOOKUP_URI, UriUtils.uriToString(updatedInfo.lookupUri));
-            values.put(Calls.CACHED_MATCHED_NUMBER, updatedInfo.number);
-            values.put(Calls.CACHED_NORMALIZED_NUMBER, updatedInfo.normalizedNumber);
-            values.put(Calls.CACHED_PHOTO_ID, updatedInfo.photoId);
-            values.put(Calls.CACHED_FORMATTED_NUMBER, updatedInfo.formattedNumber);
-            needsUpdate = true;
-        }
-
-        if (!needsUpdate) return;
-
-        if (countryIso == null) {
-            mContext.getContentResolver().update(Calls.CONTENT_URI_WITH_VOICEMAIL, values,
-                    Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " IS NULL",
-                    new String[]{ number });
-        } else {
-            mContext.getContentResolver().update(Calls.CONTENT_URI_WITH_VOICEMAIL, values,
-                    Calls.NUMBER + " = ? AND " + Calls.COUNTRY_ISO + " = ?",
-                    new String[]{ number, countryIso });
-        }
-    }
-
-    /** Returns the contact information as stored in the call log. */
-    private ContactInfo getContactInfoFromCallLog(Cursor c) {
-        ContactInfo info = new ContactInfo();
-        info.lookupUri = UriUtils.parseUriOrNull(c.getString(CallLogQuery.CACHED_LOOKUP_URI));
-        info.name = c.getString(CallLogQuery.CACHED_NAME);
-        info.type = c.getInt(CallLogQuery.CACHED_NUMBER_TYPE);
-        info.label = c.getString(CallLogQuery.CACHED_NUMBER_LABEL);
-        String matchedNumber = c.getString(CallLogQuery.CACHED_MATCHED_NUMBER);
-        info.number = matchedNumber == null ? c.getString(CallLogQuery.NUMBER) : matchedNumber;
-        info.normalizedNumber = c.getString(CallLogQuery.CACHED_NORMALIZED_NUMBER);
-        info.photoId = c.getLong(CallLogQuery.CACHED_PHOTO_ID);
-        info.photoUri = null;  // We do not cache the photo URI.
-        info.formattedNumber = c.getString(CallLogQuery.CACHED_FORMATTED_NUMBER);
-        return info;
-    }
-
-    /**
-     * Returns the call types for the given number of items in the cursor.
-     * <p>
-     * It uses the next {@code count} rows in the cursor to extract the types.
-     * <p>
-     * It position in the cursor is unchanged by this function.
-     */
-    private int[] getCallTypes(Cursor cursor, int count) {
-        int position = cursor.getPosition();
-        int[] callTypes = new int[count];
-        for (int index = 0; index < count; ++index) {
-            callTypes[index] = cursor.getInt(CallLogQuery.CALL_TYPE);
-            cursor.moveToNext();
-        }
-        cursor.moveToPosition(position);
-        return callTypes;
-    }
-
-    private void setPhoto(CallLogListItemViews views, long photoId, Uri contactUri) {
-        views.quickContactView.assignContactUri(contactUri);
-        mContactPhotoManager.loadThumbnail(views.quickContactView, photoId, true);
-    }
-
-    /**
-     * Sets whether processing of requests for contact details should be enabled.
-     * <p>
-     * This method should be called in tests to disable such processing of requests when not
-     * needed.
-     */
-    @VisibleForTesting
-    void disableRequestProcessingForTest() {
-        mRequestProcessingDisabled = true;
-    }
-
-    @VisibleForTesting
-    void injectContactInfoForTest(String number, String countryIso, ContactInfo contactInfo) {
-        NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
-        mContactInfoCache.put(numberCountryIso, contactInfo);
-    }
-
-    @Override
-    public void addGroup(int cursorPosition, int size, boolean expanded) {
-        super.addGroup(cursorPosition, size, expanded);
-    }
-
-    /*
-     * Get the number from the Contacts, if available, since sometimes
-     * the number provided by caller id may not be formatted properly
-     * depending on the carrier (roaming) in use at the time of the
-     * incoming call.
-     * Logic : If the caller-id number starts with a "+", use it
-     *         Else if the number in the contacts starts with a "+", use that one
-     *         Else if the number in the contacts is longer, use that one
-     */
-    public String getBetterNumberFromContacts(String number, String countryIso) {
-        String matchingNumber = null;
-        // Look in the cache first. If it's not found then query the Phones db
-        NumberWithCountryIso numberCountryIso = new NumberWithCountryIso(number, countryIso);
-        ContactInfo ci = mContactInfoCache.getPossiblyExpired(numberCountryIso);
-        if (ci != null && ci != ContactInfo.EMPTY) {
-            matchingNumber = ci.number;
-        } else {
-            try {
-                Cursor phonesCursor = mContext.getContentResolver().query(
-                        Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, number),
-                        PhoneQuery._PROJECTION, null, null, null);
-                if (phonesCursor != null) {
-                    if (phonesCursor.moveToFirst()) {
-                        matchingNumber = phonesCursor.getString(PhoneQuery.MATCHED_NUMBER);
-                    }
-                    phonesCursor.close();
-                }
-            } catch (Exception e) {
-                // Use the number from the call log
-            }
-        }
-        if (!TextUtils.isEmpty(matchingNumber) &&
-                (matchingNumber.startsWith("+")
-                        || matchingNumber.length() > number.length())) {
-            number = matchingNumber;
-        }
-        return number;
-    }
-}
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
deleted file mode 100644
index f9d21c0..0000000
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ /dev/null
@@ -1,549 +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.app.Activity;
-import android.app.KeyguardManager;
-import android.app.ListFragment;
-import android.content.Context;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.preference.PreferenceManager;
-import android.provider.CallLog;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import com.android.common.io.MoreCloseables;
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.util.Constants;
-import com.android.contacts.util.EmptyLoader;
-import com.android.contacts.voicemail.VoicemailStatusHelper;
-import com.android.contacts.voicemail.VoicemailStatusHelper.StatusMessage;
-import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
-import com.android.internal.telephony.CallerInfo;
-import com.android.internal.telephony.ITelephony;
-import com.google.common.annotations.VisibleForTesting;
-
-import java.util.List;
-
-/**
- * Displays a list of call log entries.
- */
-public class CallLogFragment extends ListFragment
-        implements CallLogQueryHandler.Listener, CallLogAdapter.CallFetcher {
-    private static final String TAG = "CallLogFragment";
-
-    /**
-     * ID of the empty loader to defer other fragments.
-     */
-    private static final int EMPTY_LOADER_ID = 0;
-
-    private static final String PREF_CALL_LOG_FILTER_LAST_CALL_TYPE = "CallLogFragment_last_filter";
-
-    private CallLogAdapter mAdapter;
-    private CallLogQueryHandler mCallLogQueryHandler;
-    private boolean mScrollToTop;
-
-    /** Whether there is at least one voicemail source installed. */
-    private boolean mVoicemailSourcesAvailable = false;
-    /** Whether we are currently filtering over voicemail. */
-    private boolean mShowingVoicemailOnly = false;
-
-    private VoicemailStatusHelper mVoicemailStatusHelper;
-    private View mStatusMessageView;
-    private TextView mStatusMessageText;
-    private TextView mStatusMessageAction;
-    private TextView mFilterStatusView;
-    private KeyguardManager mKeyguardManager;
-
-    private boolean mEmptyLoaderRunning;
-    private boolean mCallLogFetched;
-    private boolean mVoicemailStatusFetched;
-
-    private final Handler mHandler = new Handler();
-
-    private class CustomContentObserver extends ContentObserver {
-        public CustomContentObserver() {
-            super(mHandler);
-        }
-        @Override
-        public void onChange(boolean selfChange) {
-            mRefreshDataRequired = true;
-        }
-    }
-
-    // See issue 6363009
-    private final ContentObserver mCallLogObserver = new CustomContentObserver();
-    private final ContentObserver mContactsObserver = new CustomContentObserver();
-    private boolean mRefreshDataRequired = true;
-
-    // Exactly same variable is in Fragment as a package private.
-    private boolean mMenuVisible = true;
-
-    // Default to all calls.
-    private int mCallTypeFilter = CallLogQueryHandler.CALL_TYPE_ALL;
-
-    @Override
-    public void onCreate(Bundle state) {
-        super.onCreate(state);
-
-        mCallLogQueryHandler = new CallLogQueryHandler(getActivity().getContentResolver(), this);
-        mKeyguardManager =
-                (KeyguardManager) getActivity().getSystemService(Context.KEYGUARD_SERVICE);
-        getActivity().getContentResolver().registerContentObserver(
-                CallLog.CONTENT_URI, true, mCallLogObserver);
-        getActivity().getContentResolver().registerContentObserver(
-                ContactsContract.Contacts.CONTENT_URI, true, mContactsObserver);
-        setHasOptionsMenu(true);
-
-        // Load the last filter used.
-        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
-        mCallTypeFilter = prefs.getInt(PREF_CALL_LOG_FILTER_LAST_CALL_TYPE,
-                CallLogQueryHandler.CALL_TYPE_ALL);
-    }
-
-    /** Called by the CallLogQueryHandler when the list of calls has been fetched or updated. */
-    @Override
-    public void onCallsFetched(Cursor cursor) {
-        if (getActivity() == null || getActivity().isFinishing()) {
-            return;
-        }
-        mAdapter.setLoading(false);
-        mAdapter.changeCursor(cursor);
-        // This will update the state of the "Clear call log" menu item.
-        getActivity().invalidateOptionsMenu();
-        if (mScrollToTop) {
-            final ListView listView = getListView();
-            // The smooth-scroll animation happens over a fixed time period.
-            // As a result, if it scrolls through a large portion of the list,
-            // each frame will jump so far from the previous one that the user
-            // will not experience the illusion of downward motion.  Instead,
-            // if we're not already near the top of the list, we instantly jump
-            // near the top, and animate from there.
-            if (listView.getFirstVisiblePosition() > 5) {
-                listView.setSelection(5);
-            }
-            // Workaround for framework issue: the smooth-scroll doesn't
-            // occur if setSelection() is called immediately before.
-            mHandler.post(new Runnable() {
-               @Override
-               public void run() {
-                   if (getActivity() == null || getActivity().isFinishing()) {
-                       return;
-                   }
-                   listView.smoothScrollToPosition(0);
-               }
-            });
-
-            mScrollToTop = false;
-        }
-        mCallLogFetched = true;
-        destroyEmptyLoaderIfAllDataFetched();
-    }
-
-    /**
-     * Called by {@link CallLogQueryHandler} after a successful query to voicemail status provider.
-     */
-    @Override
-    public void onVoicemailStatusFetched(Cursor statusCursor) {
-        if (getActivity() == null || getActivity().isFinishing()) {
-            return;
-        }
-        updateVoicemailStatusMessage(statusCursor);
-
-        int activeSources = mVoicemailStatusHelper.getNumberActivityVoicemailSources(statusCursor);
-        setVoicemailSourcesAvailable(activeSources != 0);
-        MoreCloseables.closeQuietly(statusCursor);
-        mVoicemailStatusFetched = true;
-        destroyEmptyLoaderIfAllDataFetched();
-    }
-
-    private void destroyEmptyLoaderIfAllDataFetched() {
-        if (mCallLogFetched && mVoicemailStatusFetched && mEmptyLoaderRunning) {
-            mEmptyLoaderRunning = false;
-            getLoaderManager().destroyLoader(EMPTY_LOADER_ID);
-        }
-    }
-
-    /** Sets whether there are any voicemail sources available in the platform. */
-    private void setVoicemailSourcesAvailable(boolean voicemailSourcesAvailable) {
-        if (mVoicemailSourcesAvailable == voicemailSourcesAvailable) return;
-        mVoicemailSourcesAvailable = voicemailSourcesAvailable;
-
-        Activity activity = getActivity();
-        if (activity != null) {
-            // This is so that the options menu content is updated.
-            activity.invalidateOptionsMenu();
-        }
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        View view = inflater.inflate(R.layout.call_log_fragment, container, false);
-        mVoicemailStatusHelper = new VoicemailStatusHelperImpl();
-        mStatusMessageView = view.findViewById(R.id.voicemail_status);
-        mStatusMessageText = (TextView) view.findViewById(R.id.voicemail_status_message);
-        mStatusMessageAction = (TextView) view.findViewById(R.id.voicemail_status_action);
-        mFilterStatusView = (TextView) view.findViewById(R.id.filter_status);
-        return view;
-    }
-
-    @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-        String currentCountryIso = ContactsUtils.getCurrentCountryIso(getActivity());
-        mAdapter = new CallLogAdapter(getActivity(), this,
-                new ContactInfoHelper(getActivity(), currentCountryIso));
-        setListAdapter(mAdapter);
-        getListView().setItemsCanFocus(true);
-
-        updateFilterHeader();
-    }
-
-    /**
-     * Based on the new intent, decide whether the list should be configured
-     * to scroll up to display the first item.
-     */
-    public void configureScreenFromIntent(Intent newIntent) {
-        // Typically, when switching to the call-log we want to show the user
-        // the same section of the list that they were most recently looking
-        // at.  However, under some circumstances, we want to automatically
-        // scroll to the top of the list to present the newest call items.
-        // For example, immediately after a call is finished, we want to
-        // display information about that call.
-        mScrollToTop = Calls.CONTENT_TYPE.equals(newIntent.getType());
-    }
-
-    @Override
-    public void onStart() {
-        // Start the empty loader now to defer other fragments.  We destroy it when both calllog
-        // and the voicemail status are fetched.
-        getLoaderManager().initLoader(EMPTY_LOADER_ID, null,
-                new EmptyLoader.Callback(getActivity()));
-        mEmptyLoaderRunning = true;
-        super.onStart();
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-        refreshData();
-    }
-
-    private void updateVoicemailStatusMessage(Cursor statusCursor) {
-        List<StatusMessage> messages = mVoicemailStatusHelper.getStatusMessages(statusCursor);
-        if (messages.size() == 0) {
-            mStatusMessageView.setVisibility(View.GONE);
-        } else {
-            mStatusMessageView.setVisibility(View.VISIBLE);
-            // TODO: Change the code to show all messages. For now just pick the first message.
-            final StatusMessage message = messages.get(0);
-            if (message.showInCallLog()) {
-                mStatusMessageText.setText(message.callLogMessageId);
-            }
-            if (message.actionMessageId != -1) {
-                mStatusMessageAction.setText(message.actionMessageId);
-            }
-            if (message.actionUri != null) {
-                mStatusMessageAction.setVisibility(View.VISIBLE);
-                mStatusMessageAction.setOnClickListener(new View.OnClickListener() {
-                    @Override
-                    public void onClick(View v) {
-                        getActivity().startActivity(
-                                new Intent(Intent.ACTION_VIEW, message.actionUri));
-                    }
-                });
-            } else {
-                mStatusMessageAction.setVisibility(View.GONE);
-            }
-        }
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        // Kill the requests thread
-        mAdapter.stopRequestProcessing();
-
-        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
-        prefs.edit()
-                .putInt(PREF_CALL_LOG_FILTER_LAST_CALL_TYPE, mCallTypeFilter)
-                .apply();
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-        updateOnExit();
-    }
-
-    @Override
-    public void onDestroy() {
-        super.onDestroy();
-        mAdapter.stopRequestProcessing();
-        mAdapter.changeCursor(null);
-        getActivity().getContentResolver().unregisterContentObserver(mCallLogObserver);
-        getActivity().getContentResolver().unregisterContentObserver(mContactsObserver);
-    }
-
-    @Override
-    public void fetchCalls() {
-        mCallLogQueryHandler.fetchCalls(mCallTypeFilter);
-    }
-
-    public void startCallsQuery() {
-        mAdapter.setLoading(true);
-        mCallLogQueryHandler.fetchCalls(mCallTypeFilter);
-        if (mShowingVoicemailOnly) {
-            mShowingVoicemailOnly = false;
-            getActivity().invalidateOptionsMenu();
-        }
-    }
-
-    private void startVoicemailStatusQuery() {
-        mCallLogQueryHandler.fetchVoicemailStatus();
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        super.onCreateOptionsMenu(menu, inflater);
-        inflater.inflate(R.menu.call_log_options, menu);
-    }
-
-    @Override
-    public void onPrepareOptionsMenu(Menu menu) {
-        final MenuItem itemDeleteAll = menu.findItem(R.id.delete_all);
-        // Check if all the menu items are inflated correctly. As a shortcut, we assume all
-        // menu items are ready if the first item is non-null.
-        if (itemDeleteAll != null) {
-            itemDeleteAll.setEnabled(mAdapter != null && !mAdapter.isEmpty());
-            menu.findItem(R.id.show_voicemails_only).setVisible(mVoicemailSourcesAvailable);
-        }
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.delete_all:
-                ClearCallLogDialog.show(getFragmentManager());
-                return true;
-
-            case R.id.show_outgoing_only:
-                mCallLogQueryHandler.fetchCalls(Calls.OUTGOING_TYPE);
-                mCallTypeFilter = Calls.OUTGOING_TYPE;
-                updateFilterHeader();
-                return true;
-
-            case R.id.show_incoming_only:
-                mCallLogQueryHandler.fetchCalls(Calls.INCOMING_TYPE);
-                mCallTypeFilter = Calls.INCOMING_TYPE;
-                updateFilterHeader();
-                return true;
-
-            case R.id.show_missed_only:
-                mCallLogQueryHandler.fetchCalls(Calls.MISSED_TYPE);
-                mCallTypeFilter = Calls.MISSED_TYPE;
-                updateFilterHeader();
-                return true;
-
-            case R.id.show_voicemails_only:
-                mCallLogQueryHandler.fetchCalls(Calls.VOICEMAIL_TYPE);
-                mCallTypeFilter = Calls.VOICEMAIL_TYPE;
-                updateFilterHeader();
-                mShowingVoicemailOnly = true;
-                return true;
-
-            case R.id.show_all_calls:
-                mCallLogQueryHandler.fetchCalls(CallLogQueryHandler.CALL_TYPE_ALL);
-                mCallTypeFilter = CallLogQueryHandler.CALL_TYPE_ALL;
-                updateFilterHeader();
-                mShowingVoicemailOnly = false;
-                return true;
-
-            default:
-                return false;
-        }
-    }
-
-    private void updateFilterHeader() {
-        switch (mCallTypeFilter) {
-            case CallLogQueryHandler.CALL_TYPE_ALL:
-                mFilterStatusView.setVisibility(View.GONE);
-                break;
-            case Calls.INCOMING_TYPE:
-                showFilterStatus(R.string.call_log_incoming_header);
-                break;
-            case Calls.OUTGOING_TYPE:
-                showFilterStatus(R.string.call_log_outgoing_header);
-                break;
-            case Calls.MISSED_TYPE:
-                showFilterStatus(R.string.call_log_missed_header);
-                break;
-            case Calls.VOICEMAIL_TYPE:
-                showFilterStatus(R.string.call_log_voicemail_header);
-                break;
-        }
-    }
-
-    private void showFilterStatus(int resId) {
-        mFilterStatusView.setText(resId);
-        mFilterStatusView.setVisibility(View.VISIBLE);
-    }
-
-    public void callSelectedEntry() {
-        int position = getListView().getSelectedItemPosition();
-        if (position < 0) {
-            // In touch mode you may often not have something selected, so
-            // just call the first entry to make sure that [send] [send] calls the
-            // most recent entry.
-            position = 0;
-        }
-        final Cursor cursor = (Cursor)mAdapter.getItem(position);
-        if (cursor != null) {
-            String number = cursor.getString(CallLogQuery.NUMBER);
-            if (TextUtils.isEmpty(number)
-                    || number.equals(CallerInfo.UNKNOWN_NUMBER)
-                    || number.equals(CallerInfo.PRIVATE_NUMBER)
-                    || number.equals(CallerInfo.PAYPHONE_NUMBER)) {
-                // This number can't be called, do nothing
-                return;
-            }
-            Intent intent;
-            // If "number" is really a SIP address, construct a sip: URI.
-            if (PhoneNumberUtils.isUriNumber(number)) {
-                intent = ContactsUtils.getCallIntent(
-                        Uri.fromParts(Constants.SCHEME_SIP, number, null));
-            } else {
-                // We're calling a regular PSTN phone number.
-                // Construct a tel: URI, but do some other possible cleanup first.
-                int callType = cursor.getInt(CallLogQuery.CALL_TYPE);
-                if (!number.startsWith("+") &&
-                       (callType == Calls.INCOMING_TYPE
-                                || callType == Calls.MISSED_TYPE)) {
-                    // If the caller-id matches a contact with a better qualified number, use it
-                    String countryIso = cursor.getString(CallLogQuery.COUNTRY_ISO);
-                    number = mAdapter.getBetterNumberFromContacts(number, countryIso);
-                }
-                intent = ContactsUtils.getCallIntent(
-                        Uri.fromParts(Constants.SCHEME_TEL, number, null));
-            }
-            intent.setFlags(
-                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-            startActivity(intent);
-        }
-    }
-
-    @VisibleForTesting
-    CallLogAdapter getAdapter() {
-        return mAdapter;
-    }
-
-    @Override
-    public void setMenuVisibility(boolean menuVisible) {
-        super.setMenuVisibility(menuVisible);
-        if (mMenuVisible != menuVisible) {
-            mMenuVisible = menuVisible;
-            if (!menuVisible) {
-                updateOnExit();
-            } else if (isResumed()) {
-                refreshData();
-            }
-        }
-    }
-
-    /** Requests updates to the data to be shown. */
-    private void refreshData() {
-        // Prevent unnecessary refresh.
-        if (mRefreshDataRequired) {
-            // Mark all entries in the contact info cache as out of date, so they will be looked up
-            // again once being shown.
-            mAdapter.invalidateCache();
-            startCallsQuery();
-            startVoicemailStatusQuery();
-            updateOnEntry();
-            mRefreshDataRequired = false;
-        }
-    }
-
-    /** Removes the missed call notifications. */
-    private void removeMissedCallNotifications() {
-        try {
-            ITelephony telephony =
-                    ITelephony.Stub.asInterface(ServiceManager.getService("phone"));
-            if (telephony != null) {
-                telephony.cancelMissedCallsNotification();
-            } else {
-                Log.w(TAG, "Telephony service is null, can't call " +
-                        "cancelMissedCallsNotification");
-            }
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to clear missed calls notification due to remote exception");
-        }
-    }
-
-    /** Updates call data and notification state while leaving the call log tab. */
-    private void updateOnExit() {
-        updateOnTransition(false);
-    }
-
-    /** Updates call data and notification state while entering the call log tab. */
-    private void updateOnEntry() {
-        updateOnTransition(true);
-    }
-
-    private void updateOnTransition(boolean onEntry) {
-        // We don't want to update any call data when keyguard is on because the user has likely not
-        // seen the new calls yet.
-        // This might be called before onCreate() and thus we need to check null explicitly.
-        if (mKeyguardManager != null && !mKeyguardManager.inKeyguardRestrictedInputMode()) {
-            // On either of the transitions we reset the new flag and update the notifications.
-            // While exiting we additionally consume all missed calls (by marking them as read).
-            // This will ensure that they no more appear in the "new" section when we return back.
-            mCallLogQueryHandler.markNewCallsAsOld();
-            if (!onEntry) {
-                mCallLogQueryHandler.markMissedCallsAsRead();
-            }
-            removeMissedCallNotifications();
-            updateVoicemailNotifications();
-        }
-    }
-
-    private void updateVoicemailNotifications() {
-        Intent serviceIntent = new Intent(getActivity(), CallLogNotificationsService.class);
-        serviceIntent.setAction(CallLogNotificationsService.ACTION_UPDATE_NOTIFICATIONS);
-        getActivity().startService(serviceIntent);
-    }
-}
diff --git a/src/com/android/contacts/calllog/CallLogGroupBuilder.java b/src/com/android/contacts/calllog/CallLogGroupBuilder.java
deleted file mode 100644
index 5c7d3ee..0000000
--- a/src/com/android/contacts/calllog/CallLogGroupBuilder.java
+++ /dev/null
@@ -1,159 +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.database.Cursor;
-import android.provider.CallLog.Calls;
-import android.telephony.PhoneNumberUtils;
-
-import com.android.common.widget.GroupingListAdapter;
-import com.google.common.annotations.VisibleForTesting;
-
-/**
- * Groups together calls in the call log.
- * <p>
- * This class is meant to be used in conjunction with {@link GroupingListAdapter}.
- */
-public class CallLogGroupBuilder {
-    public interface GroupCreator {
-        public void addGroup(int cursorPosition, int size, boolean expanded);
-    }
-
-    /** The object on which the groups are created. */
-    private final GroupCreator mGroupCreator;
-
-    public CallLogGroupBuilder(GroupCreator groupCreator) {
-        mGroupCreator = groupCreator;
-    }
-
-    /**
-     * Finds all groups of adjacent entries in the call log which should be grouped together and
-     * calls {@link GroupCreator#addGroup(int, int, boolean)} on {@link #mGroupCreator} for each of
-     * them.
-     * <p>
-     * For entries that are not grouped with others, we do not need to create a group of size one.
-     * <p>
-     * It assumes that the cursor will not change during its execution.
-     *
-     * @see GroupingListAdapter#addGroups(Cursor)
-     */
-    public void addGroups(Cursor cursor) {
-        final int count = cursor.getCount();
-        if (count == 0) {
-            return;
-        }
-
-        int currentGroupSize = 1;
-        cursor.moveToFirst();
-        // The number of the first entry in the group.
-        String firstNumber = cursor.getString(CallLogQuery.NUMBER);
-        // This is the type of the first call in the group.
-        int firstCallType = cursor.getInt(CallLogQuery.CALL_TYPE);
-        while (cursor.moveToNext()) {
-            // The number of the current row in the cursor.
-            final String currentNumber = cursor.getString(CallLogQuery.NUMBER);
-            final int callType = cursor.getInt(CallLogQuery.CALL_TYPE);
-            final boolean sameNumber = equalNumbers(firstNumber, currentNumber);
-            final boolean shouldGroup;
-
-            if (CallLogQuery.isSectionHeader(cursor)) {
-                // Cannot group headers.
-                shouldGroup = false;
-            } else if (!sameNumber) {
-                // Should only group with calls from the same number.
-                shouldGroup = false;
-            } else if (firstCallType == Calls.VOICEMAIL_TYPE) {
-                // never group voicemail.
-                shouldGroup = false;
-            } else {
-                // Incoming, outgoing, and missed calls group together.
-                shouldGroup = (callType == Calls.INCOMING_TYPE || callType == Calls.OUTGOING_TYPE ||
-                        callType == Calls.MISSED_TYPE);
-            }
-
-            if (shouldGroup) {
-                // Increment the size of the group to include the current call, but do not create
-                // the group until we find a call that does not match.
-                currentGroupSize++;
-            } else {
-                // Create a group for the previous set of calls, excluding the current one, but do
-                // not create a group for a single call.
-                if (currentGroupSize > 1) {
-                    addGroup(cursor.getPosition() - currentGroupSize, currentGroupSize);
-                }
-                // Start a new group; it will include at least the current call.
-                currentGroupSize = 1;
-                // The current entry is now the first in the group.
-                firstNumber = currentNumber;
-                firstCallType = callType;
-            }
-        }
-        // If the last set of calls at the end of the call log was itself a group, create it now.
-        if (currentGroupSize > 1) {
-            addGroup(count - currentGroupSize, currentGroupSize);
-        }
-    }
-
-    /**
-     * Creates a group of items in the cursor.
-     * <p>
-     * The group is always unexpanded.
-     *
-     * @see CallLogAdapter#addGroup(int, int, boolean)
-     */
-    private void addGroup(int cursorPosition, int size) {
-        mGroupCreator.addGroup(cursorPosition, size, false);
-    }
-
-    @VisibleForTesting
-    boolean equalNumbers(String number1, String number2) {
-        if (PhoneNumberUtils.isUriNumber(number1) || PhoneNumberUtils.isUriNumber(number2)) {
-            return compareSipAddresses(number1, number2);
-        } else {
-            return PhoneNumberUtils.compare(number1, number2);
-        }
-    }
-
-    @VisibleForTesting
-    boolean compareSipAddresses(String number1, String number2) {
-        if (number1 == null || number2 == null) return number1 == number2;
-
-        int index1 = number1.indexOf('@');
-        final String userinfo1;
-        final String rest1;
-        if (index1 != -1) {
-            userinfo1 = number1.substring(0, index1);
-            rest1 = number1.substring(index1);
-        } else {
-            userinfo1 = number1;
-            rest1 = "";
-        }
-
-        int index2 = number2.indexOf('@');
-        final String userinfo2;
-        final String rest2;
-        if (index2 != -1) {
-            userinfo2 = number2.substring(0, index2);
-            rest2 = number2.substring(index2);
-        } else {
-            userinfo2 = number2;
-            rest2 = "";
-        }
-
-        return userinfo1.equals(userinfo2) && rest1.equalsIgnoreCase(rest2);
-    }
-}
diff --git a/src/com/android/contacts/calllog/CallLogListItemHelper.java b/src/com/android/contacts/calllog/CallLogListItemHelper.java
deleted file mode 100644
index eb30c81..0000000
--- a/src/com/android/contacts/calllog/CallLogListItemHelper.java
+++ /dev/null
@@ -1,109 +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;
-import android.provider.CallLog.Calls;
-import android.text.TextUtils;
-import android.view.View;
-
-import com.android.contacts.PhoneCallDetails;
-import com.android.contacts.PhoneCallDetailsHelper;
-import com.android.contacts.R;
-
-/**
- * Helper class to fill in the views of a call log entry.
- */
-/*package*/ class CallLogListItemHelper {
-    /** Helper for populating the details of a phone call. */
-    private final PhoneCallDetailsHelper mPhoneCallDetailsHelper;
-    /** Helper for handling phone numbers. */
-    private final PhoneNumberHelper mPhoneNumberHelper;
-    /** Resources to look up strings. */
-    private final Resources mResources;
-
-    /**
-     * Creates a new helper instance.
-     *
-     * @param phoneCallDetailsHelper used to set the details of a phone call
-     * @param phoneNumberHelper used to process phone number
-     */
-    public CallLogListItemHelper(PhoneCallDetailsHelper phoneCallDetailsHelper,
-            PhoneNumberHelper phoneNumberHelper, Resources resources) {
-        mPhoneCallDetailsHelper = phoneCallDetailsHelper;
-        mPhoneNumberHelper = phoneNumberHelper;
-        mResources = resources;
-    }
-
-    /**
-     * Sets the name, label, and number for a contact.
-     *
-     * @param views the views to populate
-     * @param details the details of a phone call needed to fill in the data
-     * @param isHighlighted whether to use the highlight text for the call
-     */
-    public void setPhoneCallDetails(CallLogListItemViews views, PhoneCallDetails details,
-            boolean isHighlighted) {
-        mPhoneCallDetailsHelper.setPhoneCallDetails(views.phoneCallDetailsViews, details,
-                isHighlighted);
-        boolean canCall = mPhoneNumberHelper.canPlaceCallsTo(details.number);
-        boolean canPlay = details.callTypes[0] == Calls.VOICEMAIL_TYPE;
-
-        if (canPlay) {
-            // Playback action takes preference.
-            configurePlaySecondaryAction(views, isHighlighted);
-            views.dividerView.setVisibility(View.VISIBLE);
-        } else if (canCall) {
-            // Call is the secondary action.
-            configureCallSecondaryAction(views, details);
-            views.dividerView.setVisibility(View.VISIBLE);
-        } else {
-            // No action available.
-            views.secondaryActionView.setVisibility(View.GONE);
-            views.dividerView.setVisibility(View.GONE);
-        }
-    }
-
-    /** Sets the secondary action to correspond to the call button. */
-    private void configureCallSecondaryAction(CallLogListItemViews views,
-            PhoneCallDetails details) {
-        views.secondaryActionView.setVisibility(View.VISIBLE);
-        views.secondaryActionView.setImageResource(R.drawable.ic_ab_dialer_holo_dark);
-        views.secondaryActionView.setContentDescription(getCallActionDescription(details));
-    }
-
-    /** Returns the description used by the call action for this phone call. */
-    private CharSequence getCallActionDescription(PhoneCallDetails details) {
-        final CharSequence recipient;
-        if (!TextUtils.isEmpty(details.name)) {
-            recipient = details.name;
-        } else {
-            recipient = mPhoneNumberHelper.getDisplayNumber(
-                    details.number, details.formattedNumber);
-        }
-        return mResources.getString(R.string.description_call, recipient);
-    }
-
-    /** Sets the secondary action to correspond to the play button. */
-    private void configurePlaySecondaryAction(CallLogListItemViews views, boolean isHighlighted) {
-        views.secondaryActionView.setVisibility(View.VISIBLE);
-        views.secondaryActionView.setImageResource(
-                isHighlighted ? R.drawable.ic_play_active_holo_dark : R.drawable.ic_play_holo_dark);
-        views.secondaryActionView.setContentDescription(
-                mResources.getString(R.string.description_call_log_play_button));
-    }
-}
diff --git a/src/com/android/contacts/calllog/CallLogListItemView.java b/src/com/android/contacts/calllog/CallLogListItemView.java
deleted file mode 100644
index 584a7f2..0000000
--- a/src/com/android/contacts/calllog/CallLogListItemView.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 android.content.Context;
-import android.util.AttributeSet;
-import android.widget.LinearLayout;
-
-/**
- * An entry in the call log.
- */
-public class CallLogListItemView extends LinearLayout {
-    public CallLogListItemView(Context context) {
-        super(context);
-    }
-
-    public CallLogListItemView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public CallLogListItemView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    @Override
-    public void requestLayout() {
-        // We will assume that once measured this will not need to resize
-        // itself, so there is no need to pass the layout request to the parent
-        // view (ListView).
-        forceLayout();
-    }
-}
diff --git a/src/com/android/contacts/calllog/CallLogListItemViews.java b/src/com/android/contacts/calllog/CallLogListItemViews.java
deleted file mode 100644
index 348cd2f..0000000
--- a/src/com/android/contacts/calllog/CallLogListItemViews.java
+++ /dev/null
@@ -1,83 +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.view.View;
-import android.widget.ImageView;
-import android.widget.QuickContactBadge;
-import android.widget.TextView;
-
-import com.android.contacts.PhoneCallDetailsViews;
-import com.android.contacts.R;
-import com.android.contacts.test.NeededForTesting;
-
-/**
- * Simple value object containing the various views within a call log entry.
- */
-public final class CallLogListItemViews {
-    /** The quick contact badge for the contact. */
-    public final QuickContactBadge quickContactView;
-    /** The primary action view of the entry. */
-    public final View primaryActionView;
-    /** The secondary action button on the entry. */
-    public final ImageView secondaryActionView;
-    /** The divider between the primary and secondary actions. */
-    public final View dividerView;
-    /** The details of the phone call. */
-    public final PhoneCallDetailsViews phoneCallDetailsViews;
-    /** The text of the header of a section. */
-    public final TextView listHeaderTextView;
-    /** The divider to be shown below items. */
-    public final View bottomDivider;
-
-    private CallLogListItemViews(QuickContactBadge quickContactView, View primaryActionView,
-            ImageView secondaryActionView, View dividerView,
-            PhoneCallDetailsViews phoneCallDetailsViews,
-            TextView listHeaderTextView, View bottomDivider) {
-        this.quickContactView = quickContactView;
-        this.primaryActionView = primaryActionView;
-        this.secondaryActionView = secondaryActionView;
-        this.dividerView = dividerView;
-        this.phoneCallDetailsViews = phoneCallDetailsViews;
-        this.listHeaderTextView = listHeaderTextView;
-        this.bottomDivider = bottomDivider;
-    }
-
-    public static CallLogListItemViews fromView(View view) {
-        return new CallLogListItemViews(
-                (QuickContactBadge) view.findViewById(R.id.quick_contact_photo),
-                view.findViewById(R.id.primary_action_view),
-                (ImageView) view.findViewById(R.id.secondary_action_icon),
-                view.findViewById(R.id.divider),
-                PhoneCallDetailsViews.fromView(view),
-                (TextView) view.findViewById(R.id.call_log_header),
-                view.findViewById(R.id.call_log_divider));
-    }
-
-    @NeededForTesting
-    public static CallLogListItemViews createForTest(Context context) {
-        return new CallLogListItemViews(
-                new QuickContactBadge(context),
-                new View(context),
-                new ImageView(context),
-                new View(context),
-                PhoneCallDetailsViews.createForTest(context),
-                new TextView(context),
-                new View(context));
-    }
-}
diff --git a/src/com/android/contacts/calllog/CallLogNotificationsService.java b/src/com/android/contacts/calllog/CallLogNotificationsService.java
deleted file mode 100644
index be540ad..0000000
--- a/src/com/android/contacts/calllog/CallLogNotificationsService.java
+++ /dev/null
@@ -1,82 +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.app.IntentService;
-import android.content.Intent;
-import android.net.Uri;
-import android.util.Log;
-
-/**
- * Provides operations for managing notifications.
- * <p>
- * It handles the following actions:
- * <ul>
- * <li>{@link #ACTION_MARK_NEW_VOICEMAILS_AS_OLD}: marks all the new voicemails in the call log as
- * old; this is called when a notification is dismissed.</li>
- * <li>{@link #ACTION_UPDATE_NOTIFICATIONS}: updates the content of the new items notification; it
- * may include an optional extra {@link #EXTRA_NEW_VOICEMAIL_URI}, containing the URI of the new
- * voicemail that has triggered this update (if any).</li>
- * </ul>
- */
-public class CallLogNotificationsService extends IntentService {
-    private static final String TAG = "CallLogNotificationsService";
-
-    /** Action to mark all the new voicemails as old. */
-    public static final String ACTION_MARK_NEW_VOICEMAILS_AS_OLD =
-            "com.android.contacts.calllog.ACTION_MARK_NEW_VOICEMAILS_AS_OLD";
-
-    /**
-     * Action to update the notifications.
-     * <p>
-     * May include an optional extra {@link #EXTRA_NEW_VOICEMAIL_URI}.
-     */
-    public static final String ACTION_UPDATE_NOTIFICATIONS =
-            "com.android.contacts.calllog.UPDATE_NOTIFICATIONS";
-
-    /**
-     * Extra to included with {@link #ACTION_UPDATE_NOTIFICATIONS} to identify the new voicemail
-     * that triggered an update.
-     * <p>
-     * It must be a {@link Uri}.
-     */
-    public static final String EXTRA_NEW_VOICEMAIL_URI = "NEW_VOICEMAIL_URI";
-
-    private CallLogQueryHandler mCallLogQueryHandler;
-
-    public CallLogNotificationsService() {
-        super("CallLogNotificationsService");
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mCallLogQueryHandler = new CallLogQueryHandler(getContentResolver(), null /*listener*/);
-    }
-
-    @Override
-    protected void onHandleIntent(Intent intent) {
-        if (ACTION_MARK_NEW_VOICEMAILS_AS_OLD.equals(intent.getAction())) {
-            mCallLogQueryHandler.markNewVoicemailsAsOld();
-        } else if (ACTION_UPDATE_NOTIFICATIONS.equals(intent.getAction())) {
-            Uri voicemailUri = (Uri) intent.getParcelableExtra(EXTRA_NEW_VOICEMAIL_URI);
-            DefaultVoicemailNotifier.getInstance(this).updateNotification(voicemailUri);
-        } else {
-            Log.d(TAG, "onHandleIntent: could not handle: " + intent);
-        }
-    }
-}
diff --git a/src/com/android/contacts/calllog/CallLogQuery.java b/src/com/android/contacts/calllog/CallLogQuery.java
deleted file mode 100644
index 90017b7..0000000
--- a/src/com/android/contacts/calllog/CallLogQuery.java
+++ /dev/null
@@ -1,103 +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.database.Cursor;
-import android.provider.CallLog.Calls;
-
-/**
- * The query for the call log table.
- */
-public final class CallLogQuery {
-    // If you alter this, you must also alter the method that inserts a fake row to the headers
-    // in the CallLogQueryHandler class called createHeaderCursorFor().
-    public static final String[] _PROJECTION = new String[] {
-            Calls._ID,                       // 0
-            Calls.NUMBER,                    // 1
-            Calls.DATE,                      // 2
-            Calls.DURATION,                  // 3
-            Calls.TYPE,                      // 4
-            Calls.COUNTRY_ISO,               // 5
-            Calls.VOICEMAIL_URI,             // 6
-            Calls.GEOCODED_LOCATION,         // 7
-            Calls.CACHED_NAME,               // 8
-            Calls.CACHED_NUMBER_TYPE,        // 9
-            Calls.CACHED_NUMBER_LABEL,       // 10
-            Calls.CACHED_LOOKUP_URI,         // 11
-            Calls.CACHED_MATCHED_NUMBER,     // 12
-            Calls.CACHED_NORMALIZED_NUMBER,  // 13
-            Calls.CACHED_PHOTO_ID,           // 14
-            Calls.CACHED_FORMATTED_NUMBER,   // 15
-            Calls.IS_READ,                   // 16
-    };
-
-    public static final int ID = 0;
-    public static final int NUMBER = 1;
-    public static final int DATE = 2;
-    public static final int DURATION = 3;
-    public static final int CALL_TYPE = 4;
-    public static final int COUNTRY_ISO = 5;
-    public static final int VOICEMAIL_URI = 6;
-    public static final int GEOCODED_LOCATION = 7;
-    public static final int CACHED_NAME = 8;
-    public static final int CACHED_NUMBER_TYPE = 9;
-    public static final int CACHED_NUMBER_LABEL = 10;
-    public static final int CACHED_LOOKUP_URI = 11;
-    public static final int CACHED_MATCHED_NUMBER = 12;
-    public static final int CACHED_NORMALIZED_NUMBER = 13;
-    public static final int CACHED_PHOTO_ID = 14;
-    public static final int CACHED_FORMATTED_NUMBER = 15;
-    public static final int IS_READ = 16;
-    /** The index of the synthetic "section" column in the extended projection. */
-    public static final int SECTION = 17;
-
-    /**
-     * The name of the synthetic "section" column.
-     * <p>
-     * This column identifies whether a row is a header or an actual item, and whether it is
-     * part of the new or old calls.
-     */
-    public static final String SECTION_NAME = "section";
-    /** The value of the "section" column for the header of the new section. */
-    public static final int SECTION_NEW_HEADER = 0;
-    /** The value of the "section" column for the items of the new section. */
-    public static final int SECTION_NEW_ITEM = 1;
-    /** The value of the "section" column for the header of the old section. */
-    public static final int SECTION_OLD_HEADER = 2;
-    /** The value of the "section" column for the items of the old section. */
-    public static final int SECTION_OLD_ITEM = 3;
-
-    /** The call log projection including the section name. */
-    public static final String[] EXTENDED_PROJECTION;
-    static {
-        EXTENDED_PROJECTION = new String[_PROJECTION.length + 1];
-        System.arraycopy(_PROJECTION, 0, EXTENDED_PROJECTION, 0, _PROJECTION.length);
-        EXTENDED_PROJECTION[_PROJECTION.length] = SECTION_NAME;
-    }
-
-    public static boolean isSectionHeader(Cursor cursor) {
-        int section = cursor.getInt(CallLogQuery.SECTION);
-        return section == CallLogQuery.SECTION_NEW_HEADER
-                || section == CallLogQuery.SECTION_OLD_HEADER;
-    }
-
-    public static boolean isNewSection(Cursor cursor) {
-        int section = cursor.getInt(CallLogQuery.SECTION);
-        return section == CallLogQuery.SECTION_NEW_ITEM
-                || section == CallLogQuery.SECTION_NEW_HEADER;
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/calllog/CallLogQueryHandler.java b/src/com/android/contacts/calllog/CallLogQueryHandler.java
deleted file mode 100644
index a6382b6..0000000
--- a/src/com/android/contacts/calllog/CallLogQueryHandler.java
+++ /dev/null
@@ -1,365 +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.AsyncQueryHandler;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.database.MergeCursor;
-import android.database.sqlite.SQLiteDatabaseCorruptException;
-import android.database.sqlite.SQLiteDiskIOException;
-import android.database.sqlite.SQLiteException;
-import android.database.sqlite.SQLiteFullException;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.CallLog;
-import android.provider.CallLog.Calls;
-import android.provider.VoicemailContract.Status;
-import android.util.Log;
-
-import com.android.common.io.MoreCloseables;
-import com.android.contacts.voicemail.VoicemailStatusHelperImpl;
-import com.google.common.collect.Lists;
-
-import java.lang.ref.WeakReference;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.GuardedBy;
-
-/** Handles asynchronous queries to the call log. */
-/*package*/ class CallLogQueryHandler extends AsyncQueryHandler {
-    private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
-    private static final String TAG = "CallLogQueryHandler";
-    private static final int NUM_LOGS_TO_DISPLAY = 1000;
-
-    /** The token for the query to fetch the new entries from the call log. */
-    private static final int QUERY_NEW_CALLS_TOKEN = 53;
-    /** The token for the query to fetch the old entries from the call log. */
-    private static final int QUERY_OLD_CALLS_TOKEN = 54;
-    /** The token for the query to mark all missed calls as old after seeing the call log. */
-    private static final int UPDATE_MARK_AS_OLD_TOKEN = 55;
-    /** The token for the query to mark all new voicemails as old. */
-    private static final int UPDATE_MARK_VOICEMAILS_AS_OLD_TOKEN = 56;
-    /** The token for the query to mark all missed calls as read after seeing the call log. */
-    private static final int UPDATE_MARK_MISSED_CALL_AS_READ_TOKEN = 57;
-    /** The token for the query to fetch voicemail status messages. */
-    private static final int QUERY_VOICEMAIL_STATUS_TOKEN = 58;
-
-    /**
-     * Call type similar to Calls.INCOMING_TYPE used to specify all types instead of one particular
-     * type.
-     */
-    public static final int CALL_TYPE_ALL = -1;
-
-    /**
-     * The time window from the current time within which an unread entry will be added to the new
-     * section.
-     */
-    private static final long NEW_SECTION_TIME_WINDOW = TimeUnit.DAYS.toMillis(7);
-
-    private final WeakReference<Listener> mListener;
-
-    /** The cursor containing the new calls, or null if they have not yet been fetched. */
-    @GuardedBy("this") private Cursor mNewCallsCursor;
-    /** The cursor containing the old calls, or null if they have not yet been fetched. */
-    @GuardedBy("this") private Cursor mOldCallsCursor;
-    /**
-     * The identifier of the latest calls request.
-     * <p>
-     * A request for the list of calls requires two queries and hence the two cursor
-     * {@link #mNewCallsCursor} and {@link #mOldCallsCursor} above, corresponding to
-     * {@link #QUERY_NEW_CALLS_TOKEN} and {@link #QUERY_OLD_CALLS_TOKEN}.
-     * <p>
-     * When a new request is about to be started, existing cursors are closed. However, it is
-     * possible that one of the queries completes after the new request has started. This means that
-     * we might merge two cursors that do not correspond to the same request. Moreover, this may
-     * lead to a resource leak if the same query completes and we override the cursor without
-     * closing it first.
-     * <p>
-     * To make sure we only join two cursors from the same request, we use this variable to store
-     * the request id of the latest request and make sure we only process cursors corresponding to
-     * the this request.
-     */
-    @GuardedBy("this") private int mCallsRequestId;
-
-    /**
-     * Simple handler that wraps background calls to catch
-     * {@link SQLiteException}, such as when the disk is full.
-     */
-    protected class CatchingWorkerHandler extends AsyncQueryHandler.WorkerHandler {
-        public CatchingWorkerHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            try {
-                // Perform same query while catching any exceptions
-                super.handleMessage(msg);
-            } catch (SQLiteDiskIOException e) {
-                Log.w(TAG, "Exception on background worker thread", e);
-            } catch (SQLiteFullException e) {
-                Log.w(TAG, "Exception on background worker thread", e);
-            } catch (SQLiteDatabaseCorruptException e) {
-                Log.w(TAG, "Exception on background worker thread", e);
-            }
-        }
-    }
-
-    @Override
-    protected Handler createHandler(Looper looper) {
-        // Provide our special handler that catches exceptions
-        return new CatchingWorkerHandler(looper);
-    }
-
-    public CallLogQueryHandler(ContentResolver contentResolver, Listener listener) {
-        super(contentResolver);
-        mListener = new WeakReference<Listener>(listener);
-    }
-
-    /** Creates a cursor that contains a single row and maps the section to the given value. */
-    private Cursor createHeaderCursorFor(int section) {
-        MatrixCursor matrixCursor =
-                new MatrixCursor(CallLogQuery.EXTENDED_PROJECTION);
-        // The values in this row correspond to default values for _PROJECTION from CallLogQuery
-        // plus the section value.
-        matrixCursor.addRow(new Object[]{
-                0L, "", 0L, 0L, 0, "", "", "", null, 0, null, null, null, null, 0L, null, 0,
-                section
-        });
-        return matrixCursor;
-    }
-
-    /** Returns a cursor for the old calls header. */
-    private Cursor createOldCallsHeaderCursor() {
-        return createHeaderCursorFor(CallLogQuery.SECTION_OLD_HEADER);
-    }
-
-    /** Returns a cursor for the new calls header. */
-    private Cursor createNewCallsHeaderCursor() {
-        return createHeaderCursorFor(CallLogQuery.SECTION_NEW_HEADER);
-    }
-
-    /**
-     * Fetches the list of calls from the call log for a given type.
-     * <p>
-     * It will asynchronously update the content of the list view when the fetch completes.
-     */
-    public void fetchCalls(int callType) {
-        cancelFetch();
-        int requestId = newCallsRequest();
-        fetchCalls(QUERY_NEW_CALLS_TOKEN, requestId, true /*isNew*/, callType);
-        fetchCalls(QUERY_OLD_CALLS_TOKEN, requestId, false /*isNew*/, callType);
-    }
-
-    public void fetchVoicemailStatus() {
-        startQuery(QUERY_VOICEMAIL_STATUS_TOKEN, null, Status.CONTENT_URI,
-                VoicemailStatusHelperImpl.PROJECTION, null, null, null);
-    }
-
-    /** Fetches the list of calls in the call log, either the new one or the old ones. */
-    private void fetchCalls(int token, int requestId, boolean isNew, int callType) {
-        // We need to check for NULL explicitly otherwise entries with where READ is NULL
-        // may not match either the query or its negation.
-        // We consider the calls that are not yet consumed (i.e. IS_READ = 0) as "new".
-        String selection = String.format("%s IS NOT NULL AND %s = 0 AND %s > ?",
-                Calls.IS_READ, Calls.IS_READ, Calls.DATE);
-        List<String> selectionArgs = Lists.newArrayList(
-                Long.toString(System.currentTimeMillis() - NEW_SECTION_TIME_WINDOW));
-        if (!isNew) {
-            // Negate the query.
-            selection = String.format("NOT (%s)", selection);
-        }
-        if (callType > CALL_TYPE_ALL) {
-            // Add a clause to fetch only items of type voicemail.
-            selection = String.format("(%s) AND (%s = ?)", selection, Calls.TYPE);
-            selectionArgs.add(Integer.toString(callType));
-        }
-        Uri uri = Calls.CONTENT_URI_WITH_VOICEMAIL.buildUpon()
-                .appendQueryParameter(Calls.LIMIT_PARAM_KEY, Integer.toString(NUM_LOGS_TO_DISPLAY))
-                .build();
-        startQuery(token, requestId, uri,
-                CallLogQuery._PROJECTION, selection, selectionArgs.toArray(EMPTY_STRING_ARRAY),
-                Calls.DEFAULT_SORT_ORDER);
-    }
-
-    /** Cancel any pending fetch request. */
-    private void cancelFetch() {
-        cancelOperation(QUERY_NEW_CALLS_TOKEN);
-        cancelOperation(QUERY_OLD_CALLS_TOKEN);
-    }
-
-    /** Updates all new calls to mark them as old. */
-    public void markNewCallsAsOld() {
-        // Mark all "new" calls as not new anymore.
-        StringBuilder where = new StringBuilder();
-        where.append(Calls.NEW);
-        where.append(" = 1");
-
-        ContentValues values = new ContentValues(1);
-        values.put(Calls.NEW, "0");
-
-        startUpdate(UPDATE_MARK_AS_OLD_TOKEN, null, Calls.CONTENT_URI_WITH_VOICEMAIL,
-                values, where.toString(), null);
-    }
-
-    /** Updates all new voicemails to mark them as old. */
-    public void markNewVoicemailsAsOld() {
-        // Mark all "new" voicemails as not new anymore.
-        StringBuilder where = new StringBuilder();
-        where.append(Calls.NEW);
-        where.append(" = 1 AND ");
-        where.append(Calls.TYPE);
-        where.append(" = ?");
-
-        ContentValues values = new ContentValues(1);
-        values.put(Calls.NEW, "0");
-
-        startUpdate(UPDATE_MARK_VOICEMAILS_AS_OLD_TOKEN, null, Calls.CONTENT_URI_WITH_VOICEMAIL,
-                values, where.toString(), new String[]{ Integer.toString(Calls.VOICEMAIL_TYPE) });
-    }
-
-    /** Updates all missed calls to mark them as read. */
-    public void markMissedCallsAsRead() {
-        // Mark all "new" calls as not new anymore.
-        StringBuilder where = new StringBuilder();
-        where.append(Calls.IS_READ).append(" = 0");
-        where.append(" AND ");
-        where.append(Calls.TYPE).append(" = ").append(Calls.MISSED_TYPE);
-
-        ContentValues values = new ContentValues(1);
-        values.put(Calls.IS_READ, "1");
-
-        startUpdate(UPDATE_MARK_MISSED_CALL_AS_READ_TOKEN, null, Calls.CONTENT_URI, values,
-                where.toString(), null);
-    }
-
-    /**
-     * Start a new request and return its id. The request id will be used as the cookie for the
-     * background request.
-     * <p>
-     * Closes any open cursor that has not yet been sent to the requester.
-     */
-    private synchronized int newCallsRequest() {
-        MoreCloseables.closeQuietly(mNewCallsCursor);
-        MoreCloseables.closeQuietly(mOldCallsCursor);
-        mNewCallsCursor = null;
-        mOldCallsCursor = null;
-        return ++mCallsRequestId;
-    }
-
-    @Override
-    protected synchronized void onQueryComplete(int token, Object cookie, Cursor cursor) {
-        if (token == QUERY_NEW_CALLS_TOKEN) {
-            int requestId = ((Integer) cookie).intValue();
-            if (requestId != mCallsRequestId) {
-                // Ignore this query since it does not correspond to the latest request.
-                return;
-            }
-
-            // Store the returned cursor.
-            MoreCloseables.closeQuietly(mNewCallsCursor);
-            mNewCallsCursor = new ExtendedCursor(
-                    cursor, CallLogQuery.SECTION_NAME, CallLogQuery.SECTION_NEW_ITEM);
-        } else if (token == QUERY_OLD_CALLS_TOKEN) {
-            int requestId = ((Integer) cookie).intValue();
-            if (requestId != mCallsRequestId) {
-                // Ignore this query since it does not correspond to the latest request.
-                return;
-            }
-
-            // Store the returned cursor.
-            MoreCloseables.closeQuietly(mOldCallsCursor);
-            mOldCallsCursor = new ExtendedCursor(
-                    cursor, CallLogQuery.SECTION_NAME, CallLogQuery.SECTION_OLD_ITEM);
-        } else if (token == QUERY_VOICEMAIL_STATUS_TOKEN) {
-            updateVoicemailStatus(cursor);
-            return;
-        } else {
-            Log.w(TAG, "Unknown query completed: ignoring: " + token);
-            return;
-        }
-
-        if (mNewCallsCursor != null && mOldCallsCursor != null) {
-            updateAdapterData(createMergedCursor());
-        }
-    }
-
-    /** Creates the merged cursor representing the data to show in the call log. */
-    @GuardedBy("this")
-    private Cursor createMergedCursor() {
-        try {
-            final boolean hasNewCalls = mNewCallsCursor.getCount() != 0;
-            final boolean hasOldCalls = mOldCallsCursor.getCount() != 0;
-
-            if (!hasNewCalls) {
-                // Return only the old calls, without the header.
-                MoreCloseables.closeQuietly(mNewCallsCursor);
-                return mOldCallsCursor;
-            }
-
-            if (!hasOldCalls) {
-                // Return only the new calls.
-                MoreCloseables.closeQuietly(mOldCallsCursor);
-                return new MergeCursor(
-                        new Cursor[]{ createNewCallsHeaderCursor(), mNewCallsCursor });
-            }
-
-            return new MergeCursor(new Cursor[]{
-                    createNewCallsHeaderCursor(), mNewCallsCursor,
-                    createOldCallsHeaderCursor(), mOldCallsCursor});
-        } finally {
-            // Any cursor still open is now owned, directly or indirectly, by the caller.
-            mNewCallsCursor = null;
-            mOldCallsCursor = null;
-        }
-    }
-
-    /**
-     * Updates the adapter in the call log fragment to show the new cursor data.
-     */
-    private void updateAdapterData(Cursor combinedCursor) {
-        final Listener listener = mListener.get();
-        if (listener != null) {
-            listener.onCallsFetched(combinedCursor);
-        }
-    }
-
-    private void updateVoicemailStatus(Cursor statusCursor) {
-        final Listener listener = mListener.get();
-        if (listener != null) {
-            listener.onVoicemailStatusFetched(statusCursor);
-        }
-    }
-
-    /** Listener to completion of various queries. */
-    public interface Listener {
-        /** Called when {@link CallLogQueryHandler#fetchVoicemailStatus()} completes. */
-        void onVoicemailStatusFetched(Cursor statusCursor);
-
-        /**
-         * Called when {@link CallLogQueryHandler#fetchCalls(int)}complete.
-         */
-        void onCallsFetched(Cursor combinedCursor);
-    }
-}
diff --git a/src/com/android/contacts/calllog/CallLogReceiver.java b/src/com/android/contacts/calllog/CallLogReceiver.java
deleted file mode 100644
index 14bfa64..0000000
--- a/src/com/android/contacts/calllog/CallLogReceiver.java
+++ /dev/null
@@ -1,50 +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.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.provider.VoicemailContract;
-import android.util.Log;
-
-/**
- * Receiver for call log events.
- * <p>
- * It is currently used to handle {@link VoicemailContract#ACTION_NEW_VOICEMAIL} and
- * {@link Intent#ACTION_BOOT_COMPLETED}.
- */
-public class CallLogReceiver extends BroadcastReceiver {
-    private static final String TAG = "CallLogReceiver";
-
-    @Override
-    public void onReceive(Context context, Intent intent) {
-        if (VoicemailContract.ACTION_NEW_VOICEMAIL.equals(intent.getAction())) {
-            Intent serviceIntent = new Intent(context, CallLogNotificationsService.class);
-            serviceIntent.setAction(CallLogNotificationsService.ACTION_UPDATE_NOTIFICATIONS);
-            serviceIntent.putExtra(
-                    CallLogNotificationsService.EXTRA_NEW_VOICEMAIL_URI, intent.getData());
-            context.startService(serviceIntent);
-        } else if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
-            Intent serviceIntent = new Intent(context, CallLogNotificationsService.class);
-            serviceIntent.setAction(CallLogNotificationsService.ACTION_UPDATE_NOTIFICATIONS);
-            context.startService(serviceIntent);
-        } else {
-            Log.w(TAG, "onReceive: could not handle: " + intent);
-        }
-    }
-}
diff --git a/src/com/android/contacts/calllog/CallTypeHelper.java b/src/com/android/contacts/calllog/CallTypeHelper.java
deleted file mode 100644
index 2ca0db0..0000000
--- a/src/com/android/contacts/calllog/CallTypeHelper.java
+++ /dev/null
@@ -1,92 +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;
-import android.provider.CallLog.Calls;
-
-import com.android.contacts.R;
-
-/**
- * Helper class to perform operations related to call types.
- */
-public class CallTypeHelper {
-    /** Name used to identify incoming calls. */
-    private final CharSequence mIncomingName;
-    /** Name used to identify outgoing calls. */
-    private final CharSequence mOutgoingName;
-    /** Name used to identify missed calls. */
-    private final CharSequence mMissedName;
-    /** Name used to identify voicemail calls. */
-    private final CharSequence mVoicemailName;
-    /** Color used to identify new missed calls. */
-    private final int mNewMissedColor;
-    /** Color used to identify new voicemail calls. */
-    private final int mNewVoicemailColor;
-
-    public CallTypeHelper(Resources resources) {
-        // Cache these values so that we do not need to look them up each time.
-        mIncomingName = resources.getString(R.string.type_incoming);
-        mOutgoingName = resources.getString(R.string.type_outgoing);
-        mMissedName = resources.getString(R.string.type_missed);
-        mVoicemailName = resources.getString(R.string.type_voicemail);
-        mNewMissedColor = resources.getColor(R.color.call_log_missed_call_highlight_color);
-        mNewVoicemailColor = resources.getColor(R.color.call_log_voicemail_highlight_color);
-    }
-
-    /** Returns the text used to represent the given call type. */
-    public CharSequence getCallTypeText(int callType) {
-        switch (callType) {
-            case Calls.INCOMING_TYPE:
-                return mIncomingName;
-
-            case Calls.OUTGOING_TYPE:
-                return mOutgoingName;
-
-            case Calls.MISSED_TYPE:
-                return mMissedName;
-
-            case Calls.VOICEMAIL_TYPE:
-                return mVoicemailName;
-
-            default:
-                throw new IllegalArgumentException("invalid call type: " + callType);
-        }
-    }
-
-    /** Returns the color used to highlight the given call type, null if not highlight is needed. */
-    public Integer getHighlightedColor(int callType) {
-        switch (callType) {
-            case Calls.INCOMING_TYPE:
-                // New incoming calls are not highlighted.
-                return null;
-
-            case Calls.OUTGOING_TYPE:
-                // New outgoing calls are not highlighted.
-                return null;
-
-            case Calls.MISSED_TYPE:
-                return mNewMissedColor;
-
-            case Calls.VOICEMAIL_TYPE:
-                return mNewVoicemailColor;
-
-            default:
-                throw new IllegalArgumentException("invalid call type: " + callType);
-        }
-    }
-}
diff --git a/src/com/android/contacts/calllog/CallTypeIconsView.java b/src/com/android/contacts/calllog/CallTypeIconsView.java
deleted file mode 100644
index 384b597..0000000
--- a/src/com/android/contacts/calllog/CallTypeIconsView.java
+++ /dev/null
@@ -1,126 +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.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.provider.CallLog.Calls;
-import android.util.AttributeSet;
-import android.view.View;
-
-import com.android.contacts.R;
-import com.android.contacts.test.NeededForTesting;
-import com.google.common.collect.Lists;
-
-import java.util.List;
-
-/**
- * View that draws one or more symbols for different types of calls (missed calls, outgoing etc).
- * The symbols are set up horizontally. As this view doesn't create subviews, it is better suited
- * for ListView-recycling that a regular LinearLayout using ImageViews.
- */
-public class CallTypeIconsView extends View {
-    private List<Integer> mCallTypes = Lists.newArrayListWithCapacity(3);
-    private Resources mResources;
-    private int mWidth;
-    private int mHeight;
-
-    public CallTypeIconsView(Context context) {
-        this(context, null);
-    }
-
-    public CallTypeIconsView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        mResources = new Resources(context);
-    }
-
-    public void clear() {
-        mCallTypes.clear();
-        mWidth = 0;
-        mHeight = 0;
-        invalidate();
-    }
-
-    public void add(int callType) {
-        mCallTypes.add(callType);
-
-        final Drawable drawable = getCallTypeDrawable(callType);
-        mWidth += drawable.getIntrinsicWidth() + mResources.iconMargin;
-        mHeight = Math.max(mHeight, drawable.getIntrinsicHeight());
-        invalidate();
-    }
-
-    @NeededForTesting
-    public int getCount() {
-        return mCallTypes.size();
-    }
-
-    @NeededForTesting
-    public int getCallType(int index) {
-        return mCallTypes.get(index);
-    }
-
-    private Drawable getCallTypeDrawable(int callType) {
-        switch (callType) {
-            case Calls.INCOMING_TYPE:
-                return mResources.incoming;
-            case Calls.OUTGOING_TYPE:
-                return mResources.outgoing;
-            case Calls.MISSED_TYPE:
-                return mResources.missed;
-            case Calls.VOICEMAIL_TYPE:
-                return mResources.voicemail;
-            default:
-                throw new IllegalArgumentException("invalid call type: " + callType);
-        }
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        setMeasuredDimension(mWidth, mHeight);
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        int left = 0;
-        for (Integer callType : mCallTypes) {
-            final Drawable drawable = getCallTypeDrawable(callType);
-            final int right = left + drawable.getIntrinsicWidth();
-            drawable.setBounds(left, 0, right, drawable.getIntrinsicHeight());
-            drawable.draw(canvas);
-            left = right + mResources.iconMargin;
-        }
-    }
-
-    private static class Resources {
-        public final Drawable incoming;
-        public final Drawable outgoing;
-        public final Drawable missed;
-        public final Drawable voicemail;
-        public final int iconMargin;
-
-        public Resources(Context context) {
-            final android.content.res.Resources r = context.getResources();
-            incoming = r.getDrawable(R.drawable.ic_call_incoming_holo_dark);
-            outgoing = r.getDrawable(R.drawable.ic_call_outgoing_holo_dark);
-            missed = r.getDrawable(R.drawable.ic_call_missed_holo_dark);
-            voicemail = r.getDrawable(R.drawable.ic_call_voicemail_holo_dark);
-            iconMargin = r.getDimensionPixelSize(R.dimen.call_log_icon_margin);
-        }
-    }
-}
diff --git a/src/com/android/contacts/calllog/ClearCallLogDialog.java b/src/com/android/contacts/calllog/ClearCallLogDialog.java
deleted file mode 100644
index c4dbb7e..0000000
--- a/src/com/android/contacts/calllog/ClearCallLogDialog.java
+++ /dev/null
@@ -1,78 +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.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.FragmentManager;
-import android.app.ProgressDialog;
-import android.content.ContentResolver;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.provider.CallLog.Calls;
-
-import com.android.contacts.R;
-
-/**
- * Dialog that clears the call log after confirming with the user
- */
-public class ClearCallLogDialog extends DialogFragment {
-    /** Preferred way to show this dialog */
-    public static void show(FragmentManager fragmentManager) {
-        ClearCallLogDialog dialog = new ClearCallLogDialog();
-        dialog.show(fragmentManager, "deleteCallLog");
-    }
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        final ContentResolver resolver = getActivity().getContentResolver();
-        final OnClickListener okListener = new OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                final ProgressDialog progressDialog = ProgressDialog.show(getActivity(),
-                        getString(R.string.clearCallLogProgress_title),
-                        "", true, false);
-                final AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
-                    @Override
-                    protected Void doInBackground(Void... params) {
-                        resolver.delete(Calls.CONTENT_URI, null, null);
-                        return null;
-                    }
-                    @Override
-                    protected void onPostExecute(Void result) {
-                        progressDialog.dismiss();
-                    }
-                };
-                // TODO: Once we have the API, we should configure this ProgressDialog
-                // to only show up after a certain time (e.g. 150ms)
-                progressDialog.show();
-                task.execute();
-            }
-        };
-        return new AlertDialog.Builder(getActivity())
-            .setTitle(R.string.clearCallLogConfirmation_title)
-            .setIconAttribute(android.R.attr.alertDialogIcon)
-            .setMessage(R.string.clearCallLogConfirmation)
-            .setNegativeButton(android.R.string.cancel, null)
-            .setPositiveButton(android.R.string.ok, okListener)
-            .setCancelable(true)
-            .create();
-    }
-}
diff --git a/src/com/android/contacts/calllog/ContactInfo.java b/src/com/android/contacts/calllog/ContactInfo.java
deleted file mode 100644
index 30e7e71..0000000
--- a/src/com/android/contacts/calllog/ContactInfo.java
+++ /dev/null
@@ -1,71 +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.net.Uri;
-import android.text.TextUtils;
-
-import com.android.contacts.util.UriUtils;
-
-/**
- * Information for a contact as needed by the Call Log.
- */
-public final class ContactInfo {
-    public Uri lookupUri;
-    public String name;
-    public int type;
-    public String label;
-    public String number;
-    public String formattedNumber;
-    public String normalizedNumber;
-    /** The photo for the contact, if available. */
-    public long photoId;
-    /** The high-res photo for the contact, if available. */
-    public Uri photoUri;
-
-    public static ContactInfo EMPTY = new ContactInfo();
-
-    @Override
-    public int hashCode() {
-        // Uses only name and contactUri to determine hashcode.
-        // This should be sufficient to have a reasonable distribution of hash codes.
-        // Moreover, there should be no two people with the same lookupUri.
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((lookupUri == null) ? 0 : lookupUri.hashCode());
-        result = prime * result + ((name == null) ? 0 : name.hashCode());
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) return true;
-        if (obj == null) return false;
-        if (getClass() != obj.getClass()) return false;
-        ContactInfo other = (ContactInfo) obj;
-        if (!UriUtils.areEqual(lookupUri, other.lookupUri)) return false;
-        if (!TextUtils.equals(name, other.name)) return false;
-        if (type != other.type) return false;
-        if (!TextUtils.equals(label, other.label)) return false;
-        if (!TextUtils.equals(number, other.number)) return false;
-        if (!TextUtils.equals(formattedNumber, other.formattedNumber)) return false;
-        if (!TextUtils.equals(normalizedNumber, other.normalizedNumber)) return false;
-        if (photoId != other.photoId) return false;
-        if (!UriUtils.areEqual(photoUri, other.photoUri)) return false;
-        return true;
-    }
-}
diff --git a/src/com/android/contacts/calllog/ContactInfoHelper.java b/src/com/android/contacts/calllog/ContactInfoHelper.java
deleted file mode 100644
index edca00c..0000000
--- a/src/com/android/contacts/calllog/ContactInfoHelper.java
+++ /dev/null
@@ -1,215 +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.Cursor;
-import android.net.Uri;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.PhoneLookup;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-
-import com.android.contacts.util.UriUtils;
-
-/**
- * Utility class to look up the contact information for a given number.
- */
-public class ContactInfoHelper {
-    private final Context mContext;
-    private final String mCurrentCountryIso;
-
-    public ContactInfoHelper(Context context, String currentCountryIso) {
-        mContext = context;
-        mCurrentCountryIso = currentCountryIso;
-    }
-
-    /**
-     * Returns the contact information for the given number.
-     * <p>
-     * If the number does not match any contact, returns a contact info containing only the number
-     * and the formatted number.
-     * <p>
-     * If an error occurs during the lookup, it returns null.
-     *
-     * @param number the number to look up
-     * @param countryIso the country associated with this number
-     */
-    public ContactInfo lookupNumber(String number, String countryIso) {
-        final ContactInfo info;
-
-        // Determine the contact info.
-        if (PhoneNumberUtils.isUriNumber(number)) {
-            // This "number" is really a SIP address.
-            ContactInfo sipInfo = queryContactInfoForSipAddress(number);
-            if (sipInfo == null || sipInfo == ContactInfo.EMPTY) {
-                // Check whether the "username" part of the SIP address is
-                // actually the phone number of a contact.
-                String username = PhoneNumberUtils.getUsernameFromUriNumber(number);
-                if (PhoneNumberUtils.isGlobalPhoneNumber(username)) {
-                    sipInfo = queryContactInfoForPhoneNumber(username, countryIso);
-                }
-            }
-            info = sipInfo;
-        } else {
-            // Look for a contact that has the given phone number.
-            ContactInfo phoneInfo = queryContactInfoForPhoneNumber(number, countryIso);
-
-            if (phoneInfo == null || phoneInfo == ContactInfo.EMPTY) {
-                // Check whether the phone number has been saved as an "Internet call" number.
-                phoneInfo = queryContactInfoForSipAddress(number);
-            }
-            info = phoneInfo;
-        }
-
-        final ContactInfo updatedInfo;
-        if (info == null) {
-            // The lookup failed.
-            updatedInfo = null;
-        } else {
-            // If we did not find a matching contact, generate an empty contact info for the number.
-            if (info == ContactInfo.EMPTY) {
-                // Did not find a matching contact.
-                updatedInfo = new ContactInfo();
-                updatedInfo.number = number;
-                updatedInfo.formattedNumber = formatPhoneNumber(number, null, countryIso);
-            } else {
-                updatedInfo = info;
-            }
-        }
-        return updatedInfo;
-    }
-
-    /**
-     * Looks up a contact using the given URI.
-     * <p>
-     * It returns null if an error occurs, {@link ContactInfo#EMPTY} if no matching contact is
-     * found, or the {@link ContactInfo} for the given contact.
-     * <p>
-     * The {@link ContactInfo#formattedNumber} field is always set to {@code null} in the returned
-     * value.
-     */
-    private ContactInfo lookupContactFromUri(Uri uri) {
-        final ContactInfo info;
-        Cursor phonesCursor =
-                mContext.getContentResolver().query(
-                        uri, PhoneQuery._PROJECTION, null, null, null);
-
-        if (phonesCursor != null) {
-            try {
-                if (phonesCursor.moveToFirst()) {
-                    info = new ContactInfo();
-                    long contactId = phonesCursor.getLong(PhoneQuery.PERSON_ID);
-                    String lookupKey = phonesCursor.getString(PhoneQuery.LOOKUP_KEY);
-                    info.lookupUri = Contacts.getLookupUri(contactId, lookupKey);
-                    info.name = phonesCursor.getString(PhoneQuery.NAME);
-                    info.type = phonesCursor.getInt(PhoneQuery.PHONE_TYPE);
-                    info.label = phonesCursor.getString(PhoneQuery.LABEL);
-                    info.number = phonesCursor.getString(PhoneQuery.MATCHED_NUMBER);
-                    info.normalizedNumber = phonesCursor.getString(PhoneQuery.NORMALIZED_NUMBER);
-                    info.photoId = phonesCursor.getLong(PhoneQuery.PHOTO_ID);
-                    info.photoUri =
-                            UriUtils.parseUriOrNull(phonesCursor.getString(PhoneQuery.PHOTO_URI));
-                    info.formattedNumber = null;
-                } else {
-                    info = ContactInfo.EMPTY;
-                }
-            } finally {
-                phonesCursor.close();
-            }
-        } else {
-            // Failed to fetch the data, ignore this request.
-            info = null;
-        }
-        return info;
-    }
-
-    /**
-     * Determines the contact information for the given SIP address.
-     * <p>
-     * It returns the contact info if found.
-     * <p>
-     * If no contact corresponds to the given SIP address, returns {@link ContactInfo#EMPTY}.
-     * <p>
-     * If the lookup fails for some other reason, it returns null.
-     */
-    private ContactInfo queryContactInfoForSipAddress(String sipAddress) {
-        final ContactInfo info;
-
-        // "contactNumber" is a SIP address, so use the PhoneLookup table with the SIP parameter.
-        Uri.Builder uriBuilder = PhoneLookup.CONTENT_FILTER_URI.buildUpon();
-        uriBuilder.appendPath(Uri.encode(sipAddress));
-        uriBuilder.appendQueryParameter(PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, "1");
-        return lookupContactFromUri(uriBuilder.build());
-    }
-
-    /**
-     * Determines the contact information for the given phone number.
-     * <p>
-     * It returns the contact info if found.
-     * <p>
-     * If no contact corresponds to the given phone number, returns {@link ContactInfo#EMPTY}.
-     * <p>
-     * If the lookup fails for some other reason, it returns null.
-     */
-    private ContactInfo queryContactInfoForPhoneNumber(String number, String countryIso) {
-        String contactNumber = number;
-        if (!TextUtils.isEmpty(countryIso)) {
-            // Normalize the number: this is needed because the PhoneLookup query below does not
-            // accept a country code as an input.
-            String numberE164 = PhoneNumberUtils.formatNumberToE164(number, countryIso);
-            if (!TextUtils.isEmpty(numberE164)) {
-                // Only use it if the number could be formatted to E164.
-                contactNumber = numberE164;
-            }
-        }
-
-        // The "contactNumber" is a regular phone number, so use the PhoneLookup table.
-        Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(contactNumber));
-        ContactInfo info = lookupContactFromUri(uri);
-        if (info != null && info != ContactInfo.EMPTY) {
-            info.formattedNumber = formatPhoneNumber(number, null, countryIso);
-        }
-        return info;
-    }
-
-    /**
-     * Format the given phone number
-     *
-     * @param number the number to be formatted.
-     * @param normalizedNumber the normalized number of the given number.
-     * @param countryIso the ISO 3166-1 two letters country code, the country's
-     *        convention will be used to format the number if the normalized
-     *        phone is null.
-     *
-     * @return the formatted number, or the given number if it was formatted.
-     */
-    private String formatPhoneNumber(String number, String normalizedNumber,
-            String countryIso) {
-        if (TextUtils.isEmpty(number)) {
-            return "";
-        }
-        // If "number" is really a SIP address, don't try to do any formatting at all.
-        if (PhoneNumberUtils.isUriNumber(number)) {
-            return number;
-        }
-        if (TextUtils.isEmpty(countryIso)) {
-            countryIso = mCurrentCountryIso;
-        }
-        return PhoneNumberUtils.formatNumber(number, normalizedNumber, countryIso);
-    }
-}
diff --git a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
deleted file mode 100644
index cfac1de..0000000
--- a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
+++ /dev/null
@@ -1,340 +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.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.PhoneLookup;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.common.io.MoreCloseables;
-import com.android.contacts.CallDetailActivity;
-import com.android.contacts.R;
-import com.google.common.collect.Maps;
-
-import java.util.Map;
-
-/**
- * Implementation of {@link VoicemailNotifier} that shows a notification in the
- * status bar.
- */
-public class DefaultVoicemailNotifier implements VoicemailNotifier {
-    public static final String TAG = "DefaultVoicemailNotifier";
-
-    /** The tag used to identify notifications from this class. */
-    private static final String NOTIFICATION_TAG = "DefaultVoicemailNotifier";
-    /** The identifier of the notification of new voicemails. */
-    private static final int NOTIFICATION_ID = 1;
-
-    /** The singleton instance of {@link DefaultVoicemailNotifier}. */
-    private static DefaultVoicemailNotifier sInstance;
-
-    private final Context mContext;
-    private final NotificationManager mNotificationManager;
-    private final NewCallsQuery mNewCallsQuery;
-    private final NameLookupQuery mNameLookupQuery;
-    private final PhoneNumberHelper mPhoneNumberHelper;
-
-    /** Returns the singleton instance of the {@link DefaultVoicemailNotifier}. */
-    public static synchronized DefaultVoicemailNotifier getInstance(Context context) {
-        if (sInstance == null) {
-            NotificationManager notificationManager =
-                    (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
-            ContentResolver contentResolver = context.getContentResolver();
-            sInstance = new DefaultVoicemailNotifier(context, notificationManager,
-                    createNewCallsQuery(contentResolver),
-                    createNameLookupQuery(contentResolver),
-                    createPhoneNumberHelper(context));
-        }
-        return sInstance;
-    }
-
-    private DefaultVoicemailNotifier(Context context,
-            NotificationManager notificationManager, NewCallsQuery newCallsQuery,
-            NameLookupQuery nameLookupQuery, PhoneNumberHelper phoneNumberHelper) {
-        mContext = context;
-        mNotificationManager = notificationManager;
-        mNewCallsQuery = newCallsQuery;
-        mNameLookupQuery = nameLookupQuery;
-        mPhoneNumberHelper = phoneNumberHelper;
-    }
-
-    /** Updates the notification and notifies of the call with the given URI. */
-    @Override
-    public void updateNotification(Uri newCallUri) {
-        // Lookup the list of new voicemails to include in the notification.
-        // TODO: Move this into a service, to avoid holding the receiver up.
-        final NewCall[] newCalls = mNewCallsQuery.query();
-
-        if (newCalls == null) {
-            // Query failed, just return.
-            return;
-        }
-
-        if (newCalls.length == 0) {
-            // No voicemails to notify about: clear the notification.
-            clearNotification();
-            return;
-        }
-
-        Resources resources = mContext.getResources();
-
-        // This represents a list of names to include in the notification.
-        String callers = null;
-
-        // Maps each number into a name: if a number is in the map, it has already left a more
-        // recent voicemail.
-        final Map<String, String> names = Maps.newHashMap();
-
-        // Determine the call corresponding to the new voicemail we have to notify about.
-        NewCall callToNotify = null;
-
-        // Iterate over the new voicemails to determine all the information above.
-        for (NewCall newCall : newCalls) {
-            // Check if we already know the name associated with this number.
-            String name = names.get(newCall.number);
-            if (name == null) {
-                // Look it up in the database.
-                name = mNameLookupQuery.query(newCall.number);
-                // If we cannot lookup the contact, use the number instead.
-                if (name == null) {
-                    name = mPhoneNumberHelper.getDisplayNumber(newCall.number, "").toString();
-                    if (TextUtils.isEmpty(name)) {
-                        name = newCall.number;
-                    }
-                }
-                names.put(newCall.number, name);
-                // This is a new caller. Add it to the back of the list of callers.
-                if (TextUtils.isEmpty(callers)) {
-                    callers = name;
-                } else {
-                    callers = resources.getString(
-                            R.string.notification_voicemail_callers_list, callers, name);
-                }
-            }
-            // Check if this is the new call we need to notify about.
-            if (newCallUri != null && newCallUri.equals(newCall.voicemailUri)) {
-                callToNotify = newCall;
-            }
-        }
-
-        if (newCallUri != null && callToNotify == null) {
-            Log.e(TAG, "The new call could not be found in the call log: " + newCallUri);
-        }
-
-        // Determine the title of the notification and the icon for it.
-        final String title = resources.getQuantityString(
-                R.plurals.notification_voicemail_title, newCalls.length, newCalls.length);
-        // TODO: Use the photo of contact if all calls are from the same person.
-        final int icon = android.R.drawable.stat_notify_voicemail;
-
-        Notification.Builder notificationBuilder = new Notification.Builder(mContext)
-                .setSmallIcon(icon)
-                .setContentTitle(title)
-                .setContentText(callers)
-                .setDefaults(callToNotify != null ? Notification.DEFAULT_ALL : 0)
-                .setDeleteIntent(createMarkNewVoicemailsAsOldIntent())
-                .setAutoCancel(true);
-
-        // Determine the intent to fire when the notification is clicked on.
-        final Intent contentIntent;
-        if (newCalls.length == 1) {
-            // Open the voicemail directly.
-            contentIntent = new Intent(mContext, CallDetailActivity.class);
-            contentIntent.setData(newCalls[0].callsUri);
-            contentIntent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
-                    newCalls[0].voicemailUri);
-            Intent playIntent = new Intent(mContext, CallDetailActivity.class);
-            playIntent.setData(newCalls[0].callsUri);
-            playIntent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
-                    newCalls[0].voicemailUri);
-            playIntent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK, true);
-            playIntent.putExtra(CallDetailActivity.EXTRA_FROM_NOTIFICATION, true);
-            notificationBuilder.addAction(R.drawable.ic_play_holo_dark,
-                    resources.getString(R.string.notification_action_voicemail_play),
-                    PendingIntent.getActivity(mContext, 0, playIntent, 0));
-        } else {
-            // Open the call log.
-            contentIntent = new Intent(Intent.ACTION_VIEW, Calls.CONTENT_URI);
-        }
-        notificationBuilder.setContentIntent(
-                PendingIntent.getActivity(mContext, 0, contentIntent, 0));
-
-        // The text to show in the ticker, describing the new event.
-        if (callToNotify != null) {
-            notificationBuilder.setTicker(resources.getString(
-                    R.string.notification_new_voicemail_ticker, names.get(callToNotify.number)));
-        }
-
-        mNotificationManager.notify(NOTIFICATION_TAG, NOTIFICATION_ID, notificationBuilder.build());
-    }
-
-    /** Creates a pending intent that marks all new voicemails as old. */
-    private PendingIntent createMarkNewVoicemailsAsOldIntent() {
-        Intent intent = new Intent(mContext, CallLogNotificationsService.class);
-        intent.setAction(CallLogNotificationsService.ACTION_MARK_NEW_VOICEMAILS_AS_OLD);
-        return PendingIntent.getService(mContext, 0, intent, 0);
-    }
-
-    @Override
-    public void clearNotification() {
-        mNotificationManager.cancel(NOTIFICATION_TAG, NOTIFICATION_ID);
-    }
-
-    /** Information about a new voicemail. */
-    private static final class NewCall {
-        public final Uri callsUri;
-        public final Uri voicemailUri;
-        public final String number;
-
-        public NewCall(Uri callsUri, Uri voicemailUri, String number) {
-            this.callsUri = callsUri;
-            this.voicemailUri = voicemailUri;
-            this.number = number;
-        }
-    }
-
-    /** Allows determining the new calls for which a notification should be generated. */
-    public interface NewCallsQuery {
-        /**
-         * Returns the new calls for which a notification should be generated.
-         */
-        public NewCall[] query();
-    }
-
-    /** Create a new instance of {@link NewCallsQuery}. */
-    public static NewCallsQuery createNewCallsQuery(ContentResolver contentResolver) {
-        return new DefaultNewCallsQuery(contentResolver);
-    }
-
-    /**
-     * Default implementation of {@link NewCallsQuery} that looks up the list of new calls to
-     * notify about in the call log.
-     */
-    private static final class DefaultNewCallsQuery implements NewCallsQuery {
-        private static final String[] PROJECTION = {
-            Calls._ID, Calls.NUMBER, Calls.VOICEMAIL_URI
-        };
-        private static final int ID_COLUMN_INDEX = 0;
-        private static final int NUMBER_COLUMN_INDEX = 1;
-        private static final int VOICEMAIL_URI_COLUMN_INDEX = 2;
-
-        private final ContentResolver mContentResolver;
-
-        private DefaultNewCallsQuery(ContentResolver contentResolver) {
-            mContentResolver = contentResolver;
-        }
-
-        @Override
-        public NewCall[] query() {
-            final String selection = String.format("%s = 1 AND %s = ?", Calls.NEW, Calls.TYPE);
-            final String[] selectionArgs = new String[]{ Integer.toString(Calls.VOICEMAIL_TYPE) };
-            Cursor cursor = null;
-            try {
-                cursor = mContentResolver.query(Calls.CONTENT_URI_WITH_VOICEMAIL, PROJECTION,
-                        selection, selectionArgs, Calls.DEFAULT_SORT_ORDER);
-                if (cursor == null) {
-                    return null;
-                }
-                NewCall[] newCalls = new NewCall[cursor.getCount()];
-                while (cursor.moveToNext()) {
-                    newCalls[cursor.getPosition()] = createNewCallsFromCursor(cursor);
-                }
-                return newCalls;
-            } finally {
-                MoreCloseables.closeQuietly(cursor);
-            }
-        }
-
-        /** Returns an instance of {@link NewCall} created by using the values of the cursor. */
-        private NewCall createNewCallsFromCursor(Cursor cursor) {
-            String voicemailUriString = cursor.getString(VOICEMAIL_URI_COLUMN_INDEX);
-            Uri callsUri = ContentUris.withAppendedId(
-                    Calls.CONTENT_URI_WITH_VOICEMAIL, cursor.getLong(ID_COLUMN_INDEX));
-            Uri voicemailUri = voicemailUriString == null ? null : Uri.parse(voicemailUriString);
-            return new NewCall(callsUri, voicemailUri, cursor.getString(NUMBER_COLUMN_INDEX));
-        }
-    }
-
-    /** Allows determining the name associated with a given phone number. */
-    public interface NameLookupQuery {
-        /**
-         * Returns the name associated with the given number in the contacts database, or null if
-         * the number does not correspond to any of the contacts.
-         * <p>
-         * If there are multiple contacts with the same phone number, it will return the name of one
-         * of the matching contacts.
-         */
-        public String query(String number);
-    }
-
-    /** Create a new instance of {@link NameLookupQuery}. */
-    public static NameLookupQuery createNameLookupQuery(ContentResolver contentResolver) {
-        return new DefaultNameLookupQuery(contentResolver);
-    }
-
-    /**
-     * Default implementation of {@link NameLookupQuery} that looks up the name of a contact in the
-     * contacts database.
-     */
-    private static final class DefaultNameLookupQuery implements NameLookupQuery {
-        private static final String[] PROJECTION = { PhoneLookup.DISPLAY_NAME };
-        private static final int DISPLAY_NAME_COLUMN_INDEX = 0;
-
-        private final ContentResolver mContentResolver;
-
-        private DefaultNameLookupQuery(ContentResolver contentResolver) {
-            mContentResolver = contentResolver;
-        }
-
-        @Override
-        public String query(String number) {
-            Cursor cursor = null;
-            try {
-                cursor = mContentResolver.query(
-                        Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)),
-                        PROJECTION, null, null, null);
-                if (cursor == null || !cursor.moveToFirst()) return null;
-                return cursor.getString(DISPLAY_NAME_COLUMN_INDEX);
-            } finally {
-                if (cursor != null) {
-                    cursor.close();
-                }
-            }
-        }
-    }
-
-    /**
-     * Create a new PhoneNumberHelper.
-     * <p>
-     * This will cause some Disk I/O, at least the first time it is created, so it should not be
-     * called from the main thread.
-     */
-    public static PhoneNumberHelper createPhoneNumberHelper(Context context) {
-        return new PhoneNumberHelper(context.getResources());
-    }
-}
diff --git a/src/com/android/contacts/calllog/ExtendedCursor.java b/src/com/android/contacts/calllog/ExtendedCursor.java
deleted file mode 100644
index 3894192..0000000
--- a/src/com/android/contacts/calllog/ExtendedCursor.java
+++ /dev/null
@@ -1,154 +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.database.AbstractCursor;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.database.DataSetObserver;
-
-import com.android.common.io.MoreCloseables;
-
-/**
- * Wraps a cursor to add an additional column with the same value for all rows.
- * <p>
- * The number of rows in the cursor and the set of columns is determined by the cursor being
- * wrapped.
- */
-public class ExtendedCursor extends AbstractCursor {
-    /** The cursor to wrap. */
-    private final Cursor mCursor;
-    /** The name of the additional column. */
-    private final String mColumnName;
-    /** The value to be assigned to the additional column. */
-    private final Object mValue;
-
-    /**
-     * Creates a new cursor which extends the given cursor by adding a column with a constant value.
-     *
-     * @param cursor the cursor to extend
-     * @param columnName the name of the additional column
-     * @param value the value to be assigned to the additional column
-     */
-    public ExtendedCursor(Cursor cursor, String columnName, Object value) {
-        mCursor = cursor;
-        mColumnName = columnName;
-        mValue = value;
-    }
-
-    @Override
-    public int getCount() {
-        return mCursor.getCount();
-    }
-
-    @Override
-    public String[] getColumnNames() {
-        String[] columnNames = mCursor.getColumnNames();
-        int length = columnNames.length;
-        String[] extendedColumnNames = new String[length + 1];
-        System.arraycopy(columnNames, 0, extendedColumnNames, 0, length);
-        extendedColumnNames[length] = mColumnName;
-        return extendedColumnNames;
-    }
-
-    @Override
-    public String getString(int column) {
-        if (column == mCursor.getColumnCount()) {
-            return (String) mValue;
-        }
-        return mCursor.getString(column);
-    }
-
-    @Override
-    public short getShort(int column) {
-        if (column == mCursor.getColumnCount()) {
-            return (Short) mValue;
-        }
-        return mCursor.getShort(column);
-    }
-
-    @Override
-    public int getInt(int column) {
-        if (column == mCursor.getColumnCount()) {
-            return (Integer) mValue;
-        }
-        return mCursor.getInt(column);
-    }
-
-    @Override
-    public long getLong(int column) {
-        if (column == mCursor.getColumnCount()) {
-            return (Long) mValue;
-        }
-        return mCursor.getLong(column);
-    }
-
-    @Override
-    public float getFloat(int column) {
-        if (column == mCursor.getColumnCount()) {
-            return (Float) mValue;
-        }
-        return mCursor.getFloat(column);
-    }
-
-    @Override
-    public double getDouble(int column) {
-        if (column == mCursor.getColumnCount()) {
-            return (Double) mValue;
-        }
-        return mCursor.getDouble(column);
-    }
-
-    @Override
-    public boolean isNull(int column) {
-        if (column == mCursor.getColumnCount()) {
-            return mValue == null;
-        }
-        return mCursor.isNull(column);
-    }
-
-    @Override
-    public boolean onMove(int oldPosition, int newPosition) {
-        return mCursor.moveToPosition(newPosition);
-    }
-
-    @Override
-    public void close() {
-        MoreCloseables.closeQuietly(mCursor);
-        super.close();
-    }
-
-    @Override
-    public void registerContentObserver(ContentObserver observer) {
-        mCursor.registerContentObserver(observer);
-    }
-
-    @Override
-    public void unregisterContentObserver(ContentObserver observer) {
-        mCursor.unregisterContentObserver(observer);
-    }
-
-    @Override
-    public void registerDataSetObserver(DataSetObserver observer) {
-        mCursor.registerDataSetObserver(observer);
-    }
-
-    @Override
-    public void unregisterDataSetObserver(DataSetObserver observer) {
-        mCursor.unregisterDataSetObserver(observer);
-    }
-}
diff --git a/src/com/android/contacts/calllog/IntentProvider.java b/src/com/android/contacts/calllog/IntentProvider.java
deleted file mode 100644
index 487799c..0000000
--- a/src/com/android/contacts/calllog/IntentProvider.java
+++ /dev/null
@@ -1,102 +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.ContentUris;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.CallLog.Calls;
-
-import com.android.contacts.CallDetailActivity;
-import com.android.contacts.ContactsUtils;
-
-/**
- * Used to create an intent to attach to an action in the call log.
- * <p>
- * The intent is constructed lazily with the given information.
- */
-public abstract class IntentProvider {
-    public abstract Intent getIntent(Context context);
-
-    public static IntentProvider getReturnCallIntentProvider(final String number) {
-        return new IntentProvider() {
-            @Override
-            public Intent getIntent(Context context) {
-                return ContactsUtils.getCallIntent(number);
-            }
-        };
-    }
-
-    public static IntentProvider getPlayVoicemailIntentProvider(final long rowId,
-            final String voicemailUri) {
-        return new IntentProvider() {
-            @Override
-            public Intent getIntent(Context context) {
-                Intent intent = new Intent(context, CallDetailActivity.class);
-                intent.setData(ContentUris.withAppendedId(
-                        Calls.CONTENT_URI_WITH_VOICEMAIL, rowId));
-                if (voicemailUri != null) {
-                    intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
-                            Uri.parse(voicemailUri));
-                }
-                intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK, true);
-                return intent;
-            }
-        };
-    }
-
-    public static IntentProvider getCallDetailIntentProvider(
-            final CallLogAdapter adapter, final int position, final long id, final int groupSize) {
-        return new IntentProvider() {
-            @Override
-            public Intent getIntent(Context context) {
-                Cursor cursor = adapter.getCursor();
-                cursor.moveToPosition(position);
-                if (CallLogQuery.isSectionHeader(cursor)) {
-                    // Do nothing when a header is clicked.
-                    return null;
-                }
-                Intent intent = new Intent(context, CallDetailActivity.class);
-                // Check if the first item is a voicemail.
-                String voicemailUri = cursor.getString(CallLogQuery.VOICEMAIL_URI);
-                if (voicemailUri != null) {
-                    intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
-                            Uri.parse(voicemailUri));
-                }
-                intent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK, false);
-
-                if (groupSize > 1) {
-                    // We want to restore the position in the cursor at the end.
-                    long[] ids = new long[groupSize];
-                    // Copy the ids of the rows in the group.
-                    for (int index = 0; index < groupSize; ++index) {
-                        ids[index] = cursor.getLong(CallLogQuery.ID);
-                        cursor.moveToNext();
-                    }
-                    intent.putExtra(CallDetailActivity.EXTRA_CALL_LOG_IDS, ids);
-                } else {
-                    // If there is a single item, use the direct URI for it.
-                    intent.setData(ContentUris.withAppendedId(
-                            Calls.CONTENT_URI_WITH_VOICEMAIL, id));
-                }
-                return intent;
-            }
-        };
-    }
-}
diff --git a/src/com/android/contacts/calllog/PhoneNumberHelper.java b/src/com/android/contacts/calllog/PhoneNumberHelper.java
deleted file mode 100644
index e24d0ae..0000000
--- a/src/com/android/contacts/calllog/PhoneNumberHelper.java
+++ /dev/null
@@ -1,93 +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;
-import android.telephony.PhoneNumberUtils;
-import android.text.TextUtils;
-
-import com.android.contacts.R;
-import com.android.internal.telephony.CallerInfo;
-
-/**
- * Helper for formatting and managing phone numbers.
- */
-public class PhoneNumberHelper {
-    private final Resources mResources;
-
-    public PhoneNumberHelper(Resources resources) {
-        mResources = resources;
-    }
-
-    /** Returns true if it is possible to place a call to the given number. */
-    public boolean canPlaceCallsTo(CharSequence number) {
-        return !(TextUtils.isEmpty(number)
-                || number.equals(CallerInfo.UNKNOWN_NUMBER)
-                || number.equals(CallerInfo.PRIVATE_NUMBER)
-                || number.equals(CallerInfo.PAYPHONE_NUMBER));
-    }
-
-    /** Returns true if it is possible to send an SMS to the given number. */
-    public boolean canSendSmsTo(CharSequence number) {
-        return canPlaceCallsTo(number) && !isVoicemailNumber(number) && !isSipNumber(number);
-    }
-
-    /**
-     * Returns the string to display for the given phone number.
-     *
-     * @param number the number to display
-     * @param formattedNumber the formatted number if available, may be null
-     */
-    public CharSequence getDisplayNumber(CharSequence number, CharSequence formattedNumber) {
-        if (TextUtils.isEmpty(number)) {
-            return "";
-        }
-        if (number.equals(CallerInfo.UNKNOWN_NUMBER)) {
-            return mResources.getString(R.string.unknown);
-        }
-        if (number.equals(CallerInfo.PRIVATE_NUMBER)) {
-            return mResources.getString(R.string.private_num);
-        }
-        if (number.equals(CallerInfo.PAYPHONE_NUMBER)) {
-            return mResources.getString(R.string.payphone);
-        }
-        if (isVoicemailNumber(number)) {
-            return mResources.getString(R.string.voicemail);
-        }
-        if (TextUtils.isEmpty(formattedNumber)) {
-            return number;
-        } else {
-            return formattedNumber;
-        }
-    }
-
-    /**
-     * Returns true if the given number is the number of the configured voicemail.
-     * To be able to mock-out this, it is not a static method.
-     */
-    public boolean isVoicemailNumber(CharSequence number) {
-        return PhoneNumberUtils.isVoiceMailNumber(number.toString());
-    }
-
-    /**
-     * Returns true if the given number is a SIP address.
-     * To be able to mock-out this, it is not a static method.
-     */
-    public boolean isSipNumber(CharSequence number) {
-        return PhoneNumberUtils.isUriNumber(number.toString());
-    }
-}
diff --git a/src/com/android/contacts/calllog/PhoneQuery.java b/src/com/android/contacts/calllog/PhoneQuery.java
deleted file mode 100644
index af44add..0000000
--- a/src/com/android/contacts/calllog/PhoneQuery.java
+++ /dev/null
@@ -1,45 +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.provider.ContactsContract.PhoneLookup;
-
-/**
- * The query to look up the {@link ContactInfo} for a given number in the Call Log.
- */
-final class PhoneQuery {
-    public static final String[] _PROJECTION = new String[] {
-            PhoneLookup._ID,
-            PhoneLookup.DISPLAY_NAME,
-            PhoneLookup.TYPE,
-            PhoneLookup.LABEL,
-            PhoneLookup.NUMBER,
-            PhoneLookup.NORMALIZED_NUMBER,
-            PhoneLookup.PHOTO_ID,
-            PhoneLookup.LOOKUP_KEY,
-            PhoneLookup.PHOTO_URI};
-
-    public static final int PERSON_ID = 0;
-    public static final int NAME = 1;
-    public static final int PHONE_TYPE = 2;
-    public static final int LABEL = 3;
-    public static final int MATCHED_NUMBER = 4;
-    public static final int NORMALIZED_NUMBER = 5;
-    public static final int PHOTO_ID = 6;
-    public static final int LOOKUP_KEY = 7;
-    public static final int PHOTO_URI = 8;
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/calllog/VoicemailNotifier.java b/src/com/android/contacts/calllog/VoicemailNotifier.java
deleted file mode 100644
index 8d45486..0000000
--- a/src/com/android/contacts/calllog/VoicemailNotifier.java
+++ /dev/null
@@ -1,38 +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.net.Uri;
-
-/**
- * Handles notifications for voicemails.
- */
-public interface VoicemailNotifier {
-    /**
-     * Updates the notification and clears it if there are no new voicemails.
-     * <p>
-     * If the given URI corresponds to a new voicemail, also notifies about it.
-     * <p>
-     * It is not safe to call this method from the main thread.
-     *
-     * @param newCallUri URI of the new call, may be null
-     */
-    public void updateNotification(Uri newCallUri);
-
-    /** Clears the new voicemail notification. */
-    public void clearNotification();
-}
diff --git a/src/com/android/contacts/dialpad/DialpadFragment.java b/src/com/android/contacts/dialpad/DialpadFragment.java
deleted file mode 100644
index 6ba4178..0000000
--- a/src/com/android/contacts/dialpad/DialpadFragment.java
+++ /dev/null
@@ -1,1629 +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.dialpad;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.Fragment;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.media.AudioManager;
-import android.media.ToneGenerator;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.provider.Contacts.Intents.Insert;
-import android.provider.Contacts.People;
-import android.provider.Contacts.Phones;
-import android.provider.Contacts.PhonesColumns;
-import android.provider.Settings;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.PhoneStateListener;
-import android.telephony.TelephonyManager;
-import android.text.Editable;
-import android.text.SpannableString;
-import android.text.TextUtils;
-import android.text.TextWatcher;
-import android.text.method.DialerKeyListener;
-import android.text.style.RelativeSizeSpan;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.PopupMenu;
-import android.widget.TextView;
-
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.SpecialCharSequenceMgr;
-import com.android.contacts.activities.DialtactsActivity;
-import com.android.contacts.util.Constants;
-import com.android.contacts.util.PhoneNumberFormatter;
-import com.android.contacts.util.StopWatch;
-import com.android.internal.telephony.ITelephony;
-import com.android.phone.CallLogAsync;
-import com.android.phone.HapticFeedback;
-
-/**
- * Fragment that displays a twelve-key phone dialpad.
- */
-public class DialpadFragment extends Fragment
-        implements View.OnClickListener,
-        View.OnLongClickListener, View.OnKeyListener,
-        AdapterView.OnItemClickListener, TextWatcher,
-        PopupMenu.OnMenuItemClickListener,
-        DialpadImageButton.OnPressedListener {
-    private static final String TAG = DialpadFragment.class.getSimpleName();
-
-    private static final boolean DEBUG = DialtactsActivity.DEBUG;
-
-    private static final String EMPTY_NUMBER = "";
-
-    /** The length of DTMF tones in milliseconds */
-    private static final int TONE_LENGTH_MS = 150;
-    private static final int TONE_LENGTH_INFINITE = -1;
-
-    /** The DTMF tone volume relative to other sounds in the stream */
-    private static final int TONE_RELATIVE_VOLUME = 80;
-
-    /** Stream type used to play the DTMF tones off call, and mapped to the volume control keys */
-    private static final int DIAL_TONE_STREAM_TYPE = AudioManager.STREAM_DTMF;
-
-    /**
-     * View (usually FrameLayout) containing mDigits field. This can be null, in which mDigits
-     * isn't enclosed by the container.
-     */
-    private View mDigitsContainer;
-    private EditText mDigits;
-
-    /** Remembers if we need to clear digits field when the screen is completely gone. */
-    private boolean mClearDigitsOnStop;
-
-    private View mDelete;
-    private ToneGenerator mToneGenerator;
-    private final Object mToneGeneratorLock = new Object();
-    private View mDialpad;
-    /**
-     * Remembers the number of dialpad buttons which are pressed at this moment.
-     * If it becomes 0, meaning no buttons are pressed, we'll call
-     * {@link ToneGenerator#stopTone()}; the method shouldn't be called unless the last key is
-     * released.
-     */
-    private int mDialpadPressCount;
-
-    private View mDialButtonContainer;
-    private View mDialButton;
-    private ListView mDialpadChooser;
-    private DialpadChooserAdapter mDialpadChooserAdapter;
-
-    /**
-     * Regular expression prohibiting manual phone call. Can be empty, which means "no rule".
-     */
-    private String mProhibitedPhoneNumberRegexp;
-
-
-    // Last number dialed, retrieved asynchronously from the call DB
-    // in onCreate. This number is displayed when the user hits the
-    // send key and cleared in onPause.
-    private final CallLogAsync mCallLog = new CallLogAsync();
-    private String mLastNumberDialed = EMPTY_NUMBER;
-
-    // determines if we want to playback local DTMF tones.
-    private boolean mDTMFToneEnabled;
-
-    // Vibration (haptic feedback) for dialer key presses.
-    private final HapticFeedback mHaptic = new HapticFeedback();
-
-    /** Identifier for the "Add Call" intent extra. */
-    private static final String ADD_CALL_MODE_KEY = "add_call_mode";
-
-    /**
-     * Identifier for intent extra for sending an empty Flash message for
-     * CDMA networks. This message is used by the network to simulate a
-     * press/depress of the "hookswitch" of a landline phone. Aka "empty flash".
-     *
-     * TODO: Using an intent extra to tell the phone to send this flash is a
-     * temporary measure. To be replaced with an ITelephony call in the future.
-     * TODO: Keep in sync with the string defined in OutgoingCallBroadcaster.java
-     * in Phone app until this is replaced with the ITelephony API.
-     */
-    private static final String EXTRA_SEND_EMPTY_FLASH
-            = "com.android.phone.extra.SEND_EMPTY_FLASH";
-
-    private String mCurrentCountryIso;
-
-    private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
-        /**
-         * Listen for phone state changes so that we can take down the
-         * "dialpad chooser" if the phone becomes idle while the
-         * chooser UI is visible.
-         */
-        @Override
-        public void onCallStateChanged(int state, String incomingNumber) {
-            // Log.i(TAG, "PhoneStateListener.onCallStateChanged: "
-            //       + state + ", '" + incomingNumber + "'");
-            if ((state == TelephonyManager.CALL_STATE_IDLE) && dialpadChooserVisible()) {
-                // Log.i(TAG, "Call ended with dialpad chooser visible!  Taking it down...");
-                // Note there's a race condition in the UI here: the
-                // dialpad chooser could conceivably disappear (on its
-                // own) at the exact moment the user was trying to select
-                // one of the choices, which would be confusing.  (But at
-                // least that's better than leaving the dialpad chooser
-                // onscreen, but useless...)
-                showDialpadChooser(false);
-            }
-        }
-    };
-
-    private boolean mWasEmptyBeforeTextChange;
-
-    /**
-     * This field is set to true while processing an incoming DIAL intent, in order to make sure
-     * that SpecialCharSequenceMgr actions can be triggered by user input but *not* by a
-     * tel: URI passed by some other app.  It will be set to false when all digits are cleared.
-     */
-    private boolean mDigitsFilledByIntent;
-
-    private static final String PREF_DIGITS_FILLED_BY_INTENT = "pref_digits_filled_by_intent";
-
-    @Override
-    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
-        mWasEmptyBeforeTextChange = TextUtils.isEmpty(s);
-    }
-
-    @Override
-    public void onTextChanged(CharSequence input, int start, int before, int changeCount) {
-        if (mWasEmptyBeforeTextChange != TextUtils.isEmpty(input)) {
-            final Activity activity = getActivity();
-            if (activity != null) {
-                activity.invalidateOptionsMenu();
-            }
-        }
-
-        // DTMF Tones do not need to be played here any longer -
-        // the DTMF dialer handles that functionality now.
-    }
-
-    @Override
-    public void afterTextChanged(Editable input) {
-        // When DTMF dialpad buttons are being pressed, we delay SpecialCharSequencMgr sequence,
-        // since some of SpecialCharSequenceMgr's behavior is too abrupt for the "touch-down"
-        // behavior.
-        if (!mDigitsFilledByIntent &&
-                SpecialCharSequenceMgr.handleChars(getActivity(), input.toString(), mDigits)) {
-            // A special sequence was entered, clear the digits
-            mDigits.getText().clear();
-        }
-
-        if (isDigitsEmpty()) {
-            mDigitsFilledByIntent = false;
-            mDigits.setCursorVisible(false);
-        }
-
-        updateDialAndDeleteButtonEnabledState();
-    }
-
-    @Override
-    public void onCreate(Bundle state) {
-        super.onCreate(state);
-
-        mCurrentCountryIso = ContactsUtils.getCurrentCountryIso(getActivity());
-
-        try {
-            mHaptic.init(getActivity(),
-                         getResources().getBoolean(R.bool.config_enable_dialer_key_vibration));
-        } catch (Resources.NotFoundException nfe) {
-             Log.e(TAG, "Vibrate control bool missing.", nfe);
-        }
-
-        setHasOptionsMenu(true);
-
-        mProhibitedPhoneNumberRegexp = getResources().getString(
-                R.string.config_prohibited_phone_number_regexp);
-
-        if (state != null) {
-            mDigitsFilledByIntent = state.getBoolean(PREF_DIGITS_FILLED_BY_INTENT);
-        }
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        View fragmentView = inflater.inflate(R.layout.dialpad_fragment, container, false);
-
-        // Load up the resources for the text field.
-        Resources r = getResources();
-
-        mDigitsContainer = fragmentView.findViewById(R.id.digits_container);
-        mDigits = (EditText) fragmentView.findViewById(R.id.digits);
-        mDigits.setKeyListener(DialerKeyListener.getInstance());
-        mDigits.setOnClickListener(this);
-        mDigits.setOnKeyListener(this);
-        mDigits.setOnLongClickListener(this);
-        mDigits.addTextChangedListener(this);
-
-        PhoneNumberFormatter.setPhoneNumberFormattingTextWatcher(getActivity(), mDigits);
-
-        // Check for the presence of the keypad
-        View oneButton = fragmentView.findViewById(R.id.one);
-        if (oneButton != null) {
-            setupKeypad(fragmentView);
-        }
-
-        DisplayMetrics dm = getResources().getDisplayMetrics();
-        int minCellSize = (int) (56 * dm.density); // 56dip == minimum size of menu buttons
-        int cellCount = dm.widthPixels / minCellSize;
-        int fakeMenuItemWidth = dm.widthPixels / cellCount;
-        mDialButtonContainer = fragmentView.findViewById(R.id.dialButtonContainer);
-        // If in portrait, add padding to the dial button since we need space for the
-        // search and menu/overflow buttons.
-        if (mDialButtonContainer != null && !ContactsUtils.isLandscape(this.getActivity())) {
-            mDialButtonContainer.setPadding(
-                    fakeMenuItemWidth, mDialButtonContainer.getPaddingTop(),
-                    fakeMenuItemWidth, mDialButtonContainer.getPaddingBottom());
-        }
-        mDialButton = fragmentView.findViewById(R.id.dialButton);
-        if (r.getBoolean(R.bool.config_show_onscreen_dial_button)) {
-            mDialButton.setOnClickListener(this);
-            mDialButton.setOnLongClickListener(this);
-        } else {
-            mDialButton.setVisibility(View.GONE); // It's VISIBLE by default
-            mDialButton = null;
-        }
-
-        mDelete = fragmentView.findViewById(R.id.deleteButton);
-        if (mDelete != null) {
-            mDelete.setOnClickListener(this);
-            mDelete.setOnLongClickListener(this);
-        }
-
-        mDialpad = fragmentView.findViewById(R.id.dialpad);  // This is null in landscape mode.
-
-        // In landscape we put the keyboard in phone mode.
-        if (null == mDialpad) {
-            mDigits.setInputType(android.text.InputType.TYPE_CLASS_PHONE);
-        } else {
-            mDigits.setCursorVisible(false);
-        }
-
-        // Set up the "dialpad chooser" UI; see showDialpadChooser().
-        mDialpadChooser = (ListView) fragmentView.findViewById(R.id.dialpadChooser);
-        mDialpadChooser.setOnItemClickListener(this);
-
-        configureScreenFromIntent(getActivity().getIntent());
-
-        return fragmentView;
-    }
-
-    private boolean isLayoutReady() {
-        return mDigits != null;
-    }
-
-    public EditText getDigitsWidget() {
-        return mDigits;
-    }
-
-    /**
-     * @return true when {@link #mDigits} is actually filled by the Intent.
-     */
-    private boolean fillDigitsIfNecessary(Intent intent) {
-        final String action = intent.getAction();
-        if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
-            Uri uri = intent.getData();
-            if (uri != null) {
-                if (Constants.SCHEME_TEL.equals(uri.getScheme())) {
-                    // Put the requested number into the input area
-                    String data = uri.getSchemeSpecificPart();
-                    // Remember it is filled via Intent.
-                    mDigitsFilledByIntent = true;
-                    setFormattedDigits(data, null);
-                    return true;
-                } else {
-                    String type = intent.getType();
-                    if (People.CONTENT_ITEM_TYPE.equals(type)
-                            || Phones.CONTENT_ITEM_TYPE.equals(type)) {
-                        // Query the phone number
-                        Cursor c = getActivity().getContentResolver().query(intent.getData(),
-                                new String[] {PhonesColumns.NUMBER, PhonesColumns.NUMBER_KEY},
-                                null, null, null);
-                        if (c != null) {
-                            try {
-                                if (c.moveToFirst()) {
-                                    // Remember it is filled via Intent.
-                                    mDigitsFilledByIntent = true;
-                                    // Put the number into the input area
-                                    setFormattedDigits(c.getString(0), c.getString(1));
-                                    return true;
-                                }
-                            } finally {
-                                c.close();
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * @see #showDialpadChooser(boolean)
-     */
-    private static boolean needToShowDialpadChooser(Intent intent, boolean isAddCallMode) {
-        final String action = intent.getAction();
-
-        boolean needToShowDialpadChooser = false;
-
-        if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
-            Uri uri = intent.getData();
-            if (uri == null) {
-                // ACTION_DIAL or ACTION_VIEW with no data.
-                // This behaves basically like ACTION_MAIN: If there's
-                // already an active call, bring up an intermediate UI to
-                // make the user confirm what they really want to do.
-                // Be sure *not* to show the dialpad chooser if this is an
-                // explicit "Add call" action, though.
-                if (!isAddCallMode && phoneIsInUse()) {
-                    needToShowDialpadChooser = true;
-                }
-            }
-        } else if (Intent.ACTION_MAIN.equals(action)) {
-            // The MAIN action means we're bringing up a blank dialer
-            // (e.g. by selecting the Home shortcut, or tabbing over from
-            // Contacts or Call log.)
-            //
-            // At this point, IF there's already an active call, there's a
-            // good chance that the user got here accidentally (but really
-            // wanted the in-call dialpad instead).  So we bring up an
-            // intermediate UI to make the user confirm what they really
-            // want to do.
-            if (phoneIsInUse()) {
-                // Log.i(TAG, "resolveIntent(): phone is in use; showing dialpad chooser!");
-                needToShowDialpadChooser = true;
-            }
-        }
-
-        return needToShowDialpadChooser;
-    }
-
-    private static boolean isAddCallMode(Intent intent) {
-        final String action = intent.getAction();
-        if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
-            // see if we are "adding a call" from the InCallScreen; false by default.
-            return intent.getBooleanExtra(ADD_CALL_MODE_KEY, false);
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Checks the given Intent and changes dialpad's UI state. For example, if the Intent requires
-     * the screen to enter "Add Call" mode, this method will show correct UI for the mode.
-     */
-    public void configureScreenFromIntent(Intent intent) {
-        if (!isLayoutReady()) {
-            // This happens typically when parent's Activity#onNewIntent() is called while
-            // Fragment#onCreateView() isn't called yet, and thus we cannot configure Views at
-            // this point. onViewCreate() should call this method after preparing layouts, so
-            // just ignore this call now.
-            Log.i(TAG,
-                    "Screen configuration is requested before onCreateView() is called. Ignored");
-            return;
-        }
-
-        boolean needToShowDialpadChooser = false;
-
-        final boolean isAddCallMode = isAddCallMode(intent);
-        if (!isAddCallMode) {
-            final boolean digitsFilled = fillDigitsIfNecessary(intent);
-            if (!digitsFilled) {
-                needToShowDialpadChooser = needToShowDialpadChooser(intent, isAddCallMode);
-            }
-        }
-        showDialpadChooser(needToShowDialpadChooser);
-    }
-
-    /**
-     * Sets formatted digits to digits field.
-     */
-    private void setFormattedDigits(String data, String normalizedNumber) {
-        // strip the non-dialable numbers out of the data string.
-        String dialString = PhoneNumberUtils.extractNetworkPortion(data);
-        dialString =
-                PhoneNumberUtils.formatNumber(dialString, normalizedNumber, mCurrentCountryIso);
-        if (!TextUtils.isEmpty(dialString)) {
-            Editable digits = mDigits.getText();
-            digits.replace(0, digits.length(), dialString);
-            // for some reason this isn't getting called in the digits.replace call above..
-            // but in any case, this will make sure the background drawable looks right
-            afterTextChanged(digits);
-        }
-    }
-
-    private void setupKeypad(View fragmentView) {
-        int[] buttonIds = new int[] { R.id.one, R.id.two, R.id.three, R.id.four, R.id.five,
-                R.id.six, R.id.seven, R.id.eight, R.id.nine, R.id.zero, R.id.star, R.id.pound};
-        for (int id : buttonIds) {
-            ((DialpadImageButton) fragmentView.findViewById(id)).setOnPressedListener(this);
-        }
-
-        // Long-pressing one button will initiate Voicemail.
-        fragmentView.findViewById(R.id.one).setOnLongClickListener(this);
-
-        // Long-pressing zero button will enter '+' instead.
-        fragmentView.findViewById(R.id.zero).setOnLongClickListener(this);
-
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        final StopWatch stopWatch = StopWatch.start("Dialpad.onResume");
-
-        // Query the last dialed number. Do it first because hitting
-        // the DB is 'slow'. This call is asynchronous.
-        queryLastOutgoingCall();
-
-        stopWatch.lap("qloc");
-
-        // retrieve the DTMF tone play back setting.
-        mDTMFToneEnabled = Settings.System.getInt(getActivity().getContentResolver(),
-                Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
-
-        stopWatch.lap("dtwd");
-
-        // Retrieve the haptic feedback setting.
-        mHaptic.checkSystemSetting();
-
-        stopWatch.lap("hptc");
-
-        // if the mToneGenerator creation fails, just continue without it.  It is
-        // a local audio signal, and is not as important as the dtmf tone itself.
-        synchronized (mToneGeneratorLock) {
-            if (mToneGenerator == null) {
-                try {
-                    mToneGenerator = new ToneGenerator(DIAL_TONE_STREAM_TYPE, TONE_RELATIVE_VOLUME);
-                } catch (RuntimeException e) {
-                    Log.w(TAG, "Exception caught while creating local tone generator: " + e);
-                    mToneGenerator = null;
-                }
-            }
-        }
-        stopWatch.lap("tg");
-        // Prevent unnecessary confusion. Reset the press count anyway.
-        mDialpadPressCount = 0;
-
-        Activity parent = getActivity();
-        if (parent instanceof DialtactsActivity) {
-            // See if we were invoked with a DIAL intent. If we were, fill in the appropriate
-            // digits in the dialer field.
-            fillDigitsIfNecessary(parent.getIntent());
-        }
-
-        stopWatch.lap("fdin");
-
-        // While we're in the foreground, listen for phone state changes,
-        // purely so that we can take down the "dialpad chooser" if the
-        // phone becomes idle while the chooser UI is visible.
-        TelephonyManager telephonyManager =
-                (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
-        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
-
-        stopWatch.lap("tm");
-
-        // Potentially show hint text in the mDigits field when the user
-        // hasn't typed any digits yet.  (If there's already an active call,
-        // this hint text will remind the user that he's about to add a new
-        // call.)
-        //
-        // TODO: consider adding better UI for the case where *both* lines
-        // are currently in use.  (Right now we let the user try to add
-        // another call, but that call is guaranteed to fail.  Perhaps the
-        // entire dialer UI should be disabled instead.)
-        if (phoneIsInUse()) {
-            final SpannableString hint = new SpannableString(
-                    getActivity().getString(R.string.dialerDialpadHintText));
-            hint.setSpan(new RelativeSizeSpan(0.8f), 0, hint.length(), 0);
-            mDigits.setHint(hint);
-        } else {
-            // Common case; no hint necessary.
-            mDigits.setHint(null);
-
-            // Also, a sanity-check: the "dialpad chooser" UI should NEVER
-            // be visible if the phone is idle!
-            showDialpadChooser(false);
-        }
-
-        stopWatch.lap("hnt");
-
-        updateDialAndDeleteButtonEnabledState();
-
-        stopWatch.lap("bes");
-
-        stopWatch.stopAndLog(TAG, 50);
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-
-        // Stop listening for phone state changes.
-        TelephonyManager telephonyManager =
-                (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
-        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
-
-        // Make sure we don't leave this activity with a tone still playing.
-        stopTone();
-        // Just in case reset the counter too.
-        mDialpadPressCount = 0;
-
-        synchronized (mToneGeneratorLock) {
-            if (mToneGenerator != null) {
-                mToneGenerator.release();
-                mToneGenerator = null;
-            }
-        }
-        // TODO: I wonder if we should not check if the AsyncTask that
-        // lookup the last dialed number has completed.
-        mLastNumberDialed = EMPTY_NUMBER;  // Since we are going to query again, free stale number.
-
-        SpecialCharSequenceMgr.cleanup();
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-        if (mClearDigitsOnStop) {
-            mClearDigitsOnStop = false;
-            mDigits.getText().clear();
-        }
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putBoolean(PREF_DIGITS_FILLED_BY_INTENT, mDigitsFilledByIntent);
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        super.onCreateOptionsMenu(menu, inflater);
-        // Landscape dialer uses the real actionbar menu, whereas portrait uses a fake one
-        // that is created using constructPopupMenu()
-        if (ContactsUtils.isLandscape(this.getActivity()) ||
-                ViewConfiguration.get(getActivity()).hasPermanentMenuKey() &&
-                isLayoutReady() && mDialpadChooser != null) {
-            inflater.inflate(R.menu.dialpad_options, menu);
-        }
-    }
-
-    @Override
-    public void onPrepareOptionsMenu(Menu menu) {
-        // Hardware menu key should be available and Views should already be ready.
-        if (ContactsUtils.isLandscape(this.getActivity()) ||
-                ViewConfiguration.get(getActivity()).hasPermanentMenuKey() &&
-                isLayoutReady() && mDialpadChooser != null) {
-            setupMenuItems(menu);
-        }
-    }
-
-    private void setupMenuItems(Menu menu) {
-        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings_dialpad);
-        final MenuItem addToContactMenuItem = menu.findItem(R.id.menu_add_contacts);
-        final MenuItem twoSecPauseMenuItem = menu.findItem(R.id.menu_2s_pause);
-        final MenuItem waitMenuItem = menu.findItem(R.id.menu_add_wait);
-
-        // Check if all the menu items are inflated correctly. As a shortcut, we assume all menu
-        // items are ready if the first item is non-null.
-        if (callSettingsMenuItem == null) {
-            return;
-        }
-
-        final Activity activity = getActivity();
-        if (activity != null && ViewConfiguration.get(activity).hasPermanentMenuKey()) {
-            // Call settings should be available via its parent Activity.
-            callSettingsMenuItem.setVisible(false);
-        } else {
-            callSettingsMenuItem.setVisible(true);
-            callSettingsMenuItem.setIntent(DialtactsActivity.getCallSettingsIntent());
-        }
-
-        // We show "add to contacts", "2sec pause", and "add wait" menus only when the user is
-        // seeing usual dialpads and has typed at least one digit.
-        // We never show a menu if the "choose dialpad" UI is up.
-        if (dialpadChooserVisible() || isDigitsEmpty()) {
-            addToContactMenuItem.setVisible(false);
-            twoSecPauseMenuItem.setVisible(false);
-            waitMenuItem.setVisible(false);
-        } else {
-            final CharSequence digits = mDigits.getText();
-
-            // Put the current digits string into an intent
-            addToContactMenuItem.setIntent(getAddToContactIntent(digits));
-            addToContactMenuItem.setVisible(true);
-
-            // Check out whether to show Pause & Wait option menu items
-            int selectionStart;
-            int selectionEnd;
-            String strDigits = digits.toString();
-
-            selectionStart = mDigits.getSelectionStart();
-            selectionEnd = mDigits.getSelectionEnd();
-
-            if (selectionStart != -1) {
-                if (selectionStart > selectionEnd) {
-                    // swap it as we want start to be less then end
-                    int tmp = selectionStart;
-                    selectionStart = selectionEnd;
-                    selectionEnd = tmp;
-                }
-
-                if (selectionStart != 0) {
-                    // Pause can be visible if cursor is not in the begining
-                    twoSecPauseMenuItem.setVisible(true);
-
-                    // For Wait to be visible set of condition to meet
-                    waitMenuItem.setVisible(showWait(selectionStart, selectionEnd, strDigits));
-                } else {
-                    // cursor in the beginning both pause and wait to be invisible
-                    twoSecPauseMenuItem.setVisible(false);
-                    waitMenuItem.setVisible(false);
-                }
-            } else {
-                twoSecPauseMenuItem.setVisible(true);
-
-                // cursor is not selected so assume new digit is added to the end
-                int strLength = strDigits.length();
-                waitMenuItem.setVisible(showWait(strLength, strLength, strDigits));
-            }
-        }
-    }
-
-    private static Intent getAddToContactIntent(CharSequence digits) {
-        final Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
-        intent.putExtra(Insert.PHONE, digits);
-        intent.setType(People.CONTENT_ITEM_TYPE);
-        return intent;
-    }
-
-    private void keyPressed(int keyCode) {
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_1:
-                playTone(ToneGenerator.TONE_DTMF_1, TONE_LENGTH_INFINITE);
-                break;
-            case KeyEvent.KEYCODE_2:
-                playTone(ToneGenerator.TONE_DTMF_2, TONE_LENGTH_INFINITE);
-                break;
-            case KeyEvent.KEYCODE_3:
-                playTone(ToneGenerator.TONE_DTMF_3, TONE_LENGTH_INFINITE);
-                break;
-            case KeyEvent.KEYCODE_4:
-                playTone(ToneGenerator.TONE_DTMF_4, TONE_LENGTH_INFINITE);
-                break;
-            case KeyEvent.KEYCODE_5:
-                playTone(ToneGenerator.TONE_DTMF_5, TONE_LENGTH_INFINITE);
-                break;
-            case KeyEvent.KEYCODE_6:
-                playTone(ToneGenerator.TONE_DTMF_6, TONE_LENGTH_INFINITE);
-                break;
-            case KeyEvent.KEYCODE_7:
-                playTone(ToneGenerator.TONE_DTMF_7, TONE_LENGTH_INFINITE);
-                break;
-            case KeyEvent.KEYCODE_8:
-                playTone(ToneGenerator.TONE_DTMF_8, TONE_LENGTH_INFINITE);
-                break;
-            case KeyEvent.KEYCODE_9:
-                playTone(ToneGenerator.TONE_DTMF_9, TONE_LENGTH_INFINITE);
-                break;
-            case KeyEvent.KEYCODE_0:
-                playTone(ToneGenerator.TONE_DTMF_0, TONE_LENGTH_INFINITE);
-                break;
-            case KeyEvent.KEYCODE_POUND:
-                playTone(ToneGenerator.TONE_DTMF_P, TONE_LENGTH_INFINITE);
-                break;
-            case KeyEvent.KEYCODE_STAR:
-                playTone(ToneGenerator.TONE_DTMF_S, TONE_LENGTH_INFINITE);
-                break;
-            default:
-                break;
-        }
-
-        mHaptic.vibrate();
-        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
-        mDigits.onKeyDown(keyCode, event);
-
-        // If the cursor is at the end of the text we hide it.
-        final int length = mDigits.length();
-        if (length == mDigits.getSelectionStart() && length == mDigits.getSelectionEnd()) {
-            mDigits.setCursorVisible(false);
-        }
-    }
-
-    @Override
-    public boolean onKey(View view, int keyCode, KeyEvent event) {
-        switch (view.getId()) {
-            case R.id.digits:
-                if (keyCode == KeyEvent.KEYCODE_ENTER) {
-                    dialButtonPressed();
-                    return true;
-                }
-                break;
-        }
-        return false;
-    }
-
-    /**
-     * When a key is pressed, we start playing DTMF tone, do vibration, and enter the digit
-     * immediately. When a key is released, we stop the tone. Note that the "key press" event will
-     * be delivered by the system with certain amount of delay, it won't be synced with user's
-     * actual "touch-down" behavior.
-     */
-    @Override
-    public void onPressed(View view, boolean pressed) {
-        if (DEBUG) Log.d(TAG, "onPressed(). view: " + view + ", pressed: " + pressed);
-        if (pressed) {
-            switch (view.getId()) {
-                case R.id.one: {
-                    keyPressed(KeyEvent.KEYCODE_1);
-                    break;
-                }
-                case R.id.two: {
-                    keyPressed(KeyEvent.KEYCODE_2);
-                    break;
-                }
-                case R.id.three: {
-                    keyPressed(KeyEvent.KEYCODE_3);
-                    break;
-                }
-                case R.id.four: {
-                    keyPressed(KeyEvent.KEYCODE_4);
-                    break;
-                }
-                case R.id.five: {
-                    keyPressed(KeyEvent.KEYCODE_5);
-                    break;
-                }
-                case R.id.six: {
-                    keyPressed(KeyEvent.KEYCODE_6);
-                    break;
-                }
-                case R.id.seven: {
-                    keyPressed(KeyEvent.KEYCODE_7);
-                    break;
-                }
-                case R.id.eight: {
-                    keyPressed(KeyEvent.KEYCODE_8);
-                    break;
-                }
-                case R.id.nine: {
-                    keyPressed(KeyEvent.KEYCODE_9);
-                    break;
-                }
-                case R.id.zero: {
-                    keyPressed(KeyEvent.KEYCODE_0);
-                    break;
-                }
-                case R.id.pound: {
-                    keyPressed(KeyEvent.KEYCODE_POUND);
-                    break;
-                }
-                case R.id.star: {
-                    keyPressed(KeyEvent.KEYCODE_STAR);
-                    break;
-                }
-                default: {
-                    Log.wtf(TAG, "Unexpected onTouch(ACTION_DOWN) event from: " + view);
-                    break;
-                }
-            }
-            mDialpadPressCount++;
-        } else {
-            view.jumpDrawablesToCurrentState();
-            mDialpadPressCount--;
-            if (mDialpadPressCount < 0) {
-                // e.g.
-                // - when the user action is detected as horizontal swipe, at which only
-                //   "up" event is thrown.
-                // - when the user long-press '0' button, at which dialpad will decrease this count
-                //   while it still gets press-up event here.
-                if (DEBUG) Log.d(TAG, "mKeyPressCount become negative.");
-                stopTone();
-                mDialpadPressCount = 0;
-            } else if (mDialpadPressCount == 0) {
-                stopTone();
-            }
-        }
-    }
-
-    @Override
-    public void onClick(View view) {
-        switch (view.getId()) {
-            case R.id.deleteButton: {
-                keyPressed(KeyEvent.KEYCODE_DEL);
-                return;
-            }
-            case R.id.dialButton: {
-                mHaptic.vibrate();  // Vibrate here too, just like we do for the regular keys
-                dialButtonPressed();
-                return;
-            }
-            case R.id.digits: {
-                if (!isDigitsEmpty()) {
-                    mDigits.setCursorVisible(true);
-                }
-                return;
-            }
-            default: {
-                Log.wtf(TAG, "Unexpected onClick() event from: " + view);
-                return;
-            }
-        }
-    }
-
-    public PopupMenu constructPopupMenu(View anchorView) {
-        final Context context = getActivity();
-        if (context == null) {
-            return null;
-        }
-        final PopupMenu popupMenu = new PopupMenu(context, anchorView);
-        final Menu menu = popupMenu.getMenu();
-        popupMenu.inflate(R.menu.dialpad_options);
-        popupMenu.setOnMenuItemClickListener(this);
-        setupMenuItems(menu);
-        return popupMenu;
-    }
-
-    @Override
-    public boolean onLongClick(View view) {
-        final Editable digits = mDigits.getText();
-        final int id = view.getId();
-        switch (id) {
-            case R.id.deleteButton: {
-                digits.clear();
-                // TODO: The framework forgets to clear the pressed
-                // status of disabled button. Until this is fixed,
-                // clear manually the pressed status. b/2133127
-                mDelete.setPressed(false);
-                return true;
-            }
-            case R.id.one: {
-                // '1' may be already entered since we rely on onTouch() event for numeric buttons.
-                // Just for safety we also check if the digits field is empty or not.
-                if (isDigitsEmpty() || TextUtils.equals(mDigits.getText(), "1")) {
-                    // We'll try to initiate voicemail and thus we want to remove irrelevant string.
-                    removePreviousDigitIfPossible();
-
-                    if (isVoicemailAvailable()) {
-                        callVoicemail();
-                    } else if (getActivity() != null) {
-                        // Voicemail is unavailable maybe because Airplane mode is turned on.
-                        // Check the current status and show the most appropriate error message.
-                        final boolean isAirplaneModeOn =
-                                Settings.System.getInt(getActivity().getContentResolver(),
-                                Settings.System.AIRPLANE_MODE_ON, 0) != 0;
-                        if (isAirplaneModeOn) {
-                            DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
-                                    R.string.dialog_voicemail_airplane_mode_message);
-                            dialogFragment.show(getFragmentManager(),
-                                    "voicemail_request_during_airplane_mode");
-                        } else {
-                            DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
-                                    R.string.dialog_voicemail_not_ready_message);
-                            dialogFragment.show(getFragmentManager(), "voicemail_not_ready");
-                        }
-                    }
-                    return true;
-                }
-                return false;
-            }
-            case R.id.zero: {
-                // Remove tentative input ('0') done by onTouch().
-                removePreviousDigitIfPossible();
-                keyPressed(KeyEvent.KEYCODE_PLUS);
-
-                // Stop tone immediately and decrease the press count, so that possible subsequent
-                // dial button presses won't honor the 0 click any more.
-                // Note: this *will* make mDialpadPressCount negative when the 0 key is released,
-                // which should be handled appropriately.
-                stopTone();
-                if (mDialpadPressCount > 0) mDialpadPressCount--;
-
-                return true;
-            }
-            case R.id.digits: {
-                // Right now EditText does not show the "paste" option when cursor is not visible.
-                // To show that, make the cursor visible, and return false, letting the EditText
-                // show the option by itself.
-                mDigits.setCursorVisible(true);
-                return false;
-            }
-            case R.id.dialButton: {
-                if (isDigitsEmpty()) {
-                    handleDialButtonClickWithEmptyDigits();
-                    // This event should be consumed so that onClick() won't do the exactly same
-                    // thing.
-                    return true;
-                } else {
-                    return false;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Remove the digit just before the current position. This can be used if we want to replace
-     * the previous digit or cancel previously entered character.
-     */
-    private void removePreviousDigitIfPossible() {
-        final Editable editable = mDigits.getText();
-        final int currentPosition = mDigits.getSelectionStart();
-        if (currentPosition > 0) {
-            mDigits.setSelection(currentPosition);
-            mDigits.getText().delete(currentPosition - 1, currentPosition);
-        }
-    }
-
-    public void callVoicemail() {
-        startActivity(ContactsUtils.getVoicemailIntent());
-        mClearDigitsOnStop = true;
-        getActivity().finish();
-    }
-
-    public static class ErrorDialogFragment extends DialogFragment {
-        private int mTitleResId;
-        private int mMessageResId;
-
-        private static final String ARG_TITLE_RES_ID = "argTitleResId";
-        private static final String ARG_MESSAGE_RES_ID = "argMessageResId";
-
-        public static ErrorDialogFragment newInstance(int messageResId) {
-            return newInstance(0, messageResId);
-        }
-
-        public static ErrorDialogFragment newInstance(int titleResId, int messageResId) {
-            final ErrorDialogFragment fragment = new ErrorDialogFragment();
-            final Bundle args = new Bundle();
-            args.putInt(ARG_TITLE_RES_ID, titleResId);
-            args.putInt(ARG_MESSAGE_RES_ID, messageResId);
-            fragment.setArguments(args);
-            return fragment;
-        }
-
-        @Override
-        public void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
-            mTitleResId = getArguments().getInt(ARG_TITLE_RES_ID);
-            mMessageResId = getArguments().getInt(ARG_MESSAGE_RES_ID);
-        }
-
-        @Override
-        public Dialog onCreateDialog(Bundle savedInstanceState) {
-            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-            if (mTitleResId != 0) {
-                builder.setTitle(mTitleResId);
-            }
-            if (mMessageResId != 0) {
-                builder.setMessage(mMessageResId);
-            }
-            builder.setPositiveButton(android.R.string.ok,
-                    new DialogInterface.OnClickListener() {
-                            @Override
-                            public void onClick(DialogInterface dialog, int which) {
-                                dismiss();
-                            }
-                    });
-            return builder.create();
-        }
-    }
-
-    /**
-     * In most cases, when the dial button is pressed, there is a
-     * number in digits area. Pack it in the intent, start the
-     * outgoing call broadcast as a separate task and finish this
-     * activity.
-     *
-     * When there is no digit and the phone is CDMA and off hook,
-     * we're sending a blank flash for CDMA. CDMA networks use Flash
-     * messages when special processing needs to be done, mainly for
-     * 3-way or call waiting scenarios. Presumably, here we're in a
-     * special 3-way scenario where the network needs a blank flash
-     * before being able to add the new participant.  (This is not the
-     * case with all 3-way calls, just certain CDMA infrastructures.)
-     *
-     * Otherwise, there is no digit, display the last dialed
-     * number. Don't finish since the user may want to edit it. The
-     * user needs to press the dial button again, to dial it (general
-     * case described above).
-     */
-    public void dialButtonPressed() {
-        if (isDigitsEmpty()) { // No number entered.
-            handleDialButtonClickWithEmptyDigits();
-        } else {
-            final String number = mDigits.getText().toString();
-
-            // "persist.radio.otaspdial" is a temporary hack needed for one carrier's automated
-            // test equipment.
-            // TODO: clean it up.
-            if (number != null
-                    && !TextUtils.isEmpty(mProhibitedPhoneNumberRegexp)
-                    && number.matches(mProhibitedPhoneNumberRegexp)
-                    && (SystemProperties.getInt("persist.radio.otaspdial", 0) != 1)) {
-                Log.i(TAG, "The phone number is prohibited explicitly by a rule.");
-                if (getActivity() != null) {
-                    DialogFragment dialogFragment = ErrorDialogFragment.newInstance(
-                            R.string.dialog_phone_call_prohibited_message);
-                    dialogFragment.show(getFragmentManager(), "phone_prohibited_dialog");
-                }
-
-                // Clear the digits just in case.
-                mDigits.getText().clear();
-            } else {
-                final Intent intent = ContactsUtils.getCallIntent(number,
-                        (getActivity() instanceof DialtactsActivity ?
-                                ((DialtactsActivity)getActivity()).getCallOrigin() : null));
-                startActivity(intent);
-                mClearDigitsOnStop = true;
-                getActivity().finish();
-            }
-        }
-    }
-
-    private void handleDialButtonClickWithEmptyDigits() {
-        if (phoneIsCdma() && phoneIsOffhook()) {
-            // This is really CDMA specific. On GSM is it possible
-            // to be off hook and wanted to add a 3rd party using
-            // the redial feature.
-            startActivity(newFlashIntent());
-        } else {
-            if (!TextUtils.isEmpty(mLastNumberDialed)) {
-                // Recall the last number dialed.
-                mDigits.setText(mLastNumberDialed);
-
-                // ...and move the cursor to the end of the digits string,
-                // so you'll be able to delete digits using the Delete
-                // button (just as if you had typed the number manually.)
-                //
-                // Note we use mDigits.getText().length() here, not
-                // mLastNumberDialed.length(), since the EditText widget now
-                // contains a *formatted* version of mLastNumberDialed (due to
-                // mTextWatcher) and its length may have changed.
-                mDigits.setSelection(mDigits.getText().length());
-            } else {
-                // There's no "last number dialed" or the
-                // background query is still running. There's
-                // nothing useful for the Dial button to do in
-                // this case.  Note: with a soft dial button, this
-                // can never happens since the dial button is
-                // disabled under these conditons.
-                playTone(ToneGenerator.TONE_PROP_NACK);
-            }
-        }
-    }
-
-    /**
-     * Plays the specified tone for TONE_LENGTH_MS milliseconds.
-     */
-    private void playTone(int tone) {
-        playTone(tone, TONE_LENGTH_MS);
-    }
-
-    /**
-     * Play the specified tone for the specified milliseconds
-     *
-     * The tone is played locally, using the audio stream for phone calls.
-     * Tones are played only if the "Audible touch tones" user preference
-     * is checked, and are NOT played if the device is in silent mode.
-     *
-     * The tone length can be -1, meaning "keep playing the tone." If the caller does so, it should
-     * call stopTone() afterward.
-     *
-     * @param tone a tone code from {@link ToneGenerator}
-     * @param durationMs tone length.
-     */
-    private void playTone(int tone, int durationMs) {
-        // if local tone playback is disabled, just return.
-        if (!mDTMFToneEnabled) {
-            return;
-        }
-
-        // Also do nothing if the phone is in silent mode.
-        // We need to re-check the ringer mode for *every* playTone()
-        // call, rather than keeping a local flag that's updated in
-        // onResume(), since it's possible to toggle silent mode without
-        // leaving the current activity (via the ENDCALL-longpress menu.)
-        AudioManager audioManager =
-                (AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE);
-        int ringerMode = audioManager.getRingerMode();
-        if ((ringerMode == AudioManager.RINGER_MODE_SILENT)
-            || (ringerMode == AudioManager.RINGER_MODE_VIBRATE)) {
-            return;
-        }
-
-        synchronized (mToneGeneratorLock) {
-            if (mToneGenerator == null) {
-                Log.w(TAG, "playTone: mToneGenerator == null, tone: " + tone);
-                return;
-            }
-
-            // Start the new tone (will stop any playing tone)
-            mToneGenerator.startTone(tone, durationMs);
-        }
-    }
-
-    /**
-     * Stop the tone if it is played.
-     */
-    private void stopTone() {
-        // if local tone playback is disabled, just return.
-        if (!mDTMFToneEnabled) {
-            return;
-        }
-        synchronized (mToneGeneratorLock) {
-            if (mToneGenerator == null) {
-                Log.w(TAG, "stopTone: mToneGenerator == null");
-                return;
-            }
-            mToneGenerator.stopTone();
-        }
-    }
-
-    /**
-     * Brings up the "dialpad chooser" UI in place of the usual Dialer
-     * elements (the textfield/button and the dialpad underneath).
-     *
-     * We show this UI if the user brings up the Dialer while a call is
-     * already in progress, since there's a good chance we got here
-     * accidentally (and the user really wanted the in-call dialpad instead).
-     * So in this situation we display an intermediate UI that lets the user
-     * explicitly choose between the in-call dialpad ("Use touch tone
-     * keypad") and the regular Dialer ("Add call").  (Or, the option "Return
-     * to call in progress" just goes back to the in-call UI with no dialpad
-     * at all.)
-     *
-     * @param enabled If true, show the "dialpad chooser" instead
-     *                of the regular Dialer UI
-     */
-    private void showDialpadChooser(boolean enabled) {
-        // Check if onCreateView() is already called by checking one of View objects.
-        if (!isLayoutReady()) {
-            return;
-        }
-
-        if (enabled) {
-            // Log.i(TAG, "Showing dialpad chooser!");
-            if (mDigitsContainer != null) {
-                mDigitsContainer.setVisibility(View.GONE);
-            } else {
-                // mDigits is not enclosed by the container. Make the digits field itself gone.
-                mDigits.setVisibility(View.GONE);
-            }
-            if (mDialpad != null) mDialpad.setVisibility(View.GONE);
-            if (mDialButtonContainer != null) mDialButtonContainer.setVisibility(View.GONE);
-
-            mDialpadChooser.setVisibility(View.VISIBLE);
-
-            // Instantiate the DialpadChooserAdapter and hook it up to the
-            // ListView.  We do this only once.
-            if (mDialpadChooserAdapter == null) {
-                mDialpadChooserAdapter = new DialpadChooserAdapter(getActivity());
-            }
-            mDialpadChooser.setAdapter(mDialpadChooserAdapter);
-        } else {
-            // Log.i(TAG, "Displaying normal Dialer UI.");
-            if (mDigitsContainer != null) {
-                mDigitsContainer.setVisibility(View.VISIBLE);
-            } else {
-                mDigits.setVisibility(View.VISIBLE);
-            }
-            if (mDialpad != null) mDialpad.setVisibility(View.VISIBLE);
-            if (mDialButtonContainer != null) mDialButtonContainer.setVisibility(View.VISIBLE);
-            mDialpadChooser.setVisibility(View.GONE);
-        }
-    }
-
-    /**
-     * @return true if we're currently showing the "dialpad chooser" UI.
-     */
-    private boolean dialpadChooserVisible() {
-        return mDialpadChooser.getVisibility() == View.VISIBLE;
-    }
-
-    /**
-     * Simple list adapter, binding to an icon + text label
-     * for each item in the "dialpad chooser" list.
-     */
-    private static class DialpadChooserAdapter extends BaseAdapter {
-        private LayoutInflater mInflater;
-
-        // Simple struct for a single "choice" item.
-        static class ChoiceItem {
-            String text;
-            Bitmap icon;
-            int id;
-
-            public ChoiceItem(String s, Bitmap b, int i) {
-                text = s;
-                icon = b;
-                id = i;
-            }
-        }
-
-        // IDs for the possible "choices":
-        static final int DIALPAD_CHOICE_USE_DTMF_DIALPAD = 101;
-        static final int DIALPAD_CHOICE_RETURN_TO_CALL = 102;
-        static final int DIALPAD_CHOICE_ADD_NEW_CALL = 103;
-
-        private static final int NUM_ITEMS = 3;
-        private ChoiceItem mChoiceItems[] = new ChoiceItem[NUM_ITEMS];
-
-        public DialpadChooserAdapter(Context context) {
-            // Cache the LayoutInflate to avoid asking for a new one each time.
-            mInflater = LayoutInflater.from(context);
-
-            // Initialize the possible choices.
-            // TODO: could this be specified entirely in XML?
-
-            // - "Use touch tone keypad"
-            mChoiceItems[0] = new ChoiceItem(
-                    context.getString(R.string.dialer_useDtmfDialpad),
-                    BitmapFactory.decodeResource(context.getResources(),
-                                                 R.drawable.ic_dialer_fork_tt_keypad),
-                    DIALPAD_CHOICE_USE_DTMF_DIALPAD);
-
-            // - "Return to call in progress"
-            mChoiceItems[1] = new ChoiceItem(
-                    context.getString(R.string.dialer_returnToInCallScreen),
-                    BitmapFactory.decodeResource(context.getResources(),
-                                                 R.drawable.ic_dialer_fork_current_call),
-                    DIALPAD_CHOICE_RETURN_TO_CALL);
-
-            // - "Add call"
-            mChoiceItems[2] = new ChoiceItem(
-                    context.getString(R.string.dialer_addAnotherCall),
-                    BitmapFactory.decodeResource(context.getResources(),
-                                                 R.drawable.ic_dialer_fork_add_call),
-                    DIALPAD_CHOICE_ADD_NEW_CALL);
-        }
-
-        @Override
-        public int getCount() {
-            return NUM_ITEMS;
-        }
-
-        /**
-         * Return the ChoiceItem for a given position.
-         */
-        @Override
-        public Object getItem(int position) {
-            return mChoiceItems[position];
-        }
-
-        /**
-         * Return a unique ID for each possible choice.
-         */
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
-
-        /**
-         * Make a view for each row.
-         */
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            // When convertView is non-null, we can reuse it (there's no need
-            // to reinflate it.)
-            if (convertView == null) {
-                convertView = mInflater.inflate(R.layout.dialpad_chooser_list_item, null);
-            }
-
-            TextView text = (TextView) convertView.findViewById(R.id.text);
-            text.setText(mChoiceItems[position].text);
-
-            ImageView icon = (ImageView) convertView.findViewById(R.id.icon);
-            icon.setImageBitmap(mChoiceItems[position].icon);
-
-            return convertView;
-        }
-    }
-
-    /**
-     * Handle clicks from the dialpad chooser.
-     */
-    @Override
-    public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
-        DialpadChooserAdapter.ChoiceItem item =
-                (DialpadChooserAdapter.ChoiceItem) parent.getItemAtPosition(position);
-        int itemId = item.id;
-        switch (itemId) {
-            case DialpadChooserAdapter.DIALPAD_CHOICE_USE_DTMF_DIALPAD:
-                // Log.i(TAG, "DIALPAD_CHOICE_USE_DTMF_DIALPAD");
-                // Fire off an intent to go back to the in-call UI
-                // with the dialpad visible.
-                returnToInCallScreen(true);
-                break;
-
-            case DialpadChooserAdapter.DIALPAD_CHOICE_RETURN_TO_CALL:
-                // Log.i(TAG, "DIALPAD_CHOICE_RETURN_TO_CALL");
-                // Fire off an intent to go back to the in-call UI
-                // (with the dialpad hidden).
-                returnToInCallScreen(false);
-                break;
-
-            case DialpadChooserAdapter.DIALPAD_CHOICE_ADD_NEW_CALL:
-                // Log.i(TAG, "DIALPAD_CHOICE_ADD_NEW_CALL");
-                // Ok, guess the user really did want to be here (in the
-                // regular Dialer) after all.  Bring back the normal Dialer UI.
-                showDialpadChooser(false);
-                break;
-
-            default:
-                Log.w(TAG, "onItemClick: unexpected itemId: " + itemId);
-                break;
-        }
-    }
-
-    /**
-     * Returns to the in-call UI (where there's presumably a call in
-     * progress) in response to the user selecting "use touch tone keypad"
-     * or "return to call" from the dialpad chooser.
-     */
-    private void returnToInCallScreen(boolean showDialpad) {
-        try {
-            ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
-            if (phone != null) phone.showCallScreenWithDialpad(showDialpad);
-        } catch (RemoteException e) {
-            Log.w(TAG, "phone.showCallScreenWithDialpad() failed", e);
-        }
-
-        // Finally, finish() ourselves so that we don't stay on the
-        // activity stack.
-        // Note that we do this whether or not the showCallScreenWithDialpad()
-        // call above had any effect or not!  (That call is a no-op if the
-        // phone is idle, which can happen if the current call ends while
-        // the dialpad chooser is up.  In this case we can't show the
-        // InCallScreen, and there's no point staying here in the Dialer,
-        // so we just take the user back where he came from...)
-        getActivity().finish();
-    }
-
-    /**
-     * @return true if the phone is "in use", meaning that at least one line
-     *              is active (ie. off hook or ringing or dialing).
-     */
-    public static boolean phoneIsInUse() {
-        boolean phoneInUse = false;
-        try {
-            ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
-            if (phone != null) phoneInUse = !phone.isIdle();
-        } catch (RemoteException e) {
-            Log.w(TAG, "phone.isIdle() failed", e);
-        }
-        return phoneInUse;
-    }
-
-    /**
-     * @return true if the phone is a CDMA phone type
-     */
-    private boolean phoneIsCdma() {
-        boolean isCdma = false;
-        try {
-            ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
-            if (phone != null) {
-                isCdma = (phone.getActivePhoneType() == TelephonyManager.PHONE_TYPE_CDMA);
-            }
-        } catch (RemoteException e) {
-            Log.w(TAG, "phone.getActivePhoneType() failed", e);
-        }
-        return isCdma;
-    }
-
-    /**
-     * @return true if the phone state is OFFHOOK
-     */
-    private boolean phoneIsOffhook() {
-        boolean phoneOffhook = false;
-        try {
-            ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
-            if (phone != null) phoneOffhook = phone.isOffhook();
-        } catch (RemoteException e) {
-            Log.w(TAG, "phone.isOffhook() failed", e);
-        }
-        return phoneOffhook;
-    }
-
-    /**
-     * Returns true whenever any one of the options from the menu is selected.
-     * Code changes to support dialpad options
-     */
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.menu_2s_pause:
-                updateDialString(",");
-                return true;
-            case R.id.menu_add_wait:
-                updateDialString(";");
-                return true;
-            default:
-                return false;
-        }
-    }
-
-    @Override
-    public boolean onMenuItemClick(MenuItem item) {
-        return onOptionsItemSelected(item);
-    }
-
-    /**
-     * Updates the dial string (mDigits) after inserting a Pause character (,)
-     * or Wait character (;).
-     */
-    private void updateDialString(String newDigits) {
-        int selectionStart;
-        int selectionEnd;
-
-        // SpannableStringBuilder editable_text = new SpannableStringBuilder(mDigits.getText());
-        int anchor = mDigits.getSelectionStart();
-        int point = mDigits.getSelectionEnd();
-
-        selectionStart = Math.min(anchor, point);
-        selectionEnd = Math.max(anchor, point);
-
-        Editable digits = mDigits.getText();
-        if (selectionStart != -1) {
-            if (selectionStart == selectionEnd) {
-                // then there is no selection. So insert the pause at this
-                // position and update the mDigits.
-                digits.replace(selectionStart, selectionStart, newDigits);
-            } else {
-                digits.replace(selectionStart, selectionEnd, newDigits);
-                // Unselect: back to a regular cursor, just pass the character inserted.
-                mDigits.setSelection(selectionStart + 1);
-            }
-        } else {
-            int len = mDigits.length();
-            digits.replace(len, len, newDigits);
-        }
-    }
-
-    /**
-     * Update the enabledness of the "Dial" and "Backspace" buttons if applicable.
-     */
-    private void updateDialAndDeleteButtonEnabledState() {
-        final boolean digitsNotEmpty = !isDigitsEmpty();
-
-        if (mDialButton != null) {
-            // On CDMA phones, if we're already on a call, we *always*
-            // enable the Dial button (since you can press it without
-            // entering any digits to send an empty flash.)
-            if (phoneIsCdma() && phoneIsOffhook()) {
-                mDialButton.setEnabled(true);
-            } else {
-                // Common case: GSM, or CDMA but not on a call.
-                // Enable the Dial button if some digits have
-                // been entered, or if there is a last dialed number
-                // that could be redialed.
-                mDialButton.setEnabled(digitsNotEmpty ||
-                        !TextUtils.isEmpty(mLastNumberDialed));
-            }
-        }
-        mDelete.setEnabled(digitsNotEmpty);
-    }
-
-    /**
-     * Check if voicemail is enabled/accessible.
-     *
-     * @return true if voicemail is enabled and accessibly. Note that this can be false
-     * "temporarily" after the app boot.
-     * @see TelephonyManager#getVoiceMailNumber()
-     */
-    private boolean isVoicemailAvailable() {
-        try {
-            return (TelephonyManager.getDefault().getVoiceMailNumber() != null);
-        } catch (SecurityException se) {
-            // Possibly no READ_PHONE_STATE privilege.
-            Log.w(TAG, "SecurityException is thrown. Maybe privilege isn't sufficient.");
-        }
-        return false;
-    }
-
-    /**
-     * This function return true if Wait menu item can be shown
-     * otherwise returns false. Assumes the passed string is non-empty
-     * and the 0th index check is not required.
-     */
-    private static boolean showWait(int start, int end, String digits) {
-        if (start == end) {
-            // visible false in this case
-            if (start > digits.length()) return false;
-
-            // preceding char is ';', so visible should be false
-            if (digits.charAt(start - 1) == ';') return false;
-
-            // next char is ';', so visible should be false
-            if ((digits.length() > start) && (digits.charAt(start) == ';')) return false;
-        } else {
-            // visible false in this case
-            if (start > digits.length() || end > digits.length()) return false;
-
-            // In this case we need to just check for ';' preceding to start
-            // or next to end
-            if (digits.charAt(start - 1) == ';') return false;
-        }
-        return true;
-    }
-
-    /**
-     * @return true if the widget with the phone number digits is empty.
-     */
-    private boolean isDigitsEmpty() {
-        return mDigits.length() == 0;
-    }
-
-    /**
-     * Starts the asyn query to get the last dialed/outgoing
-     * number. When the background query finishes, mLastNumberDialed
-     * is set to the last dialed number or an empty string if none
-     * exists yet.
-     */
-    private void queryLastOutgoingCall() {
-        mLastNumberDialed = EMPTY_NUMBER;
-        CallLogAsync.GetLastOutgoingCallArgs lastCallArgs =
-                new CallLogAsync.GetLastOutgoingCallArgs(
-                    getActivity(),
-                    new CallLogAsync.OnLastOutgoingCallComplete() {
-                        @Override
-                        public void lastOutgoingCall(String number) {
-                            // TODO: Filter out emergency numbers if
-                            // the carrier does not want redial for
-                            // these.
-                            mLastNumberDialed = number;
-                            updateDialAndDeleteButtonEnabledState();
-                        }
-                    });
-        mCallLog.getLastOutgoingCall(lastCallArgs);
-    }
-
-    private Intent newFlashIntent() {
-        final Intent intent = ContactsUtils.getCallIntent(EMPTY_NUMBER);
-        intent.putExtra(EXTRA_SEND_EMPTY_FLASH, true);
-        return intent;
-    }
-}
diff --git a/src/com/android/contacts/dialpad/DialpadImageButton.java b/src/com/android/contacts/dialpad/DialpadImageButton.java
deleted file mode 100644
index a18cbb8..0000000
--- a/src/com/android/contacts/dialpad/DialpadImageButton.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2012 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.dialpad;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.ImageButton;
-
-/**
- * Custom {@link ImageButton} for dialpad buttons.
- *
- * During horizontal swipe, we want to exit "fading out" animation offered by its background
- * just after starting the swipe.This class overrides {@link #onTouchEvent(MotionEvent)} to achieve
- * the behavior.
- */
-public class DialpadImageButton extends ImageButton {
-    public interface OnPressedListener {
-        public void onPressed(View view, boolean pressed);
-    }
-
-    private OnPressedListener mOnPressedListener;
-
-    public void setOnPressedListener(OnPressedListener onPressedListener) {
-        mOnPressedListener = onPressedListener;
-    }
-
-    public DialpadImageButton(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public DialpadImageButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    @Override
-    public void setPressed(boolean pressed) {
-        super.setPressed(pressed);
-        if (mOnPressedListener != null) {
-            mOnPressedListener.onPressed(this, pressed);
-        }
-    }
-}
diff --git a/src/com/android/contacts/dialpad/DigitsEditText.java b/src/com/android/contacts/dialpad/DigitsEditText.java
deleted file mode 100644
index 7b3e8b2..0000000
--- a/src/com/android/contacts/dialpad/DigitsEditText.java
+++ /dev/null
@@ -1,86 +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.dialpad;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.text.InputType;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.EditText;
-
-/**
- * EditText which suppresses IME show up.
- */
-public class DigitsEditText extends EditText {
-    public DigitsEditText(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        setInputType(getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
-        setShowSoftInputOnFocus(false);
-    }
-
-    @Override
-    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
-        super.onFocusChanged(focused, direction, previouslyFocusedRect);
-        final InputMethodManager imm = ((InputMethodManager) getContext()
-                .getSystemService(Context.INPUT_METHOD_SERVICE));
-        if (imm != null && imm.isActive(this)) {
-            imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
-        }
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        final boolean ret = super.onTouchEvent(event);
-        // Must be done after super.onTouchEvent()
-        final InputMethodManager imm = ((InputMethodManager) getContext()
-                .getSystemService(Context.INPUT_METHOD_SERVICE));
-        if (imm != null && imm.isActive(this)) {
-            imm.hideSoftInputFromWindow(getApplicationWindowToken(), 0);
-        }
-        return ret;
-    }
-
-    @Override
-    public void sendAccessibilityEventUnchecked(AccessibilityEvent event) {
-        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED) {
-            // Since we're replacing the text every time we add or remove a
-            // character, only read the difference. (issue 5337550)
-            final int added = event.getAddedCount();
-            final int removed = event.getRemovedCount();
-            final int length = event.getBeforeText().length();
-            if (added > removed) {
-                event.setRemovedCount(0);
-                event.setAddedCount(1);
-                event.setFromIndex(length);
-            } else if (removed > added) {
-                event.setRemovedCount(1);
-                event.setAddedCount(0);
-                event.setFromIndex(length - 1);
-            } else {
-                return;
-            }
-        } else if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_FOCUSED) {
-            // The parent EditText class lets tts read "edit box" when this View has a focus, which
-            // confuses users on app launch (issue 5275935).
-            return;
-        }
-        super.sendAccessibilityEventUnchecked(event);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/interactions/PhoneNumberInteraction.java b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
index 207ceea..551eab4 100644
--- a/src/com/android/contacts/interactions/PhoneNumberInteraction.java
+++ b/src/com/android/contacts/interactions/PhoneNumberInteraction.java
@@ -51,7 +51,6 @@
 import com.android.contacts.ContactSaveService;
 import com.android.contacts.ContactsUtils;
 import com.android.contacts.R;
-import com.android.contacts.activities.DialtactsActivity;
 import com.android.contacts.activities.TransactionSafeActivity;
 import com.android.contacts.model.account.AccountType;
 import com.android.contacts.model.account.AccountType.StringInflater;
@@ -456,7 +455,7 @@
      * @param activity that is calling this interaction. This must be of type
      * {@link TransactionSafeActivity} because we need to check on the activity state after the
      * phone numbers have been queried for.
-     * @param callOrigin If non null, {@link DialtactsActivity#EXTRA_CALL_ORIGIN} will be
+     * @param callOrigin If non null, {@link PhoneConstants#EXTRA_CALL_ORIGIN} will be
      * appended to the Intent initiating phone call. See comments in Phone package (PhoneApp)
      * for more detail.
      */
diff --git a/src/com/android/contacts/list/ContactListFilterController.java b/src/com/android/contacts/list/ContactListFilterController.java
index ddcb1ae..5377df2 100644
--- a/src/com/android/contacts/list/ContactListFilterController.java
+++ b/src/com/android/contacts/list/ContactListFilterController.java
@@ -30,20 +30,19 @@
  */
 public abstract class ContactListFilterController {
 
-    public static final String CONTACT_LIST_FILTER_SERVICE = "contactListFilter";
+    // singleton to cache the filter controller
+    private static ContactListFilterControllerImpl sFilterController = null;
 
     public interface ContactListFilterListener {
         void onContactListFilterChanged();
     }
 
     public static ContactListFilterController getInstance(Context context) {
-        return (ContactListFilterController)
-                context.getApplicationContext().getSystemService(CONTACT_LIST_FILTER_SERVICE);
-    }
-
-    public static ContactListFilterController
-            createContactListFilterController(Context context) {
-        return new ContactListFilterControllerImpl(context);
+        // We may need to synchronize this in the future if background task will call this.
+        if (sFilterController == null) {
+            sFilterController = new ContactListFilterControllerImpl(context);
+        }
+        return sFilterController;
     }
 
     public abstract void addListener(ContactListFilterListener listener);
diff --git a/src/com/android/contacts/test/FragmentTestActivity.java b/src/com/android/contacts/test/FragmentTestActivity.java
deleted file mode 100644
index 80c6731..0000000
--- a/src/com/android/contacts/test/FragmentTestActivity.java
+++ /dev/null
@@ -1,44 +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.test;
-
-import android.os.Bundle;
-import android.view.Window;
-import android.view.WindowManager;
-
-import com.android.contacts.ContactsActivity;
-import com.android.contacts.R;
-
-/**
- * An activity that is used for testing fragments.  A unit test starts this
- * activity, adds a fragment and then tests the fragment.
- */
-public class FragmentTestActivity extends ContactsActivity {
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        // Normally fragment/activity onStart() methods will not be called when screen is locked.
-        // Use the following flags to ensure that activities can be show for testing.
-        Window window = getWindow();
-        window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON |
-                WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
-
-        setContentView(R.layout.fragment_test);
-    }
-}
diff --git a/src/com/android/contacts/util/ExpirableCache.java b/src/com/android/contacts/util/ExpirableCache.java
deleted file mode 100644
index 3f19a26..0000000
--- a/src/com/android/contacts/util/ExpirableCache.java
+++ /dev/null
@@ -1,266 +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.util.LruCache;
-
-import com.android.contacts.test.NeededForTesting;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.annotation.concurrent.Immutable;
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * An LRU cache in which all items can be marked as expired at a given time and it is possible to
- * query whether a particular cached value is expired or not.
- * <p>
- * A typical use case for this is caching of values which are expensive to compute but which are
- * still useful when out of date.
- * <p>
- * Consider a cache for contact information:
- * <pre>{@code
- *     private ExpirableCache<String, Contact> mContactCache;}</pre>
- * which stores the contact information for a given phone number.
- * <p>
- * When we need to store contact information for a given phone number, we can look up the info in
- * the cache:
- * <pre>{@code
- *     CachedValue<Contact> cachedContact = mContactCache.getCachedValue(phoneNumber);
- * }</pre>
- * We might also want to fetch the contact information again if the item is expired.
- * <pre>
- *     if (cachedContact.isExpired()) {
- *         fetchContactForNumber(phoneNumber,
- *                 new FetchListener() {
- *                     &#64;Override
- *                     public void onFetched(Contact contact) {
- *                         mContactCache.put(phoneNumber, contact);
- *                     }
- *                 });
- *     }</pre>
- * and insert it back into the cache when the fetch completes.
- * <p>
- * At a certain point we want to expire the content of the cache because we know the content may
- * no longer be up-to-date, for instance, when resuming the activity this is shown into:
- * <pre>
- *     &#64;Override
- *     protected onResume() {
- *         // We were paused for some time, the cached value might no longer be up to date.
- *         mContactCache.expireAll();
- *         super.onResume();
- *     }
- * </pre>
- * The values will be still available from the cache, but they will be expired.
- * <p>
- * If interested only in the value itself, not whether it is expired or not, one should use the
- * {@link #getPossiblyExpired(Object)} method. If interested only in non-expired values, one should
- * use the {@link #get(Object)} method instead.
- * <p>
- * This class wraps around an {@link LruCache} instance: it follows the {@link LruCache} behavior
- * for evicting items when the cache is full. It is possible to supply your own subclass of LruCache
- * by using the {@link #create(LruCache)} method, which can define a custom expiration policy.
- * Since the underlying cache maps keys to cached values it can determine which items are expired
- * and which are not, allowing for an implementation that evicts expired items before non expired
- * ones.
- * <p>
- * This class is thread-safe.
- *
- * @param <K> the type of the keys
- * @param <V> the type of the values
- */
-@ThreadSafe
-public class ExpirableCache<K, V> {
-    /**
-     * A cached value stored inside the cache.
-     * <p>
-     * It provides access to the value stored in the cache but also allows to check whether the
-     * value is expired.
-     *
-     * @param <V> the type of value stored in the cache
-     */
-    public interface CachedValue<V> {
-        /** Returns the value stored in the cache for a given key. */
-        public V getValue();
-
-        /**
-         * Checks whether the value, while still being present in the cache, is expired.
-         *
-         * @return true if the value is expired
-         */
-        public boolean isExpired();
-    }
-
-    /**
-     * Cached values storing the generation at which they were added.
-     */
-    @Immutable
-    private static class GenerationalCachedValue<V> implements ExpirableCache.CachedValue<V> {
-        /** The value stored in the cache. */
-        public final V mValue;
-        /** The generation at which the value was added to the cache. */
-        private final int mGeneration;
-        /** The atomic integer storing the current generation of the cache it belongs to. */
-        private final AtomicInteger mCacheGeneration;
-
-        /**
-         * @param cacheGeneration the atomic integer storing the generation of the cache in which
-         *        this value will be stored
-         */
-        public GenerationalCachedValue(V value, AtomicInteger cacheGeneration) {
-            mValue = value;
-            mCacheGeneration = cacheGeneration;
-            // Snapshot the current generation.
-            mGeneration = mCacheGeneration.get();
-        }
-
-        @Override
-        public V getValue() {
-            return mValue;
-        }
-
-        @Override
-        public boolean isExpired() {
-            return mGeneration != mCacheGeneration.get();
-        }
-    }
-
-    /** The underlying cache used to stored the cached values. */
-    private LruCache<K, CachedValue<V>> mCache;
-
-    /**
-     * The current generation of items added to the cache.
-     * <p>
-     * Items in the cache can belong to a previous generation, but in that case they would be
-     * expired.
-     *
-     * @see ExpirableCache.CachedValue#isExpired()
-     */
-    private final AtomicInteger mGeneration;
-
-    private ExpirableCache(LruCache<K, CachedValue<V>> cache) {
-        mCache = cache;
-        mGeneration = new AtomicInteger(0);
-    }
-
-    /**
-     * Returns the cached value for the given key, or null if no value exists.
-     * <p>
-     * The cached value gives access both to the value associated with the key and whether it is
-     * expired or not.
-     * <p>
-     * If not interested in whether the value is expired, use {@link #getPossiblyExpired(Object)}
-     * instead.
-     * <p>
-     * If only wants values that are not expired, use {@link #get(Object)} instead.
-     *
-     * @param key the key to look up
-     */
-    public CachedValue<V> getCachedValue(K key) {
-        return mCache.get(key);
-    }
-
-    /**
-     * Returns the value for the given key, or null if no value exists.
-     * <p>
-     * When using this method, it is not possible to determine whether the value is expired or not.
-     * Use {@link #getCachedValue(Object)} to achieve that instead. However, if using
-     * {@link #getCachedValue(Object)} to determine if an item is expired, one should use the item
-     * within the {@link CachedValue} and not call {@link #getPossiblyExpired(Object)} to get the
-     * value afterwards, since that is not guaranteed to return the same value or that the newly
-     * returned value is in the same state.
-     *
-     * @param key the key to look up
-     */
-    public V getPossiblyExpired(K key) {
-        CachedValue<V> cachedValue = getCachedValue(key);
-        return cachedValue == null ? null : cachedValue.getValue();
-    }
-
-    /**
-     * Returns the value for the given key only if it is not expired, or null if no value exists or
-     * is expired.
-     * <p>
-     * This method will return null if either there is no value associated with this key or if the
-     * associated value is expired.
-     *
-     * @param key the key to look up
-     */
-    @NeededForTesting
-    public V get(K key) {
-        CachedValue<V> cachedValue = getCachedValue(key);
-        return cachedValue == null || cachedValue.isExpired() ? null : cachedValue.getValue();
-    }
-
-    /**
-     * Puts an item in the cache.
-     * <p>
-     * Newly added item will not be expired until {@link #expireAll()} is next called.
-     *
-     * @param key the key to look up
-     * @param value the value to associate with the key
-     */
-    public void put(K key, V value) {
-        mCache.put(key, newCachedValue(value));
-    }
-
-    /**
-     * Mark all items currently in the cache as expired.
-     * <p>
-     * Newly added items after this call will be marked as not expired.
-     * <p>
-     * Expiring the items in the cache does not imply they will be evicted.
-     */
-    public void expireAll() {
-        mGeneration.incrementAndGet();
-    }
-
-    /**
-     * Creates a new {@link CachedValue} instance to be stored in this cache.
-     * <p>
-     * Implementation of {@link LruCache#create(K)} can use this method to create a new entry.
-     */
-    public CachedValue<V> newCachedValue(V value) {
-        return new GenerationalCachedValue<V>(value, mGeneration);
-    }
-
-    /**
-     * Creates a new {@link ExpirableCache} that wraps the given {@link LruCache}.
-     * <p>
-     * The created cache takes ownership of the cache passed in as an argument.
-     *
-     * @param <K> the type of the keys
-     * @param <V> the type of the values
-     * @param cache the cache to store the value in
-     * @return the newly created expirable cache
-     * @throws IllegalArgumentException if the cache is not empty
-     */
-    public static <K, V> ExpirableCache<K, V> create(LruCache<K, CachedValue<V>> cache) {
-        return new ExpirableCache<K, V>(cache);
-    }
-
-    /**
-     * Creates a new {@link ExpirableCache} with the given maximum size.
-     *
-     * @param <K> the type of the keys
-     * @param <V> the type of the values
-     * @return the newly created expirable cache
-     */
-    public static <K, V> ExpirableCache<K, V> create(int maxSize) {
-        return create(new LruCache<K, CachedValue<V>>(maxSize));
-    }
-}
diff --git a/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java b/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java
deleted file mode 100644
index 5973387..0000000
--- a/src/com/android/contacts/voicemail/VoicemailPlaybackFragment.java
+++ /dev/null
@@ -1,474 +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 com.android.contacts.CallDetailActivity.EXTRA_VOICEMAIL_START_PLAYBACK;
-import static com.android.contacts.CallDetailActivity.EXTRA_VOICEMAIL_URI;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.PowerManager;
-import android.provider.VoicemailContract;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageButton;
-import android.widget.SeekBar;
-import android.widget.TextView;
-
-import com.android.common.io.MoreCloseables;
-import com.android.contacts.ProximitySensorAware;
-import com.android.contacts.R;
-import com.android.contacts.util.AsyncTaskExecutors;
-import com.android.ex.variablespeed.MediaPlayerProxy;
-import com.android.ex.variablespeed.VariableSpeed;
-import com.google.common.base.Preconditions;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.NotThreadSafe;
-
-/**
- * Displays and plays back a single voicemail.
- * <p>
- * When the Activity containing this Fragment is created, voicemail playback
- * will begin immediately. The Activity is expected to be started via an intent
- * containing a suitable voicemail uri to playback.
- * <p>
- * This class is not thread-safe, it is thread-confined. All calls to all public
- * methods on this class are expected to come from the main ui thread.
- */
-@NotThreadSafe
-public class VoicemailPlaybackFragment extends Fragment {
-    private static final String TAG = "VoicemailPlayback";
-    private static final int NUMBER_OF_THREADS_IN_POOL = 2;
-    private static final String[] HAS_CONTENT_PROJECTION = new String[] {
-        VoicemailContract.Voicemails.HAS_CONTENT,
-    };
-
-    private VoicemailPlaybackPresenter mPresenter;
-    private ScheduledExecutorService mScheduledExecutorService;
-    private View mPlaybackLayout;
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        mPlaybackLayout = inflater.inflate(R.layout.playback_layout, null);
-        return mPlaybackLayout;
-    }
-
-    @Override
-    public void onActivityCreated(Bundle savedInstanceState) {
-        super.onActivityCreated(savedInstanceState);
-        mScheduledExecutorService = createScheduledExecutorService();
-        Bundle arguments = getArguments();
-        Preconditions.checkNotNull(arguments, "fragment must be started with arguments");
-        Uri voicemailUri = arguments.getParcelable(EXTRA_VOICEMAIL_URI);
-        Preconditions.checkNotNull(voicemailUri, "fragment must contain EXTRA_VOICEMAIL_URI");
-        boolean startPlayback = arguments.getBoolean(EXTRA_VOICEMAIL_START_PLAYBACK, false);
-        PowerManager powerManager =
-                (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
-        PowerManager.WakeLock wakeLock =
-                powerManager.newWakeLock(
-                        PowerManager.SCREEN_DIM_WAKE_LOCK, getClass().getSimpleName());
-        mPresenter = new VoicemailPlaybackPresenter(createPlaybackViewImpl(),
-                createMediaPlayer(mScheduledExecutorService), voicemailUri,
-                mScheduledExecutorService, startPlayback,
-                AsyncTaskExecutors.createAsyncTaskExecutor(), wakeLock);
-        mPresenter.onCreate(savedInstanceState);
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        mPresenter.onSaveInstanceState(outState);
-        super.onSaveInstanceState(outState);
-    }
-
-    @Override
-    public void onDestroy() {
-        mPresenter.onDestroy();
-        mScheduledExecutorService.shutdown();
-        super.onDestroy();
-    }
-
-    @Override
-    public void onPause() {
-        mPresenter.onPause();
-        super.onPause();
-    }
-
-    private PlaybackViewImpl createPlaybackViewImpl() {
-        return new PlaybackViewImpl(new ActivityReference(), getActivity().getApplicationContext(),
-                mPlaybackLayout);
-    }
-
-    private MediaPlayerProxy createMediaPlayer(ExecutorService executorService) {
-        return VariableSpeed.createVariableSpeed(executorService);
-    }
-
-    private ScheduledExecutorService createScheduledExecutorService() {
-        return Executors.newScheduledThreadPool(NUMBER_OF_THREADS_IN_POOL);
-    }
-
-    /**
-     * Formats a number of milliseconds as something that looks like {@code 00:05}.
-     * <p>
-     * We always use four digits, two for minutes two for seconds.  In the very unlikely event
-     * that the voicemail duration exceeds 99 minutes, the display is capped at 99 minutes.
-     */
-    private static String formatAsMinutesAndSeconds(int millis) {
-        int seconds = millis / 1000;
-        int minutes = seconds / 60;
-        seconds -= minutes * 60;
-        if (minutes > 99) {
-            minutes = 99;
-        }
-        return String.format("%02d:%02d", minutes, seconds);
-    }
-
-    /**
-     * An object that can provide us with an Activity.
-     * <p>
-     * Fragments suffer the drawback that the Activity they belong to may sometimes be null. This
-     * can happen if the Fragment is detached, for example. In that situation a call to
-     * {@link Fragment#getString(int)} will throw and {@link IllegalStateException}. Also, calling
-     * {@link Fragment#getActivity()} is dangerous - it may sometimes return null. And thus blindly
-     * calling a method on the result of getActivity() is dangerous too.
-     * <p>
-     * To work around this, I have made the {@link PlaybackViewImpl} class static, so that it does
-     * not have access to any Fragment methods directly. Instead it uses an application Context for
-     * things like accessing strings, accessing system services. It only uses the Activity when it
-     * absolutely needs it - and does so through this class. This makes it easy to see where we have
-     * to check for null properly.
-     */
-    private final class ActivityReference {
-        /** Gets this Fragment's Activity: <b>may be null</b>. */
-        public final Activity get() {
-            return getActivity();
-        }
-    }
-
-    /**  Methods required by the PlaybackView for the VoicemailPlaybackPresenter. */
-    private static final class PlaybackViewImpl implements VoicemailPlaybackPresenter.PlaybackView {
-        private final ActivityReference mActivityReference;
-        private final Context mApplicationContext;
-        private final SeekBar mPlaybackSeek;
-        private final ImageButton mStartStopButton;
-        private final ImageButton mPlaybackSpeakerphone;
-        private final ImageButton mRateDecreaseButton;
-        private final ImageButton mRateIncreaseButton;
-        private final TextViewWithMessagesController mTextController;
-
-        public PlaybackViewImpl(ActivityReference activityReference, Context applicationContext,
-                View playbackLayout) {
-            Preconditions.checkNotNull(activityReference);
-            Preconditions.checkNotNull(applicationContext);
-            Preconditions.checkNotNull(playbackLayout);
-            mActivityReference = activityReference;
-            mApplicationContext = applicationContext;
-            mPlaybackSeek = (SeekBar) playbackLayout.findViewById(R.id.playback_seek);
-            mStartStopButton = (ImageButton) playbackLayout.findViewById(
-                    R.id.playback_start_stop);
-            mPlaybackSpeakerphone = (ImageButton) playbackLayout.findViewById(
-                    R.id.playback_speakerphone);
-            mRateDecreaseButton = (ImageButton) playbackLayout.findViewById(
-                    R.id.rate_decrease_button);
-            mRateIncreaseButton = (ImageButton) playbackLayout.findViewById(
-                    R.id.rate_increase_button);
-            mTextController = new TextViewWithMessagesController(
-                    (TextView) playbackLayout.findViewById(R.id.playback_position_text),
-                    (TextView) playbackLayout.findViewById(R.id.playback_speed_text));
-        }
-
-        @Override
-        public void finish() {
-            Activity activity = mActivityReference.get();
-            if (activity != null) {
-                activity.finish();
-            }
-        }
-
-        @Override
-        public void runOnUiThread(Runnable runnable) {
-            Activity activity = mActivityReference.get();
-            if (activity != null) {
-                activity.runOnUiThread(runnable);
-            }
-        }
-
-        @Override
-        public Context getDataSourceContext() {
-            return mApplicationContext;
-        }
-
-        @Override
-        public void setRateDecreaseButtonListener(View.OnClickListener listener) {
-            mRateDecreaseButton.setOnClickListener(listener);
-        }
-
-        @Override
-        public void setRateIncreaseButtonListener(View.OnClickListener listener) {
-            mRateIncreaseButton.setOnClickListener(listener);
-        }
-
-        @Override
-        public void setStartStopListener(View.OnClickListener listener) {
-            mStartStopButton.setOnClickListener(listener);
-        }
-
-        @Override
-        public void setSpeakerphoneListener(View.OnClickListener listener) {
-            mPlaybackSpeakerphone.setOnClickListener(listener);
-        }
-
-        @Override
-        public void setRateDisplay(float rate, int stringResourceId) {
-            mTextController.setTemporaryText(
-                    mApplicationContext.getString(stringResourceId), 1, TimeUnit.SECONDS);
-        }
-
-        @Override
-        public void setPositionSeekListener(SeekBar.OnSeekBarChangeListener listener) {
-            mPlaybackSeek.setOnSeekBarChangeListener(listener);
-        }
-
-        @Override
-        public void playbackStarted() {
-            mStartStopButton.setImageResource(R.drawable.ic_hold_pause_holo_dark);
-        }
-
-        @Override
-        public void playbackStopped() {
-            mStartStopButton.setImageResource(R.drawable.ic_play);
-        }
-
-        @Override
-        public void enableProximitySensor() {
-            // Only change the state if the activity is still around.
-            Activity activity = mActivityReference.get();
-            if (activity != null && activity instanceof ProximitySensorAware) {
-                ((ProximitySensorAware) activity).enableProximitySensor();
-            }
-        }
-
-        @Override
-        public void disableProximitySensor() {
-            // Only change the state if the activity is still around.
-            Activity activity = mActivityReference.get();
-            if (activity != null && activity instanceof ProximitySensorAware) {
-                ((ProximitySensorAware) activity).disableProximitySensor(true);
-            }
-        }
-
-        @Override
-        public void registerContentObserver(Uri uri, ContentObserver observer) {
-            mApplicationContext.getContentResolver().registerContentObserver(uri, false, observer);
-        }
-
-        @Override
-        public void unregisterContentObserver(ContentObserver observer) {
-            mApplicationContext.getContentResolver().unregisterContentObserver(observer);
-        }
-
-        @Override
-        public void setClipPosition(int clipPositionInMillis, int clipLengthInMillis) {
-            int seekBarPosition = Math.max(0, clipPositionInMillis);
-            int seekBarMax = Math.max(seekBarPosition, clipLengthInMillis);
-            if (mPlaybackSeek.getMax() != seekBarMax) {
-                mPlaybackSeek.setMax(seekBarMax);
-            }
-            mPlaybackSeek.setProgress(seekBarPosition);
-            mTextController.setPermanentText(
-                    formatAsMinutesAndSeconds(seekBarMax - seekBarPosition));
-        }
-
-        private String getString(int resId) {
-            return mApplicationContext.getString(resId);
-        }
-
-        @Override
-        public void setIsBuffering() {
-            disableUiElements();
-            mTextController.setPermanentText(getString(R.string.voicemail_buffering));
-        }
-
-        @Override
-        public void setIsFetchingContent() {
-            disableUiElements();
-            mTextController.setPermanentText(getString(R.string.voicemail_fetching_content));
-        }
-
-        @Override
-        public void setFetchContentTimeout() {
-            disableUiElements();
-            mTextController.setPermanentText(getString(R.string.voicemail_fetching_timout));
-        }
-
-        @Override
-        public int getDesiredClipPosition() {
-            return mPlaybackSeek.getProgress();
-        }
-
-        @Override
-        public void disableUiElements() {
-            mRateIncreaseButton.setEnabled(false);
-            mRateDecreaseButton.setEnabled(false);
-            mStartStopButton.setEnabled(false);
-            mPlaybackSpeakerphone.setEnabled(false);
-            mPlaybackSeek.setProgress(0);
-            mPlaybackSeek.setEnabled(false);
-        }
-
-        @Override
-        public void playbackError(Exception e) {
-            disableUiElements();
-            mTextController.setPermanentText(getString(R.string.voicemail_playback_error));
-            Log.e(TAG, "Could not play voicemail", e);
-        }
-
-        @Override
-        public void enableUiElements() {
-            mRateIncreaseButton.setEnabled(true);
-            mRateDecreaseButton.setEnabled(true);
-            mStartStopButton.setEnabled(true);
-            mPlaybackSpeakerphone.setEnabled(true);
-            mPlaybackSeek.setEnabled(true);
-        }
-
-        @Override
-        public void sendFetchVoicemailRequest(Uri voicemailUri) {
-            Intent intent = new Intent(VoicemailContract.ACTION_FETCH_VOICEMAIL, voicemailUri);
-            mApplicationContext.sendBroadcast(intent);
-        }
-
-        @Override
-        public boolean queryHasContent(Uri voicemailUri) {
-            ContentResolver contentResolver = mApplicationContext.getContentResolver();
-            Cursor cursor = contentResolver.query(
-                    voicemailUri, HAS_CONTENT_PROJECTION, null, null, null);
-            try {
-                if (cursor != null && cursor.moveToNext()) {
-                    return cursor.getInt(cursor.getColumnIndexOrThrow(
-                            VoicemailContract.Voicemails.HAS_CONTENT)) == 1;
-                }
-            } finally {
-                MoreCloseables.closeQuietly(cursor);
-            }
-            return false;
-        }
-
-        private AudioManager getAudioManager() {
-            return (AudioManager) mApplicationContext.getSystemService(Context.AUDIO_SERVICE);
-        }
-
-        @Override
-        public boolean isSpeakerPhoneOn() {
-            return getAudioManager().isSpeakerphoneOn();
-        }
-
-        @Override
-        public void setSpeakerPhoneOn(boolean on) {
-            getAudioManager().setSpeakerphoneOn(on);
-            if (on) {
-                mPlaybackSpeakerphone.setImageResource(R.drawable.ic_speakerphone_on);
-            } else {
-                mPlaybackSpeakerphone.setImageResource(R.drawable.ic_speakerphone_off);
-            }
-        }
-
-        @Override
-        public void setVolumeControlStream(int streamType) {
-            Activity activity = mActivityReference.get();
-            if (activity != null) {
-                activity.setVolumeControlStream(streamType);
-            }
-        }
-    }
-
-    /**
-     * Controls a TextView with dynamically changing text.
-     * <p>
-     * There are two methods here of interest,
-     * {@link TextViewWithMessagesController#setPermanentText(String)} and
-     * {@link TextViewWithMessagesController#setTemporaryText(String, long, TimeUnit)}.  The
-     * former is used to set the text on the text view immediately, and is used in our case for
-     * the countdown of duration remaining during voicemail playback.  The second is used to
-     * temporarily replace this countdown with a message, in our case faster voicemail speed or
-     * slower voicemail speed, before returning to the countdown display.
-     * <p>
-     * All the methods on this class must be called from the ui thread.
-     */
-    private static final class TextViewWithMessagesController {
-        private static final float VISIBLE = 1;
-        private static final float INVISIBLE = 0;
-        private static final long SHORT_ANIMATION_MS = 200;
-        private static final long LONG_ANIMATION_MS = 400;
-        private final Object mLock = new Object();
-        private final TextView mPermanentTextView;
-        private final TextView mTemporaryTextView;
-        @GuardedBy("mLock") private Runnable mRunnable;
-
-        public TextViewWithMessagesController(TextView permanentTextView,
-                TextView temporaryTextView) {
-            mPermanentTextView = permanentTextView;
-            mTemporaryTextView = temporaryTextView;
-        }
-
-        public void setPermanentText(String text) {
-            mPermanentTextView.setText(text);
-        }
-
-        public void setTemporaryText(String text, long duration, TimeUnit units) {
-            synchronized (mLock) {
-                mTemporaryTextView.setText(text);
-                mTemporaryTextView.animate().alpha(VISIBLE).setDuration(SHORT_ANIMATION_MS);
-                mPermanentTextView.animate().alpha(INVISIBLE).setDuration(SHORT_ANIMATION_MS);
-                mRunnable = new Runnable() {
-                    @Override
-                    public void run() {
-                        synchronized (mLock) {
-                            // We check for (mRunnable == this) becuase if not true, then another
-                            // setTemporaryText call has taken place in the meantime, and this
-                            // one is now defunct and needs to take no action.
-                            if (mRunnable == this) {
-                                mRunnable = null;
-                                mTemporaryTextView.animate()
-                                        .alpha(INVISIBLE).setDuration(LONG_ANIMATION_MS);
-                                mPermanentTextView.animate()
-                                        .alpha(VISIBLE).setDuration(LONG_ANIMATION_MS);
-                            }
-                        }
-                    }
-                };
-                mTemporaryTextView.postDelayed(mRunnable, units.toMillis(duration));
-            }
-        }
-    }
-}
diff --git a/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java b/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
deleted file mode 100644
index 2c7ba52..0000000
--- a/src/com/android/contacts/voicemail/VoicemailPlaybackPresenter.java
+++ /dev/null
@@ -1,630 +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.util.MathUtils.constrain;
-
-import android.content.Context;
-import android.database.ContentObserver;
-import android.media.AudioManager;
-import android.media.MediaPlayer;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.PowerManager;
-import android.view.View;
-import android.widget.SeekBar;
-
-import com.android.contacts.R;
-import com.android.contacts.util.AsyncTaskExecutor;
-import com.android.ex.variablespeed.MediaPlayerProxy;
-import com.android.ex.variablespeed.SingleThreadedMediaPlayerProxy;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.NotThreadSafe;
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * Contains the controlling logic for a voicemail playback ui.
- * <p>
- * Specifically right now this class is used to control the
- * {@link com.android.contacts.voicemail.VoicemailPlaybackFragment}.
- * <p>
- * This class is not thread safe. The thread policy for this class is
- * thread-confinement, all calls into this class from outside must be done from
- * the main ui thread.
- */
-@NotThreadSafe
-@VisibleForTesting
-public class VoicemailPlaybackPresenter {
-    /** The stream used to playback voicemail. */
-    private static final int PLAYBACK_STREAM = AudioManager.STREAM_VOICE_CALL;
-
-    /** Contract describing the behaviour we need from the ui we are controlling. */
-    public interface PlaybackView {
-        Context getDataSourceContext();
-        void runOnUiThread(Runnable runnable);
-        void setStartStopListener(View.OnClickListener listener);
-        void setPositionSeekListener(SeekBar.OnSeekBarChangeListener listener);
-        void setSpeakerphoneListener(View.OnClickListener listener);
-        void setIsBuffering();
-        void setClipPosition(int clipPositionInMillis, int clipLengthInMillis);
-        int getDesiredClipPosition();
-        void playbackStarted();
-        void playbackStopped();
-        void playbackError(Exception e);
-        boolean isSpeakerPhoneOn();
-        void setSpeakerPhoneOn(boolean on);
-        void finish();
-        void setRateDisplay(float rate, int stringResourceId);
-        void setRateIncreaseButtonListener(View.OnClickListener listener);
-        void setRateDecreaseButtonListener(View.OnClickListener listener);
-        void setIsFetchingContent();
-        void disableUiElements();
-        void enableUiElements();
-        void sendFetchVoicemailRequest(Uri voicemailUri);
-        boolean queryHasContent(Uri voicemailUri);
-        void setFetchContentTimeout();
-        void registerContentObserver(Uri uri, ContentObserver observer);
-        void unregisterContentObserver(ContentObserver observer);
-        void enableProximitySensor();
-        void disableProximitySensor();
-        void setVolumeControlStream(int streamType);
-    }
-
-    /** The enumeration of {@link AsyncTask} objects we use in this class. */
-    public enum Tasks {
-        CHECK_FOR_CONTENT,
-        CHECK_CONTENT_AFTER_CHANGE,
-        PREPARE_MEDIA_PLAYER,
-        RESET_PREPARE_START_MEDIA_PLAYER,
-    }
-
-    /** Update rate for the slider, 30fps. */
-    private static final int SLIDER_UPDATE_PERIOD_MILLIS = 1000 / 30;
-    /** Time our ui will wait for content to be fetched before reporting not available. */
-    private static final long FETCH_CONTENT_TIMEOUT_MS = 20000;
-    /**
-     * If present in the saved instance bundle, we should not resume playback on
-     * create.
-     */
-    private static final String PAUSED_STATE_KEY = VoicemailPlaybackPresenter.class.getName()
-            + ".PAUSED_STATE_KEY";
-    /**
-     * If present in the saved instance bundle, indicates where to set the
-     * playback slider.
-     */
-    private static final String CLIP_POSITION_KEY = VoicemailPlaybackPresenter.class.getName()
-            + ".CLIP_POSITION_KEY";
-
-    /** The preset variable-speed rates.  Each is greater than the previous by 25%. */
-    private static final float[] PRESET_RATES = new float[] {
-        0.64f, 0.8f, 1.0f, 1.25f, 1.5625f
-    };
-    /** The string resource ids corresponding to the names given to the above preset rates. */
-    private static final int[] PRESET_NAMES = new int[] {
-        R.string.voicemail_speed_slowest,
-        R.string.voicemail_speed_slower,
-        R.string.voicemail_speed_normal,
-        R.string.voicemail_speed_faster,
-        R.string.voicemail_speed_fastest,
-    };
-
-    /**
-     * Pointer into the {@link VoicemailPlaybackPresenter#PRESET_RATES} array.
-     * <p>
-     * This doesn't need to be synchronized, it's used only by the {@link RateChangeListener}
-     * which in turn is only executed on the ui thread.  This can't be encapsulated inside the
-     * rate change listener since multiple rate change listeners must share the same value.
-     */
-    private int mRateIndex = 2;
-
-    /**
-     * The most recently calculated duration.
-     * <p>
-     * We cache this in a field since we don't want to keep requesting it from the player, as
-     * this can easily lead to throwing {@link IllegalStateException} (any time the player is
-     * released, it's illegal to ask for the duration).
-     */
-    private final AtomicInteger mDuration = new AtomicInteger(0);
-
-    private final PlaybackView mView;
-    private final MediaPlayerProxy mPlayer;
-    private final PositionUpdater mPositionUpdater;
-
-    /** Voicemail uri to play. */
-    private final Uri mVoicemailUri;
-    /** Start playing in onCreate iff this is true. */
-    private final boolean mStartPlayingImmediately;
-    /** Used to run async tasks that need to interact with the ui. */
-    private final AsyncTaskExecutor mAsyncTaskExecutor;
-
-    /**
-     * Used to handle the result of a successful or time-out fetch result.
-     * <p>
-     * This variable is thread-contained, accessed only on the ui thread.
-     */
-    private FetchResultHandler mFetchResultHandler;
-    private PowerManager.WakeLock mWakeLock;
-    private AsyncTask<Void, ?, ?> mPrepareTask;
-
-    public VoicemailPlaybackPresenter(PlaybackView view, MediaPlayerProxy player,
-            Uri voicemailUri, ScheduledExecutorService executorService,
-            boolean startPlayingImmediately, AsyncTaskExecutor asyncTaskExecutor,
-            PowerManager.WakeLock wakeLock) {
-        mView = view;
-        mPlayer = player;
-        mVoicemailUri = voicemailUri;
-        mStartPlayingImmediately = startPlayingImmediately;
-        mAsyncTaskExecutor = asyncTaskExecutor;
-        mPositionUpdater = new PositionUpdater(executorService, SLIDER_UPDATE_PERIOD_MILLIS);
-        mWakeLock = wakeLock;
-    }
-
-    public void onCreate(Bundle bundle) {
-        mView.setVolumeControlStream(PLAYBACK_STREAM);
-        checkThatWeHaveContent();
-    }
-
-    /**
-     * Checks to see if we have content available for this voicemail.
-     * <p>
-     * This method will be called once, after the fragment has been created, before we know if the
-     * voicemail we've been asked to play has any content available.
-     * <p>
-     * This method will notify the user through the ui that we are fetching the content, then check
-     * to see if the content field in the db is set. If set, we proceed to
-     * {@link #postSuccessfullyFetchedContent()} method. If not set, we will make a request to fetch
-     * the content asynchronously via {@link #makeRequestForContent()}.
-     */
-    private void checkThatWeHaveContent() {
-        mView.setIsFetchingContent();
-        mAsyncTaskExecutor.submit(Tasks.CHECK_FOR_CONTENT, new AsyncTask<Void, Void, Boolean>() {
-            @Override
-            public Boolean doInBackground(Void... params) {
-                return mView.queryHasContent(mVoicemailUri);
-            }
-
-            @Override
-            public void onPostExecute(Boolean hasContent) {
-                if (hasContent) {
-                    postSuccessfullyFetchedContent();
-                } else {
-                    makeRequestForContent();
-                }
-            }
-        });
-    }
-
-    /**
-     * Makes a broadcast request to ask that a voicemail source fetch this content.
-     * <p>
-     * This method <b>must be called on the ui thread</b>.
-     * <p>
-     * This method will be called when we realise that we don't have content for this voicemail. It
-     * will trigger a broadcast to request that the content be downloaded. It will add a listener to
-     * the content resolver so that it will be notified when the has_content field changes. It will
-     * also set a timer. If the has_content field changes to true within the allowed time, we will
-     * proceed to {@link #postSuccessfullyFetchedContent()}. If the has_content field does not
-     * become true within the allowed time, we will update the ui to reflect the fact that content
-     * was not available.
-     */
-    private void makeRequestForContent() {
-        Handler handler = new Handler();
-        Preconditions.checkState(mFetchResultHandler == null, "mFetchResultHandler should be null");
-        mFetchResultHandler = new FetchResultHandler(handler);
-        mView.registerContentObserver(mVoicemailUri, mFetchResultHandler);
-        handler.postDelayed(mFetchResultHandler.getTimeoutRunnable(), FETCH_CONTENT_TIMEOUT_MS);
-        mView.sendFetchVoicemailRequest(mVoicemailUri);
-    }
-
-    @ThreadSafe
-    private class FetchResultHandler extends ContentObserver implements Runnable {
-        private AtomicBoolean mResultStillPending = new AtomicBoolean(true);
-        private final Handler mHandler;
-
-        public FetchResultHandler(Handler handler) {
-            super(handler);
-            mHandler = handler;
-        }
-
-        public Runnable getTimeoutRunnable() {
-            return this;
-        }
-
-        @Override
-        public void run() {
-            if (mResultStillPending.getAndSet(false)) {
-                mView.unregisterContentObserver(FetchResultHandler.this);
-                mView.setFetchContentTimeout();
-            }
-        }
-
-        public void destroy() {
-            if (mResultStillPending.getAndSet(false)) {
-                mView.unregisterContentObserver(FetchResultHandler.this);
-                mHandler.removeCallbacks(this);
-            }
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            mAsyncTaskExecutor.submit(Tasks.CHECK_CONTENT_AFTER_CHANGE,
-                    new AsyncTask<Void, Void, Boolean>() {
-                @Override
-                public Boolean doInBackground(Void... params) {
-                    return mView.queryHasContent(mVoicemailUri);
-                }
-
-                @Override
-                public void onPostExecute(Boolean hasContent) {
-                    if (hasContent) {
-                        if (mResultStillPending.getAndSet(false)) {
-                            mView.unregisterContentObserver(FetchResultHandler.this);
-                            postSuccessfullyFetchedContent();
-                        }
-                    }
-                }
-            });
-        }
-    }
-
-    /**
-     * Prepares the voicemail content for playback.
-     * <p>
-     * This method will be called once we know that our voicemail has content (according to the
-     * content provider). This method will try to prepare the data source through the media player.
-     * If preparing the media player works, we will call through to
-     * {@link #postSuccessfulPrepareActions()}. If preparing the media player fails (perhaps the
-     * file the content provider points to is actually missing, perhaps it is of an unknown file
-     * format that we can't play, who knows) then we will show an error on the ui.
-     */
-    private void postSuccessfullyFetchedContent() {
-        mView.setIsBuffering();
-        mAsyncTaskExecutor.submit(Tasks.PREPARE_MEDIA_PLAYER,
-                new AsyncTask<Void, Void, Exception>() {
-                    @Override
-                    public Exception doInBackground(Void... params) {
-                        try {
-                            mPlayer.reset();
-                            mPlayer.setDataSource(mView.getDataSourceContext(), mVoicemailUri);
-                            mPlayer.setAudioStreamType(PLAYBACK_STREAM);
-                            mPlayer.prepare();
-                            return null;
-                        } catch (Exception e) {
-                            return e;
-                        }
-                    }
-
-                    @Override
-                    public void onPostExecute(Exception exception) {
-                        if (exception == null) {
-                            postSuccessfulPrepareActions();
-                        } else {
-                            mView.playbackError(exception);
-                        }
-                    }
-                });
-    }
-
-    /**
-     * Enables the ui, and optionally starts playback immediately.
-     * <p>
-     * This will be called once we have successfully prepared the media player, and will optionally
-     * playback immediately.
-     */
-    private void postSuccessfulPrepareActions() {
-        mView.enableUiElements();
-        mView.setPositionSeekListener(new PlaybackPositionListener());
-        mView.setStartStopListener(new StartStopButtonListener());
-        mView.setSpeakerphoneListener(new SpeakerphoneListener());
-        mPlayer.setOnErrorListener(new MediaPlayerErrorListener());
-        mPlayer.setOnCompletionListener(new MediaPlayerCompletionListener());
-        mView.setSpeakerPhoneOn(mView.isSpeakerPhoneOn());
-        mView.setRateDecreaseButtonListener(createRateDecreaseListener());
-        mView.setRateIncreaseButtonListener(createRateIncreaseListener());
-        mView.setClipPosition(0, mPlayer.getDuration());
-        mView.playbackStopped();
-        // Always disable on stop.
-        mView.disableProximitySensor();
-        if (mStartPlayingImmediately) {
-            resetPrepareStartPlaying(0);
-        }
-        // TODO: Now I'm ignoring the bundle, when previously I was checking for contains against
-        // the PAUSED_STATE_KEY, and CLIP_POSITION_KEY.
-    }
-
-    public void onSaveInstanceState(Bundle outState) {
-        outState.putInt(CLIP_POSITION_KEY, mView.getDesiredClipPosition());
-        if (!mPlayer.isPlaying()) {
-            outState.putBoolean(PAUSED_STATE_KEY, true);
-        }
-    }
-
-    public void onDestroy() {
-        mPlayer.release();
-        if (mFetchResultHandler != null) {
-            mFetchResultHandler.destroy();
-            mFetchResultHandler = null;
-        }
-        mPositionUpdater.stopUpdating();
-        if (mWakeLock.isHeld()) {
-            mWakeLock.release();
-        }
-    }
-
-    private class MediaPlayerErrorListener implements MediaPlayer.OnErrorListener {
-        @Override
-        public boolean onError(MediaPlayer mp, int what, int extra) {
-            mView.runOnUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    handleError(new IllegalStateException("MediaPlayer error listener invoked"));
-                }
-            });
-            return true;
-        }
-    }
-
-    private class MediaPlayerCompletionListener implements MediaPlayer.OnCompletionListener {
-        @Override
-        public void onCompletion(final MediaPlayer mp) {
-            mView.runOnUiThread(new Runnable() {
-                @Override
-                public void run() {
-                    handleCompletion(mp);
-                }
-            });
-        }
-    }
-
-    public View.OnClickListener createRateDecreaseListener() {
-        return new RateChangeListener(false);
-    }
-
-    public View.OnClickListener createRateIncreaseListener() {
-        return new RateChangeListener(true);
-    }
-
-    /**
-     * Listens to clicks on the rate increase and decrease buttons.
-     * <p>
-     * This class is not thread-safe, but all interactions with it will happen on the ui thread.
-     */
-    private class RateChangeListener implements View.OnClickListener {
-        private final boolean mIncrease;
-
-        public RateChangeListener(boolean increase) {
-            mIncrease = increase;
-        }
-
-        @Override
-        public void onClick(View v) {
-            // Adjust the current rate, then clamp it to the allowed values.
-            mRateIndex = constrain(mRateIndex + (mIncrease ? 1 : -1), 0, PRESET_RATES.length - 1);
-            // Whether or not we have actually changed the index, call changeRate().
-            // This will ensure that we show the "fastest" or "slowest" text on the ui to indicate
-            // to the user that it doesn't get any faster or slower.
-            changeRate(PRESET_RATES[mRateIndex], PRESET_NAMES[mRateIndex]);
-        }
-    }
-
-    private void resetPrepareStartPlaying(final int clipPositionInMillis) {
-        if (mPrepareTask != null) {
-            mPrepareTask.cancel(false);
-        }
-        mPrepareTask = mAsyncTaskExecutor.submit(Tasks.RESET_PREPARE_START_MEDIA_PLAYER,
-                new AsyncTask<Void, Void, Exception>() {
-                    @Override
-                    public Exception doInBackground(Void... params) {
-                        try {
-                            mPlayer.reset();
-                            mPlayer.setDataSource(mView.getDataSourceContext(), mVoicemailUri);
-                            mPlayer.setAudioStreamType(PLAYBACK_STREAM);
-                            mPlayer.prepare();
-                            return null;
-                        } catch (Exception e) {
-                            return e;
-                        }
-                    }
-
-                    @Override
-                    public void onPostExecute(Exception exception) {
-                        mPrepareTask = null;
-                        if (exception == null) {
-                            mDuration.set(mPlayer.getDuration());
-                            int startPosition =
-                                    constrain(clipPositionInMillis, 0, mDuration.get());
-                            mView.setClipPosition(startPosition, mDuration.get());
-                            mPlayer.seekTo(startPosition);
-                            mPlayer.start();
-                            mView.playbackStarted();
-                            if (!mWakeLock.isHeld()) {
-                                mWakeLock.acquire();
-                            }
-                            // Only enable if we are not currently using the speaker phone.
-                            if (!mView.isSpeakerPhoneOn()) {
-                                mView.enableProximitySensor();
-                            }
-                            mPositionUpdater.startUpdating(startPosition, mDuration.get());
-                        } else {
-                            handleError(exception);
-                        }
-                    }
-                });
-    }
-
-    private void handleError(Exception e) {
-        mView.playbackError(e);
-        mPositionUpdater.stopUpdating();
-        mPlayer.release();
-    }
-
-    public void handleCompletion(MediaPlayer mediaPlayer) {
-        stopPlaybackAtPosition(0, mDuration.get());
-    }
-
-    private void stopPlaybackAtPosition(int clipPosition, int duration) {
-        mPositionUpdater.stopUpdating();
-        mView.playbackStopped();
-        if (mWakeLock.isHeld()) {
-            mWakeLock.release();
-        }
-        // Always disable on stop.
-        mView.disableProximitySensor();
-        mView.setClipPosition(clipPosition, duration);
-        if (mPlayer.isPlaying()) {
-            mPlayer.pause();
-        }
-    }
-
-    private class PlaybackPositionListener implements SeekBar.OnSeekBarChangeListener {
-        private boolean mShouldResumePlaybackAfterSeeking;
-
-        @Override
-        public void onStartTrackingTouch(SeekBar arg0) {
-            if (mPlayer.isPlaying()) {
-                mShouldResumePlaybackAfterSeeking = true;
-                stopPlaybackAtPosition(mPlayer.getCurrentPosition(), mDuration.get());
-            } else {
-                mShouldResumePlaybackAfterSeeking = false;
-            }
-        }
-
-        @Override
-        public void onStopTrackingTouch(SeekBar arg0) {
-            if (mPlayer.isPlaying()) {
-                stopPlaybackAtPosition(mPlayer.getCurrentPosition(), mDuration.get());
-            }
-            if (mShouldResumePlaybackAfterSeeking) {
-                resetPrepareStartPlaying(mView.getDesiredClipPosition());
-            }
-        }
-
-        @Override
-        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-            mView.setClipPosition(seekBar.getProgress(), seekBar.getMax());
-        }
-    }
-
-    private void changeRate(float rate, int stringResourceId) {
-        ((SingleThreadedMediaPlayerProxy) mPlayer).setVariableSpeed(rate);
-        mView.setRateDisplay(rate, stringResourceId);
-    }
-
-    private class SpeakerphoneListener implements View.OnClickListener {
-        @Override
-        public void onClick(View v) {
-            boolean previousState = mView.isSpeakerPhoneOn();
-            mView.setSpeakerPhoneOn(!previousState);
-            if (mPlayer.isPlaying() && previousState) {
-                // If we are currently playing and we are disabling the speaker phone, enable the
-                // sensor.
-                mView.enableProximitySensor();
-            } else {
-                // If we are not currently playing, disable the sensor.
-                mView.disableProximitySensor();
-            }
-        }
-    }
-
-    private class StartStopButtonListener implements View.OnClickListener {
-        @Override
-        public void onClick(View arg0) {
-            if (mPlayer.isPlaying()) {
-                stopPlaybackAtPosition(mPlayer.getCurrentPosition(), mDuration.get());
-            } else {
-                resetPrepareStartPlaying(mView.getDesiredClipPosition());
-            }
-        }
-    }
-
-    /**
-     * Controls the animation of the playback slider.
-     */
-    @ThreadSafe
-    private final class PositionUpdater implements Runnable {
-        private final ScheduledExecutorService mExecutorService;
-        private final int mPeriodMillis;
-        private final Object mLock = new Object();
-        @GuardedBy("mLock") private ScheduledFuture<?> mScheduledFuture;
-        private final Runnable mSetClipPostitionRunnable = new Runnable() {
-            @Override
-            public void run() {
-                int currentPosition = 0;
-                synchronized (mLock) {
-                    if (mScheduledFuture == null) {
-                        // This task has been canceled. Just stop now.
-                        return;
-                    }
-                    currentPosition = mPlayer.getCurrentPosition();
-                }
-                mView.setClipPosition(currentPosition, mDuration.get());
-            }
-        };
-
-        public PositionUpdater(ScheduledExecutorService executorService, int periodMillis) {
-            mExecutorService = executorService;
-            mPeriodMillis = periodMillis;
-        }
-
-        @Override
-        public void run() {
-            mView.runOnUiThread(mSetClipPostitionRunnable);
-        }
-
-        public void startUpdating(int beginPosition, int endPosition) {
-            synchronized (mLock) {
-                if (mScheduledFuture != null) {
-                    mScheduledFuture.cancel(false);
-                }
-                mScheduledFuture = mExecutorService.scheduleAtFixedRate(this, 0, mPeriodMillis,
-                        TimeUnit.MILLISECONDS);
-            }
-        }
-
-        public void stopUpdating() {
-            synchronized (mLock) {
-                if (mScheduledFuture != null) {
-                    mScheduledFuture.cancel(false);
-                    mScheduledFuture = null;
-                }
-            }
-        }
-    }
-
-    public void onPause() {
-        if (mPlayer.isPlaying()) {
-            stopPlaybackAtPosition(mPlayer.getCurrentPosition(), mDuration.get());
-        }
-        if (mPrepareTask != null) {
-            mPrepareTask.cancel(false);
-        }
-        if (mWakeLock.isHeld()) {
-            mWakeLock.release();
-        }
-    }
-}
diff --git a/src/com/android/contacts/voicemail/VoicemailStatusHelper.java b/src/com/android/contacts/voicemail/VoicemailStatusHelper.java
deleted file mode 100644
index 6664b88..0000000
--- a/src/com/android/contacts/voicemail/VoicemailStatusHelper.java
+++ /dev/null
@@ -1,86 +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 android.database.Cursor;
-import android.net.Uri;
-import android.provider.VoicemailContract.Status;
-
-import java.util.List;
-
-/**
- * Interface used by the call log UI to determine what user message, if any, related to voicemail
- * source status needs to be shown. The messages are returned in the order of importance.
- * <p>
- * The implementation of this interface interacts with the voicemail content provider to fetch
- * statuses of all the registered voicemail sources and determines if any status message needs to
- * be shown. The user of this interface must observe/listen to provider changes and invoke
- * this class to check if any message needs to be shown.
- */
-public interface VoicemailStatusHelper {
-    public class StatusMessage {
-        /** Package of the source on behalf of which this message has to be shown.*/
-        public final String sourcePackage;
-        /**
-         * The string resource id of the status message that should be shown in the call log
-         * page. Set to -1, if this message is not to be shown in call log.
-         */
-        public final int callLogMessageId;
-        /**
-         * The string resource id of the status message that should be shown in the call details
-         * page. Set to -1, if this message is not to be shown in call details page.
-         */
-        public final int callDetailsMessageId;
-        /** The string resource id of the action message that should be shown. */
-        public final int actionMessageId;
-        /** URI for the corrective action, where applicable. Null if no action URI is available. */
-        public final Uri actionUri;
-        public StatusMessage(String sourcePackage, int callLogMessageId, int callDetailsMessageId,
-                int actionMessageId, Uri actionUri) {
-            this.sourcePackage = sourcePackage;
-            this.callLogMessageId = callLogMessageId;
-            this.callDetailsMessageId = callDetailsMessageId;
-            this.actionMessageId = actionMessageId;
-            this.actionUri = actionUri;
-        }
-
-        /** Whether this message should be shown in the call log page. */
-        public boolean showInCallLog() {
-            return callLogMessageId != -1;
-        }
-
-        /** Whether this message should be shown in the call details page. */
-        public boolean showInCallDetails() {
-            return callDetailsMessageId != -1;
-        }
-    }
-
-    /**
-     * Returns a list of messages, in the order or priority that should be shown to the user. An
-     * empty list is returned if no message needs to be shown.
-     * @param cursor The cursor pointing to the query on {@link Status#CONTENT_URI}. The projection
-     *      to be used is defined by the implementation class of this interface.
-     */
-    public List<StatusMessage> getStatusMessages(Cursor cursor);
-
-    /**
-     * Returns the number of active voicemail sources installed.
-     * <p>
-     * The number of sources is counted by querying the voicemail status table.
-     */
-    public int getNumberActivityVoicemailSources(Cursor cursor);
-}
diff --git a/src/com/android/contacts/voicemail/VoicemailStatusHelperImpl.java b/src/com/android/contacts/voicemail/VoicemailStatusHelperImpl.java
deleted file mode 100644
index c7f9c8f..0000000
--- a/src/com/android/contacts/voicemail/VoicemailStatusHelperImpl.java
+++ /dev/null
@@ -1,272 +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_CAN_BE_CONFIGURED;
-import static android.provider.VoicemailContract.Status.CONFIGURATION_STATE_OK;
-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_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.database.Cursor;
-import android.net.Uri;
-import android.provider.VoicemailContract.Status;
-
-import com.android.contacts.R;
-import com.android.contacts.util.UriUtils;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-/** Implementation of {@link VoicemailStatusHelper}. */
-public class VoicemailStatusHelperImpl implements VoicemailStatusHelper {
-    private static final int SOURCE_PACKAGE_INDEX = 0;
-    private static final int CONFIGURATION_STATE_INDEX = 1;
-    private static final int DATA_CHANNEL_STATE_INDEX = 2;
-    private static final int NOTIFICATION_CHANNEL_STATE_INDEX = 3;
-    private static final int SETTINGS_URI_INDEX = 4;
-    private static final int VOICEMAIL_ACCESS_URI_INDEX = 5;
-    private static final int NUM_COLUMNS = 6;
-    /** Projection on the voicemail_status table used by this class. */
-    public static final String[] PROJECTION = new String[NUM_COLUMNS];
-    static {
-        PROJECTION[SOURCE_PACKAGE_INDEX] = Status.SOURCE_PACKAGE;
-        PROJECTION[CONFIGURATION_STATE_INDEX] = Status.CONFIGURATION_STATE;
-        PROJECTION[DATA_CHANNEL_STATE_INDEX] = Status.DATA_CHANNEL_STATE;
-        PROJECTION[NOTIFICATION_CHANNEL_STATE_INDEX] = Status.NOTIFICATION_CHANNEL_STATE;
-        PROJECTION[SETTINGS_URI_INDEX] = Status.SETTINGS_URI;
-        PROJECTION[VOICEMAIL_ACCESS_URI_INDEX] = Status.VOICEMAIL_ACCESS_URI;
-    }
-
-    /** Possible user actions. */
-    public static enum Action {
-        NONE(-1),
-        CALL_VOICEMAIL(R.string.voicemail_status_action_call_server),
-        CONFIGURE_VOICEMAIL(R.string.voicemail_status_action_configure);
-
-        private final int mMessageId;
-        private Action(int messageId) {
-            mMessageId = messageId;
-        }
-
-        public int getMessageId() {
-            return mMessageId;
-        }
-    }
-
-    /**
-     * Overall state of the source status. Each state is associated with the corresponding display
-     * string and the corrective action. The states are also assigned a relative priority which is
-     * used to order the messages from different sources.
-     */
-    private static enum OverallState {
-        // TODO: Add separate string for call details and call log pages for the states that needs
-        // to be shown in both.
-        /** Both notification and data channel are not working. */
-        NO_CONNECTION(0, Action.CALL_VOICEMAIL, R.string.voicemail_status_voicemail_not_available,
-                R.string.voicemail_status_audio_not_available),
-        /** Notifications working, but data channel is not working. Audio cannot be downloaded. */
-        NO_DATA(1, Action.CALL_VOICEMAIL, R.string.voicemail_status_voicemail_not_available,
-                R.string.voicemail_status_audio_not_available),
-        /** Messages are known to be waiting but data channel is not working. */
-        MESSAGE_WAITING(2, Action.CALL_VOICEMAIL, R.string.voicemail_status_messages_waiting,
-                R.string.voicemail_status_audio_not_available),
-        /** Notification channel not working, but data channel is. */
-        NO_NOTIFICATIONS(3, Action.CALL_VOICEMAIL,
-                R.string.voicemail_status_voicemail_not_available),
-        /** Invite user to set up voicemail. */
-        INVITE_FOR_CONFIGURATION(4, Action.CONFIGURE_VOICEMAIL,
-                R.string.voicemail_status_configure_voicemail),
-        /**
-         * No detailed notifications, but data channel is working.
-         * This is normal mode of operation for certain sources. No action needed.
-         */
-        NO_DETAILED_NOTIFICATION(5, Action.NONE, -1),
-        /** Visual voicemail not yet set up. No local action needed. */
-        NOT_CONFIGURED(6, Action.NONE, -1),
-        /** Everything is OK. */
-        OK(7, Action.NONE, -1),
-        /** If one or more state value set by the source is not valid. */
-        INVALID(8, Action.NONE, -1);
-
-        private final int mPriority;
-        private final Action mAction;
-        private final int mCallLogMessageId;
-        private final int mCallDetailsMessageId;
-
-        private OverallState(int priority, Action action, int callLogMessageId) {
-            this(priority, action, callLogMessageId, -1);
-        }
-
-        private OverallState(int priority, Action action, int callLogMessageId,
-                int callDetailsMessageId) {
-            mPriority = priority;
-            mAction = action;
-            mCallLogMessageId = callLogMessageId;
-            mCallDetailsMessageId = callDetailsMessageId;
-        }
-
-        public Action getAction() {
-            return mAction;
-        }
-
-        public int getPriority() {
-            return mPriority;
-        }
-
-        public int getCallLogMessageId() {
-            return mCallLogMessageId;
-        }
-
-        public int getCallDetailsMessageId() {
-            return mCallDetailsMessageId;
-        }
-    }
-
-    /** A wrapper on {@link StatusMessage} which additionally stores the priority of the message. */
-    private static class MessageStatusWithPriority {
-        private final StatusMessage mMessage;
-        private final int mPriority;
-
-        public MessageStatusWithPriority(StatusMessage message, int priority) {
-            mMessage = message;
-            mPriority = priority;
-        }
-    }
-
-    @Override
-    public List<StatusMessage> getStatusMessages(Cursor cursor) {
-        List<MessageStatusWithPriority> messages =
-            new ArrayList<VoicemailStatusHelperImpl.MessageStatusWithPriority>();
-        cursor.moveToPosition(-1);
-        while(cursor.moveToNext()) {
-            MessageStatusWithPriority message = getMessageForStatusEntry(cursor);
-            if (message != null) {
-                messages.add(message);
-            }
-        }
-        // Finally reorder the messages by their priority.
-        return reorderMessages(messages);
-    }
-
-    @Override
-    public int getNumberActivityVoicemailSources(Cursor cursor) {
-        int count = 0;
-        cursor.moveToPosition(-1);
-        while(cursor.moveToNext()) {
-            if (isVoicemailSourceActive(cursor)) {
-                ++count;
-            }
-        }
-        return count;
-    }
-
-    /** Returns whether the source status in the cursor corresponds to an active source. */
-    private boolean isVoicemailSourceActive(Cursor cursor) {
-        return cursor.getString(SOURCE_PACKAGE_INDEX) != null
-                &&  cursor.getInt(CONFIGURATION_STATE_INDEX) == Status.CONFIGURATION_STATE_OK;
-    }
-
-    private List<StatusMessage> reorderMessages(List<MessageStatusWithPriority> messageWrappers) {
-        Collections.sort(messageWrappers, new Comparator<MessageStatusWithPriority>() {
-            @Override
-            public int compare(MessageStatusWithPriority msg1, MessageStatusWithPriority msg2) {
-                return msg1.mPriority - msg2.mPriority;
-            }
-        });
-        List<StatusMessage> reorderMessages = new ArrayList<VoicemailStatusHelper.StatusMessage>();
-        // Copy the ordered message objects into the final list.
-        for (MessageStatusWithPriority messageWrapper : messageWrappers) {
-            reorderMessages.add(messageWrapper.mMessage);
-        }
-        return reorderMessages;
-    }
-
-    /**
-     * Returns the message for the status entry pointed to by the cursor.
-     */
-    private MessageStatusWithPriority getMessageForStatusEntry(Cursor cursor) {
-        final String sourcePackage = cursor.getString(SOURCE_PACKAGE_INDEX);
-        if (sourcePackage == null) {
-            return null;
-        }
-        final OverallState overallState = getOverallState(cursor.getInt(CONFIGURATION_STATE_INDEX),
-                cursor.getInt(DATA_CHANNEL_STATE_INDEX),
-                cursor.getInt(NOTIFICATION_CHANNEL_STATE_INDEX));
-        final Action action = overallState.getAction();
-
-        // No source package or no action, means no message shown.
-        if (action == Action.NONE) {
-            return null;
-        }
-
-        Uri actionUri = null;
-        if (action == Action.CALL_VOICEMAIL) {
-            actionUri = UriUtils.parseUriOrNull(cursor.getString(VOICEMAIL_ACCESS_URI_INDEX));
-            // Even if actionUri is null, it is still be useful to show the notification.
-        } else if (action == Action.CONFIGURE_VOICEMAIL) {
-            actionUri = UriUtils.parseUriOrNull(cursor.getString(SETTINGS_URI_INDEX));
-            // If there is no settings URI, there is no point in showing the notification.
-            if (actionUri == null) {
-                return null;
-            }
-        }
-        return new MessageStatusWithPriority(
-                new StatusMessage(sourcePackage, overallState.getCallLogMessageId(),
-                        overallState.getCallDetailsMessageId(), action.getMessageId(),
-                        actionUri),
-                overallState.getPriority());
-    }
-
-    private OverallState getOverallState(int configurationState, int dataChannelState,
-            int notificationChannelState) {
-        if (configurationState == CONFIGURATION_STATE_OK) {
-            // Voicemail is configured. Let's see how is the data channel.
-            if (dataChannelState == DATA_CHANNEL_STATE_OK) {
-                // Data channel is fine. What about notification channel?
-                if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_OK) {
-                    return OverallState.OK;
-                } else if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING) {
-                    return OverallState.NO_DETAILED_NOTIFICATION;
-                } else if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_NO_CONNECTION) {
-                    return OverallState.NO_NOTIFICATIONS;
-                }
-            } else if (dataChannelState == DATA_CHANNEL_STATE_NO_CONNECTION) {
-                // Data channel is not working. What about notification channel?
-                if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_OK) {
-                    return OverallState.NO_DATA;
-                } else if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_MESSAGE_WAITING) {
-                    return OverallState.MESSAGE_WAITING;
-                } else if (notificationChannelState == NOTIFICATION_CHANNEL_STATE_NO_CONNECTION) {
-                    return OverallState.NO_CONNECTION;
-                }
-            }
-        } else if (configurationState == CONFIGURATION_STATE_CAN_BE_CONFIGURED) {
-            // Voicemail not configured. data/notification channel states are irrelevant.
-            return OverallState.INVITE_FOR_CONFIGURATION;
-        } else if (configurationState == Status.CONFIGURATION_STATE_NOT_CONFIGURED) {
-            // Voicemail not configured. data/notification channel states are irrelevant.
-            return OverallState.NOT_CONFIGURED;
-        }
-        // Will reach here only if the source has set an invalid value.
-        return OverallState.INVALID;
-    }
-}
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();
-    }
-}
