Remove call log and sms permissions

Bug: 120483108
Test: Manual https://photos.app.goo.gl/ZkM7eyqoexYEnVzk6
Change-Id: I98f3f29c9d6da0dda1db974e599d369a5959a8c5
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4caa981..b0783d4 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -46,11 +46,6 @@
     <uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
     <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
-    <!-- Following used for QuickContacts -->
-    <uses-permission android:name="android.permission.READ_CALL_LOG"/>
-    <uses-permission android:name="android.permission.READ_SMS"/>
-    <uses-permission android:name="android.permission.READ_CALENDAR"/>
-    <uses-permission android:name="com.android.voicemail.permission.READ_VOICEMAIL"/>
     <!-- Following used for Contact metadata syncing -->
     <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
     <!-- Following used for getting the status of the contacts sync adapter -->
@@ -284,11 +279,6 @@
             android:theme="@style/PeopleTheme"/>
 
         <activity
-            android:name=".activities.RequestDesiredPermissionsActivity"
-            android:exported="false"
-            android:theme="@style/PeopleTheme"/>
-
-        <activity
             android:name=".activities.RequestImportVCardPermissionsActivity"
             android:exported="false"
             android:theme="@style/PeopleTheme"/>
diff --git a/proguard.flags b/proguard.flags
index 07ec5d2..782aa7e 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -32,8 +32,6 @@
 -keep class com.android.contacts.format.FormatUtils { *; }
 -keep class com.android.contacts.format.TextHighlighter { *; }
 -keep class com.android.contacts.group.GroupUtil { *; }
--keep class com.android.contacts.interactions.CallLogInteraction { *; }
--keep class com.android.contacts.interactions.CallLogInteractionsLoader { *; }
 -keep class com.android.contacts.interactions.ContactDeletionInteraction { *; }
 -keep class com.android.contacts.interactions.ContactInteractionUtil { *; }
 -keep class com.android.contacts.list.ContactListItemView { *; }
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d461455..56c4aaa 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -584,29 +584,11 @@
     <!-- Button Label to see less on an ExpandingEntryCardView [CHAR LIMIT=40] -->
     <string name="expanding_entry_card_view_see_less">See less</string>
 
-    <!-- Title of recent card. [CHAR LIMIT=60] -->
-    <string name="recent_card_title">Recent</string>
-
-    <!-- Title of recent card. [CHAR LIMIT=40] -->
+    <!-- Title of about card. [CHAR LIMIT=40] -->
     <string name="about_card_title">About</string>
 
     <!-- Toast that appears when you are copying a directory contact into your personal contacts -->
     <string name="toast_making_personal_copy">Creating a personal copy&#8230;</string>
-    <!-- Timestamp string for interactions from tomorrow. [CHAR LIMIT=40] -->
-    <string name="tomorrow">Tomorrow</string>
-    <!-- Timestamp string for interactions from today. [CHAR LIMIT=40] -->
-    <string name="today">Today</string>
-    <!-- Text for an event starting on the current day with a start and end time.
-         For ex, "Today at 5:00pm-6:00pm" [CHAR LIMIT=NONE] -->
-    <string name="today_at_time_fmt">"Today at <xliff:g id="time_interval">%s</xliff:g>"</string>
-    <!-- Text for an event starting on the next day with a start and end time.
-         For ex, "Tomorrow at 5:00pm-6:00pm" [CHAR LIMIT=NONE] -->
-    <string name="tomorrow_at_time_fmt">"Tomorrow at <xliff:g id="time_interval">%s</xliff:g>"</string>
-    <!-- Format string for a date and time description.  For ex:
-         "April 19, 2012, 3:00pm - 4:00pm" [CHAR LIMIT=NONE] -->
-    <string name="date_time_fmt">"<xliff:g id="date">%1$s</xliff:g>, <xliff:g id="time_interval">%2$s</xliff:g>"</string>
-    <!-- Title for untitled calendar interactions [CHAR LIMIT=40] -->
-    <string name="untitled_event">(Untitled event)</string>
 
     <!-- Name of the button in the date/time picker to accept the date/time change [CHAR LIMIT=15] -->
     <string name="date_time_set">Set</string>
@@ -635,22 +617,6 @@
     <!-- Content description for directions secondary button [CHAR LIMIT=NONE] -->
     <string name="content_description_directions">directions to location</string>
 
-    <!-- Content description for recent sms interaction [CHAR LIMIT=NONE] -->
-    <string name="content_description_recent_sms">recent sms. <xliff:g id="message_body">%1$s</xliff:g>. <xliff:g id="phone_number">%2$s</xliff:g>. <xliff:g id="date">%3$s</xliff:g>. click to respond</string>
-
-    <!-- Header for the Relation entry [CHAR LIMIT=NONE] -->
-    <string name="content_description_recent_call_type_incoming">incoming</string>
-    <!-- Header for the Relation entry [CHAR LIMIT=NONE] -->
-    <string name="content_description_recent_call_type_outgoing">outgoing</string>
-    <!-- Header for the Relation entry [CHAR LIMIT=NONE] -->
-    <string name="content_description_recent_call_type_missed">missed</string>
-
-    <!-- Content description for recent sms interaction [CHAR LIMIT=NONE] -->
-    <string name="content_description_recent_call">recent call. <xliff:g id="call_type">%1$s</xliff:g>. <xliff:g id="phone_number">%2$s</xliff:g>. <xliff:g id="date">%3$s</xliff:g>. click to call back</string>
-
-    <!-- Prefix for messages that you sent [CHAR LIMIT=40] -->
-    <string name="message_from_you_prefix">You: <xliff:g id="sms_body">%s</xliff:g></string>
-
     <!-- Button to expand the contact editor to show all available input fields. [CHAR LIMIT=60] -->
     <string name="editor_more_fields">More fields</string>
 
@@ -716,22 +682,6 @@
     <!-- Menu section title of "accounts" [CHAR LIMIT=20] -->
     <string name="menu_title_filters">Accounts</string>
 
-    <!-- Contacts app asking for permissions in QuickContact activity,
-         in order to display calendar and SMS history [CHAR LIMIT=60] -->
-    <string name="permission_explanation_header">See your history together</string>
-
-    <!-- Content displayed in QuickContact activity after Contacts app receiving
-         Calendar and SMS permissions [CHAR LIMIT=60] -->
-    <string name="permission_explanation_subheader_calendar_and_SMS">Events and messages</string>
-
-    <!-- Content displayed in QuickContact activity after Contacts app receiving
-         Calendar permission [CHAR LIMIT=40] -->
-    <string name="permission_explanation_subheader_calendar">Events</string>
-
-    <!-- Content displayed in QuickContact activity after Contacts app receiving
-         SMS permission [CHAR LIMIT=40] -->
-    <string name="permission_explanation_subheader_SMS">Messages</string>
-
     <!-- The header text for hamburger promo [CHAR LIMIT=60]-->
     <string name="hamburger_feature_highlight_header">Suggestions</string>
     <!-- The body text for hamburger promo [CHAR LIMIT=200]-->
@@ -1495,15 +1445,6 @@
     <!-- Content description for (...) in no name header [CHAR LIMIT=30]-->
     <string name="description_no_name_header">Ellipsis</string>
 
-    <!-- Formatted call duration displayed in recent card in QuickContact, for duration less than 1 minute -->
-    <string name="callDurationSecondFormat"><xliff:g id="seconds">%s</xliff:g> sec</string>
-
-    <!-- Formatted call duration displayed in recent card in QuickContact, for duration less than 1 hour -->
-    <string name="callDurationMinuteFormat"><xliff:g id="minutes">%1$s</xliff:g> min <xliff:g id="seconds">%2$s</xliff:g> sec</string>
-
-    <!-- Formatted call duration displayed in recent card in QuickContact, for duration more than 1 hour -->
-    <string name="callDurationHourFormat"><xliff:g id="minutes">%1$s</xliff:g> hr <xliff:g id="minutes">%2$s</xliff:g> min <xliff:g id="seconds">%3$s</xliff:g> sec</string>
-
     <!-- Toast shown when a dynamic shortcut is tapped after being disabled because the experiment was turned off on the device -->
     <string name="dynamic_shortcut_disabled_message">This shortcut has been disabled</string>
 
@@ -1592,4 +1533,4 @@
     <!-- Text of Negative Button in dialog -->
     <string name="no_button">No</string>
 
