diff --git a/src/com/android/dialer/DialerBackupAgent.java b/src/com/android/dialer/DialerBackupAgent.java
index cbcdf5b..928be02 100644
--- a/src/com/android/dialer/DialerBackupAgent.java
+++ b/src/com/android/dialer/DialerBackupAgent.java
@@ -33,6 +33,6 @@
     @Override
     public void onCreate() {
         addHelper(SHARED_KEY, new SharedPreferencesBackupHelper(this,
-               OldDialtactsActivity.SHARED_PREFS_NAME));
+                DialtactsActivity.SHARED_PREFS_NAME));
     }
 }
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index 5e2eee3..a0153ea 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -68,7 +68,7 @@
 import com.android.contacts.common.list.OnPhoneNumberPickerActionListener;
 import com.android.contacts.common.list.PhoneNumberPickerFragment;
 import com.android.dialer.calllog.CallLogActivity;
-import com.android.dialer.dialpad.NewDialpadFragment;
+import com.android.dialer.dialpad.DialpadFragment;
 import com.android.dialer.dialpad.SmartDialNameMatcher;
 import com.android.dialer.interactions.PhoneNumberInteraction;
 import com.android.dialer.list.NewPhoneFavoriteFragment;
@@ -86,14 +86,16 @@
  * be renamed more appropriately before shipping.
  */
 public class DialtactsActivity extends TransactionSafeActivity implements View.OnClickListener,
-        NewDialpadFragment.OnDialpadQueryChangedListener, PopupMenu.OnMenuItemClickListener,
+        DialpadFragment.OnDialpadQueryChangedListener, PopupMenu.OnMenuItemClickListener,
         OnListFragmentScrolledListener,
         NewPhoneFavoriteFragment.OnPhoneFavoriteFragmentStartedListener,
