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