-</resources>
+</resources>
\ No newline at end of file
diff --git a/src/com/android/contacts/activities/RequestDesiredPermissionsActivity.java b/src/com/android/contacts/activities/RequestDesiredPermissionsActivity.java
deleted file mode 100644
index 0e0d5da..0000000
--- a/src/com/android/contacts/activities/RequestDesiredPermissionsActivity.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.activities;
-
-import android.Manifest.permission;
-import android.app.Activity;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.os.Bundle;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Requests permissions that are not absolutely required by the calling Activity;
- * if permissions are denied, the calling Activity is still restarted.
- *
- * Activities that have a set of permissions that must be granted in order for the Activity to
- * function propertly should call
- * {@link RequestPermissionsActivity#startPermissionActivity(Activity, String[], Class)}
- * before calling {@link RequestDesiredPermissionsActivity#startPermissionActivity(Activity)}.
- */
-public class RequestDesiredPermissionsActivity extends RequestPermissionsActivityBase {
-
-    private static String[] sDesiredPermissions;
-
-    @Override
-    protected String[] getPermissions() {
-        return getPermissions(getPackageManager());
-    }
-
-    /**
-     * If any desired permission that Contacts app needs are missing, open an Activity
-     * to prompt user for these permissions. After that calling activity is restarted
-     * and in the second run permission check is skipped.
-     *
-     * This is designed to be called inside {@link android.app.Activity#onCreate}
-     */
-    public static boolean startPermissionActivity(Activity activity) {
-        final Bundle extras = activity.getIntent().getExtras();
-        if (extras != null && extras.getBoolean(EXTRA_STARTED_PERMISSIONS_ACTIVITY, false)) {
-            return false;
-        }
-        return startPermissionActivity(activity,
-                getPermissions(activity.getPackageManager()),
-                RequestDesiredPermissionsActivity.class);
-    }
-
-    private static String[] getPermissions(PackageManager packageManager) {
-        if (sDesiredPermissions == null) {
-            final List<String> permissions = new ArrayList<>();
-            // Calendar group
-            permissions.add(permission.READ_CALENDAR);
-
-            if (packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
-                // SMS group
-                permissions.add(permission.READ_SMS);
-            }
-            sDesiredPermissions = permissions.toArray(new String[0]);
-        }
-        return sDesiredPermissions;
-    }
-
-    @Override
-    public void onRequestPermissionsResult(
-            int requestCode, String permissions[], int[] grantResults) {
-        mPreviousActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
-        startActivity(mPreviousActivityIntent);
-        overridePendingTransition(0, 0);
-
-        finish();
-        overridePendingTransition(0, 0);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/activities/RequestPermissionsActivity.java b/src/com/android/contacts/activities/RequestPermissionsActivity.java
index e086cea..aac8a6b 100644
--- a/src/com/android/contacts/activities/RequestPermissionsActivity.java
+++ b/src/com/android/contacts/activities/RequestPermissionsActivity.java
@@ -21,11 +21,9 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
-import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 import android.widget.Toast;
-
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
 import com.android.contacts.R;
-
 import java.util.ArrayList;
 import java.util.List;
 
@@ -70,7 +68,6 @@
                 // ImportExportDialogFragment.  We work around missing this permission when
                 // telephony is not available on the device (i.e. on tablets).
                 permissions.add(permission.CALL_PHONE);
-                permissions.add(permission.READ_CALL_LOG);
                 permissions.add(permission.READ_PHONE_STATE);
             }
             sRequiredPermissions = permissions.toArray(new String[0]);
diff --git a/src/com/android/contacts/interactions/CalendarInteraction.java b/src/com/android/contacts/interactions/CalendarInteraction.java
deleted file mode 100644
index 9b7ab31..0000000
--- a/src/com/android/contacts/interactions/CalendarInteraction.java
+++ /dev/null
@@ -1,288 +0,0 @@
-package com.android.contacts.interactions;
-
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.provider.CalendarContract.Attendees;
-import android.provider.CalendarContract.Events;
-import android.text.Spannable;
-import android.text.TextUtils;
-import android.text.format.Time;
-
-import com.android.contacts.R;
-
-/**
- * Represents a calendar event interaction, wrapping the columns in
- * {@link android.provider.CalendarContract.Attendees}.
- */
-public class CalendarInteraction implements ContactInteraction {
-    private static final String TAG = CalendarInteraction.class.getSimpleName();
-
-    private static final int CALENDAR_ICON_RES = R.drawable.quantum_ic_event_vd_theme_24;
-
-    private ContentValues mValues;
-
-    public CalendarInteraction(ContentValues values) {
-        mValues = values;
-    }
-
-    @Override
-    public Intent getIntent() {
-        return new Intent(Intent.ACTION_VIEW).setData(
-                ContentUris.withAppendedId(Events.CONTENT_URI, getEventId()));
-    }
-
-    @Override
-    public long getInteractionDate() {
-        return getDtstart();
-    }
-
-    @Override
-    public String getViewHeader(Context context) {
-        String title = getTitle();
-        if (TextUtils.isEmpty(title)) {
-            return context.getResources().getString(R.string.untitled_event);
-        }
-        return title;
-    }
-
-    @Override
-    public String getViewBody(Context context) {
-        return null;
-    }
-
-    @Override
-    public String getViewFooter(Context context) {
-        // Pulled from com.android.calendar.EventInfoFragment.updateEvent(View view)
-        // TODO: build callback to update time zone if different than preferences
-        String localTimezone = Time.getCurrentTimezone();
-
-        Long dateEnd = getDtend();
-        Long dateStart = getDtstart();
-        if (dateStart == null && dateEnd == null) {
-            return null;
-        } else if (dateEnd == null) {
-            dateEnd = dateStart;
-        } else if (dateStart == null) {
-            dateStart = dateEnd;
-        }
-
-        String displayedDatetime = CalendarInteractionUtils.getDisplayedDatetime(
-                dateStart, dateEnd, System.currentTimeMillis(), localTimezone,
-                getAllDay(), context);
-
-        return displayedDatetime;
-    }
-
-    @Override
-    public Drawable getIcon(Context context) {
-        return context.getResources().getDrawable(CALENDAR_ICON_RES);
-    }
-
-    @Override
-    public Drawable getBodyIcon(Context context) {
-        return null;
-    }
-
-    @Override
-    public Drawable getFooterIcon(Context context) {
-        return null;
-    }
-
-    public String getAttendeeEmail() {
-        return mValues.getAsString(Attendees.ATTENDEE_EMAIL);
-    }
-
-    public String getAttendeeIdentity() {
-        return mValues.getAsString(Attendees.ATTENDEE_IDENTITY);
-    }
-
-    public String getAttendeeIdNamespace() {
-        return mValues.getAsString(Attendees.ATTENDEE_ID_NAMESPACE);
-    }
-
-    public String getAttendeeName() {
-        return mValues.getAsString(Attendees.ATTENDEE_NAME);
-    }
-
-    public Integer getAttendeeRelationship() {
-        return mValues.getAsInteger(Attendees.ATTENDEE_RELATIONSHIP);
-    }
-
-    public Integer getAttendeeStatus() {
-        return mValues.getAsInteger(Attendees.ATTENDEE_STATUS);
-    }
-
-    public Integer getAttendeeType() {
-        return mValues.getAsInteger(Attendees.ATTENDEE_TYPE);
-    }
-
-    public Integer getEventId() {
-        return mValues.getAsInteger(Attendees.EVENT_ID);
-    }
-
-    public Integer getAccessLevel() {
-        return mValues.getAsInteger(Attendees.ACCESS_LEVEL);
-    }
-
-    public Boolean getAllDay() {
-        return mValues.getAsInteger(Attendees.ALL_DAY) == 1 ? true : false;
-    }
-
-    public Integer getAvailability() {
-        return mValues.getAsInteger(Attendees.AVAILABILITY);
-    }
-
-    public Integer getCalendarId() {
-        return mValues.getAsInteger(Attendees.CALENDAR_ID);
-    }
-
-    public Boolean getCanInviteOthers() {
-        return mValues.getAsBoolean(Attendees.CAN_INVITE_OTHERS);
-    }
-
-    public String getCustomAppPackage() {
-        return mValues.getAsString(Attendees.CUSTOM_APP_PACKAGE);
-    }
-
-    public String getCustomAppUri() {
-        return mValues.getAsString(Attendees.CUSTOM_APP_URI);
-    }
-
-    public String getDescription() {
-        return mValues.getAsString(Attendees.DESCRIPTION);
-    }
-
-    public Integer getDisplayColor() {
-        return mValues.getAsInteger(Attendees.DISPLAY_COLOR);
-    }
-
-    public Long getDtend() {
-        return mValues.getAsLong(Attendees.DTEND);
-    }
-
-    public Long getDtstart() {
-        return mValues.getAsLong(Attendees.DTSTART);
-    }
-
-    public String getDuration() {
-        return mValues.getAsString(Attendees.DURATION);
-    }
-
-    public Integer getEventColor() {
-        return mValues.getAsInteger(Attendees.EVENT_COLOR);
-    }
-
-    public String getEventColorKey() {
-        return mValues.getAsString(Attendees.EVENT_COLOR_KEY);
-    }
-
-    public String getEventEndTimezone() {
-        return mValues.getAsString(Attendees.EVENT_END_TIMEZONE);
-    }
-
-    public String getEventLocation() {
-        return mValues.getAsString(Attendees.EVENT_LOCATION);
-    }
-
-    public String getExdate() {
-        return mValues.getAsString(Attendees.EXDATE);
-    }
-
-    public String getExrule() {
-        return mValues.getAsString(Attendees.EXRULE);
-    }
-
-    public Boolean getGuestsCanInviteOthers() {
-        return mValues.getAsBoolean(Attendees.GUESTS_CAN_INVITE_OTHERS);
-    }
-
-    public Boolean getGuestsCanModify() {
-        return mValues.getAsBoolean(Attendees.GUESTS_CAN_MODIFY);
-    }
-
-    public Boolean getGuestsCanSeeGuests() {
-        return mValues.getAsBoolean(Attendees.GUESTS_CAN_SEE_GUESTS);
-    }
-
-    public Boolean getHasAlarm() {
-        return mValues.getAsBoolean(Attendees.HAS_ALARM);
-    }
-
-    public Boolean getHasAttendeeData() {
-        return mValues.getAsBoolean(Attendees.HAS_ATTENDEE_DATA);
-    }
-
-    public Boolean getHasExtendedProperties() {
-        return mValues.getAsBoolean(Attendees.HAS_EXTENDED_PROPERTIES);
-    }
-
-    public String getIsOrganizer() {
-        return mValues.getAsString(Attendees.IS_ORGANIZER);
-    }
-
-    public Long getLastDate() {
-        return mValues.getAsLong(Attendees.LAST_DATE);
-    }
-
-    public Boolean getLastSynced() {
-        return mValues.getAsBoolean(Attendees.LAST_SYNCED);
-    }
-
-    public String getOrganizer() {
-        return mValues.getAsString(Attendees.ORGANIZER);
-    }
-
-    public Boolean getOriginalAllDay() {
-        return mValues.getAsBoolean(Attendees.ORIGINAL_ALL_DAY);
-    }
-
-    public String getOriginalId() {
-        return mValues.getAsString(Attendees.ORIGINAL_ID);
-    }
-
-    public Long getOriginalInstanceTime() {
-        return mValues.getAsLong(Attendees.ORIGINAL_INSTANCE_TIME);
-    }
-
-    public String getOriginalSyncId() {
-        return mValues.getAsString(Attendees.ORIGINAL_SYNC_ID);
-    }
-
-    public String getRdate() {
-        return mValues.getAsString(Attendees.RDATE);
-    }
-
-    public String getRrule() {
-        return mValues.getAsString(Attendees.RRULE);
-    }
-
-    public Integer getSelfAttendeeStatus() {
-        return mValues.getAsInteger(Attendees.SELF_ATTENDEE_STATUS);
-    }
-
-    public Integer getStatus() {
-        return mValues.getAsInteger(Attendees.STATUS);
-    }
-
-    public String getTitle() {
-        return mValues.getAsString(Attendees.TITLE);
-    }
-
-    public String getUid2445() {
-        return mValues.getAsString(Attendees.UID_2445);
-    }
-
-    @Override
-    public Spannable getContentDescription(Context context) {
-        // The default TalkBack is good
-        return null;
-    }
-
-    @Override
-    public int getIconResourceId() {
-        return CALENDAR_ICON_RES;
-    }
-}
diff --git a/src/com/android/contacts/interactions/CalendarInteractionUtils.java b/src/com/android/contacts/interactions/CalendarInteractionUtils.java
deleted file mode 100644
index 36a5621..0000000
--- a/src/com/android/contacts/interactions/CalendarInteractionUtils.java
+++ /dev/null
@@ -1,192 +0,0 @@
-package com.android.contacts.interactions;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.text.format.DateFormat;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-
-import com.android.contacts.R;
-
-import java.util.Formatter;
-import java.util.Locale;
-
-/**
- * The following methods were pulled from
- * {@link com.android.calendar.EventInfoFragment.updateEvent(View view)}
- * TODO: Move this to frameworks/opt
- */
-public class CalendarInteractionUtils {
-
-    // Using int constants as a return value instead of an enum to minimize resources.
-    private static final int TODAY = 1;
-    private static final int TOMORROW = 2;
-    private static final int NONE = 0;
-
-    /**
-     * Returns a string description of the specified time interval.
-     */
-    public static String getDisplayedDatetime(long startMillis, long endMillis, long currentMillis,
-            String localTimezone, boolean allDay, Context context) {
-        // Configure date/time formatting.
-        int flagsDate = DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY;
-        int flagsTime = DateUtils.FORMAT_SHOW_TIME;
-        if (DateFormat.is24HourFormat(context)) {
-            flagsTime |= DateUtils.FORMAT_24HOUR;
-        }
-
-        Time currentTime = new Time(localTimezone);
-        currentTime.set(currentMillis);
-        Resources resources = context.getResources();
-        String datetimeString = null;
-        if (allDay) {
-            // All day events require special timezone adjustment.
-            long localStartMillis = convertAlldayUtcToLocal(null, startMillis, localTimezone);
-            long localEndMillis = convertAlldayUtcToLocal(null, endMillis, localTimezone);
-            if (singleDayEvent(localStartMillis, localEndMillis, currentTime.gmtoff)) {
-                // If possible, use "Today" or "Tomorrow" instead of a full date string.
-                int todayOrTomorrow = isTodayOrTomorrow(context.getResources(),
-                        localStartMillis, currentMillis, currentTime.gmtoff);
-                if (TODAY == todayOrTomorrow) {
-                    datetimeString = resources.getString(R.string.today);
-                } else if (TOMORROW == todayOrTomorrow) {
-                    datetimeString = resources.getString(R.string.tomorrow);
-                }
-            }
-            if (datetimeString == null) {
-                // For multi-day allday events or single-day all-day events that are not
-                // today or tomorrow, use framework formatter.
-                Formatter f = new Formatter(new StringBuilder(50), Locale.getDefault());
-                datetimeString = DateUtils.formatDateRange(context, f, startMillis,
-                        endMillis, flagsDate, Time.TIMEZONE_UTC).toString();
-            }
-        } else {
-            if (singleDayEvent(startMillis, endMillis, currentTime.gmtoff)) {
-                // Format the time.
-                String timeString = formatDateRange(context, startMillis, endMillis,
-                        flagsTime);
-
-                // If possible, use "Today" or "Tomorrow" instead of a full date string.
-                int todayOrTomorrow = isTodayOrTomorrow(context.getResources(), startMillis,
-                        currentMillis, currentTime.gmtoff);
-                if (TODAY == todayOrTomorrow) {
-                    // Example: "Today at 1:00pm - 2:00 pm"
-                    datetimeString = resources.getString(R.string.today_at_time_fmt,
-                            timeString);
-                } else if (TOMORROW == todayOrTomorrow) {
-                    // Example: "Tomorrow at 1:00pm - 2:00 pm"
-                    datetimeString = resources.getString(R.string.tomorrow_at_time_fmt,
-                            timeString);
-                } else {
-                    // Format the full date. Example: "Thursday, April 12, 1:00pm - 2:00pm"
-                    String dateString = formatDateRange(context, startMillis, endMillis,
-                            flagsDate);
-                    datetimeString = resources.getString(R.string.date_time_fmt, dateString,
-                            timeString);
-                }
-            } else {
-                // For multiday events, shorten day/month names.
-                // Example format: "Fri Apr 6, 5:00pm - Sun, Apr 8, 6:00pm"
-                int flagsDatetime = flagsDate | flagsTime | DateUtils.FORMAT_ABBREV_MONTH |
-                        DateUtils.FORMAT_ABBREV_WEEKDAY;
-                datetimeString = formatDateRange(context, startMillis, endMillis,
-                        flagsDatetime);
-            }
-        }
-        return datetimeString;
-    }
-
-    /**
-     * Convert given UTC time into current local time. This assumes it is for an
-     * allday event and will adjust the time to be on a midnight boundary.
-     *
-     * @param recycle Time object to recycle, otherwise null.
-     * @param utcTime Time to convert, in UTC.
-     * @param tz The time zone to convert this time to.
-     */
-    private static long convertAlldayUtcToLocal(Time recycle, long utcTime, String tz) {
-        if (recycle == null) {
-            recycle = new Time();
-        }
-        recycle.timezone = Time.TIMEZONE_UTC;
-        recycle.set(utcTime);
-        recycle.timezone = tz;
-        return recycle.normalize(true);
-    }
-
-    public static long convertAlldayLocalToUTC(Time recycle, long localTime, String tz) {
-        if (recycle == null) {
-            recycle = new Time();
-        }
-        recycle.timezone = tz;
-        recycle.set(localTime);
-        recycle.timezone = Time.TIMEZONE_UTC;
-        return recycle.normalize(true);
-    }
-
-    /**
-     * Returns whether the specified time interval is in a single day.
-     */
-    private static boolean singleDayEvent(long startMillis, long endMillis, long localGmtOffset) {
-        if (startMillis == endMillis) {
-            return true;
-        }
-
-        // An event ending at midnight should still be a single-day event, so check
-        // time end-1.
-        int startDay = Time.getJulianDay(startMillis, localGmtOffset);
-        int endDay = Time.getJulianDay(endMillis - 1, localGmtOffset);
-        return startDay == endDay;
-    }
-
-    /**
-     * Returns TODAY or TOMORROW if applicable.  Otherwise returns NONE.
-     */
-    private static int isTodayOrTomorrow(Resources r, long dayMillis,
-            long currentMillis, long localGmtOffset) {
-        int startDay = Time.getJulianDay(dayMillis, localGmtOffset);
-        int currentDay = Time.getJulianDay(currentMillis, localGmtOffset);
-
-        int days = startDay - currentDay;
-        if (days == 1) {
-            return TOMORROW;
-        } else if (days == 0) {
-            return TODAY;
-        } else {
-            return NONE;
-        }
-    }
-
-    /**
-     * Formats a date or a time range according to the local conventions.
-     *
-     * This formats a date/time range using Calendar's time zone and the
-     * local conventions for the region of the device.
-     *
-     * If the {@link DateUtils#FORMAT_UTC} flag is used it will pass in
-     * the UTC time zone instead.
-     *
-     * @param context the context is required only if the time is shown
-     * @param startMillis the start time in UTC milliseconds
-     * @param endMillis the end time in UTC milliseconds
-     * @param flags a bit mask of options See
-     * {@link DateUtils#formatDateRange(Context, Formatter, long, long, int, String) formatDateRange}
-     * @return a string containing the formatted date/time range.
-     */
-    private static String formatDateRange(Context context, long startMillis,
-            long endMillis, int flags) {
-        String date;
-        String tz;
-        if ((flags & DateUtils.FORMAT_UTC) != 0) {
-            tz = Time.TIMEZONE_UTC;
-        } else {
-            tz = Time.getCurrentTimezone();
-        }
-        StringBuilder sb = new StringBuilder(50);
-        Formatter f = new Formatter(sb, Locale.getDefault());
-        sb.setLength(0);
-        date = DateUtils.formatDateRange(context, f, startMillis, endMillis, flags,
-                tz).toString();
-        return date;
-    }
-}
diff --git a/src/com/android/contacts/interactions/CalendarInteractionsLoader.java b/src/com/android/contacts/interactions/CalendarInteractionsLoader.java
deleted file mode 100644
index 646b2db..0000000
--- a/src/com/android/contacts/interactions/CalendarInteractionsLoader.java
+++ /dev/null
@@ -1,239 +0,0 @@
-package com.android.contacts.interactions;
-
-import android.Manifest.permission;
-import android.content.AsyncTaskLoader;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.provider.CalendarContract;
-import android.provider.CalendarContract.Calendars;
-import android.util.Log;
-
-import com.android.contacts.util.PermissionsUtil;
-
-import com.google.common.base.Preconditions;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-
-/**
- * Loads a list of calendar interactions showing shared calendar events with everyone passed in
- * {@param emailAddresses}.
- *
- * Note: the calendar provider treats mailing lists as atomic email addresses.
- */
-public class CalendarInteractionsLoader extends AsyncTaskLoader<List<ContactInteraction>> {
-    private static final String TAG = "CalendarInteractions";
-
-    private List<String> mEmailAddresses;
-    private int mMaxFutureToRetrieve;
-    private int mMaxPastToRetrieve;
-    private long mNumberFutureMillisecondToSearchLocalCalendar;
-    private long mNumberPastMillisecondToSearchLocalCalendar;
-    private List<ContactInteraction> mData;
-
-
-    /**
-     * @param maxFutureToRetrieve The maximum number of future events to retrieve
-     * @param maxPastToRetrieve The maximum number of past events to retrieve
-     */
-    public CalendarInteractionsLoader(Context context, List<String> emailAddresses,
-            int maxFutureToRetrieve, int maxPastToRetrieve,
-            long numberFutureMillisecondToSearchLocalCalendar,
-            long numberPastMillisecondToSearchLocalCalendar) {
-        super(context);
-        mEmailAddresses = emailAddresses;
-        mMaxFutureToRetrieve = maxFutureToRetrieve;
-        mMaxPastToRetrieve = maxPastToRetrieve;
-        mNumberFutureMillisecondToSearchLocalCalendar =
-                numberFutureMillisecondToSearchLocalCalendar;
-        mNumberPastMillisecondToSearchLocalCalendar = numberPastMillisecondToSearchLocalCalendar;
-    }
-
-    @Override
-    public List<ContactInteraction> loadInBackground() {
-        if (!PermissionsUtil.hasPermission(getContext(), permission.READ_CALENDAR)
-                || mEmailAddresses == null || mEmailAddresses.size() < 1) {
-            return Collections.emptyList();
-        }
-        // Perform separate calendar queries for events in the past and future.
-        Cursor cursor = getSharedEventsCursor(/* isFuture= */ true, mMaxFutureToRetrieve);
-        List<ContactInteraction> interactions = getInteractionsFromEventsCursor(cursor);
-        cursor = getSharedEventsCursor(/* isFuture= */ false, mMaxPastToRetrieve);
-        List<ContactInteraction> interactions2 = getInteractionsFromEventsCursor(cursor);
-
-        ArrayList<ContactInteraction> allInteractions = new ArrayList<ContactInteraction>(
-                interactions.size() + interactions2.size());
-        allInteractions.addAll(interactions);
-        allInteractions.addAll(interactions2);
-
-        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-            Log.v(TAG, "# ContactInteraction Loaded: " + allInteractions.size());
-        }
-        return allInteractions;
-    }
-
-    /**
-     * @return events inside phone owners' calendars, that are shared with people inside mEmails
-     */
-    private Cursor getSharedEventsCursor(boolean isFuture, int limit) {
-        List<String> calendarIds = getOwnedCalendarIds();
-        if (calendarIds == null) {
-            return null;
-        }
-        long timeMillis = System.currentTimeMillis();
-
-        List<String> selectionArgs = new ArrayList<>();
-        selectionArgs.addAll(mEmailAddresses);
-        selectionArgs.addAll(calendarIds);
-
-        // Add time constraints to selectionArgs
-        String timeOperator = isFuture ? " > " : " < ";
-        long pastTimeCutoff = timeMillis - mNumberPastMillisecondToSearchLocalCalendar;
-        long futureTimeCutoff = timeMillis
-                + mNumberFutureMillisecondToSearchLocalCalendar;
-        String[] timeArguments = {String.valueOf(timeMillis), String.valueOf(pastTimeCutoff),
-                String.valueOf(futureTimeCutoff)};
-        selectionArgs.addAll(Arrays.asList(timeArguments));
-
-        // When LAST_SYNCED = 1, the event is not a real event. We should ignore all such events.
-        String IS_NOT_TEMPORARY_COPY_OF_LOCAL_EVENT
-                = CalendarContract.Attendees.LAST_SYNCED + " = 0";
-
-        String orderBy = CalendarContract.Attendees.DTSTART + (isFuture ? " ASC " : " DESC ");
-        String selection = caseAndDotInsensitiveEmailComparisonClause(mEmailAddresses.size())
-                + " AND " + CalendarContract.Attendees.CALENDAR_ID
-                + " IN " + ContactInteractionUtil.questionMarks(calendarIds.size())
-                + " AND " + CalendarContract.Attendees.DTSTART + timeOperator + " ? "
-                + " AND " + CalendarContract.Attendees.DTSTART + " > ? "
-                + " AND " + CalendarContract.Attendees.DTSTART + " < ? "
-                + " AND " + IS_NOT_TEMPORARY_COPY_OF_LOCAL_EVENT;
-
-        return getContext().getContentResolver().query(CalendarContract.Attendees.CONTENT_URI,
-                /* projection = */ null, selection,
-                selectionArgs.toArray(new String[selectionArgs.size()]),
-                orderBy + " LIMIT " + limit);
-    }
-
-    /**
-     * Returns a clause that checks whether an attendee's email is equal to one of
-     * {@param count} values. The comparison is insensitive to dots and case.
-     *
-     * NOTE #1: This function is only needed for supporting non google accounts. For calendars
-     * synced by a google account, attendee email values will be be modified by the server to ensure
-     * they match an entry in contacts.google.com.
-     *
-     * NOTE #2: This comparison clause can result in false positives. Ex#1, test@gmail.com will
-     * match test@gmailco.m. Ex#2, a.2@exchange.com will match a2@exchange.com (exchange addresses
-     * should be dot sensitive). This probably isn't a large concern.
-     */
-    private String caseAndDotInsensitiveEmailComparisonClause(int count) {
-        Preconditions.checkArgument(count > 0, "Count needs to be positive");
-        final String COMPARISON
-                = " REPLACE(" + CalendarContract.Attendees.ATTENDEE_EMAIL
-                + ", '.', '') = REPLACE(?, '.', '') COLLATE NOCASE";
-        StringBuilder sb = new StringBuilder("( " + COMPARISON);
-        for (int i = 1; i < count; i++) {
-            sb.append(" OR " + COMPARISON);
-        }
-        return sb.append(")").toString();
-    }
-
-    /**
-     * @return A list with upto one Card. The Card contains events from {@param Cursor}.
-     * Only returns unique events.
-     */
-    private List<ContactInteraction> getInteractionsFromEventsCursor(Cursor cursor) {
-        try {
-            if (cursor == null || cursor.getCount() == 0) {
-                return Collections.emptyList();
-            }
-            Set<String> uniqueUris = new HashSet<String>();
-            ArrayList<ContactInteraction> interactions = new ArrayList<ContactInteraction>();
-            while (cursor.moveToNext()) {
-                ContentValues values = new ContentValues();
-                DatabaseUtils.cursorRowToContentValues(cursor, values);
-                CalendarInteraction calendarInteraction = new CalendarInteraction(values);
-                if (!uniqueUris.contains(calendarInteraction.getIntent().getData().toString())) {
-                    uniqueUris.add(calendarInteraction.getIntent().getData().toString());
-                    interactions.add(calendarInteraction);
-                }
-            }
-
-            return interactions;
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-    }
-
-    /**
-     * @return the Ids of calendars that are owned by accounts on the phone.
-     */
-    private List<String> getOwnedCalendarIds() {
-        String[] projection = new String[] {Calendars._ID, Calendars.CALENDAR_ACCESS_LEVEL};
-        Cursor cursor = getContext().getContentResolver().query(Calendars.CONTENT_URI, projection,
-                Calendars.VISIBLE + " = 1 AND " + Calendars.CALENDAR_ACCESS_LEVEL + " = ? ",
-                new String[] {String.valueOf(Calendars.CAL_ACCESS_OWNER)}, null);
-        try {
-            if (cursor == null || cursor.getCount() < 1) {
-                return null;
-            }
-            cursor.moveToPosition(-1);
-            List<String> calendarIds = new ArrayList<>(cursor.getCount());
-            while (cursor.moveToNext()) {
-                calendarIds.add(String.valueOf(cursor.getInt(0)));
-            }
-            return calendarIds;
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-    }
-
-    @Override
-    protected void onStartLoading() {
-        super.onStartLoading();
-
-        if (mData != null) {
-            deliverResult(mData);
-        }
-
-        if (takeContentChanged() || mData == null) {
-            forceLoad();
-        }
-    }
-
-    @Override
-    protected void onStopLoading() {
-        // Attempt to cancel the current load task if possible.
-        cancelLoad();
-    }
-
-    @Override
-    protected void onReset() {
-        super.onReset();
-
-        // Ensure the loader is stopped
-        onStopLoading();
-        if (mData != null) {
-            mData.clear();
-        }
-    }
-
-    @Override
-    public void deliverResult(List<ContactInteraction> data) {
-        mData = data;
-        if (isStarted()) {
-            super.deliverResult(data);
-        }
-    }
-}
diff --git a/src/com/android/contacts/interactions/CallLogInteraction.java b/src/com/android/contacts/interactions/CallLogInteraction.java
deleted file mode 100644
index 8890478..0000000
--- a/src/com/android/contacts/interactions/CallLogInteraction.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 2014 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.interactions;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.provider.CallLog.Calls;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.text.BidiFormatter;
-import android.text.Spannable;
-import android.text.TextDirectionHeuristics;
-
-import com.android.contacts.GeoUtil;
-import com.android.contacts.R;
-import com.android.contacts.compat.PhoneNumberUtilsCompat;
-import com.android.contacts.util.BitmapUtil;
-import com.android.contacts.util.ContactDisplayUtils;
-
-/**
- * Represents a call log event interaction, wrapping the columns in
- * {@link android.provider.CallLog.Calls}.
- *
- * This class does not return log entries related to voicemail or SIP calls. Additionally,
- * this class ignores number presentation. Number presentation affects how to identify phone
- * numbers. Since, we already know the identity of the phone number owner we can ignore number
- * presentation.
- *
- * As a result of ignoring voicemail and number presentation, we don't need to worry about API
- * version.
- */
-public class CallLogInteraction implements ContactInteraction {
-
-    private static final String URI_TARGET_PREFIX = "tel:";
-    private static final int CALL_LOG_ICON_RES = R.drawable.quantum_ic_phone_vd_theme_24;
-    private static final int CALL_ARROW_ICON_RES = R.drawable.ic_call_arrow;
-    private static BidiFormatter sBidiFormatter = BidiFormatter.getInstance();
-
-    private ContentValues mValues;
-
-    public CallLogInteraction(ContentValues values) {
-        mValues = values;
-    }
-
-    @Override
-    public Intent getIntent() {
-        String number = getNumber();
-        return number == null ? null : new Intent(Intent.ACTION_CALL).setData(
-                Uri.parse(URI_TARGET_PREFIX + number));
-    }
-
-    @Override
-    public String getViewHeader(Context context) {
-        String number = mValues.getAsString(Calls.NUMBER);
-        if (number != null) {
-            number = PhoneNumberUtilsCompat.formatNumber(number,
-                    PhoneNumberUtilsCompat.normalizeNumber(number),
-                    GeoUtil.getCurrentCountryIso(context));
-            return sBidiFormatter.unicodeWrap(number, TextDirectionHeuristics.LTR);
-        }
-        return null;
-    }
-
-    @Override
-    public long getInteractionDate() {
-        Long date = getDate();
-        return date == null ? -1 : date;
-    }
-
-    @Override
-    public String getViewBody(Context context) {
-        Integer numberType = getCachedNumberType();
-        if (numberType == null) {
-            return null;
-        }
-        return Phone.getTypeLabel(context.getResources(), getCachedNumberType(),
-                getCachedNumberLabel()).toString();
-    }
-
-    @Override
-    public String getViewFooter(Context context) {
-        final Long date = getDate();
-        if (date != null) {
-            final StringBuilder callDetail = new StringBuilder();
-            callDetail.append(ContactInteractionUtil.formatDateStringFromTimestamp(date, context));
-            final Long duration = getDuration();
-            if (duration != null) {
-                callDetail.append("\n");
-                callDetail.append(ContactInteractionUtil.formatDuration(duration, context));
-            }
-            return callDetail.toString();
-        }
-        return null;
-    }
-
-    @Override
-    public Drawable getIcon(Context context) {
-        return context.getResources().getDrawable(CALL_LOG_ICON_RES);
-    }
-
-    @Override
-    public Drawable getBodyIcon(Context context) {
-        return null;
-    }
-
-    @Override
-    public Drawable getFooterIcon(Context context) {
-        Drawable callArrow = null;
-        Resources res = context.getResources();
-        Integer type = getType();
-        if (type == null) {
-            return null;
-        }
-        switch (type) {
-            case Calls.INCOMING_TYPE:
-                callArrow = res.getDrawable(CALL_ARROW_ICON_RES);
-                callArrow.mutate().setColorFilter(res.getColor(R.color.call_arrow_green),
-                        PorterDuff.Mode.MULTIPLY);
-                break;
-            case Calls.MISSED_TYPE:
-                callArrow = res.getDrawable(CALL_ARROW_ICON_RES);
-                callArrow.mutate().setColorFilter(res.getColor(R.color.call_arrow_red),
-                        PorterDuff.Mode.MULTIPLY);
-                break;
-            case Calls.OUTGOING_TYPE:
-                callArrow = BitmapUtil.getRotatedDrawable(res, CALL_ARROW_ICON_RES, 180f);
-                callArrow.setColorFilter(res.getColor(R.color.call_arrow_green),
-                        PorterDuff.Mode.MULTIPLY);
-                break;
-        }
-        return callArrow;
-    }
-
-    public String getCachedName() {
-        return mValues.getAsString(Calls.CACHED_NAME);
-    }
-
-    public String getCachedNumberLabel() {
-        return mValues.getAsString(Calls.CACHED_NUMBER_LABEL);
-    }
-
-    public Integer getCachedNumberType() {
-        return mValues.getAsInteger(Calls.CACHED_NUMBER_TYPE);
-    }
-
-    public Long getDate() {
-        return mValues.getAsLong(Calls.DATE);
-    }
-
-    public Long getDuration() {
-        return mValues.getAsLong(Calls.DURATION);
-    }
-
-    public Boolean getIsRead() {
-        return mValues.getAsBoolean(Calls.IS_READ);
-    }
-
-    public Integer getLimitParamKey() {
-        return mValues.getAsInteger(Calls.LIMIT_PARAM_KEY);
-    }
-
-    public Boolean getNew() {
-        return mValues.getAsBoolean(Calls.NEW);
-    }
-
-    public String getNumber() {
-        final String number = mValues.getAsString(Calls.NUMBER);
-        return number == null ? null :
-            sBidiFormatter.unicodeWrap(number, TextDirectionHeuristics.LTR);
-    }
-
-    public Integer getNumberPresentation() {
-        return mValues.getAsInteger(Calls.NUMBER_PRESENTATION);
-    }
-
-    public Integer getOffsetParamKey() {
-        return mValues.getAsInteger(Calls.OFFSET_PARAM_KEY);
-    }
-
-    public Integer getType() {
-        return mValues.getAsInteger(Calls.TYPE);
-    }
-
-    @Override
-    public Spannable getContentDescription(Context context) {
-        final String phoneNumber = getViewHeader(context);
-        final String contentDescription = context.getResources().getString(
-                R.string.content_description_recent_call,
-                getCallTypeString(context), phoneNumber, getViewFooter(context));
-        return ContactDisplayUtils.getTelephoneTtsSpannable(contentDescription, phoneNumber);
-    }
-
-    private String getCallTypeString(Context context) {
-        String callType = "";
-        Resources res = context.getResources();
-        Integer type = getType();
-        if (type == null) {
-            return callType;
-        }
-        switch (type) {
-            case Calls.INCOMING_TYPE:
-                callType = res.getString(R.string.content_description_recent_call_type_incoming);
-                break;
-            case Calls.MISSED_TYPE:
-                callType = res.getString(R.string.content_description_recent_call_type_missed);
-                break;
-            case Calls.OUTGOING_TYPE:
-                callType = res.getString(R.string.content_description_recent_call_type_outgoing);
-                break;
-        }
-        return callType;
-    }
-
-    @Override
-    public int getIconResourceId() {
-        return CALL_LOG_ICON_RES;
-    }
-}
diff --git a/src/com/android/contacts/interactions/CallLogInteractionsLoader.java b/src/com/android/contacts/interactions/CallLogInteractionsLoader.java
deleted file mode 100644
index 8813ecc..0000000
--- a/src/com/android/contacts/interactions/CallLogInteractionsLoader.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2014 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.interactions;
-
-import android.content.AsyncTaskLoader;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.net.Uri;
-import android.provider.CallLog.Calls;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.contacts.compat.PhoneNumberUtilsCompat;
-import com.android.contacts.util.PermissionsUtil;
-
-import com.google.common.annotations.VisibleForTesting;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-public class CallLogInteractionsLoader extends AsyncTaskLoader<List<ContactInteraction>> {
-
-    private static final String TAG = "CallLogInteractions";
-
-    private final String[] mPhoneNumbers;
-    private final String[] mSipNumbers;
-    private final int mMaxToRetrieve;
-    private List<ContactInteraction> mData;
-
-    public CallLogInteractionsLoader(Context context, String[] phoneNumbers, String[] sipNumbers,
-            int maxToRetrieve) {
-        super(context);
-        mPhoneNumbers = phoneNumbers;
-        mSipNumbers = sipNumbers;
-        mMaxToRetrieve = maxToRetrieve;
-    }
-
-    @Override
-    public List<ContactInteraction> loadInBackground() {
-        final boolean hasPhoneNumber = mPhoneNumbers != null && mPhoneNumbers.length > 0;
-        final boolean hasSipNumber = mSipNumbers != null && mSipNumbers.length > 0;
-        if (!PermissionsUtil.hasPhonePermissions(getContext())
-                || !getContext().getPackageManager()
-                        .hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
-                || (!hasPhoneNumber && !hasSipNumber) || mMaxToRetrieve <= 0) {
-            return Collections.emptyList();
-        }
-
-        final List<ContactInteraction> interactions = new ArrayList<>();
-        if (hasPhoneNumber) {
-            for (String number : mPhoneNumbers) {
-                final String normalizedNumber = PhoneNumberUtilsCompat.normalizeNumber(number);
-                if (!TextUtils.isEmpty(normalizedNumber)) {
-                    interactions.addAll(getCallLogInteractions(normalizedNumber));
-                }
-            }
-        }
-        if (hasSipNumber) {
-            for (String number : mSipNumbers) {
-                interactions.addAll(getCallLogInteractions(number));
-            }
-        }
-
-        // Sort the call log interactions by date for duplicate removal
-        Collections.sort(interactions, new Comparator<ContactInteraction>() {
-            @Override
-            public int compare(ContactInteraction i1, ContactInteraction i2) {
-                if (i2.getInteractionDate() - i1.getInteractionDate() > 0) {
-                    return 1;
-                } else if (i2.getInteractionDate() == i1.getInteractionDate()) {
-                    return 0;
-                } else {
-                    return -1;
-                }
-            }
-        });
-        // Duplicates only occur because of fuzzy matching. No need to dedupe a single number.
-        if ((hasPhoneNumber && mPhoneNumbers.length == 1 && !hasSipNumber)
-                || (hasSipNumber && mSipNumbers.length == 1 && !hasPhoneNumber)) {
-            return interactions;
-        }
-        return pruneDuplicateCallLogInteractions(interactions, mMaxToRetrieve);
-    }
-
-    /**
-     * Two different phone numbers can match the same call log entry (since phone number
-     * matching is inexact). Therefore, we need to remove duplicates. In a reasonable call log,
-     * every entry should have a distinct date. Therefore, we can assume duplicate entries are
-     * adjacent entries.
-     * @param interactions The interaction list potentially containing duplicates
-     * @return The list with duplicates removed
-     */
-    @VisibleForTesting
-    static List<ContactInteraction> pruneDuplicateCallLogInteractions(
-            List<ContactInteraction> interactions, int maxToRetrieve) {
-        final List<ContactInteraction> subsetInteractions = new ArrayList<>();
-        for (int i = 0; i < interactions.size(); i++) {
-            if (i >= 1 && interactions.get(i).getInteractionDate() ==
-                    interactions.get(i-1).getInteractionDate()) {
-                continue;
-            }
-            subsetInteractions.add(interactions.get(i));
-            if (subsetInteractions.size() >= maxToRetrieve) {
-                break;
-            }
-        }
-        return subsetInteractions;
-    }
-
-    private List<ContactInteraction> getCallLogInteractions(String phoneNumber) {
-        final Uri uri = Uri.withAppendedPath(Calls.CONTENT_FILTER_URI,
-                Uri.encode(phoneNumber));
-        // Append the LIMIT clause onto the ORDER BY clause. This won't cause crashes as long
-        // as we don't also set the {@link android.provider.CallLog.Calls.LIMIT_PARAM_KEY} that
-        // becomes available in KK.
-        final String orderByAndLimit = Calls.DATE + " DESC LIMIT " + mMaxToRetrieve;
-        Cursor cursor = null;
-        try {
-            cursor = getContext().getContentResolver().query(uri, null, null, null,
-                    orderByAndLimit);
-        } catch (Exception e) {
-            Log.e(TAG, "Can not query calllog", e);
-        }
-        try {
-            if (cursor == null || cursor.getCount() < 1) {
-                return Collections.emptyList();
-            }
-            cursor.moveToPosition(-1);
-            List<ContactInteraction> interactions = new ArrayList<>();
-            while (cursor.moveToNext()) {
-                final ContentValues values = new ContentValues();
-                DatabaseUtils.cursorRowToContentValues(cursor, values);
-                interactions.add(new CallLogInteraction(values));
-            }
-            return interactions;
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-    }
-
-    @Override
-    protected void onStartLoading() {
-        super.onStartLoading();
-
-        if (mData != null) {
-            deliverResult(mData);
-        }
-
-        if (takeContentChanged() || mData == null) {
-            forceLoad();
-        }
-    }
-
-    @Override
-    protected void onStopLoading() {
-        // Attempt to cancel the current load task if possible.
-        cancelLoad();
-    }
-
-    @Override
-    public void deliverResult(List<ContactInteraction> data) {
-        mData = data;
-        if (isStarted()) {
-            super.deliverResult(data);
-        }
-    }
-
-    @Override
-    protected void onReset() {
-        super.onReset();
-
-        // Ensure the loader is stopped
-        onStopLoading();
-        if (mData != null) {
-            mData.clear();
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/contacts/interactions/ContactInteraction.java b/src/com/android/contacts/interactions/ContactInteraction.java
deleted file mode 100644
index 6bca0af..0000000
--- a/src/com/android/contacts/interactions/ContactInteraction.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2014 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.interactions;
-
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.text.Spannable;
-
-/**
- * Represents a default interaction between the phone's owner and a contact
- */
-public interface ContactInteraction {
-    Intent getIntent();
-    long getInteractionDate();
-    String getViewHeader(Context context);
-    String getViewBody(Context context);
-    String getViewFooter(Context context);
-    Drawable getIcon(Context context);
-    Drawable getBodyIcon(Context context);
-    Drawable getFooterIcon(Context context);
-    Spannable getContentDescription(Context context);
-    /** The resource id for the icon, if available. May be 0 if one is not available. */
-    int getIconResourceId();
-}
diff --git a/src/com/android/contacts/interactions/ContactInteractionUtil.java b/src/com/android/contacts/interactions/ContactInteractionUtil.java
index e7a7a6d..daeadef 100644
--- a/src/com/android/contacts/interactions/ContactInteractionUtil.java
+++ b/src/com/android/contacts/interactions/ContactInteractionUtil.java
@@ -15,16 +15,8 @@
  */
 package com.android.contacts.interactions;
 
-import android.content.Context;
-import android.text.format.DateUtils;
-
-import com.android.contacts.R;
-
 import com.google.common.base.Preconditions;
 
-import java.text.DateFormat;
-import java.util.Calendar;
-
 /**
  * Utility methods for interactions and their loaders
  */
@@ -41,61 +33,4 @@
         }
         return sb.append(")").toString();
     }
-
-    /**
-     * Same as {@link formatDateStringFromTimestamp(long, Context, Calendar)} but uses the current
-     * time.
-     */
-    public static String formatDateStringFromTimestamp(long timestamp, Context context) {
-        return formatDateStringFromTimestamp(timestamp, context, Calendar.getInstance());
-    }
-
-    /**
-     * Takes in a timestamp and outputs a human legible date. This checks the timestamp against
-     * compareCalendar.
-     * This formats the date based on a few conditions:
-     * 1. If the timestamp is today, the time is shown
-     * 2. Otherwise show full date and time
-     */
-    public static String formatDateStringFromTimestamp(long timestamp, Context context,
-            Calendar compareCalendar) {
-        Calendar interactionCalendar = Calendar.getInstance();
-        interactionCalendar.setTimeInMillis(timestamp);
-
-        // compareCalendar is initialized to today
-        if (compareCalendarDayYear(interactionCalendar, compareCalendar)) {
-            return DateFormat.getTimeInstance(DateFormat.SHORT).format(
-                    interactionCalendar.getTime());
-        }
-
-        return DateUtils.formatDateTime(context, timestamp, DateUtils.FORMAT_SHOW_TIME
-                | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY
-                | DateUtils.FORMAT_SHOW_YEAR);
-    }
-
-    /**
-     * Compares the day and year of two calendars.
-     */
-    private static boolean compareCalendarDayYear(Calendar c1, Calendar c2) {
-        return c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR) &&
-                c1.get(Calendar.DAY_OF_YEAR) == c2.get(Calendar.DAY_OF_YEAR);
-    }
-
-    /**
-     * Takes duration of the call in seconds.
-     * Return the formatted duration in hr, min, sec order if they exist.
-     */
-    public static String formatDuration(long callDuration, Context context) {
-        final int hours = (int) callDuration / 3600;
-        final int minutes = (int) (callDuration % 3600) / 60;
-        final int seconds = (int) (callDuration % 60);
-
-        if (hours > 0) {
-            return context.getString(R.string.callDurationHourFormat, hours, minutes, seconds);
-        } else if (minutes > 0) {
-            return context.getString(R.string.callDurationMinuteFormat, minutes, seconds);
-        } else {
-            return context.getString(R.string.callDurationSecondFormat, seconds);
-        }
-    }
 }
diff --git a/src/com/android/contacts/interactions/SmsInteraction.java b/src/com/android/contacts/interactions/SmsInteraction.java
deleted file mode 100644
index 4aad07b..0000000
--- a/src/com/android/contacts/interactions/SmsInteraction.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2014 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.interactions;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.provider.Telephony.Sms;
-import android.text.BidiFormatter;
-import android.text.Spannable;
-import android.text.TextDirectionHeuristics;
-
-import com.android.contacts.R;
-import com.android.contacts.util.ContactDisplayUtils;
-
-/**
- * Represents an sms interaction, wrapping the columns in
- * {@link android.provider.Telephony.Sms}.
- */
-public class SmsInteraction implements ContactInteraction {
-
-    private static final String URI_TARGET_PREFIX = "smsto:";
-    private static final int SMS_ICON_RES = R.drawable.quantum_ic_message_vd_theme_24;
-    private static BidiFormatter sBidiFormatter = BidiFormatter.getInstance();
-
-    private ContentValues mValues;
-
-    public SmsInteraction(ContentValues values) {
-        mValues = values;
-    }
-
-    @Override
-    public Intent getIntent() {
-        String address = getAddress();
-        return address == null ? null : new Intent(Intent.ACTION_VIEW).setData(
-                Uri.parse(URI_TARGET_PREFIX + address));
-    }
-
-    @Override
-    public long getInteractionDate() {
-        Long date = getDate();
-        return date == null ? -1 : date;
-    }
-
-    @Override
-    public String getViewHeader(Context context) {
-        String body = getBody();
-        if (getType() == Sms.MESSAGE_TYPE_SENT) {
-            body = context.getResources().getString(R.string.message_from_you_prefix, body);
-        }
-        return body;
-    }
-
-    @Override
-    public String getViewBody(Context context) {
-        return getAddress();
-    }
-
-    @Override
-    public String getViewFooter(Context context) {
-        Long date = getDate();
-        return date == null ? null : ContactInteractionUtil.formatDateStringFromTimestamp(
-                date, context);
-    }
-
-    @Override
-    public Drawable getIcon(Context context) {
-        return context.getResources().getDrawable(SMS_ICON_RES);
-    }
-
-    @Override
-    public Drawable getBodyIcon(Context context) {
-        return null;
-    }
-
-    @Override
-    public Drawable getFooterIcon(Context context) {
-        return null;
-    }
-
-    public String getAddress() {
-        final String address = mValues.getAsString(Sms.ADDRESS);
-        return address == null ? null :
-            sBidiFormatter.unicodeWrap(address, TextDirectionHeuristics.LTR);
-    }
-
-    public String getBody() {
-        return mValues.getAsString(Sms.BODY);
-    }
-
-    public Long getDate() {
-        return mValues.getAsLong(Sms.DATE);
-    }
-
-
-    public Long getDateSent() {
-        return mValues.getAsLong(Sms.DATE_SENT);
-    }
-
-    public Integer getErrorCode() {
-        return mValues.getAsInteger(Sms.ERROR_CODE);
-    }
-
-    public Boolean getLocked() {
-        return mValues.getAsBoolean(Sms.LOCKED);
-    }
-
-    public Integer getPerson() {
-        return mValues.getAsInteger(Sms.PERSON);
-    }
-
-    public Integer getProtocol() {
-        return mValues.getAsInteger(Sms.PROTOCOL);
-    }
-
-    public Boolean getRead() {
-        return mValues.getAsBoolean(Sms.READ);
-    }
-
-    public Boolean getReplyPathPresent() {
-        return mValues.getAsBoolean(Sms.REPLY_PATH_PRESENT);
-    }
-
-    public Boolean getSeen() {
-        return mValues.getAsBoolean(Sms.SEEN);
-    }
-
-    public String getServiceCenter() {
-        return mValues.getAsString(Sms.SERVICE_CENTER);
-    }
-
-    public Integer getStatus() {
-        return mValues.getAsInteger(Sms.STATUS);
-    }
-
-    public String getSubject() {
-        return mValues.getAsString(Sms.SUBJECT);
-    }
-
-    public Integer getThreadId() {
-        return mValues.getAsInteger(Sms.THREAD_ID);
-    }
-
-    public Integer getType() {
-        return mValues.getAsInteger(Sms.TYPE);
-    }
-
-    @Override
-    public Spannable getContentDescription(Context context) {
-        final String phoneNumber = getViewBody(context);
-        final String contentDescription = context.getResources().getString(
-                R.string.content_description_recent_sms,
-                getViewHeader(context), phoneNumber, getViewFooter(context));
-        return ContactDisplayUtils.getTelephoneTtsSpannable(contentDescription, phoneNumber);
-    }
-
-    @Override
-    public int getIconResourceId() {
-        return SMS_ICON_RES;
-    }
-}
diff --git a/src/com/android/contacts/interactions/SmsInteractionsLoader.java b/src/com/android/contacts/interactions/SmsInteractionsLoader.java
deleted file mode 100644
index 31ab831..0000000
--- a/src/com/android/contacts/interactions/SmsInteractionsLoader.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2014 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.interactions;
-
-import android.content.AsyncTaskLoader;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.provider.Telephony;
-import android.util.Log;
-
-import com.android.contacts.compat.TelephonyThreadsCompat;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Loads the most recent sms between the passed in phone numbers.
- *
- * This is a two part process. The first step is retrieving the threadIds for each of the phone
- * numbers using fuzzy matching. The next step is to run another query against these threadIds
- * to retrieve the actual sms.
- */
-public class SmsInteractionsLoader extends AsyncTaskLoader<List<ContactInteraction>> {
-
-    private static final String TAG = SmsInteractionsLoader.class.getSimpleName();
-
-    private String[] mPhoneNums;
-    private int mMaxToRetrieve;
-    private List<ContactInteraction> mData;
-
-    /**
-     * Loads a list of SmsInteraction from the supplied phone numbers.
-     */
-    public SmsInteractionsLoader(Context context, String[] phoneNums,
-            int maxToRetrieve) {
-        super(context);
-        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-            Log.v(TAG, "SmsInteractionsLoader");
-        }
-        mPhoneNums = phoneNums;
-        mMaxToRetrieve = maxToRetrieve;
-    }
-
-    @Override
-    public List<ContactInteraction> loadInBackground() {
-        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-            Log.v(TAG, "loadInBackground");
-        }
-        // Confirm the device has Telephony and numbers were provided before proceeding
-        if (!getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
-                || mPhoneNums == null || mPhoneNums.length == 0) {
-            return Collections.emptyList();
-        }
-
-        // Retrieve the thread IDs
-        List<String> threadIdStrings = new ArrayList<>();
-        for (String phone : mPhoneNums) {
-            // TODO: the phone numbers added to the ContactInteraction result should retain their
-            // original formatting since TalkBack is not reading the normalized numbers correctly
-            try {
-                threadIdStrings.add(String.valueOf(
-                        TelephonyThreadsCompat.getOrCreateThreadId(getContext(), phone)));
-            } catch (Exception e) {
-                // Do nothing. Telephony.Threads.getOrCreateThreadId() throws exceptions when
-                // it can't find/create a threadId (b/17657656).
-            }
-        }
-
-        // Query the SMS database for the threads
-        Cursor cursor = getSmsCursorFromThreads(threadIdStrings);
-        if (cursor != null) {
-            try {
-                List<ContactInteraction> interactions = new ArrayList<>();
-                while (cursor.moveToNext()) {
-                    ContentValues values = new ContentValues();
-                    DatabaseUtils.cursorRowToContentValues(cursor, values);
-                    interactions.add(new SmsInteraction(values));
-                }
-
-                return interactions;
-            } finally {
-                cursor.close();
-            }
-        }
-
-        return Collections.emptyList();
-    }
-
-    /**
-     * Return the most recent messages between a list of threads
-     */
-    private Cursor getSmsCursorFromThreads(List<String> threadIds) {
-        if (threadIds.size() == 0) {
-            return null;
-        }
-        String selection = Telephony.Sms.THREAD_ID + " IN "
-                + ContactInteractionUtil.questionMarks(threadIds.size());
-
-        return getContext().getContentResolver().query(
-                Telephony.Sms.CONTENT_URI,
-                /* projection = */ null,
-                selection,
-                threadIds.toArray(new String[threadIds.size()]),
-                Telephony.Sms.DEFAULT_SORT_ORDER
-                        + " LIMIT " + mMaxToRetrieve);
-    }
-
-    @Override
-    protected void onStartLoading() {
-        super.onStartLoading();
-
-        if (mData != null) {
-            deliverResult(mData);
-        }
-
-        if (takeContentChanged() || mData == null) {
-            forceLoad();
-        }
-    }
-
-    @Override
-    protected void onStopLoading() {
-        // Attempt to cancel the current load task if possible.
-        cancelLoad();
-    }
-
-    @Override
-    public void deliverResult(List<ContactInteraction> data) {
-        mData = data;
-        if (isStarted()) {
-            super.deliverResult(data);
-        }
-    }
-
-    @Override
-    protected void onReset() {
-        super.onReset();
-
-        // Ensure the loader is stopped
-        onStopLoading();
-        if (mData != null) {
-            mData.clear();
-        }
-    }
-}
diff --git a/src/com/android/contacts/quickcontact/QuickContactActivity.java b/src/com/android/contacts/quickcontact/QuickContactActivity.java
index df08112..51762f4 100644
--- a/src/com/android/contacts/quickcontact/QuickContactActivity.java
+++ b/src/com/android/contacts/quickcontact/QuickContactActivity.java
@@ -17,7 +17,6 @@
 
 package com.android.contacts.quickcontact;
 
-import android.Manifest;
 import android.accounts.Account;
 import android.animation.ArgbEvaluator;
 import android.animation.ObjectAnimator;
@@ -74,11 +73,6 @@
 import android.provider.ContactsContract.Intents;
 import android.provider.ContactsContract.QuickContact;
 import android.provider.ContactsContract.RawContacts;
-import androidx.core.app.ActivityCompat;
-import androidx.localbroadcastmanager.content.LocalBroadcastManager;
-import androidx.core.content.res.ResourcesCompat;
-import androidx.core.os.BuildCompat;
-import androidx.palette.graphics.Palette;
 import android.telecom.PhoneAccount;
 import android.telecom.TelecomManager;
 import android.text.BidiFormatter;
@@ -99,7 +93,10 @@
 import android.view.WindowManager;
 import android.widget.Toast;
 import android.widget.Toolbar;
-
+import androidx.core.content.res.ResourcesCompat;
+import androidx.core.os.BuildCompat;
+import androidx.localbroadcastmanager.content.LocalBroadcastManager;
+import androidx.palette.graphics.Palette;
 import com.android.contacts.CallUtil;
 import com.android.contacts.ClipboardUtils;
 import com.android.contacts.Collapser;
@@ -113,7 +110,6 @@
 import com.android.contacts.ShortcutIntentBuilder.OnShortcutIntentCreatedListener;
 import com.android.contacts.activities.ContactEditorActivity;
 import com.android.contacts.activities.ContactSelectionActivity;
-import com.android.contacts.activities.RequestDesiredPermissionsActivity;
 import com.android.contacts.activities.RequestPermissionsActivity;
 import com.android.contacts.compat.CompatUtils;
 import com.android.contacts.compat.EventCompat;
@@ -123,11 +119,7 @@
 import com.android.contacts.editor.ContactEditorFragment;
 import com.android.contacts.editor.EditorIntents;
 import com.android.contacts.editor.EditorUiUtils;
-import com.android.contacts.interactions.CalendarInteractionsLoader;
-import com.android.contacts.interactions.CallLogInteractionsLoader;
 import com.android.contacts.interactions.ContactDeletionInteraction;
-import com.android.contacts.interactions.ContactInteraction;
-import com.android.contacts.interactions.SmsInteractionsLoader;
 import com.android.contacts.interactions.TouchPointManager;
 import com.android.contacts.lettertiles.LetterTileDrawable;
 import com.android.contacts.list.UiIntentActions;
@@ -166,7 +158,6 @@
 import com.android.contacts.util.ImplicitIntentsUtil;
 import com.android.contacts.util.MaterialColorMapUtils;
 import com.android.contacts.util.MaterialColorMapUtils.MaterialPalette;
-import com.android.contacts.util.PermissionsUtil;
 import com.android.contacts.util.PhoneCapabilityTester;
 import com.android.contacts.util.SchedulingUtils;
 import com.android.contacts.util.SharedPreferenceUtil;
@@ -177,11 +168,8 @@
 import com.android.contacts.widget.MultiShrinkScroller.MultiShrinkScrollerListener;
 import com.android.contacts.widget.QuickContactImageView;
 import com.android.contactsbind.HelpUtils;
-
 import com.google.common.collect.Lists;
-
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Collections;
 import java.util.Comparator;
@@ -189,7 +177,6 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Mostly translucent {@link Activity} that shows QuickContact dialog. It loads
@@ -231,6 +218,8 @@
     private static final String MIMETYPE_SMS = "vnd.android-dir/mms-sms";
     private static final int REQUEST_CODE_JOIN = 3;
     private static final int REQUEST_CODE_PICK_RINGTONE = 4;
+    private static final int CARD_ENTRY_ID_EDIT_CONTACT = -2;
+    private static final int MIN_NUM_CONTACT_ENTRIES_SHOWN = 3;
 
     private static final int CURRENT_API_VERSION = android.os.Build.VERSION.SDK_INT;
 
@@ -261,6 +250,8 @@
     private static final String HANGOUTS_DATA_5_MESSAGE = "conversation";
     private static final String CALL_ORIGIN_QUICK_CONTACTS_ACTIVITY =
             "com.android.contacts.quickcontact.QuickContactActivity";
+    private static final String KEY_LOADER_EXTRA_EMAILS =
+        QuickContactActivity.class.getCanonicalName() + ".KEY_LOADER_EXTRA_EMAILS";
 
     // Set true in {@link #onCreate} after orientation change for later use in processIntent().
     private boolean mIsRecreatedInstance;
@@ -290,18 +281,12 @@
     private QuickContactImageView mPhotoView;
     private ExpandingEntryCardView mContactCard;
     private ExpandingEntryCardView mNoContactDetailsCard;
-    private ExpandingEntryCardView mRecentCard;
     private ExpandingEntryCardView mAboutCard;
-    private ExpandingEntryCardView mPermissionExplanationCard;
 
     private long mPreviousContactId = 0;
-    // Permission explanation card.
-    private boolean mShouldShowPermissionExplanation = false;
-    private String mPermissionExplanationCardSubHeader = "";
 
     private MultiShrinkScroller mScroller;
     private AsyncTask<Void, Void, Cp2DataCardModel> mEntriesAndActionsTask;
-    private AsyncTask<Void, Void, Void> mRecentDataTask;
 
     /**
      * The last copy of Cp2DataCardModel that was passed to {@link #populateContactAndAboutCard}.
@@ -361,45 +346,11 @@
     /** Id for the background contact loader */
     private static final int LOADER_CONTACT_ID = 0;
 
-    /** Id for the background Sms Loader */
-    private static final int LOADER_SMS_ID = 1;
-    private static final int MAX_SMS_RETRIEVE = 3;
-
-    /** Id for the back Calendar Loader */
-    private static final int LOADER_CALENDAR_ID = 2;
-    private static final String KEY_LOADER_EXTRA_EMAILS =
-            QuickContactActivity.class.getCanonicalName() + ".KEY_LOADER_EXTRA_EMAILS";
-    private static final int MAX_PAST_CALENDAR_RETRIEVE = 3;
-    private static final int MAX_FUTURE_CALENDAR_RETRIEVE = 3;
-    private static final long PAST_MILLISECOND_TO_SEARCH_LOCAL_CALENDAR =
-            1L * 24L * 60L * 60L * 1000L /* 1 day */;
-    private static final long FUTURE_MILLISECOND_TO_SEARCH_LOCAL_CALENDAR =
-            7L * 24L * 60L * 60L * 1000L /* 7 days */;
-
-    /** Id for the background Call Log Loader */
-    private static final int LOADER_CALL_LOG_ID = 3;
-    private static final int MAX_CALL_LOG_RETRIEVE = 3;
-    private static final int MIN_NUM_CONTACT_ENTRIES_SHOWN = 3;
-    private static final int MIN_NUM_COLLAPSED_RECENT_ENTRIES_SHOWN = 3;
-    private static final int CARD_ENTRY_ID_EDIT_CONTACT = -2;
-    private static final int CARD_ENTRY_ID_REQUEST_PERMISSION = -3;
     private static final String KEY_LOADER_EXTRA_PHONES =
             QuickContactActivity.class.getCanonicalName() + ".KEY_LOADER_EXTRA_PHONES";
     private static final String KEY_LOADER_EXTRA_SIP_NUMBERS =
             QuickContactActivity.class.getCanonicalName() + ".KEY_LOADER_EXTRA_SIP_NUMBERS";
 
-    private static final int[] mRecentLoaderIds = new int[]{
-        LOADER_SMS_ID,
-        LOADER_CALENDAR_ID,
-        LOADER_CALL_LOG_ID};
-    /**
-     * ConcurrentHashMap constructor params: 4 is initial table size, 0.9f is
-     * load factor before resizing, 1 means we only expect a single thread to
-     * write to the map so make only a single shard
-     */
-    private Map<Integer, List<ContactInteraction>> mRecentLoaderResults =
-        new ConcurrentHashMap<>(4, 0.9f, 1);
-
     private static final String FRAGMENT_TAG_SELECT_ACCOUNT = "select_account_fragment";
 
     final OnClickListener mEntryClickHandler = new OnClickListener() {
@@ -419,13 +370,6 @@
                 return;
             }
 
-            if (dataId == CARD_ENTRY_ID_REQUEST_PERMISSION) {
-                finish();
-                RequestDesiredPermissionsActivity.startPermissionActivity(
-                        QuickContactActivity.this);
-                return;
-            }
-
             // Pass the touch point through the intent for use in the InCallUI
             if (Intent.ACTION_CALL.equals(intent.getAction())) {
                 if (TouchPointManager.getInstance().hasValidPoint()) {
@@ -760,43 +704,6 @@
 
         mShouldLog = true;
 
-        // There're 3 states for each permission:
-        // 1. App doesn't have permission, not asked user yet.
-        // 2. App doesn't have permission, user denied it previously.
-        // 3. App has permission.
-        // Permission explanation card is displayed only for case 1.
-        final boolean hasTelephonyFeature =
-                getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
-
-        final boolean hasCalendarPermission = PermissionsUtil.hasPermission(
-                this, Manifest.permission.READ_CALENDAR);
-        final boolean hasSMSPermission = hasTelephonyFeature
-                && PermissionsUtil.hasPermission(this, Manifest.permission.READ_SMS);
-
-        final boolean wasCalendarPermissionDenied =
-                ActivityCompat.shouldShowRequestPermissionRationale(
-                        this, Manifest.permission.READ_CALENDAR);
-        final boolean wasSMSPermissionDenied =
-                hasTelephonyFeature && ActivityCompat.shouldShowRequestPermissionRationale(
-                        this, Manifest.permission.READ_SMS);
-
-        final boolean shouldDisplayCalendarMessage =
-                !hasCalendarPermission && !wasCalendarPermissionDenied;
-        final boolean shouldDisplaySMSMessage =
-                hasTelephonyFeature && !hasSMSPermission && !wasSMSPermissionDenied;
-        mShouldShowPermissionExplanation = shouldDisplayCalendarMessage || shouldDisplaySMSMessage;
-
-        if (shouldDisplayCalendarMessage && shouldDisplaySMSMessage) {
-            mPermissionExplanationCardSubHeader =
-                    getString(R.string.permission_explanation_subheader_calendar_and_SMS);
-        } else if (shouldDisplayCalendarMessage) {
-            mPermissionExplanationCardSubHeader =
-                    getString(R.string.permission_explanation_subheader_calendar);
-        } else if (shouldDisplaySMSMessage) {
-            mPermissionExplanationCardSubHeader =
-                    getString(R.string.permission_explanation_subheader_SMS);
-        }
-
         final int previousScreenType = getIntent().getIntExtra
                 (EXTRA_PREVIOUS_SCREEN_TYPE, ScreenType.UNKNOWN);
         Logger.logScreenView(this, ScreenType.QUICK_CONTACT, previousScreenType);
@@ -825,19 +732,12 @@
 
         mContactCard = (ExpandingEntryCardView) findViewById(R.id.communication_card);
         mNoContactDetailsCard = (ExpandingEntryCardView) findViewById(R.id.no_contact_data_card);
-        mRecentCard = (ExpandingEntryCardView) findViewById(R.id.recent_card);
         mAboutCard = (ExpandingEntryCardView) findViewById(R.id.about_card);
-        mPermissionExplanationCard =
-                (ExpandingEntryCardView) findViewById(R.id.permission_explanation_card);
 
-        mPermissionExplanationCard.setOnClickListener(mEntryClickHandler);
         mNoContactDetailsCard.setOnClickListener(mEntryClickHandler);
         mContactCard.setOnClickListener(mEntryClickHandler);
         mContactCard.setOnCreateContextMenuListener(mEntryContextMenuListener);
 
-        mRecentCard.setOnClickListener(mEntryClickHandler);
-        mRecentCard.setTitle(getResources().getString(R.string.recent_card_title));
-
         mAboutCard.setOnClickListener(mEntryClickHandler);
         mAboutCard.setOnCreateContextMenuListener(mEntryContextMenuListener);
 
@@ -1026,7 +926,6 @@
             mShouldLog = true;
             // After copying a directory contact, the contact URI changes. Therefore,
             // we need to reload the new contact.
-            destroyInteractionLoaders();
             mContactLoader = (ContactLoader) (Loader<?>) getLoaderManager().getLoader(
                     LOADER_CONTACT_ID);
             mContactLoader.setNewLookup(mLookupUri);
@@ -1035,12 +934,6 @@
         mContactLoader.forceLoad();
     }
 
-    private void destroyInteractionLoaders() {
-        for (int interactionLoaderId : mRecentLoaderIds) {
-            getLoaderManager().destroyLoader(interactionLoaderId);
-        }
-    }
-
     private void runEntranceAnimation() {
         if (mHasAlreadyBeenOpened) {
             return;
@@ -1159,75 +1052,9 @@
     }
 
     private void bindDataToCards(Cp2DataCardModel cp2DataCardModel) {
-        startInteractionLoaders(cp2DataCardModel);
         populateContactAndAboutCard(cp2DataCardModel, /* shouldAddPhoneticName */ true);
     }
 
-    private void startInteractionLoaders(Cp2DataCardModel cp2DataCardModel) {
-        final Map<String, List<DataItem>> dataItemsMap = cp2DataCardModel.dataItemsMap;
-        final List<DataItem> phoneDataItems = dataItemsMap.get(Phone.CONTENT_ITEM_TYPE);
-        final List<DataItem> sipCallDataItems = dataItemsMap.get(SipAddress.CONTENT_ITEM_TYPE);
-        if (phoneDataItems != null && phoneDataItems.size() == 1) {
-            mOnlyOnePhoneNumber = true;
-        } else {
-            mOnlyOnePhoneNumber = false;
-        }
-        String[] phoneNumbers = null;
-        if (phoneDataItems != null) {
-            phoneNumbers = new String[phoneDataItems.size()];
-            for (int i = 0; i < phoneDataItems.size(); ++i) {
-                phoneNumbers[i] = ((PhoneDataItem) phoneDataItems.get(i)).getNumber();
-            }
-        }
-        String[] sipNumbers = null;
-        if (sipCallDataItems != null) {
-            sipNumbers = new String[sipCallDataItems.size()];
-            for (int i = 0; i < sipCallDataItems.size(); ++i) {
-                sipNumbers[i] = ((SipAddressDataItem) sipCallDataItems.get(i)).getSipAddress();
-            }
-        }
-        final Bundle phonesExtraBundle = new Bundle();
-        phonesExtraBundle.putStringArray(KEY_LOADER_EXTRA_PHONES, phoneNumbers);
-        phonesExtraBundle.putStringArray(KEY_LOADER_EXTRA_SIP_NUMBERS, sipNumbers);
-
-        Trace.beginSection("start sms loader");
-        getLoaderManager().initLoader(
-                LOADER_SMS_ID,
-                phonesExtraBundle,
-                mLoaderInteractionsCallbacks);
-        Trace.endSection();
-
-        Trace.beginSection("start call log loader");
-        getLoaderManager().initLoader(
-                LOADER_CALL_LOG_ID,
-                phonesExtraBundle,
-                mLoaderInteractionsCallbacks);
-        Trace.endSection();
-
-
-        Trace.beginSection("start calendar loader");
-        final List<DataItem> emailDataItems = dataItemsMap.get(Email.CONTENT_ITEM_TYPE);
-        if (emailDataItems != null && emailDataItems.size() == 1) {
-            mOnlyOneEmail = true;
-        } else {
-            mOnlyOneEmail = false;
-        }
-        String[] emailAddresses = null;
-        if (emailDataItems != null) {
-            emailAddresses = new String[emailDataItems.size()];
-            for (int i = 0; i < emailDataItems.size(); ++i) {
-                emailAddresses[i] = ((EmailDataItem) emailDataItems.get(i)).getAddress();
-            }
-        }
-        final Bundle emailsExtraBundle = new Bundle();
-        emailsExtraBundle.putStringArray(KEY_LOADER_EXTRA_EMAILS, emailAddresses);
-        getLoaderManager().initLoader(
-                LOADER_CALENDAR_ID,
-                emailsExtraBundle,
-                mLoaderInteractionsCallbacks);
-        Trace.endSection();
-    }
-
     private void showActivity() {
         if (mScroller != null) {
             mScroller.setVisibility(View.VISIBLE);
@@ -1268,13 +1095,6 @@
             populateContactAndAboutCard(mCachedCp2DataCardModel, /* shouldAddPhoneticName */ false);
         }
 
-        // When exiting the activity and resuming, we want to force a full reload of all the
-        // interaction data in case something changed in the background. On screen rotation,
-        // we don't need to do this. And, mCachedCp2DataCardModel will be null, so we won't.
-        if (mCachedCp2DataCardModel != null) {
-            destroyInteractionLoaders();
-            startInteractionLoaders(mCachedCp2DataCardModel);
-        }
         maybeShowProgressDialog();
     }
 
@@ -1373,16 +1193,13 @@
             mNoContactDetailsCard.setVisibility(View.GONE);
         }
 
-        // If the Recent card is already initialized (all recent data is loaded), show the About
-        // card if it has entries. Otherwise About card visibility will be set in bindRecentData()
+        // Show the About card if it has entries
         if (aboutCardEntries.size() > 0) {
             if (mAboutCard.getVisibility() == View.GONE && mShouldLog) {
                 Logger.logQuickContactEvent(mReferrer, mContactType, CardType.ABOUT,
                         ActionType.UNKNOWN_ACTION, /* thirdPartyAction */ null);
             }
-            if (isAllRecentDataLoaded()) {
-                mAboutCard.setVisibility(View.VISIBLE);
-            }
+            mAboutCard.setVisibility(View.VISIBLE);
         }
         Trace.endSection();
     }
@@ -2263,7 +2080,6 @@
         mColorFilter =
                 new PorterDuffColorFilter(mColorFilterColor, PorterDuff.Mode.SRC_ATOP);
         mContactCard.setColorAndFilter(mColorFilterColor, mColorFilter);
-        mRecentCard.setColorAndFilter(mColorFilterColor, mColorFilter);
         mAboutCard.setColorAndFilter(mColorFilterColor, mColorFilter);
     }
 
@@ -2296,38 +2112,6 @@
         return 0;
     }
 