-        NewDialpadFragment.OnDialpadFragmentStartedListener {
+        DialpadFragment.OnDialpadFragmentStartedListener {
     private static final String TAG = "DialtactsActivity";
 
     public static final boolean DEBUG = false;
 
+    public static final String SHARED_PREFS_NAME = "com.android.dialer_preferences";
+
     /** Used to open Call Setting */
     private static final String PHONE_PACKAGE = "com.android.phone";
     private static final String CALL_SETTINGS_CLASS_NAME =
@@ -127,7 +129,7 @@
     /**
      * Fragment containing the dialpad that slides into view
      */
-    private NewDialpadFragment mDialpadFragment;
+    private DialpadFragment mDialpadFragment;
 
     /**
      * Fragment for searching phone numbers using the alphanumeric keyboard.
@@ -245,7 +247,7 @@
 
             mRegularSearchFragment = new NewSearchFragment();
             mSmartDialSearchFragment = new SmartDialSearchFragment();
-            mDialpadFragment = new NewDialpadFragment();
+            mDialpadFragment = new DialpadFragment();
             mShowAllContactsFragment = new ShowAllContactsFragment();
             mShowAllContactsFragment.setOnPhoneNumberPickerActionListener(
                     mPhoneNumberPickerActionListener);
@@ -277,7 +279,7 @@
         final FragmentManager fm = getFragmentManager();
         mPhoneFavoriteFragment = (NewPhoneFavoriteFragment) fm.findFragmentByTag(
                 TAG_FAVORITES_FRAGMENT);
-        mDialpadFragment = (NewDialpadFragment) fm.findFragmentByTag(TAG_DIALPAD_FRAGMENT);
+        mDialpadFragment = (DialpadFragment) fm.findFragmentByTag(TAG_DIALPAD_FRAGMENT);
 
         mRegularSearchFragment = (NewSearchFragment) fm.findFragmentByTag(
                 TAG_REGULAR_SEARCH_FRAGMENT);
@@ -297,7 +299,7 @@
 
     @Override
     public void onAttachFragment(Fragment fragment) {
-        if (fragment instanceof NewDialpadFragment || fragment instanceof NewSearchFragment
+        if (fragment instanceof DialpadFragment || fragment instanceof NewSearchFragment
                 || fragment instanceof SmartDialSearchFragment
                 || fragment instanceof ShowAllContactsFragment) {
             final FragmentTransaction transaction = getFragmentManager().beginTransaction();
@@ -327,7 +329,7 @@
                 // now in Dialtacts for (potential) performance reasons. Compare with how it is
                 // done in {@link PeopleActivity}.
                 ImportExportDialogFragment.show(getFragmentManager(), true,
-                        OldDialtactsActivity.class);
+                        DialtactsActivity.class);
                 return true;
             case R.id.menu_clear_frequents:
                 ClearFrequentsDialog.show(getFragmentManager());
@@ -343,7 +345,7 @@
                 }
                 return true;
             case R.id.menu_call_settings:
-                final Intent settingsIntent = OldDialtactsActivity.getCallSettingsIntent();
+                final Intent settingsIntent = DialtactsActivity.getCallSettingsIntent();
                 startActivity(settingsIntent);
         }
         return false;
diff --git a/src/com/android/dialer/OldDialtactsActivity.java b/src/com/android/dialer/OldDialtactsActivity.java
deleted file mode 100644
index 46b22e1..0000000
--- a/src/com/android/dialer/OldDialtactsActivity.java
+++ /dev/null
@@ -1,1292 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.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.backup.BackupManager;
-import android.app.Fragment;
-import android.app.FragmentManager;
-import android.app.FragmentTransaction;
-import android.content.ActivityNotFoundException;
-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 android.widget.Toast;
-
-import com.android.contacts.common.CallUtil;
-import com.android.contacts.common.activity.TransactionSafeActivity;
-import com.android.contacts.common.list.ContactListFilterController;
-import com.android.contacts.common.list.ContactListFilterController.ContactListFilterListener;
-import com.android.contacts.common.list.ContactListItemView;
-import com.android.contacts.common.list.OnPhoneNumberPickerActionListener;
-import com.android.contacts.common.list.PhoneNumberPickerFragment;
-import com.android.contacts.common.util.AccountFilterUtil;
-import com.android.dialer.calllog.CallLogFragment;
-import com.android.dialer.dialpad.DialpadFragment;
-import com.android.dialer.interactions.PhoneNumberInteraction;
-import com.android.dialer.list.PhoneFavoriteFragment;
-import com.android.dialer.util.OrientationUtil;
-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 OldDialtactsActivity 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;
-
-    public static final String SHARED_PREFS_NAME = "com.android.dialer_preferences";
-
-    /** 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 (mDialpadFragment == null || !mDialpadFragment.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(OldDialtactsActivity.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(
-                    OldDialtactsActivity.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(
-                            OldDialtactsActivity.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 = this.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE);
-        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.getDefaultPhotoPosition(
-                    true /* opposite */));
-            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();
-        requestBackup();
-    }
-
-    private void requestBackup() {
-        final BackupManager bm = new BackupManager(this);
-        bm.dataChanged();
-    }
-
-    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 ((mDialpadFragment != null && mDialpadFragment.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.setStartedFromNewIntent(true);
-            } 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 && CallUtil.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(
-                    OldDialtactsActivity.this, contactUri, getCallOrigin());
-        }
-
-        @Override
-        public void onCallNumberDirectly(String phoneNumber) {
-            Intent intent = CallUtil.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);
-
-        callSettingsMenuItem.setIntent(OldDialtactsActivity.getCallSettingsIntent());
-        searchMenuItem.setOnMenuItemClickListener(mSearchMenuItemClickListener);
-        filterOptionMenuItem.setOnMenuItemClickListener(mFilterOptionsMenuItemClickListener);
-
-        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;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.add_contact:
-                try {
-                    startActivity(new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI));
-                } catch (ActivityNotFoundException e) {
-                    Toast toast = Toast.makeText(this, R.string.add_contact_not_available,
-                            Toast.LENGTH_SHORT);
-                    toast.show();
-                }
-                return true;
-        }
-        return super.onOptionsItemSelected(item);
-    }
-
-    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(OrientationUtil.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 && (mDialpadFragment == null ||
-                        !mDialpadFragment.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/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java
index 72f45e4..76cca33 100644
--- a/src/com/android/dialer/dialpad/DialpadFragment.java
+++ b/src/com/android/dialer/dialpad/DialpadFragment.java
@@ -32,7 +32,6 @@
 import android.media.AudioManager;
 import android.media.ToneGenerator;
 import android.net.Uri;
-import android.os.AsyncTask;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
@@ -50,6 +49,7 @@
 import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.text.style.RelativeSizeSpan;
+import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.KeyEvent;
@@ -60,13 +60,16 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnPreDrawListener;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
 import android.widget.EditText;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.PopupMenu;
-import android.widget.RelativeLayout;
+import android.widget.TableRow;
 import android.widget.TextView;
 
 import com.android.contacts.common.CallUtil;
@@ -75,7 +78,8 @@
 import com.android.contacts.common.preference.ContactsPreferences;
 import com.android.contacts.common.util.PhoneNumberFormatter;
 import com.android.contacts.common.util.StopWatch;
-import com.android.dialer.OldDialtactsActivity;
+import com.android.dialer.NeededForReflection;
+import com.android.dialer.DialtactsActivity;
 import com.android.dialer.R;
 import com.android.dialer.SpecialCharSequenceMgr;
 import com.android.dialer.database.DialerDatabaseHelper;
@@ -86,8 +90,6 @@
 import com.android.phone.common.HapticFeedback;
 import com.google.common.annotations.VisibleForTesting;
 
-import java.util.List;
-
 /**
  * Fragment that displays a twelve-key phone dialpad.
  */
@@ -96,11 +98,52 @@
         View.OnLongClickListener, View.OnKeyListener,
         AdapterView.OnItemClickListener, TextWatcher,
         PopupMenu.OnMenuItemClickListener,
-        DialpadImageButton.OnPressedListener,
-        SmartDialLoaderTask.SmartDialLoaderCallback {
+        DialpadKeyButton.OnPressedListener {
     private static final String TAG = DialpadFragment.class.getSimpleName();
 
-    private static final boolean DEBUG = OldDialtactsActivity.DEBUG;
+    public interface OnDialpadFragmentStartedListener {
+        public void onDialpadFragmentStarted();
+    }
+
+    /**
+     * LinearLayout with getter and setter methods for the translationY property using floats,
+     * for animation purposes.
+     */
+    public static class DialpadSlidingLinearLayout extends LinearLayout {
+
+        public DialpadSlidingLinearLayout(Context context) {
+            super(context);
+        }
+
+        public DialpadSlidingLinearLayout(Context context, AttributeSet attrs) {
+            super(context, attrs);
+        }
+
+        public DialpadSlidingLinearLayout(Context context, AttributeSet attrs, int defStyle) {
+            super(context, attrs, defStyle);
+        }
+
+        @NeededForReflection
+        public float getYFraction() {
+            final int height = getHeight();
+            if (height == 0) return 0;
+            return getTranslationY() / height;
+        }
+
+        @NeededForReflection
+        public void setYFraction(float yFraction) {
+            setTranslationY(yFraction * getHeight());
+        }
+    }
+
+    public interface OnDialpadQueryChangedListener {
+        void onDialpadQueryChanged(String query);
+    }
+
+    private static final boolean DEBUG = DialtactsActivity.DEBUG;
+
+    // This is the amount of screen the dialpad fragment takes up when fully displayed
+    private static final float DIALPAD_SLIDE_FRACTION = 0.67f;
 
     private static final String EMPTY_NUMBER = "";
     private static final char PAUSE = ',';
@@ -118,6 +161,8 @@
 
     private ContactsPreferences mContactsPrefs;
 
+    private OnDialpadQueryChangedListener mDialpadQueryListener;
+
     /**
      * View (usually FrameLayout) containing mDigits field. This can be null, in which mDigits
      * isn't enclosed by the container.
@@ -145,25 +190,6 @@
     private ListView mDialpadChooser;
     private DialpadChooserAdapter mDialpadChooserAdapter;
 
-    /** Will be set only if the view has the smart dialing section. */
-    private RelativeLayout mSmartDialContainer;
-
-    /**
-     * Will be set only if the view has the smart dialing section.
-     */
-    private SmartDialController mSmartDialAdapter;
-
-    /**
-     * Use latin character map by default
-     */
-    private SmartDialMap mSmartDialMap = new LatinSmartDialMap();
-
-    /**
-     * Master switch controlling whether or not smart dialing is enabled, and whether the
-     * smart dialing suggestion strip is visible.
-     */
-    private boolean mSmartDialEnabled = false;
-
     private DialerDatabaseHelper mDialerDatabaseHelper;
 
     /**
@@ -287,8 +313,10 @@
             mDigits.setCursorVisible(false);
         }
 
+        if (mDialpadQueryListener != null) {
+            mDialpadQueryListener.onDialpadQueryChanged(mDigits.getText().toString());
+        }
         updateDialAndDeleteButtonEnabledState();
-        loadSmartDialEntries();
     }
 
     @Override
@@ -308,8 +336,6 @@
              Log.e(TAG, "Vibrate control bool missing.", nfe);
         }
 
-        setHasOptionsMenu(true);
-
         mProhibitedPhoneNumberRegexp = getResources().getString(
                 R.string.config_prohibited_phone_number_regexp);
 
@@ -320,7 +346,30 @@
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedState) {
-        View fragmentView = inflater.inflate(R.layout.dialpad_fragment, container, false);
+        final View fragmentView = inflater.inflate(R.layout.new_dialpad_fragment, container,
+                false);
+        fragmentView.buildLayer();
+
+        // TODO krelease: Get rid of this ugly hack which is to prevent the first frame of the
+        // animation from drawing the fragment at translationY = 0
+        final ViewTreeObserver vto = fragmentView.getViewTreeObserver();
+        final OnPreDrawListener preDrawListener = new OnPreDrawListener() {
+
+            @Override
+            public boolean onPreDraw() {
+                if (isHidden()) return true;
+                if (fragmentView.getTranslationY() == 0) {
+                    ((DialpadSlidingLinearLayout) fragmentView).setYFraction(
+                            DIALPAD_SLIDE_FRACTION);
+                }
+                final ViewTreeObserver vto = fragmentView.getViewTreeObserver();
+                vto.removeOnPreDrawListener(this);
+                return true;
+            }
+
+        };
+
+        vto.addOnPreDrawListener(preDrawListener);
 
         // Load up the resources for the text field.
         Resources r = getResources();
@@ -339,18 +388,6 @@
             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 && !OrientationUtil.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);
@@ -379,18 +416,26 @@
         mDialpadChooser = (ListView) fragmentView.findViewById(R.id.dialpadChooser);
         mDialpadChooser.setOnItemClickListener(this);
 
-        // Smart dial container. This is null if in landscape mode since it is not present
-        // in the landscape dialer layout.
-        mSmartDialContainer = (RelativeLayout) fragmentView.findViewById(
-                R.id.dialpad_smartdial_container);
-
-        if (mSmartDialContainer != null) {
-            mSmartDialAdapter = new SmartDialController(getActivity(), mSmartDialContainer,
-                    new OnSmartDialShortClick(), new OnSmartDialLongClick());
-        }
         return fragmentView;
     }
 
+    @Override
+    public void onStart() {
+        super.onStart();
+
+        final Activity activity = getActivity();
+
+        try {
+            ((OnDialpadFragmentStartedListener) activity).onDialpadFragmentStarted();
+        } catch (ClassCastException e) {
+            throw new ClassCastException(activity.toString()
+                    + " must implement OnDialpadFragmentStartedListener");
+        }
+
+        final View overflowButton = getView().findViewById(R.id.overflow_menu_on_dialpad);
+        overflowButton.setOnClickListener(this);
+    }
+
     private boolean isLayoutReady() {
         return mDigits != null;
     }
@@ -472,11 +517,10 @@
      */
     private void configureScreenFromIntent(Activity parent) {
         // If we were not invoked with a DIAL intent,
-        if (!(parent instanceof OldDialtactsActivity)) {
+        if (!(parent instanceof DialtactsActivity)) {
             setStartedFromNewIntent(false);
             return;
         }
-
         // See if we were invoked with a DIAL intent. If we were, fill in the appropriate
         // digits in the dialer field.
         Intent intent = parent.getIntent();
@@ -542,10 +586,36 @@
     }
 
     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);
+        final int[] buttonIds = new int[] {R.id.zero, 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.star, R.id.pound};
+
+        final int[] numberIds = new int[] {R.string.dialpad_0_number, R.string.dialpad_1_number,
+                R.string.dialpad_2_number, R.string.dialpad_3_number, R.string.dialpad_4_number,
+                R.string.dialpad_5_number, R.string.dialpad_6_number, R.string.dialpad_7_number,
+                R.string.dialpad_8_number, R.string.dialpad_9_number, R.string.dialpad_star_number,
+                R.string.dialpad_pound_number};
+
+        final int[] letterIds = new int[] {R.string.dialpad_0_letters, R.string.dialpad_1_letters,
+                R.string.dialpad_2_letters, R.string.dialpad_3_letters, R.string.dialpad_4_letters,
+                R.string.dialpad_5_letters, R.string.dialpad_6_letters, R.string.dialpad_7_letters,
+                R.string.dialpad_8_letters, R.string.dialpad_9_letters,
+                R.string.dialpad_star_letters, R.string.dialpad_pound_letters};
+
+        DialpadKeyButton dialpadKey;
+        TextView numberView;
+        TextView lettersView;
+        final Resources resources = getResources();
+        for (int i = 0; i < buttonIds.length; i++) {
+            dialpadKey = (DialpadKeyButton) fragmentView.findViewById(buttonIds[i]);
+            dialpadKey.setLayoutParams(new TableRow.LayoutParams(
+                    TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT));
+            dialpadKey.setOnPressedListener(this);
+            numberView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_number);
+            lettersView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_letters);
+            numberView.setText(resources.getString(numberIds[i]));
+            if (lettersView != null) {
+                lettersView.setText(resources.getString(letterIds[i]));
+            }
         }
 
         // Long-pressing one button will initiate Voicemail.
@@ -560,6 +630,9 @@
     public void onResume() {
         super.onResume();
 
+        final DialtactsActivity activity = (DialtactsActivity) getActivity();
+        mDialpadQueryListener = activity;
+
         final StopWatch stopWatch = StopWatch.start("Dialpad.onResume");
 
         // Query the last dialed number. Do it first because hitting
@@ -568,16 +641,12 @@
 
         stopWatch.lap("qloc");
 
-        final ContentResolver contentResolver = getActivity().getContentResolver();
+        final ContentResolver contentResolver = activity.getContentResolver();
 
         // retrieve the DTMF tone play back setting.
         mDTMFToneEnabled = Settings.System.getInt(contentResolver,
                 Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;
 
-        // retrieve dialpad autocomplete setting
-        mSmartDialEnabled = Settings.Secure.getInt(contentResolver,
-                Settings.Secure.DIALPAD_AUTOCOMPLETE, 0) == 1 && mSmartDialContainer != null;
-
         stopWatch.lap("dtwd");
 
         // Retrieve the haptic feedback setting.
@@ -678,6 +747,7 @@
     @Override
     public void onStop() {
         super.onStop();
+
         if (mClearDigitsOnStop) {
             mClearDigitsOnStop = false;
             mDigits.getText().clear();
@@ -690,47 +760,9 @@
         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 (OrientationUtil.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 (OrientationUtil.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);
 
-        // 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(OldDialtactsActivity.getCallSettingsIntent());
-        }
-
         // We show "add to contacts" menu only when the user is
         // seeing usual dialpad and has typed at least one digit.
         // We never show a menu if the "choose dialpad" UI is up.
@@ -738,7 +770,6 @@
             addToContactMenuItem.setVisible(false);
         } else {
             final CharSequence digits = mDigits.getText();
-
             // Put the current digits string into an intent
             addToContactMenuItem.setIntent(getAddToContactIntent(digits));
             addToContactMenuItem.setVisible(true);
@@ -904,6 +935,15 @@
     @Override
     public void onClick(View view) {
         switch (view.getId()) {
+            case R.id.overflow_menu_on_dialpad: {
+                final PopupMenu popupMenu = new PopupMenu(getActivity(), view);
+                final Menu menu = popupMenu.getMenu();
+                popupMenu.inflate(R.menu.dialpad_options_new);
+                popupMenu.setOnMenuItemClickListener(this);
+                setupMenuItems(menu);
+                popupMenu.show();
+                break;
+            }
             case R.id.deleteButton: {
                 keyPressed(KeyEvent.KEYCODE_DEL);
                 return;
@@ -926,19 +966,6 @@
         }
     }
 
-    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();
@@ -1126,8 +1153,8 @@
                 mDigits.getText().clear();
             } else {
                 final Intent intent = CallUtil.getCallIntent(number,
-                        (getActivity() instanceof OldDialtactsActivity ?
-                                ((OldDialtactsActivity) getActivity()).getCallOrigin() : null));
+                        (getActivity() instanceof DialtactsActivity ?
+                                ((DialtactsActivity) getActivity()).getCallOrigin() : null));
                 startActivity(intent);
                 mClearDigitsOnStop = true;
                 getActivity().finish();
@@ -1136,8 +1163,8 @@
     }
 
     private String getCallOrigin() {
-        return (getActivity() instanceof OldDialtactsActivity) ?
-                ((OldDialtactsActivity) getActivity()).getCallOrigin() : null;
+        return (getActivity() instanceof DialtactsActivity) ?
+                ((DialtactsActivity) getActivity()).getCallOrigin() : null;
     }
 
     private void handleDialButtonClickWithEmptyDigits() {
@@ -1481,12 +1508,9 @@
         return getTelephonyManager().getCallState() == TelephonyManager.CALL_STATE_OFFHOOK;
     }
 
-    /**
-     * 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) {
+    public boolean onMenuItemClick(MenuItem item) {
+        // R.id.menu_add_contacts already has an add to contact intent populated by setupMenuItems
         switch (item.getItemId()) {
             case R.id.menu_2s_pause:
                 updateDialString(PAUSE);
@@ -1499,11 +1523,6 @@
         }
     }
 
-    @Override
-    public boolean onMenuItemClick(MenuItem item) {
-        return onOptionsItemSelected(item);
-    }
-
     /**
      * Updates the dial string (mDigits) after inserting a Pause character (,)
      * or Wait character (;).
@@ -1654,79 +1673,22 @@
         return intent;
     }
 
-    private String mLastDigitsForSmartDial;
-
-    private void loadSmartDialEntries() {
-        if (!mSmartDialEnabled || mSmartDialAdapter == null) {
-            // No smart dial views.  Landscape?
-            return;
-        }
-
-        // Update only when the digits have changed.
-        final String digits = SmartDialNameMatcher.normalizeNumber(mDigits.getText().toString(),
-                mSmartDialMap);
-        if (TextUtils.equals(digits, mLastDigitsForSmartDial)) {
-            return;
-        }
-        mLastDigitsForSmartDial = digits;
-
-        if (digits.length() < 1) {
-            mSmartDialAdapter.clear();
-        } else {
-            final SmartDialLoaderTask task = new SmartDialLoaderTask(this, digits, getActivity());
-            task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, new String[] {});
-        }
+    private void initializeSmartDialingState() {
+        // Handle smart dialing related state
+        // TODO krelease: This should probably be moved to somewhere more appropriate, maybe
+        // into DialtactsActivity
+        mDialerDatabaseHelper.startSmartDialUpdateThread();
     }
 
     @Override
-    public void setSmartDialAdapterEntries(List<SmartDialEntry> data, String query) {
-        if (data == null || query == null || !query.equals(mLastDigitsForSmartDial)) {
-            return;
-        }
-        mSmartDialAdapter.setEntries(data);
-    }
-
-    private void initializeSmartDialingState() {
-        // Handle smart dialing related state
-        if (mSmartDialEnabled) {
-            mSmartDialContainer.setVisibility(View.VISIBLE);
-
-            if (DEBUG) {
-                Log.w(TAG, "Creating smart dial database");
-            }
-            mDialerDatabaseHelper.startSmartDialUpdateThread();
+    public void onHiddenChanged(boolean hidden) {
+        super.onHiddenChanged(hidden);
+        final DialtactsActivity activity = (DialtactsActivity) getActivity();
+        if (activity == null) return;
+        if (hidden) {
+            activity.showSearchBar();
         } else {
-            if (mSmartDialContainer != null) {
-                mSmartDialContainer.setVisibility(View.GONE);
-            }
-        }
-    }
-
-    private class OnSmartDialLongClick implements View.OnLongClickListener {
-        @Override
-        public boolean onLongClick(View view) {
-            final SmartDialEntry entry = (SmartDialEntry) view.getTag();
-            if (entry == null) return false; // just in case.
-            mClearDigitsOnStop = true;
-            // Show the phone number disambiguation dialog without using the primary
-            // phone number so that the user can decide which number to call
-            PhoneNumberInteraction.startInteractionForPhoneCall(
-                    (TransactionSafeActivity) getActivity(), entry.contactUri, false);
-            return true;
-        }
-    }
-
-    private class OnSmartDialShortClick implements View.OnClickListener {
-        @Override
-        public void onClick(View view) {
-            final SmartDialEntry entry = (SmartDialEntry) view.getTag();
-            if (entry == null) return; // just in case.
-            // Dial the displayed phone number immediately
-            final Intent intent = CallUtil.getCallIntent(entry.phoneNumber.toString(),
-                    (getActivity() instanceof OldDialtactsActivity ?
-                            ((OldDialtactsActivity) getActivity()).getCallOrigin() : null));
-            startActivity(intent);
-            mClearDigitsOnStop = true;
+            activity.hideSearchBar();
         }
     }
 }
diff --git a/src/com/android/dialer/dialpad/DialpadImageButton.java b/src/com/android/dialer/dialpad/DialpadImageButton.java
deleted file mode 100644
index 8f9ea4d..0000000
--- a/src/com/android/dialer/dialpad/DialpadImageButton.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dialer.dialpad;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.os.Bundle;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
-import android.view.accessibility.AccessibilityNodeInfo;
-import android.widget.ImageButton;
-
-/**
- * Custom {@link ImageButton} for dialpad buttons.
- * <p>
- * This class implements lift-to-type interaction when touch exploration is
- * enabled.
- */
-public class DialpadImageButton extends ImageButton {
-    /** Accessibility manager instance used to check touch exploration state. */
-    private AccessibilityManager mAccessibilityManager;
-
-    /** Bounds used to filter HOVER_EXIT events. */
-    private Rect mHoverBounds = new Rect();
-
-    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);
-        initForAccessibility(context);
-    }
-
-    public DialpadImageButton(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        initForAccessibility(context);
-    }
-
-    private void initForAccessibility(Context context) {
-        mAccessibilityManager = (AccessibilityManager) context.getSystemService(
-                Context.ACCESSIBILITY_SERVICE);
-    }
-
-    @Override
-    public void setPressed(boolean pressed) {
-        super.setPressed(pressed);
-        if (mOnPressedListener != null) {
-            mOnPressedListener.onPressed(this, pressed);
-        }
-    }
-
-    @Override
-    public void onSizeChanged(int w, int h, int oldw, int oldh) {
-        super.onSizeChanged(w, h, oldw, oldh);
-
-        mHoverBounds.left = getPaddingLeft();
-        mHoverBounds.right = w - getPaddingRight();
-        mHoverBounds.top = getPaddingTop();
-        mHoverBounds.bottom = h - getPaddingBottom();
-    }
-
-    @Override
-    public boolean performAccessibilityAction(int action, Bundle arguments) {
-        if (action == AccessibilityNodeInfo.ACTION_CLICK) {
-            simulateClickForAccessibility();
-            return true;
-        }
-
-        return super.performAccessibilityAction(action, arguments);
-    }
-
-    @Override
-    public boolean onHoverEvent(MotionEvent event) {
-        // When touch exploration is turned on, lifting a finger while inside
-        // the button's hover target bounds should perform a click action.
-        if (mAccessibilityManager.isEnabled()
-                && mAccessibilityManager.isTouchExplorationEnabled()) {
-            switch (event.getActionMasked()) {
-                case MotionEvent.ACTION_HOVER_ENTER:
-                    // Lift-to-type temporarily disables double-tap activation.
-                    setClickable(false);
-                    break;
-                case MotionEvent.ACTION_HOVER_EXIT:
-                    if (mHoverBounds.contains((int) event.getX(), (int) event.getY())) {
-                        simulateClickForAccessibility();
-                    }
-                    setClickable(true);
-                    break;
-            }
-        }
-
-        return super.onHoverEvent(event);
-    }
-
-    /**
-     * When accessibility is on, simulate press and release to preserve the
-     * semantic meaning of performClick(). Required for Braille support.
-     */
-    private void simulateClickForAccessibility() {
-        // Checking the press state prevents double activation.
-        if (isPressed()) {
-            return;
-        }
-
-        setPressed(true);
-
-        // Stay consistent with performClick() by sending the event after
-        // setting the pressed state but before performing the action.
-        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
-
-        setPressed(false);
-    }
-}
diff --git a/src/com/android/dialer/dialpad/NewDialpadFragment.java b/src/com/android/dialer/dialpad/NewDialpadFragment.java
deleted file mode 100644
index e22c5d1..0000000
--- a/src/com/android/dialer/dialpad/NewDialpadFragment.java
+++ /dev/null
@@ -1,1689 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.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.ContentResolver;
-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.style.RelativeSizeSpan;
-import android.util.AttributeSet;
-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.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.OnPreDrawListener;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.EditText;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.PopupMenu;
-import android.widget.TableRow;
-import android.widget.TextView;
-
-import com.android.contacts.common.CallUtil;
-import com.android.contacts.common.GeoUtil;
-import com.android.contacts.common.activity.TransactionSafeActivity;
-import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.contacts.common.util.PhoneNumberFormatter;
-import com.android.contacts.common.util.StopWatch;
-import com.android.dialer.OldDialtactsActivity;
-import com.android.dialer.NeededForReflection;
-import com.android.dialer.DialtactsActivity;
-import com.android.dialer.R;
-import com.android.dialer.SpecialCharSequenceMgr;
-import com.android.dialer.database.DialerDatabaseHelper;
-import com.android.dialer.interactions.PhoneNumberInteraction;
-import com.android.dialer.util.OrientationUtil;
-import com.android.internal.telephony.ITelephony;
-import com.android.phone.common.CallLogAsync;
-import com.android.phone.common.HapticFeedback;
-import com.google.common.annotations.VisibleForTesting;
-
-/**
- * Fragment that displays a twelve-key phone dialpad.
- */
-public class NewDialpadFragment extends Fragment
-        implements View.OnClickListener,
-        View.OnLongClickListener, View.OnKeyListener,
-        AdapterView.OnItemClickListener, TextWatcher,
-        PopupMenu.OnMenuItemClickListener,
-        DialpadKeyButton.OnPressedListener {
-    private static final String TAG = NewDialpadFragment.class.getSimpleName();
-
-    public interface OnDialpadFragmentStartedListener {
-        public void onDialpadFragmentStarted();
-    }
-
-    /**
-     * LinearLayout with getter and setter methods for the translationY property using floats,
-     * for animation purposes.
-     */
-    public static class DialpadSlidingLinearLayout extends LinearLayout {
-
-        public DialpadSlidingLinearLayout(Context context) {
-            super(context);
-        }
-
-        public DialpadSlidingLinearLayout(Context context, AttributeSet attrs) {
-            super(context, attrs);
-        }
-
-        public DialpadSlidingLinearLayout(Context context, AttributeSet attrs, int defStyle) {
-            super(context, attrs, defStyle);
-        }
-
-        @NeededForReflection
-        public float getYFraction() {
-            return getTranslationY() / getHeight();
-        }
-
-        @NeededForReflection
-        public void setYFraction(float yFraction) {
-            setTranslationY(yFraction * getHeight());
-        }
-    }
-
-    public interface OnDialpadQueryChangedListener {
-        void onDialpadQueryChanged(String query);
-    }
-
-    private static final boolean DEBUG = OldDialtactsActivity.DEBUG;
-
-    private static final String EMPTY_NUMBER = "";
-    private static final char PAUSE = ',';
-    private static final char WAIT = ';';
-
-    /** 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;
-
-    private ContactsPreferences mContactsPrefs;
-
-    private OnDialpadQueryChangedListener mDialpadQueryListener;
-
-    /**
-     * 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;
-
-    private DialerDatabaseHelper mDialerDatabaseHelper;
-
-    /**
-     * 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 boolean mStartedFromNewIntent = false;
-    private boolean mFirstLaunch = false;
-
-    private static final String PREF_DIGITS_FILLED_BY_INTENT = "pref_digits_filled_by_intent";
-
-    /**
-     * Return an Intent for launching voicemail screen.
-     */
-    private static Intent getVoicemailIntent() {
-        final Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
-                Uri.fromParts("voicemail", "", null));
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        return intent;
-    }
-
-    private TelephonyManager getTelephonyManager() {
-        return (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
-    }
-
-    @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);
-        }
-
-        if (mDialpadQueryListener != null) {
-            mDialpadQueryListener.onDialpadQueryChanged(mDigits.getText().toString());
-        }
-        updateDialAndDeleteButtonEnabledState();
-    }
-
-    @Override
-    public void onCreate(Bundle state) {
-        super.onCreate(state);
-        mFirstLaunch = true;
-        mContactsPrefs = new ContactsPreferences(getActivity());
-        mCurrentCountryIso = GeoUtil.getCurrentCountryIso(getActivity());
-
-        mDialerDatabaseHelper = DialerDatabaseHelper.getInstance(getActivity());
-        SmartDialPrefix.initializeNanpSettings(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);
-        }
-
-        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) {
-        final View fragmentView = inflater.inflate(R.layout.new_dialpad_fragment, container,
-                false);
-        fragmentView.buildLayer();
-
-        // TODO krelease: Get rid of this ugly hack which is to prevent the first frame of the
-        // animation from drawing the fragment at translationY = 0
-        final ViewTreeObserver vto = fragmentView.getViewTreeObserver();
-        final OnPreDrawListener preDrawListener = new OnPreDrawListener() {
-
-            @Override
-            public boolean onPreDraw() {
-                if (isHidden()) return true;
-                if (fragmentView.getTranslationY() == 0) {
-                    ((DialpadSlidingLinearLayout) fragmentView).setYFraction(0.67f);
-                }
-                final ViewTreeObserver vto = fragmentView.getViewTreeObserver();
-                vto.removeOnPreDrawListener(this);
-                return true;
-            }
-
-        };
-
-        vto.addOnPreDrawListener(preDrawListener);
-
-        // 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(UnicodeDialerKeyListener.INSTANCE);
-        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);
-        }
-
-        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);
-
-        return fragmentView;
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-
-        final Activity activity = getActivity();
-
-        try {
-            ((OnDialpadFragmentStartedListener) activity).onDialpadFragmentStarted();
-        } catch (ClassCastException e) {
-            throw new ClassCastException(activity.toString()
-                    + " must implement OnDialpadFragmentStartedListener");
-        }
-
-        final View overflowButton = getView().findViewById(R.id.overflow_menu_on_dialpad);
-        overflowButton.setOnClickListener(this);
-    }
-
-    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) {
-        // Only fills digits from an intent if it is a new intent.
-        // Otherwise falls back to the previously used number.
-        if (!mFirstLaunch && !mStartedFromNewIntent) {
-            return false;
-        }
-
-        final String action = intent.getAction();
-        if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
-            Uri uri = intent.getData();
-            if (uri != null) {
-                if (CallUtil.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;
-                    final String converted = PhoneNumberUtils.convertKeypadLettersToDigits(
-                            PhoneNumberUtils.replaceUnicodeDigits(data));
-                    setFormattedDigits(converted, 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;
-    }
-
-    /**
-     * Determines whether an add call operation is requested.
-     *
-     * @param intent The intent.
-     * @return {@literal true} if add call operation was requested.  {@literal false} otherwise.
-     */
-    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.
-     */
-    private void configureScreenFromIntent(Activity parent) {
-        // If we were not invoked with a DIAL intent,
-        if (!(parent instanceof DialtactsActivity)) {
-            setStartedFromNewIntent(false);
-            return;
-        }
-        // See if we were invoked with a DIAL intent. If we were, fill in the appropriate
-        // digits in the dialer field.
-        Intent intent = parent.getIntent();
-
-        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;
-
-        // Be sure *not* to show the dialpad chooser if this is an
-        // explicit "Add call" action, though.
-        final boolean isAddCallMode = isAddCallMode(intent);
-        if (!isAddCallMode) {
-
-            // Don't show the chooser when called via onNewIntent() and phone number is present.
-            // i.e. User clicks a telephone link from gmail for example.
-            // In this case, we want to show the dialpad with the phone number.
-            final boolean digitsFilled = fillDigitsIfNecessary(intent);
-            if (!(mStartedFromNewIntent && digitsFilled)) {
-
-                final String action = intent.getAction();
-                if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)
-                        || Intent.ACTION_MAIN.equals(action)) {
-                    // If there's already an active call, bring up an intermediate UI to
-                    // make the user confirm what they really want to do.
-                    if (phoneIsInUse()) {
-                        needToShowDialpadChooser = true;
-                    }
-                }
-
-            }
-        }
-        showDialpadChooser(needToShowDialpadChooser);
-        setStartedFromNewIntent(false);
-    }
-
-    public void setStartedFromNewIntent(boolean value) {
-        mStartedFromNewIntent = value;
-    }
-
-    /**
-     * 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) {
-        final int[] buttonIds = new int[] {R.id.zero, 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.star, R.id.pound};
-
-        final int[] numberIds = new int[] {R.string.dialpad_0_number, R.string.dialpad_1_number,
-                R.string.dialpad_2_number, R.string.dialpad_3_number, R.string.dialpad_4_number,
-                R.string.dialpad_5_number, R.string.dialpad_6_number, R.string.dialpad_7_number,
-                R.string.dialpad_8_number, R.string.dialpad_9_number, R.string.dialpad_star_number,
-                R.string.dialpad_pound_number};
-
-        final int[] letterIds = new int[] {R.string.dialpad_0_letters, R.string.dialpad_1_letters,
-                R.string.dialpad_2_letters, R.string.dialpad_3_letters, R.string.dialpad_4_letters,
-                R.string.dialpad_5_letters, R.string.dialpad_6_letters, R.string.dialpad_7_letters,
-                R.string.dialpad_8_letters, R.string.dialpad_9_letters,
-                R.string.dialpad_star_letters, R.string.dialpad_pound_letters};
-
-        DialpadKeyButton dialpadKey;
-        TextView numberView;
-        TextView lettersView;
-        final Resources resources = getResources();
-        for (int i = 0; i < buttonIds.length; i++) {
-            dialpadKey = (DialpadKeyButton) fragmentView.findViewById(buttonIds[i]);
-            dialpadKey.setLayoutParams(new TableRow.LayoutParams(
-                    TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT));
-            dialpadKey.setOnPressedListener(this);
-            numberView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_number);
-            lettersView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_letters);
-            numberView.setText(resources.getString(numberIds[i]));
-            if (lettersView != null) {
-                lettersView.setText(resources.getString(letterIds[i]));
-            }
-        }
-
-        // 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 DialtactsActivity activity = (DialtactsActivity) getActivity();
-        mDialpadQueryListener = activity;
-
-        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");
-
-        final ContentResolver contentResolver = getActivity().getContentResolver();
-
-        // retrieve the DTMF tone play back setting.
-        mDTMFToneEnabled = Settings.System.getInt(contentResolver,
-                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;
-
-        // Initialize smart dialing state. This has to be done before anything is filled in before
-        // the dialpad edittext to prevent entries from being loaded from a null cache.
-        initializeSmartDialingState();
-
-        configureScreenFromIntent(getActivity());
-
-        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.
-        getTelephonyManager().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);
-        }
-
-        mFirstLaunch = false;
-
-        stopWatch.lap("hnt");
-
-        updateDialAndDeleteButtonEnabledState();
-
-        stopWatch.lap("bes");
-
-        stopWatch.stopAndLog(TAG, 50);
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-
-        // Stop listening for phone state changes.
-        getTelephonyManager().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);
-    }
-
-    private void setupMenuItems(Menu menu) {
-        final MenuItem addToContactMenuItem = menu.findItem(R.id.menu_add_contacts);
-
-        // We show "add to contacts" menu only when the user is
-        // seeing usual dialpad 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);
-        } else {
-            final CharSequence digits = mDigits.getText();
-            // Put the current digits string into an intent
-            addToContactMenuItem.setIntent(getAddToContactIntent(digits));
-            addToContactMenuItem.setVisible(true);
-        }
-    }
-
-    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.overflow_menu_on_dialpad: {
-                final PopupMenu popupMenu = new PopupMenu(getActivity(), view);
-                final Menu menu = popupMenu.getMenu();
-                popupMenu.inflate(R.menu.dialpad_options_new);
-                popupMenu.setOnMenuItemClickListener(this);
-                setupMenuItems(menu);
-                popupMenu.show();
-                break;
-            }
-            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;
-            }
-        }
-    }
-
-    @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(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 = CallUtil.getCallIntent(number,
-                        (getActivity() instanceof OldDialtactsActivity ?
-                                ((OldDialtactsActivity) getActivity()).getCallOrigin() : null));
-                startActivity(intent);
-                mClearDigitsOnStop = true;
-                getActivity().finish();
-            }
-        }
-    }
-
-    private String getCallOrigin() {
-        return (getActivity() instanceof OldDialtactsActivity) ?
-                ((OldDialtactsActivity) getActivity()).getCallOrigin() : null;
-    }
-
-    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 boolean phoneIsInUse() {
-        return getTelephonyManager().getCallState() != TelephonyManager.CALL_STATE_IDLE;
-    }
-
-    /**
-     * @return true if the phone is a CDMA phone type
-     */
-    private boolean phoneIsCdma() {
-        return getTelephonyManager().getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA;
-    }
-
-    /**
-     * @return true if the phone state is OFFHOOK
-     */
-    private boolean phoneIsOffhook() {
-        return getTelephonyManager().getCallState() == TelephonyManager.CALL_STATE_OFFHOOK;
-    }
-
-    @Override
-    public boolean onMenuItemClick(MenuItem item) {
-        // R.id.menu_add_contacts already has an add to contact intent populated by setupMenuItems
-        switch (item.getItemId()) {
-            case R.id.menu_2s_pause:
-                updateDialString(PAUSE);
-                return true;
-            case R.id.menu_add_wait:
-                updateDialString(WAIT);
-                return true;
-            default:
-                return false;
-        }
-    }
-
-    /**
-     * Updates the dial string (mDigits) after inserting a Pause character (,)
-     * or Wait character (;).
-     */
-    private void updateDialString(char newDigit) {
-        if(newDigit != WAIT && newDigit != PAUSE) {
-            Log.wtf(TAG, "Not expected for anything other than PAUSE & WAIT");
-            return;
-        }
-
-        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);
-
-        if (selectionStart == -1) {
-            selectionStart = selectionEnd = mDigits.length();
-        }
-
-        Editable digits = mDigits.getText();
-
-        if (canAddDigit(digits, selectionStart, selectionEnd, newDigit)) {
-            digits.replace(selectionStart, selectionEnd, Character.toString(newDigit));
-
-            if (selectionStart != selectionEnd) {
-              // Unselect: back to a regular cursor, just pass the character inserted.
-              mDigits.setSelection(selectionStart + 1);
-            }
-        }
-    }
-
-    /**
-     * 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 getTelephonyManager().getVoiceMailNumber() != null;
-        } catch (SecurityException se) {
-            // Possibly no READ_PHONE_STATE privilege.
-            Log.w(TAG, "SecurityException is thrown. Maybe privilege isn't sufficient.");
-        }
-        return false;
-    }
-
-    /**
-     * Returns true of the newDigit parameter can be added at the current selection
-     * point, otherwise returns false.
-     * Only prevents input of WAIT and PAUSE digits at an unsupported position.
-     * Fails early if start == -1 or start is larger than end.
-     */
-    @VisibleForTesting
-    /* package */ static boolean canAddDigit(CharSequence digits, int start, int end,
-                                             char newDigit) {
-        if(newDigit != WAIT && newDigit != PAUSE) {
-            Log.wtf(TAG, "Should not be called for anything other than PAUSE & WAIT");
-            return false;
-        }
-
-        // False if no selection, or selection is reversed (end < start)
-        if (start == -1 || end < start) {
-            return false;
-        }
-
-        // unsupported selection-out-of-bounds state
-        if (start > digits.length() || end > digits.length()) return false;
-
-        // Special digit cannot be the first digit
-        if (start == 0) return false;
-
-        if (newDigit == WAIT) {
-            // preceding char is ';' (WAIT)
-            if (digits.charAt(start - 1) == WAIT) return false;
-
-            // next char is ';' (WAIT)
-            if ((digits.length() > end) && (digits.charAt(end) == WAIT)) 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 = CallUtil.getCallIntent(EMPTY_NUMBER);
-        intent.putExtra(EXTRA_SEND_EMPTY_FLASH, true);
-        return intent;
-    }
-
-    private void initializeSmartDialingState() {
-        // Handle smart dialing related state
-        // TODO krelease: This should probably be moved to somewhere more appropriate, maybe
-        // into DialtactsActivity
-        mDialerDatabaseHelper.startSmartDialUpdateThread();
-    }
-
-    @Override
-    public void onHiddenChanged(boolean hidden) {
-        super.onHiddenChanged(hidden);
-        final DialtactsActivity activity = (DialtactsActivity) getActivity();
-        if (activity == null) return;
-        if (hidden) {
-            activity.showSearchBar();
-        } else {
-            activity.hideSearchBar();
-        }
-    }
-}
diff --git a/src/com/android/dialer/dialpad/SmartDialController.java b/src/com/android/dialer/dialpad/SmartDialController.java
deleted file mode 100644
index 5ce993b..0000000
--- a/src/com/android/dialer/dialpad/SmartDialController.java
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.dialer.dialpad;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.TextUtils;
-import android.text.style.ForegroundColorSpan;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.View.OnLongClickListener;
-import android.view.animation.AccelerateDecelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.view.animation.LinearInterpolator;
-import android.view.animation.OvershootInterpolator;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import com.android.dialer.R;
-
-import com.google.common.collect.Lists;
-
-import java.util.List;
-
-/**
-* This class controls the display and animation logic behind the smart dialing suggestion strip.
-*
-* It allows a list of SmartDialEntries to be assigned to the suggestion strip via
-* {@link #setEntries}, and also animates the removal of old suggestions.
-*
-* To avoid creating new views every time new entries are assigned, references to 2 *
-* {@link #NUM_SUGGESTIONS} views are kept in {@link #mViews} and {@link #mViewOverlays}.
-*
-* {@code mViews} contains the active views that are currently being displayed to the user,
-* while {@code mViewOverlays} contains the views that are used as view overlays. The view
-* overlays are used to provide the illusion of the former suggestions fading out. These two
-* lists of views are rotated each time a new set of entries is assigned to achieve the appropriate
-* cross fade animations using the new {@link View#getOverlay()} API.
-*/
-public class SmartDialController {
-    public static final String LOG_TAG = "SmartDial";
-
-    /**
-     * Handtuned interpolator used to achieve the bounce effect when suggestions slide up. It
-     * uses a combination of a decelerate interpolator and overshoot interpolator to first
-     * decelerate, and then overshoot its top bounds and bounce back to its final position.
-     */
-    private class DecelerateAndOvershootInterpolator implements Interpolator {
-        private DecelerateInterpolator a;
-        private OvershootInterpolator b;
-
-        public DecelerateAndOvershootInterpolator() {
-            a = new DecelerateInterpolator(1.5f);
-            b = new OvershootInterpolator(1.3f);
-        }
-
-        @Override
-        public float getInterpolation(float input) {
-            if (input > 0.6) {
-                return b.getInterpolation(input);
-            } else {
-                return a.getInterpolation(input);
-            }
-        }
-
-    }
-
-    private DecelerateAndOvershootInterpolator mDecelerateAndOvershootInterpolator =
-            new DecelerateAndOvershootInterpolator();
-    private AccelerateDecelerateInterpolator mAccelerateDecelerateInterpolator =
-            new AccelerateDecelerateInterpolator();
-
-    private List<SmartDialEntry> mEntries;
-    private List<SmartDialEntry> mOldEntries;
-
-    private final int mNameHighlightedTextColor;
-    private final int mNumberHighlightedTextColor;
-
-    private final LinearLayout mList;
-    private final View mBackground;
-
-    private final List<LinearLayout> mViewOverlays = Lists.newArrayList();
-    private final List<LinearLayout> mViews = Lists.newArrayList();
-
-    private static final int NUM_SUGGESTIONS = 3;
-
-    private static final long ANIM_DURATION = 200;
-
-    private static final float BACKGROUND_FADE_AMOUNT = 0.25f;
-
-    Resources mResources;
-
-    public SmartDialController(Context context, ViewGroup parent,
-            OnClickListener shortClickListener, OnLongClickListener longClickListener) {
-        final Resources res = context.getResources();
-        mResources = res;
-
-        mNameHighlightedTextColor = res.getColor(R.color.smartdial_name_highlighted_text_color);
-        mNumberHighlightedTextColor = res.getColor(
-                R.color.smartdial_number_highlighted_text_color);
-
-        mList = (LinearLayout) parent.findViewById(R.id.dialpad_smartdial_list);
-        mBackground = parent.findViewById(R.id.dialpad_smartdial_list_background);
-
-        mEntries = Lists.newArrayList();
-        for (int i = 0; i < NUM_SUGGESTIONS; i++) {
-            mEntries.add(SmartDialEntry.NULL);
-        }
-
-        mOldEntries = mEntries;
-
-        final LayoutInflater inflater = (LayoutInflater) context.getSystemService(
-                Context.LAYOUT_INFLATER_SERVICE);
-
-        for (int i = 0; i < NUM_SUGGESTIONS * 2; i++) {
-            final LinearLayout view = (LinearLayout) inflater.inflate(
-                    R.layout.dialpad_smartdial_item, mList, false);
-            view.setOnClickListener(shortClickListener);
-            view.setOnLongClickListener(longClickListener);
-            if (i < NUM_SUGGESTIONS) {
-                mViews.add(view);
-            } else {
-                mViewOverlays.add(view);
-            }
-            // Add all the views to mList so that they can get measured properly for animation
-            // purposes. Once setEntries is called they will be removed and added as appropriate.
-            view.setEnabled(false);
-            mList.addView(view);
-        }
-    }
-
-    /** Remove all entries. */
-    public void clear() {
-        mOldEntries = mEntries;
-        mEntries = Lists.newArrayList();
-        for (int i = 0; i < NUM_SUGGESTIONS; i++) {
-            mEntries.add(SmartDialEntry.NULL);
-        }
-        updateViews();
-    }
-
-    /** Set entries. At the end of this method {@link #mEntries} should contain exactly
-     *  {@link #NUM_SUGGESTIONS} entries.*/
-    public void setEntries(List<SmartDialEntry> entries) {
-        if (entries == null) throw new IllegalArgumentException();
-        mOldEntries = mEntries;
-        mEntries = entries;
-
-        final int size = mEntries.size();
-        if (size <= 1) {
-            if (size == 0) {
-                mEntries.add(SmartDialEntry.NULL);
-            }
-            // add a null entry to push the single entry into the middle
-            mEntries.add(0, SmartDialEntry.NULL);
-        } else if (size >= 2) {
-            // swap the 1st and 2nd entries so that the highest confidence match goes into the
-            // middle
-            swap(0, 1);
-        }
-
-        while (mEntries.size() < NUM_SUGGESTIONS) {
-            mEntries.add(SmartDialEntry.NULL);
-        }
-
-        updateViews();
-    }
-
-    /**
-     * This method is called every time a new set of SmartDialEntries is to be assigned to the
-     * suggestions view. The current set of active views are to be used as view overlays and
-     * faded out, while the former view overlays are assigned the current entries, added to
-     * {@link #mList} and faded into view.
-     */
-    private void updateViews() {
-        // Remove all views from the root in preparation to swap the two sets of views
-        mList.removeAllViews();
-        try {
-            mList.getOverlay().clear();
-        } catch (NullPointerException e) {
-            // Catch possible NPE b/8895794
-        }
-
-        // Used to track whether or not to animate the overlay. In the case where the suggestion
-        // at position i will slide from the left or right, or if the suggestion at position i
-        // has not changed, the overlay at i should be hidden immediately. Overlay animations are
-        // set in a separate loop from the active views to avoid unnecessarily reanimating the same
-        // overlay multiple times.
-        boolean[] dontAnimateOverlay = new boolean[NUM_SUGGESTIONS];
-        boolean noSuggestions = true;
-
-        // At this point in time {@link #mViews} contains the former active views with old
-        // suggestions that will be swapped out to serve as view overlays, while
-        // {@link #mViewOverlays} contains the former overlays that will now serve as active
-        // views.
-        for (int i = 0; i < NUM_SUGGESTIONS; i++) {
-            // Retrieve the former overlay to be used as the new active view
-            final LinearLayout active = mViewOverlays.get(i);
-            final SmartDialEntry item = mEntries.get(i);
-
-            noSuggestions &= (item == SmartDialEntry.NULL);
-
-            assignEntryToView(active, mEntries.get(i));
-            final SmartDialEntry oldItem = mOldEntries.get(i);
-            // The former active view will now be used as an overlay for the cross-fade effect
-            final LinearLayout overlay = mViews.get(i);
-            show(active);
-            if (!containsSameContact(oldItem, item)) {
-                // Determine what kind of animation to use for the new view
-                if (i == 1) { // Middle suggestion
-                    if (containsSameContact(item, mOldEntries.get(0))) {
-                        // Suggestion went from the left to the middle, slide it left to right
-                        animateSlideFromLeft(active);
-                        dontAnimateOverlay[0] = true;
-                    } else if (containsSameContact(item, mOldEntries.get(2))) {
-                        // Suggestion sent from the right to the middle, slide it right to left
-                        animateSlideFromRight(active);
-                        dontAnimateOverlay[2] = true;
-                    } else {
-                        animateFadeInAndSlideUp(active);
-                    }
-                } else { // Left/Right suggestion
-                    if (i == 2 && containsSameContact(item, mOldEntries.get(1))) {
-                        // Suggestion went from middle to the right, slide it left to right
-                        animateSlideFromLeft(active);
-                        dontAnimateOverlay[1] = true;
-                    } else if (i == 0 && containsSameContact(item, mOldEntries.get(1))) {
-                        // Suggestion went from middle to the left, slide it right to left
-                        animateSlideFromRight(active);
-                        dontAnimateOverlay[1] = true;
-                    } else {
-                        animateFadeInAndSlideUp(active);
-                    }
-                }
-            } else {
-                // Since the same item is in the same spot, don't do any animations and just
-                // show the new view.
-                dontAnimateOverlay[i] = true;
-            }
-            mList.getOverlay().add(overlay);
-            mList.addView(active);
-            // Keep track of active views and view overlays
-            mViews.set(i, active);
-            mViewOverlays.set(i, overlay);
-        }
-
-        // Separate loop for overlay animations. At this point in time {@link #mViewOverlays}
-        // contains the actual overlays.
-        for (int i = 0; i < NUM_SUGGESTIONS; i++) {
-            final LinearLayout overlay = mViewOverlays.get(i);
-            if (!dontAnimateOverlay[i]) {
-                animateFadeOutAndSlideDown(overlay);
-            } else {
-                hide(overlay);
-            }
-        }
-
-        // Fade out the background to 25% opacity if there are suggestions. If there are no
-        // suggestions, display the background as usual.
-        mBackground.animate().withLayer().alpha(noSuggestions ? 1.0f : BACKGROUND_FADE_AMOUNT);
-    }
-
-    private void show(View view) {
-        view.animate().cancel();
-        view.setAlpha(1);
-        view.setTranslationX(0);
-        view.setTranslationY(0);
-    }
-
-    private void hide(View view) {
-        view.animate().cancel();
-        view.setAlpha(0);
-    }
-
-    private void animateFadeInAndSlideUp(View view) {
-        view.animate().cancel();
-        view.setAlpha(0.2f);
-        view.setTranslationY(view.getHeight());
-        view.animate().withLayer().alpha(1).translationY(0).setDuration(ANIM_DURATION).
-                setInterpolator(mDecelerateAndOvershootInterpolator);
-    }
-
-    private void animateFadeOutAndSlideDown(View view) {
-        view.animate().cancel();
-        view.setAlpha(1);
-        view.setTranslationY(0);
-        view.animate().withLayer().alpha(0).translationY(view.getHeight()).setDuration(
-                ANIM_DURATION).setInterpolator(mAccelerateDecelerateInterpolator);
-    }
-
-    private void animateSlideFromLeft(View view) {
-        view.animate().cancel();
-        view.setAlpha(1);
-        view.setTranslationX(-1 * view.getWidth());
-        view.animate().withLayer().translationX(0).setDuration(ANIM_DURATION).setInterpolator(
-                mAccelerateDecelerateInterpolator);
-    }
-
-    private void animateSlideFromRight(View view) {
-        view.animate().cancel();
-        view.setAlpha(1);
-        view.setTranslationX(view.getWidth());
-        view.animate().withLayer().translationX(0).setDuration(ANIM_DURATION).setInterpolator(
-                mAccelerateDecelerateInterpolator);
-    }
-
-    // Swaps the items in pos1 and pos2 of mEntries
-    private void swap(int pos1, int pos2) {
-        if (pos1 == pos2) {
-            return;
-        }
-        final SmartDialEntry temp = mEntries.get(pos1);
-        mEntries.set(pos1, mEntries.get(pos2));
-        mEntries.set(pos2, temp);
-    }
-
-    // Returns whether two SmartDialEntries contain the same contact
-    private boolean containsSameContact(SmartDialEntry x, SmartDialEntry y) {
-        return x.contactUri.equals(y.contactUri);
-    }
-
-    // Sets the information within a SmartDialEntry to the provided view
-    private void assignEntryToView(LinearLayout view, SmartDialEntry item) {
-        final TextView nameView = (TextView) view.findViewById(R.id.contact_name);
-
-        final TextView numberView = (TextView) view.findViewById(
-                R.id.contact_number);
-
-        if (item == SmartDialEntry.NULL) {
-            // Clear the text in case the view was reused.
-            nameView.setText("");
-            numberView.setText("");
-            view.setEnabled(false);
-            return;
-        }
-
-        // Highlight the display name with the provided match positions
-        if (!TextUtils.isEmpty(item.displayName)) {
-            final SpannableString displayName = new SpannableString(item.displayName);
-            for (final SmartDialMatchPosition p : item.matchPositions) {
-                if (p.start < p.end) {
-                    if (p.end > displayName.length()) {
-                        p.end = displayName.length();
-                    }
-                    // Create a new ForegroundColorSpan for each section of the name to highlight,
-                    // otherwise multiple highlights won't work.
-                    displayName.setSpan(new ForegroundColorSpan(mNameHighlightedTextColor), p.start,
-                            p.end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-                }
-            }
-            nameView.setText(displayName);
-        }
-
-        // Highlight the phone number with the provided match positions
-        if (!TextUtils.isEmpty(item.phoneNumber)) {
-            final SmartDialMatchPosition p = item.phoneNumberMatchPosition;
-            final SpannableString phoneNumber = new SpannableString(item.phoneNumber);
-            if (p != null && p.start < p.end) {
-                if (p.end > phoneNumber.length()) {
-                    p.end = phoneNumber.length();
-                }
-                phoneNumber.setSpan(new ForegroundColorSpan(mNumberHighlightedTextColor), p.start,
-                        p.end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
-            }
-            numberView.setText(phoneNumber);
-        }
-        view.setEnabled(true);
-        view.setTag(item);
-    }
-}
diff --git a/src/com/android/dialer/dialpad/SmartDialLoaderTask.java b/src/com/android/dialer/dialpad/SmartDialLoaderTask.java
index 71cbfa2..38a04ad 100644
--- a/src/com/android/dialer/dialpad/SmartDialLoaderTask.java
+++ b/src/com/android/dialer/dialpad/SmartDialLoaderTask.java
@@ -16,8 +16,6 @@
 
 package com.android.dialer.dialpad;
 
-import static com.android.dialer.dialpad.SmartDialController.LOG_TAG;
-
 import android.content.Context;
 import android.os.AsyncTask;
 import android.provider.ContactsContract;
@@ -40,6 +38,7 @@
  * callback function.
  */
 public class SmartDialLoaderTask extends AsyncTask<String, Integer, List<SmartDialEntry>> {
+    private final String TAG = SmartDialLoaderTask.class.getSimpleName();
 
     public interface SmartDialLoaderCallback {
         void setSmartDialAdapterEntries(List<SmartDialEntry> list, String query);
@@ -101,7 +100,7 @@
                     ));
         }
         if (DEBUG) {
-            stopWatch.stopAndLog(LOG_TAG + " Match Complete", 0);
+            stopWatch.stopAndLog(TAG + " Match Complete", 0);
         }
         return candidates;
     }