-    private List<Entry> contactInteractionsToEntries(List<ContactInteraction> interactions) {
-        final List<Entry> entries = new ArrayList<>();
-        for (ContactInteraction interaction : interactions) {
-            if (interaction == null) {
-                continue;
-            }
-            entries.add(new Entry(/* id = */ -1,
-                    interaction.getIcon(this),
-                    interaction.getViewHeader(this),
-                    interaction.getViewBody(this),
-                    interaction.getBodyIcon(this),
-                    interaction.getViewFooter(this),
-                    interaction.getFooterIcon(this),
-                    interaction.getContentDescription(this),
-                    interaction.getIntent(),
-                    /* alternateIcon = */ null,
-                    /* alternateIntent = */ null,
-                    /* alternateContentDescription = */ null,
-                    /* shouldApplyColor = */ true,
-                    /* isEditable = */ false,
-                    /* EntryContextMenuInfo = */ null,
-                    /* thirdIcon = */ null,
-                    /* thirdIntent = */ null,
-                    /* thirdContentDescription = */ null,
-                    /* thirdAction = */ Entry.ACTION_NONE,
-                    /* thirdActionExtras = */ null,
-                    /* shouldApplyThirdIconColor = */ true,
-                    interaction.getIconResourceId()));
-        }
-        return entries;
-    }
-
     private final LoaderCallbacks<Contact> mLoaderContactCallbacks =
             new LoaderCallbacks<Contact>() {
         @Override
@@ -2411,201 +2195,6 @@
         overridePendingTransition(0, 0);
     }
 
-    private final LoaderCallbacks<List<ContactInteraction>> mLoaderInteractionsCallbacks =
-            new LoaderCallbacks<List<ContactInteraction>>() {
-
-        @Override
-        public Loader<List<ContactInteraction>> onCreateLoader(int id, Bundle args) {
-            Loader<List<ContactInteraction>> loader = null;
-            switch (id) {
-                case LOADER_SMS_ID:
-                    loader = new SmsInteractionsLoader(
-                            QuickContactActivity.this,
-                            args.getStringArray(KEY_LOADER_EXTRA_PHONES),
-                            MAX_SMS_RETRIEVE);
-                    break;
-                case LOADER_CALENDAR_ID:
-                    final String[] emailsArray = args.getStringArray(KEY_LOADER_EXTRA_EMAILS);
-                    List<String> emailsList = null;
-                    if (emailsArray != null) {
-                        emailsList = Arrays.asList(args.getStringArray(KEY_LOADER_EXTRA_EMAILS));
-                    }
-                    loader = new CalendarInteractionsLoader(
-                            QuickContactActivity.this,
-                            emailsList,
-                            MAX_FUTURE_CALENDAR_RETRIEVE,
-                            MAX_PAST_CALENDAR_RETRIEVE,
-                            FUTURE_MILLISECOND_TO_SEARCH_LOCAL_CALENDAR,
-                            PAST_MILLISECOND_TO_SEARCH_LOCAL_CALENDAR);
-                    break;
-                case LOADER_CALL_LOG_ID:
-                    loader = new CallLogInteractionsLoader(
-                            QuickContactActivity.this,
-                            args.getStringArray(KEY_LOADER_EXTRA_PHONES),
-                            args.getStringArray(KEY_LOADER_EXTRA_SIP_NUMBERS),
-                            MAX_CALL_LOG_RETRIEVE);
-            }
-            return loader;
-        }
-
-        @Override
-        public void onLoadFinished(Loader<List<ContactInteraction>> loader,
-                List<ContactInteraction> data) {
-            mRecentLoaderResults.put(loader.getId(), data);
-
-            if (isAllRecentDataLoaded()) {
-                bindRecentData();
-            }
-        }
-
-        @Override
-        public void onLoaderReset(Loader<List<ContactInteraction>> loader) {
-            mRecentLoaderResults.remove(loader.getId());
-        }
-    };
-
-    private boolean isAllRecentDataLoaded() {
-        return mRecentLoaderResults.size() == mRecentLoaderIds.length;
-    }
-
-    private void bindRecentData() {
-        final List<ContactInteraction> allInteractions = new ArrayList<>();
-        final List<List<Entry>> interactionsWrapper = new ArrayList<>();
-
-        // Serialize mRecentLoaderResults into a single list. This should be done on the main
-        // thread to avoid races against mRecentLoaderResults edits.
-        for (List<ContactInteraction> loaderInteractions : mRecentLoaderResults.values()) {
-            allInteractions.addAll(loaderInteractions);
-        }
-
-        mRecentDataTask = new AsyncTask<Void, Void, Void>() {
-            @Override
-            protected Void doInBackground(Void... params) {
-                Trace.beginSection("sort recent loader results");
-
-                // Sort the interactions by most recent
-                Collections.sort(allInteractions, new Comparator<ContactInteraction>() {
-                    @Override
-                    public int compare(ContactInteraction a, ContactInteraction b) {
-                        if (a == null && b == null) {
-                            return 0;
-                        }
-                        if (a == null) {
-                            return 1;
-                        }
-                        if (b == null) {
-                            return -1;
-                        }
-                        if (a.getInteractionDate() > b.getInteractionDate()) {
-                            return -1;
-                        }
-                        if (a.getInteractionDate() == b.getInteractionDate()) {
-                            return 0;
-                        }
-                        return 1;
-                    }
-                });
-
-                Trace.endSection();
-                Trace.beginSection("contactInteractionsToEntries");
-
-                // Wrap each interaction in its own list so that an icon is displayed for each entry
-                for (Entry contactInteraction : contactInteractionsToEntries(allInteractions)) {
-                    List<Entry> entryListWrapper = new ArrayList<>(1);
-                    entryListWrapper.add(contactInteraction);
-                    interactionsWrapper.add(entryListWrapper);
-                }
-
-                Trace.endSection();
-                return null;
-            }
-
-            @Override
-            protected void onPostExecute(Void aVoid) {
-                super.onPostExecute(aVoid);
-                Trace.beginSection("initialize recents card");
-
-                if (allInteractions.size() > 0) {
-                    mRecentCard.initialize(interactionsWrapper,
-                    /* numInitialVisibleEntries = */ MIN_NUM_COLLAPSED_RECENT_ENTRIES_SHOWN,
-                    /* isExpanded = */ mRecentCard.isExpanded(), /* isAlwaysExpanded = */ false,
-                            mExpandingEntryCardViewListener, mScroller);
-                    if (mRecentCard.getVisibility() == View.GONE && mShouldLog) {
-                        Logger.logQuickContactEvent(mReferrer, mContactType, CardType.RECENT,
-                                ActionType.UNKNOWN_ACTION, /* thirdPartyAction */ null);
-                    }
-                    mRecentCard.setVisibility(View.VISIBLE);
-                } else {
-                    mRecentCard.setVisibility(View.GONE);
-                }
-
-                Trace.endSection();
-                Trace.beginSection("initialize permission explanation card");
-
-                final Drawable historyIcon = ResourcesCompat.getDrawable(getResources(),
-                        R.drawable.quantum_ic_history_vd_theme_24, null);
-
-                final Entry permissionExplanationEntry = new Entry(CARD_ENTRY_ID_REQUEST_PERMISSION,
-                        historyIcon, getString(R.string.permission_explanation_header),
-                        mPermissionExplanationCardSubHeader, /* subHeaderIcon = */ null,
-                        /* text = */ null, /* textIcon = */ null,
-                        /* primaryContentDescription = */ null, getIntent(),
-                        /* alternateIcon = */ null, /* alternateIntent = */ null,
-                        /* alternateContentDescription = */ null, /* shouldApplyColor = */ true,
-                        /* isEditable = */ false, /* EntryContextMenuInfo = */ null,
-                        /* thirdIcon = */ null, /* thirdIntent = */ null,
-                        /* thirdContentDescription = */ null, /* thirdAction = */ Entry.ACTION_NONE,
-                        /* thirdExtras = */ null,
-                        /* shouldApplyThirdIconColor = */ true,
-                        R.drawable.quantum_ic_history_vd_theme_24);
-
-                final List<List<Entry>> permissionExplanationEntries = new ArrayList<>();
-                permissionExplanationEntries.add(new ArrayList<Entry>());
-                permissionExplanationEntries.get(0).add(permissionExplanationEntry);
-
-                final int subHeaderTextColor = getResources().getColor(android.R.color.white);
-                final PorterDuffColorFilter whiteColorFilter =
-                        new PorterDuffColorFilter(subHeaderTextColor, PorterDuff.Mode.SRC_ATOP);
-
-                mPermissionExplanationCard.initialize(permissionExplanationEntries,
-                        /* numInitialVisibleEntries = */ 1,
-                        /* isExpanded = */ true,
-                        /* isAlwaysExpanded = */ true,
-                        /* listener = */ null,
-                        mScroller);
-
-                mPermissionExplanationCard.setColorAndFilter(subHeaderTextColor, whiteColorFilter);
-                mPermissionExplanationCard.setBackgroundColor(mColorFilterColor);
-                mPermissionExplanationCard.setEntryHeaderColor(subHeaderTextColor);
-                mPermissionExplanationCard.setEntrySubHeaderColor(subHeaderTextColor);
-
-                if (mShouldShowPermissionExplanation) {
-                    if (mPermissionExplanationCard.getVisibility() == View.GONE
-                            && mShouldLog) {
-                        Logger.logQuickContactEvent(mReferrer, mContactType, CardType.PERMISSION,
-                                ActionType.UNKNOWN_ACTION, /* thirdPartyAction */ null);
-                    }
-                    mPermissionExplanationCard.setVisibility(View.VISIBLE);
-                } else {
-                    mPermissionExplanationCard.setVisibility(View.GONE);
-                }
-
-                Trace.endSection();
-
-                // About card is initialized along with the contact card, but since it appears after
-                // the recent card in the UI, we hold off until making it visible until the recent
-                // card is also ready to avoid stuttering.
-                if (mAboutCard.shouldShow()) {
-                    mAboutCard.setVisibility(View.VISIBLE);
-                } else {
-                    mAboutCard.setVisibility(View.GONE);
-                }
-                mRecentDataTask = null;
-            }
-        };
-        mRecentDataTask.execute();
-    }
-
     @Override
     protected void onStop() {
         super.onStop();
@@ -2617,9 +2206,6 @@
             // the entire process will be killed.
             mEntriesAndActionsTask.cancel(/* mayInterruptIfRunning = */ false);
         }