diff --git a/src/com/android/dialer/dialpad/SmartDialMatchPosition.java b/src/com/android/dialer/dialpad/SmartDialMatchPosition.java
index 452ac91..bab2c50 100644
--- a/src/com/android/dialer/dialpad/SmartDialMatchPosition.java
+++ b/src/com/android/dialer/dialpad/SmartDialMatchPosition.java
@@ -16,8 +16,6 @@
 
 package com.android.dialer.dialpad;
 
-import static com.android.dialer.dialpad.SmartDialController.LOG_TAG;
-
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -25,10 +23,12 @@
 /**
  * Stores information about a range of characters matched in a display name The integers
  * start and end indicate that the range start to end (exclusive) correspond to some characters
- * in the query. Used by {@link SmartDialController} to highlight certain parts of the contact's
- * display name to indicate that those ranges matched the user's query.
+ * in the query. Used to highlight certain parts of the contact's display name to indicate that
+ * those ranges matched the user's query.
  */
 public class SmartDialMatchPosition {
+    private static final String TAG = SmartDialMatchPosition.class.getSimpleName();
+
     public int start;
     public int end;
 
@@ -64,7 +64,7 @@
     public static void print(ArrayList<SmartDialMatchPosition> list) {
         for (int i = 0; i < list.size(); i ++) {
             SmartDialMatchPosition m = list.get(i);
-            Log.d(LOG_TAG, "[" + m.start + "," + m.end + "]");
+            Log.d(TAG, "[" + m.start + "," + m.end + "]");
         }
     }
 }
diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java
deleted file mode 100644
index 3b2f4d7..0000000
--- a/src/com/android/dialer/list/PhoneFavoriteFragment.java
+++ /dev/null
@@ -1,573 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.dialer.list;
-
-import android.app.Activity;
-import android.app.Fragment;
-import android.app.LoaderManager;
-import android.content.CursorLoader;
-import android.content.Intent;
-import android.content.Loader;
-import android.database.Cursor;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.Directory;
-import android.provider.Settings;
-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.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.AbsListView;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.FrameLayout;
-import android.widget.ListView;
-import android.widget.TextView;
-
-import com.android.contacts.common.ContactPhotoManager;
-import com.android.contacts.common.ContactTileLoaderFactory;
-import com.android.contacts.common.dialog.ClearFrequentsDialog;
-import com.android.contacts.common.list.ContactListFilter;
-import com.android.contacts.common.list.ContactListFilterController;
-import com.android.contacts.common.list.ContactListItemView;
-import com.android.contacts.common.list.ContactTileAdapter;
-import com.android.contacts.common.list.ContactTileView;
-import com.android.contacts.common.list.PhoneNumberListAdapter;
-import com.android.contacts.common.preference.ContactsPreferences;
-import com.android.contacts.common.util.AccountFilterUtil;
-import com.android.contacts.common.interactions.ImportExportDialogFragment;
-import com.android.dialer.OldDialtactsActivity;
-import com.android.dialer.R;
-
-/**
- * Fragment for Phone UI's favorite screen.
- *
- * This fragment contains three kinds of contacts in one screen: "starred", "frequent", and "all"
- * contacts. To show them at once, this merges results from {@link com.android.contacts.common.list.ContactTileAdapter} and
- * {@link com.android.contacts.common.list.PhoneNumberListAdapter} into one unified list using {@link PhoneFavoriteMergedAdapter}.
- * A contact filter header is also inserted between those adapters' results.
- */
-public class PhoneFavoriteFragment extends Fragment implements OnItemClickListener {
-    private static final String TAG = PhoneFavoriteFragment.class.getSimpleName();
-    private static final boolean DEBUG = false;
-
-    /**
-     * Used with LoaderManager.
-     */
-    private static int LOADER_ID_CONTACT_TILE = 1;
-    private static int LOADER_ID_ALL_CONTACTS = 2;
-
-    private static final String KEY_FILTER = "filter";
-
-    private static final int REQUEST_CODE_ACCOUNT_FILTER = 1;
-
-    public interface Listener {
-        public void onContactSelected(Uri contactUri);
-        public void onCallNumberDirectly(String phoneNumber);
-    }
-
-    private class ContactTileLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
-        @Override
-        public CursorLoader onCreateLoader(int id, Bundle args) {
-            if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onCreateLoader.");
-            return ContactTileLoaderFactory.createStrequentPhoneOnlyLoader(getActivity());
-        }
-
-        @Override
-        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
-            if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoadFinished");
-            mContactTileAdapter.setContactCursor(data);
-
-            if (mAllContactsForceReload) {
-                mAllContactsAdapter.onDataReload();
-                // Use restartLoader() to make LoaderManager to load the section again.
-                getLoaderManager().restartLoader(
-                        LOADER_ID_ALL_CONTACTS, null, mAllContactsLoaderListener);
-            } else if (!mAllContactsLoaderStarted) {
-                // Load "all" contacts if not loaded yet.
-                getLoaderManager().initLoader(
-                        LOADER_ID_ALL_CONTACTS, null, mAllContactsLoaderListener);
-            }
-            mAllContactsForceReload = false;
-            mAllContactsLoaderStarted = true;
-
-            // Show the filter header with "loading" state.
-            updateFilterHeaderView();
-            mAccountFilterHeader.setVisibility(View.VISIBLE);
-
-            // invalidate the options menu if needed
-            invalidateOptionsMenuIfNeeded();
-        }
-
-        @Override
-        public void onLoaderReset(Loader<Cursor> loader) {
-            if (DEBUG) Log.d(TAG, "ContactTileLoaderListener#onLoaderReset. ");
-        }
-    }
-
-    private class AllContactsLoaderListener implements LoaderManager.LoaderCallbacks<Cursor> {
-        @Override
-        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
-            if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onCreateLoader");
-            CursorLoader loader = new CursorLoader(getActivity(), null, null, null, null, null);
-            mAllContactsAdapter.configureLoader(loader, Directory.DEFAULT);
-            return loader;
-        }
-
-        @Override
-        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
-            if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onLoadFinished");
-            mAllContactsAdapter.changeCursor(0, data);
-            updateFilterHeaderView();
-            mHandler.removeMessages(MESSAGE_SHOW_LOADING_EFFECT);
-            mLoadingView.setVisibility(View.VISIBLE);
-        }
-
-        @Override
-        public void onLoaderReset(Loader<Cursor> loader) {
-            if (DEBUG) Log.d(TAG, "AllContactsLoaderListener#onLoaderReset. ");
-        }
-    }
-
-    private class ContactTileAdapterListener implements ContactTileView.Listener {
-        @Override
-        public void onContactSelected(Uri contactUri, Rect targetRect) {
-            if (mListener != null) {
-                mListener.onContactSelected(contactUri);
-            }
-        }
-
-        @Override
-        public void onCallNumberDirectly(String phoneNumber) {
-            if (mListener != null) {
-                mListener.onCallNumberDirectly(phoneNumber);
-            }
-        }
-
-        @Override
-        public int getApproximateTileWidth() {
-            return getView().getWidth() / mContactTileAdapter.getColumnCount();
-        }
-    }
-
-    private class FilterHeaderClickListener implements OnClickListener {
-        @Override
-        public void onClick(View view) {
-            AccountFilterUtil.startAccountFilterActivityForResult(
-                    PhoneFavoriteFragment.this,
-                    REQUEST_CODE_ACCOUNT_FILTER,
-                    mFilter);
-        }
-    }
-
-    private class ContactsPreferenceChangeListener
-            implements ContactsPreferences.ChangeListener {
-        @Override
-        public void onChange() {
-            if (loadContactsPreferences()) {
-                requestReloadAllContacts();
-            }
-        }
-    }
-
-    private class ScrollListener implements ListView.OnScrollListener {
-        private boolean mShouldShowFastScroller;
-        @Override
-        public void onScroll(AbsListView view,
-                int firstVisibleItem, int visibleItemCount, int totalItemCount) {
-            // FastScroller should be visible only when the user is seeing "all" contacts section.
-            final boolean shouldShow = mAdapter.shouldShowFirstScroller(firstVisibleItem);
-            if (shouldShow != mShouldShowFastScroller) {
-                mListView.setVerticalScrollBarEnabled(shouldShow);
-                mListView.setFastScrollEnabled(shouldShow);
-                mListView.setFastScrollAlwaysVisible(shouldShow);
-                mShouldShowFastScroller = shouldShow;
-            }
-        }
-
-        @Override
-        public void onScrollStateChanged(AbsListView view, int scrollState) {
-        }
-    }
-
-    private static final int MESSAGE_SHOW_LOADING_EFFECT = 1;
-    private static final int LOADING_EFFECT_DELAY = 500;  // ms
-    private final Handler mHandler = new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MESSAGE_SHOW_LOADING_EFFECT:
-                    mLoadingView.setVisibility(View.VISIBLE);
-                    break;
-            }
-        }
-    };
-
-    private Listener mListener;
-    private PhoneFavoriteMergedAdapter mAdapter;
-    private ContactTileAdapter mContactTileAdapter;
-    private PhoneNumberListAdapter mAllContactsAdapter;
-
-    /**
-     * true when the loader for {@link PhoneNumberListAdapter} has started already.
-     */
-    private boolean mAllContactsLoaderStarted;
-    /**
-     * true when the loader for {@link PhoneNumberListAdapter} must reload "all" contacts again.
-     * It typically happens when {@link ContactsPreferences} has changed its settings
-     * (display order and sort order)
-     */
-    private boolean mAllContactsForceReload;
-
-    private ContactsPreferences mContactsPrefs;
-    private ContactListFilter mFilter;
-
-    private TextView mEmptyView;
-    private ListView mListView;
-    /**
-     * Layout containing {@link #mAccountFilterHeader}. Used to limit area being "pressed".
-     */
-    private FrameLayout mAccountFilterHeaderContainer;
-    private View mAccountFilterHeader;
-
-    /**
-     * Layout used when contacts load is slower than expected and thus "loading" view should be
-     * shown.
-     */
-    private View mLoadingView;
-
-    private final ContactTileView.Listener mContactTileAdapterListener =
-            new ContactTileAdapterListener();
-    private final LoaderManager.LoaderCallbacks<Cursor> mContactTileLoaderListener =
-            new ContactTileLoaderListener();
-    private final LoaderManager.LoaderCallbacks<Cursor> mAllContactsLoaderListener =
-            new AllContactsLoaderListener();
-    private final OnClickListener mFilterHeaderClickListener = new FilterHeaderClickListener();
-    private final ContactsPreferenceChangeListener mContactsPreferenceChangeListener =
-            new ContactsPreferenceChangeListener();
-    private final ScrollListener mScrollListener = new ScrollListener();
-
-    private boolean mOptionsMenuHasFrequents;
-
-    @Override
-    public void onAttach(Activity activity) {
-        if (DEBUG) Log.d(TAG, "onAttach()");
-        super.onAttach(activity);
-
-        mContactsPrefs = new ContactsPreferences(activity);
-
-        // Construct two base adapters which will become part of PhoneFavoriteMergedAdapter.
-        // We don't construct the resultant adapter at this moment since it requires LayoutInflater
-        // that will be available on onCreateView().
-
-        mContactTileAdapter = new ContactTileAdapter(activity, mContactTileAdapterListener,
-                getResources().getInteger(R.integer.contact_tile_column_count_in_favorites),
-                ContactTileAdapter.DisplayType.STREQUENT_PHONE_ONLY);
-        mContactTileAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
-
-        // Setup the "all" adapter manually. See also the setup logic in ContactEntryListFragment.
-        mAllContactsAdapter = new PhoneNumberListAdapter(activity);
-        mAllContactsAdapter.setDisplayPhotos(true);
-        mAllContactsAdapter.setQuickContactEnabled(true);
-        mAllContactsAdapter.setSearchMode(false);
-        mAllContactsAdapter.setIncludeProfile(false);
-        mAllContactsAdapter.setSelectionVisible(false);
-        mAllContactsAdapter.setDarkTheme(true);
-        mAllContactsAdapter.setPhotoLoader(ContactPhotoManager.getInstance(activity));
-        // Disable directory header.
-        mAllContactsAdapter.setHasHeader(0, false);
-        // Show A-Z section index.
-        mAllContactsAdapter.setSectionHeaderDisplayEnabled(true);
-        // Disable pinned header. It doesn't work with this fragment.
-        mAllContactsAdapter.setPinnedPartitionHeadersEnabled(false);
-        // Put photos on START (LEFT in LTR layout direction and RIGHT in RTL layout direction)
-        // for consistency with "frequent" contacts section.
-        mAllContactsAdapter.setPhotoPosition(ContactListItemView.getDefaultPhotoPosition(
-                true /* opposite */ ));
-
-        // Use Callable.CONTENT_URI which will include not only phone numbers but also SIP
-        // addresses.
-        mAllContactsAdapter.setUseCallableUri(true);
-
-        mAllContactsAdapter.setContactNameDisplayOrder(mContactsPrefs.getDisplayOrder());
-        mAllContactsAdapter.setSortOrder(mContactsPrefs.getSortOrder());
-    }
-
-    @Override
-    public void onCreate(Bundle savedState) {
-        if (DEBUG) Log.d(TAG, "onCreate()");
-        super.onCreate(savedState);
-        if (savedState != null) {
-            mFilter = savedState.getParcelable(KEY_FILTER);
-
-            if (mFilter != null) {
-                mAllContactsAdapter.setFilter(mFilter);
-            }
-        }
-        setHasOptionsMenu(true);
-    }
-
-    @Override
-    public void onSaveInstanceState(Bundle outState) {
-        super.onSaveInstanceState(outState);
-        outState.putParcelable(KEY_FILTER, mFilter);
-    }
-
-    @Override
-    public View onCreateView(LayoutInflater inflater, ViewGroup container,
-            Bundle savedInstanceState) {
-        final View listLayout = inflater.inflate(
-                R.layout.phone_contact_tile_list, container, false);
-
-        mListView = (ListView) listLayout.findViewById(R.id.contact_tile_list);
-        mListView.setItemsCanFocus(true);
-        mListView.setOnItemClickListener(this);
-        mListView.setVerticalScrollBarEnabled(false);
-        mListView.setVerticalScrollbarPosition(View.SCROLLBAR_POSITION_RIGHT);
-        mListView.setScrollBarStyle(ListView.SCROLLBARS_OUTSIDE_OVERLAY);
-
-        // Create the account filter header but keep it hidden until "all" contacts are loaded.
-        mAccountFilterHeaderContainer = new FrameLayout(getActivity(), null);
-        mAccountFilterHeader = inflater.inflate(R.layout.account_filter_header_for_phone_favorite,
-                mListView, false);
-        mAccountFilterHeader.setOnClickListener(mFilterHeaderClickListener);
-        mAccountFilterHeaderContainer.addView(mAccountFilterHeader);
-
-        mLoadingView = inflater.inflate(R.layout.phone_loading_contacts, mListView, false);
-
-        mAdapter = new PhoneFavoriteMergedAdapter(getActivity(),
-                mContactTileAdapter, mAccountFilterHeaderContainer, mAllContactsAdapter,
-                mLoadingView);
-
-        mListView.setAdapter(mAdapter);
-
-        mListView.setOnScrollListener(mScrollListener);
-        mListView.setFastScrollEnabled(false);
-        mListView.setFastScrollAlwaysVisible(false);
-
-        mEmptyView = (TextView) listLayout.findViewById(R.id.contact_tile_list_empty);
-        mEmptyView.setText(getString(R.string.listTotalAllContactsZero));
-        mListView.setEmptyView(mEmptyView);
-
-        updateFilterHeaderView();
-
-        return listLayout;
-    }
-
-    private boolean isOptionsMenuChanged() {
-        return mOptionsMenuHasFrequents != hasFrequents();
-    }
-
-    private void invalidateOptionsMenuIfNeeded() {
-        if (isOptionsMenuChanged()) {
-            getActivity().invalidateOptionsMenu();
-        }
-    }
-
-    @Override
-    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
-        super.onCreateOptionsMenu(menu, inflater);
-        inflater.inflate(R.menu.phone_favorite_options, menu);
-    }
-
-    @Override
-    public void onPrepareOptionsMenu(Menu menu) {
-        final MenuItem clearFrequents = menu.findItem(R.id.menu_clear_frequents);
-        mOptionsMenuHasFrequents = hasFrequents();
-        clearFrequents.setVisible(mOptionsMenuHasFrequents);
-    }
-
-    private boolean hasFrequents() {
-        return mContactTileAdapter.getNumFrequents() > 0;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.menu_import_export:
-                // We hard-code the "contactsAreAvailable" argument because doing it properly would
-                // involve querying a {@link ProviderStatusLoader}, which we don't want to do right
-                // now in Dialtacts for (potential) performance reasons.  Compare with how it is
-                // done in {@link PeopleActivity}.
-                ImportExportDialogFragment.show(getFragmentManager(), true,
-                        OldDialtactsActivity.class);
-                return true;
-            case R.id.menu_accounts:
-                final Intent intent = new Intent(Settings.ACTION_SYNC_SETTINGS);
-                intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[] {
-                    ContactsContract.AUTHORITY
-                });
-                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
-                startActivity(intent);
-                return true;
-            case R.id.menu_clear_frequents:
-                ClearFrequentsDialog.show(getFragmentManager());
-                return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void onStart() {
-        super.onStart();
-
-        mContactsPrefs.registerChangeListener(mContactsPreferenceChangeListener);
-
-        // If ContactsPreferences has changed, we need to reload "all" contacts with the new
-        // settings. If mAllContactsFoarceReload is already true, it should be kept.
-        if (loadContactsPreferences()) {
-            mAllContactsForceReload = true;
-        }
-
-        // Use initLoader() instead of restartLoader() to refraining unnecessary reload.
-        // This method call implicitly assures ContactTileLoaderListener's onLoadFinished() will
-        // be called, on which we'll check if "all" contacts should be reloaded again or not.
-        getLoaderManager().initLoader(LOADER_ID_CONTACT_TILE, null, mContactTileLoaderListener);
-
-        // Delay showing "loading" view until certain amount of time so that users won't see
-        // instant flash of the view when the contacts load is fast enough.
-        // This will be kept shown until both tile and all sections are loaded.
-        mLoadingView.setVisibility(View.INVISIBLE);
-        mHandler.sendEmptyMessageDelayed(MESSAGE_SHOW_LOADING_EFFECT, LOADING_EFFECT_DELAY);
-    }
-
-    @Override
-    public void onStop() {
-        super.onStop();
-        mContactsPrefs.unregisterChangeListener();
-    }
-
-    /**
-     * {@inheritDoc}
-     *
-     * This is only effective for elements provided by {@link #mContactTileAdapter}.
-     * {@link #mContactTileAdapter} has its own logic for click events.
-     */
-    @Override
-    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-        final int contactTileAdapterCount = mContactTileAdapter.getCount();
-        if (position <= contactTileAdapterCount) {
-            Log.e(TAG, "onItemClick() event for unexpected position. "
-                    + "The position " + position + " is before \"all\" section. Ignored.");
-        } else {
-            final int localPosition = position - mContactTileAdapter.getCount() - 1;
-            if (mListener != null) {
-                mListener.onContactSelected(mAllContactsAdapter.getDataUri(localPosition));
-            }
-        }
-    }
-
-    @Override
-    public void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (requestCode == REQUEST_CODE_ACCOUNT_FILTER) {
-            if (getActivity() != null) {
-                AccountFilterUtil.handleAccountFilterResult(
-                        ContactListFilterController.getInstance(getActivity()), resultCode, data);
-            } else {
-                Log.e(TAG, "getActivity() returns null during Fragment#onActivityResult()");
-            }
-        }
-    }
-
-    private boolean loadContactsPreferences() {
-        if (mContactsPrefs == null || mAllContactsAdapter == null) {
-            return false;
-        }
-
-        boolean changed = false;
-        final int currentDisplayOrder = mContactsPrefs.getDisplayOrder();
-        if (mAllContactsAdapter.getContactNameDisplayOrder() != currentDisplayOrder) {
-            mAllContactsAdapter.setContactNameDisplayOrder(currentDisplayOrder);
-            changed = true;
-        }
-
-        final int currentSortOrder = mContactsPrefs.getSortOrder();
-        if (mAllContactsAdapter.getSortOrder() != currentSortOrder) {
-            mAllContactsAdapter.setSortOrder(currentSortOrder);
-            changed = true;
-        }
-
-        return changed;
-    }
-
-    /**
-     * Requests to reload "all" contacts. If the section is already loaded, this method will
-     * force reloading it now. If the section isn't loaded yet, the actual load may be done later
-     * (on {@link #onStart()}.
-     */
-    private void requestReloadAllContacts() {
-        if (DEBUG) {
-            Log.d(TAG, "requestReloadAllContacts()"
-                    + " mAllContactsAdapter: " + mAllContactsAdapter
-                    + ", mAllContactsLoaderStarted: " + mAllContactsLoaderStarted);
-        }
-
-        if (mAllContactsAdapter == null || !mAllContactsLoaderStarted) {
-            // Remember this request until next load on onStart().
-            mAllContactsForceReload = true;
-            return;
-        }
-
-        if (DEBUG) Log.d(TAG, "Reload \"all\" contacts now.");
-
-        mAllContactsAdapter.onDataReload();
-        // Use restartLoader() to make LoaderManager to load the section again.
-        getLoaderManager().restartLoader(LOADER_ID_ALL_CONTACTS, null, mAllContactsLoaderListener);
-    }
-
-    private void updateFilterHeaderView() {
-        final ContactListFilter filter = getFilter();
-        if (mAccountFilterHeader == null || mAllContactsAdapter == null || filter == null) {
-            return;
-        }
-        AccountFilterUtil.updateAccountFilterTitleForPhone(mAccountFilterHeader, filter, true);
-    }
-
-    public ContactListFilter getFilter() {
-        return mFilter;
-    }
-
-    public void setFilter(ContactListFilter filter) {
-        if ((mFilter == null && filter == null) || (mFilter != null && mFilter.equals(filter))) {
-            return;
-        }
-
-        if (DEBUG) {
-            Log.d(TAG, "setFilter(). old filter (" + mFilter
-                    + ") will be replaced with new filter (" + filter + ")");
-        }
-
-        mFilter = filter;
-
-        if (mAllContactsAdapter != null) {
-            mAllContactsAdapter.setFilter(mFilter);
-            requestReloadAllContacts();
-            updateFilterHeaderView();
-        }
-    }
-
-    public void setListener(Listener listener) {
-        mListener = listener;
-    }
-}