-        if (mRecentDataTask != null) {
-            mRecentDataTask.cancel(/* mayInterruptIfRunning = */ false);
-        }
     }
 
     @Override
diff --git a/src/com/android/contacts/util/ContactDisplayUtils.java b/src/com/android/contacts/util/ContactDisplayUtils.java
index b69a088..ff2d202 100644
--- a/src/com/android/contacts/util/ContactDisplayUtils.java
+++ b/src/com/android/contacts/util/ContactDisplayUtils.java
@@ -18,22 +18,17 @@
 
 import static android.provider.ContactsContract.CommonDataKinds.Phone;
 
-import android.content.Context;
 import android.content.res.Resources;
-import androidx.annotation.Nullable;
 import android.text.Spannable;
 import android.text.SpannableString;
 import android.text.TextUtils;
 import android.text.style.TtsSpan;
-import android.util.Log;
 import android.util.Patterns;
-
+import androidx.annotation.Nullable;
 import com.android.contacts.R;
 import com.android.contacts.compat.PhoneNumberUtilsCompat;
 import com.android.contacts.preference.ContactsPreferences;
 
-import com.google.common.base.Preconditions;
-
 /**
  * Methods for handling various contact data labels.
  */
@@ -41,9 +36,6 @@
 
     private static final String TAG = ContactDisplayUtils.class.getSimpleName();
 
-    public static final int INTERACTION_CALL = 1;
-    public static final int INTERACTION_SMS = 2;
-
     /**
      * Checks if the given data type is a custom type.
      *
@@ -55,39 +47,6 @@
     }
 
     /**
-     * Gets a display label for a given phone type.
-     *
-     * @param type The type of number.
-     * @param customLabel A custom label to use if the phone is determined to be of custom type
-     * determined by {@link #isCustomPhoneType(Integer))}
-     * @param interactionType whether this is a call or sms.  Either {@link #INTERACTION_CALL} or
-     * {@link #INTERACTION_SMS}.
-     * @param context The application context.
-     * @return An appropriate string label
-     */
-    public static CharSequence getLabelForCallOrSms(Integer type, CharSequence customLabel,
-            int interactionType, Context context) {
-        Preconditions.checkNotNull(context);
-
-        if (isCustomPhoneType(type)) {
-            return (customLabel == null) ? "" : customLabel;
-        } else {
-            int resId;
-            if (interactionType == INTERACTION_SMS) {
-                resId = getSmsLabelResourceId(type);
-            } else {
-                resId = getPhoneLabelResourceId(type);
-                if (interactionType != INTERACTION_CALL) {
-                    Log.e(TAG, "Un-recognized interaction type: " + interactionType +
-                            ". Defaulting to ContactDisplayUtils.INTERACTION_CALL.");
-                }
-            }
-
-            return context.getResources().getText(resId);
-        }
-    }
-
-    /**
      * Find a label for calling.
      *
      * @param type The type of number.
diff --git a/tests/src/com/android/contacts/NoPermissionsLaunchSmokeTest.java b/tests/src/com/android/contacts/NoPermissionsLaunchSmokeTest.java
index b8eccd7..fac9c85 100644
--- a/tests/src/com/android/contacts/NoPermissionsLaunchSmokeTest.java
+++ b/tests/src/com/android/contacts/NoPermissionsLaunchSmokeTest.java
@@ -32,7 +32,6 @@
  * $ adb shell pm revoke com.android.contacts android.permission.WRITE_CONTACTS
  * $ adb shell pm revoke com.android.contacts android.permission.GET_ACCOUNTS
  * $ adb shell pm revoke com.android.contacts android.permission.READ_PHONE_STATE
- * $ adb shell pm revoke com.android.contacts android.permission.READ_CALL_LOG
  * $ adb shell pm revoke com.android.contacts android.permission.CALL_PHONE
  * $ adb shell am instrument -w \
  *     com.google.android.contacts.tests/androidx.test.runner.AndroidJUnitRunner \
@@ -54,7 +53,6 @@
         assumeTrue(!hasPermission(mTargetContext, Manifest.permission.WRITE_CONTACTS));
         assumeTrue(!hasPermission(mTargetContext, Manifest.permission.GET_ACCOUNTS));
         assumeTrue(!hasPermission(mTargetContext, Manifest.permission.READ_PHONE_STATE));
-        assumeTrue(!hasPermission(mTargetContext, Manifest.permission.READ_CALL_LOG));
         assumeTrue(!hasPermission(mTargetContext, Manifest.permission.CALL_PHONE));
 
         // remove state that might exist outside of the app
diff --git a/tests/src/com/android/contacts/interactions/CallLogInteractionsLoaderTest.java b/tests/src/com/android/contacts/interactions/CallLogInteractionsLoaderTest.java
deleted file mode 100644
index b51affd..0000000
--- a/tests/src/com/android/contacts/interactions/CallLogInteractionsLoaderTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.android.contacts.interactions;
-
-import android.content.ContentValues;
-import android.provider.CallLog.Calls;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Tests {@link CallLogInteractionsLoader}
- */
-@SmallTest
-public class CallLogInteractionsLoaderTest extends AndroidTestCase {
-
-    public void testCallLogInteractions_pruneDuplicates_containsDuplicates() {
-        List<ContactInteraction> interactions = new ArrayList<>();
-        int maxToRetrieve = 5;
-
-        ContentValues interactionOneValues = new ContentValues();
-        interactionOneValues.put(Calls.DATE, 1L);
-        interactions.add(new CallLogInteraction(interactionOneValues));
-
-        ContentValues interactionTwoValues = new ContentValues();
-        interactionTwoValues.put(Calls.DATE, 1L);
-        interactions.add(new CallLogInteraction(interactionTwoValues));
-
-        interactions = CallLogInteractionsLoader.pruneDuplicateCallLogInteractions(interactions,
-                maxToRetrieve);
-        assertEquals(1, interactions.size());
-    }
-
-    public void testCallLogInteractions_pruneDuplicates_containsNoDuplicates() {
-        List<ContactInteraction> interactions = new ArrayList<>();
-        int maxToRetrieve = 5;
-
-        ContentValues interactionOneValues = new ContentValues();
-        interactionOneValues.put(Calls.DATE, 1L);
-        interactions.add(new CallLogInteraction(interactionOneValues));
-
-        ContentValues interactionTwoValues = new ContentValues();
-        interactionTwoValues.put(Calls.DATE, 5L);
-        interactions.add(new CallLogInteraction(interactionTwoValues));
-
-        interactions = CallLogInteractionsLoader.pruneDuplicateCallLogInteractions(interactions,
-                maxToRetrieve);
-        assertEquals(2, interactions.size());
-    }
-
-    public void testCallLogInteractions_maxToRetrieve() {
-        List<ContactInteraction> interactions = new ArrayList<>();
-        int maxToRetrieve = 1;
-
-        ContentValues interactionOneValues = new ContentValues();
-        interactionOneValues.put(Calls.DATE, 1L);
-        interactions.add(new CallLogInteraction(interactionOneValues));
-
-        ContentValues interactionTwoValues = new ContentValues();
-        interactionTwoValues.put(Calls.DATE, 5L);
-        interactions.add(new CallLogInteraction(interactionTwoValues));
-
-        interactions = CallLogInteractionsLoader.pruneDuplicateCallLogInteractions(interactions,
-                maxToRetrieve);
-        assertEquals(1, interactions.size());
-    }
-}
diff --git a/tests/src/com/android/contacts/interactions/ContactInteractionUtilTest.java b/tests/src/com/android/contacts/interactions/ContactInteractionUtilTest.java
index 5f95a1b..654533b 100644
--- a/tests/src/com/android/contacts/interactions/ContactInteractionUtilTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactInteractionUtilTest.java
@@ -15,11 +15,8 @@
  */
 package com.android.contacts.interactions;
 
-import android.content.res.Configuration;
-import android.content.res.Resources;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
-
 import java.util.Calendar;
 import java.util.Locale;
 
@@ -28,26 +25,6 @@
  */
 @SmallTest
 public class ContactInteractionUtilTest extends AndroidTestCase {
-
-    private Locale mOriginalLocale;
-    private Calendar calendar;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        calendar = Calendar.getInstance();
-
-        // Time/Date utilities rely on specific locales. Forace US and set back in tearDown()
-        mOriginalLocale = Locale.getDefault();
-        setLocale(Locale.US);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        setLocale(mOriginalLocale);
-        super.tearDown();
-    }
-
     public void testOneQuestionMark() {
         assertEquals("(?)", ContactInteractionUtil.questionMarks(1));
     }
@@ -59,69 +36,4 @@
     public void testFiveQuestionMarks() {
         assertEquals("(?,?,?,?,?)", ContactInteractionUtil.questionMarks(5));
     }
-
-    public void testFormatDateStringFromTimestamp_todaySingleMinuteAm() {
-        // Test today scenario (time shown)
-        // Single digit minute & AM
-        calendar.set(Calendar.HOUR_OF_DAY, 8);
-        calendar.set(Calendar.MINUTE, 8);
-        long todayTimestamp = calendar.getTimeInMillis();
-        assertEquals("8:08 AM", ContactInteractionUtil.formatDateStringFromTimestamp(
-                calendar.getTimeInMillis(), getContext()));
-    }
-
-    public void testFormatDateStringFromTimestamp_todayDoubleMinutePm() {
-        // Double digit minute & PM
-        calendar.set(Calendar.HOUR_OF_DAY, 22);
-        calendar.set(Calendar.MINUTE, 18);
-        assertEquals("10:18 PM",
-                ContactInteractionUtil.formatDateStringFromTimestamp(calendar.getTimeInMillis(),
-                        getContext()));
-    }
-
-    public void testFormatDateStringFromTimestamp_other() {
-        // Test other (Month Date)
-        calendar.set(
-                /* year = */ 1991,
-                /* month = */ Calendar.MONTH,
-                /* day = */ 11,
-                /* hourOfDay = */ 8,
-                /* minute = */ 8);
-        assertEquals("Monday, March 11, 1991, 8:08 AM",
-                ContactInteractionUtil.formatDateStringFromTimestamp(calendar.getTimeInMillis(),
-                        getContext()));
-    }
-
-    public void testFormatDuration_zero() {
-        assertEquals("0 sec",
-                ContactInteractionUtil.formatDuration(0, getContext()));
-    }
-
-    public void testFormatDuration_minZeroSec() {
-        assertEquals("1 min 0 sec",
-                ContactInteractionUtil.formatDuration(60, getContext()));
-    }
-
-    public void testFormatDuration_minSec() {
-        assertEquals("30 min 9 sec",
-                ContactInteractionUtil.formatDuration(1809, getContext()));
-    }
-
-    public void testFormatDuration_hrZeroMinZeroSec() {
-        assertEquals("1 hr 0 min 0 sec",
-                ContactInteractionUtil.formatDuration(3600, getContext()));
-    }
-
-    public void testFormatDuration_hrMinSec() {
-        assertEquals("2 hr 44 min 36 sec",
-                ContactInteractionUtil.formatDuration(9876, getContext()));
-    }
-
-    private void setLocale(Locale locale) {
-        Locale.setDefault(locale);
-        Resources res = getContext().getResources();
-        Configuration config = res.getConfiguration();
-        config.locale = locale;
-        res.updateConfiguration(config, res.getDisplayMetrics());
-    }
 }
\ No newline at end of file
diff --git a/tests/src/com/android/contacts/interactions/TestLoaderManager.java b/tests/src/com/android/contacts/interactions/TestLoaderManager.java
index dacf616..7a3dbe3 100644
--- a/tests/src/com/android/contacts/interactions/TestLoaderManager.java
+++ b/tests/src/com/android/contacts/interactions/TestLoaderManager.java
@@ -111,7 +111,7 @@
                 @Override
                 public void run() {
                     try {
-                        AsyncTaskLoader.class.getMethod("waitForLoader").invoke(loader, null);
+                        AsyncTaskLoader.class.getMethod("waitForLoader").invoke(loader);
                     } catch (Throwable e) {
                         Log.e(TAG, "Exception while waiting for loader: " + loader.getId(), e);
                         Assert.fail("Exception while waiting for loader: " + loader.getId());
diff --git a/tests/src/com/android/contacts/util/ContactDisplayUtilTests.java b/tests/src/com/android/contacts/util/ContactDisplayUtilTests.java
index 88c9e29..1503215 100644
--- a/tests/src/com/android/contacts/util/ContactDisplayUtilTests.java
+++ b/tests/src/com/android/contacts/util/ContactDisplayUtilTests.java
@@ -57,40 +57,6 @@
         assertFalse(ContactDisplayUtils.isCustomPhoneType(Phone.TYPE_OTHER));
     }
 
-    public void testGetLabelForCallOrSmsReturnsCustomLabel() {
-        final CharSequence smsResult = ContactDisplayUtils.getLabelForCallOrSms(Phone.TYPE_CUSTOM,
-                "expected sms label", ContactDisplayUtils.INTERACTION_SMS, getContext());
-        assertEquals("expected sms label", smsResult);
-
-        final CharSequence callResult = ContactDisplayUtils.getLabelForCallOrSms(Phone.TYPE_CUSTOM,
-                "expected call label", ContactDisplayUtils.INTERACTION_CALL, getContext());
-        assertEquals("expected call label", callResult);
-    }
-
-    public void testGetLabelForCallOrSmsReturnsCallLabels() {
-        CharSequence result = ContactDisplayUtils.getLabelForCallOrSms(Phone.TYPE_HOME, "",
-                ContactDisplayUtils.INTERACTION_CALL, getContext());
-        CharSequence expected = getContext().getResources().getText(R.string.call_home);
-        assertEquals(expected, result);
-
-        result = ContactDisplayUtils.getLabelForCallOrSms(Phone.TYPE_MOBILE, "",
-                ContactDisplayUtils.INTERACTION_CALL, getContext());
-        expected = getContext().getResources().getText(R.string.call_mobile);
-        assertEquals(expected, result);
-    }
-
-    public void testGetLabelForCallOrSmsReturnsSmsLabels() {
-        CharSequence result = ContactDisplayUtils.getLabelForCallOrSms(Phone.TYPE_HOME, "",
-                ContactDisplayUtils.INTERACTION_SMS, getContext());
-        CharSequence expected = getContext().getResources().getText(R.string.sms_home);
-        assertEquals(expected, result);
-
-        result = ContactDisplayUtils.getLabelForCallOrSms(Phone.TYPE_MOBILE, "",
-                ContactDisplayUtils.INTERACTION_SMS, getContext());
-        expected = getContext().getResources().getText(R.string.sms_mobile);
-        assertEquals(expected, result);
-    }
-
     public void testGetPhoneLabelResourceIdReturnsOther() {
         assertEquals(R.string.call_other, ContactDisplayUtils.getPhoneLabelResourceId(null));
     }