Dialpad redesign.

TESTED:
- Launch Phone UI (previous tab: dialer)
-- Fake menu items should be available
-- Bottom half of the dial button should be clickable
- Launch Phone UI (previous tab: calllog, phone favorite)
-- Real ActionBar should be visible
- Swipe around three tabs.
-- ActionBar (and real menu buttons at the bottom) should be
   visible except when dialer screen is settled down in the
   screen. During horizontal swipes, ActionBar should look
   persistent.
- Click three tabs at the top of screen
-- exactly same as "swipe around three tabs" case above.
- Go to search, and go back from the search (from three tabs)
-- ActionBar should appear/disappear appropriately.

AND, try the sequence above during a phone call, which will
expose DialpadChooser.

- With DialpadChooser, fake buttons should not appear; they should
  appear when the user explicitly choose "add call" item.

KNOWN ISSUE:
- Do horizontal swipe from CallLog to Dialpad. Before the screen
  settling down itself, start swipe from Dialpad to CallLog again.
-- Bottom ActionBar disappears during the migration (which is
   unexpected), because there's no way for the app to determine
   if the user is dragging the screen. The app wrongly detects
   the case as ViewPager.SCROLL_STATE_IDLE. We won't get the second
   ViewPager.SCROLL_STATE_DRAGGING event during the second swipe.

Bug: 6021918
Change-Id: Iaca971a195144a16f7853e3555375922ad54b81b
diff --git a/res/layout/call_log_fragment.xml b/res/layout/call_log_fragment.xml
index f87e981..d652ad7 100644
--- a/res/layout/call_log_fragment.xml
+++ b/res/layout/call_log_fragment.xml
@@ -19,7 +19,9 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
-    android:paddingBottom="?android:attr/actionBarSize">
+    android:paddingBottom="?android:attr/actionBarSize"
+    android:divider="?android:attr/dividerHorizontal"
+    android:showDividers="end">
 
     <FrameLayout
         android:id="@+id/voicemail_status"
diff --git a/res/layout/dialpad_fragment.xml b/res/layout/dialpad_fragment.xml
index 2785af0..df13372 100644
--- a/res/layout/dialpad_fragment.xml
+++ b/res/layout/dialpad_fragment.xml
@@ -38,7 +38,6 @@
             android:layout_width="0dip"
             android:layout_weight="1"
             android:layout_height="match_parent"
-            android:layout_alignParentLeft="true"
             android:gravity="center"
             android:textAppearance="@style/DialtactsDigitsTextAppearance"
             android:textColor="?android:attr/textColorPrimary"
@@ -46,15 +45,15 @@
             android:background="@android:color/transparent" />
 
         <ImageButton
-            android:id="@+id/overflow_menu"
-            android:layout_width="48dip"
+            android:id="@+id/deleteButton"
+            android:layout_width="56dip"
             android:layout_height="match_parent"
-            android:layout_alignParentRight="true"
-            android:src="@drawable/ic_menu_overflow"
-            android:contentDescription="@*android:string/action_menu_overflow_description"
-            android:nextFocusLeft="@id/digits"
-            android:background="?android:attr/selectableItemBackground"/>
-
+            android:layout_gravity="center_vertical"
+            android:gravity="center"
+            android:state_enabled="false"
+            android:background="?android:attr/selectableItemBackground"
+            android:contentDescription="@string/description_delete_button"
+            android:src="@drawable/ic_dial_action_delete" />
     </LinearLayout>
 
     <!-- Keypad section -->
@@ -65,8 +64,44 @@
        android:layout_height="@dimen/dialpad_vertical_margin"
        android:background="#66000000"/>
 
-    <!-- Horizontal row of buttons (Search + DialButton + Delete.) -->
-    <include layout="@layout/dialpad_additional_buttons" />
+    <LinearLayout
+        android:id="@+id/dialButtonContainer"
+        android:layout_width="match_parent"
+        android:layout_height="0px"
+        android:layout_weight="@integer/dialpad_layout_weight_additional_buttons"
+        android:layout_gravity="center_horizontal"
+        android:background="@drawable/dialpad_background">
+        <ImageButton
+            android:id="@+id/searchButton"
+            android:layout_width="wrap_content"
+            android:layout_height="?android:attr/actionBarSize"
+            android:layout_gravity="bottom|center_horizontal"
+            android:state_enabled="false"
+            android:background="?android:attr/selectableItemBackground"
+            android:contentDescription="@string/description_search_button"
+            android:src="@drawable/ic_dial_action_search"/>
+
+        <ImageButton
+            android:id="@+id/dialButton"
+            android:layout_width="0px"
+            android:layout_weight="1"
+            android:layout_height="match_parent"
+            android:layout_gravity="center"
+            android:state_enabled="false"
+            android:background="@drawable/btn_call"
+            android:contentDescription="@string/description_dial_button"
+            android:src="@drawable/ic_dial_action_call" />
+
+        <ImageButton
+            android:id="@+id/overflow_menu"
+            android:layout_width="wrap_content"
+            android:layout_height="?android:attr/actionBarSize"
+            android:layout_gravity="bottom|center_horizontal"
+            android:src="@drawable/ic_menu_overflow"
+            android:contentDescription="@*android:string/action_menu_overflow_description"
+            android:nextFocusLeft="@id/digits"
+            android:background="?android:attr/selectableItemBackground"/>
+    </LinearLayout>
 
     <!-- "Dialpad chooser" UI, shown only when the user brings up the
          Dialer while a call is already in progress.
diff --git a/res/layout/empty2.xml b/res/layout/empty2.xml
new file mode 100644
index 0000000..349dcfa
--- /dev/null
+++ b/res/layout/empty2.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Hack for show empty hidden menu item without using android:icon.
+     See dialtact_options.xml for more detail.
+
+     TODO: figure out better way -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:src="@drawable/ic_dial_action_search"
+        android:visibility="invisible"/>
+</FrameLayout>
diff --git a/res/layout/phone_contact_tile_list.xml b/res/layout/phone_contact_tile_list.xml
new file mode 100644
index 0000000..29ceb19
--- /dev/null
+++ b/res/layout/phone_contact_tile_list.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Use LinearLayout + FrameLayout, just to rely on android:divider and android:showDividers -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical"
+    android:paddingBottom="?android:attr/actionBarSize"
+    android:divider="?android:attr/dividerHorizontal"
+    android:showDividers="end">
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <ListView
+            android:id="@+id/contact_tile_list"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:paddingTop="@dimen/contact_tile_list_padding_top"
+            android:clipToPadding="false"
+            android:fadingEdge="none"
+            android:divider="@null" />
+
+        <TextView
+            android:id="@+id/contact_tile_list_empty"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:gravity="center_horizontal"
+            android:layout_marginTop="@dimen/empty_message_top_margin"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textAppearance="?android:attr/textAppearanceLarge"/>
+    </FrameLayout>
+</LinearLayout>
diff --git a/res/menu/dialtacts_options.xml b/res/menu/dialtacts_options.xml
index 54ca086..d8c79e4 100644
--- a/res/menu/dialtacts_options.xml
+++ b/res/menu/dialtacts_options.xml
@@ -37,4 +37,16 @@
         android:id="@+id/add_contact"
         android:title="@string/menu_newContact"
         android:showAsAction="withText" />
+
+    <!-- Ugly hack: empty item never clickable.
+         This is for forcing search icon on left even when there's a single item
+         in the bottom ActionBar.
+         We intentionally don't use android:icon to avoid other issues around item with
+         a null icon.
+
+         TODO: look for better idea. -->
+    <item
+        android:id="@+id/fake_menu_item"
+        android:actionLayout="@layout/empty2"
+        android:showAsAction="ifRoom" />
 </menu>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index ece881e..f22ff1d 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -284,7 +284,7 @@
     </style>
 
     <style name="DialtactsActionBarStyle" parent="android:Widget.Holo.ActionBar">
-        <item name="android:backgroundSplit">@drawable/ab_bottom_opaque_dark_holo</item>
+        <item name="android:backgroundSplit">@null</item>
         <item name="android:backgroundStacked">@drawable/ab_stacked_opaque_dark_holo</item>
         <item name="android:displayOptions"></item>
     </style>
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index 7e95fed..9abcdf4 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -78,6 +78,8 @@
 public class DialtactsActivity extends TransactionSafeActivity {
     private static final String TAG = "DialtactsActivity";
 
+    private 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 =
@@ -143,6 +145,23 @@
         }
     }
 
+    /**
+     * 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;
         /**
@@ -158,7 +177,17 @@
 
         @Override
         public void onPageSelected(int position) {
+            if (DEBUG) Log.d(TAG, "onPageSelected: " + position);
             final ActionBar actionBar = getActionBar();
+            if (mDialpadFragment != null && !mDuringSwipe) {
+                if (DEBUG) {
+                    Log.d(TAG, "Immediately show/hide fake menu buttons. position: "
+                            + position + ", dragging: " + mDuringSwipe);
+                }
+                mDialpadFragment.updateFakeMenuButtonsVisibility(
+                        position == TAB_INDEX_DIALER && !mDuringSwipe);
+            }
+
             if (mCurrentPosition == position) {
                 Log.w(TAG, "Previous position and next position became same (" + position + ")");
             }
@@ -175,6 +204,11 @@
         public void onPageScrollStateChanged(int state) {
             switch (state) {
                 case ViewPager.SCROLL_STATE_IDLE: {
+                    if (DEBUG) Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_IDLE");
+                    // Interpret IDLE as the end of migration (both swipe and tab click)
+                    mDuringSwipe = false;
+                    mUserTabClick = false;
+
                     if (mCurrentPosition >= 0) {
                         sendFragmentVisibilityChange(mCurrentPosition, false);
                     }
@@ -186,8 +220,24 @@
                     mCurrentPosition = mNextPosition;
                     break;
                 }
-                case ViewPager.SCROLL_STATE_DRAGGING:
-                case ViewPager.SCROLL_STATE_SETTLING:
+                case ViewPager.SCROLL_STATE_DRAGGING: {
+                    if (DEBUG) Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_DRAGGING");
+                    mDuringSwipe = true;
+                    mUserTabClick = false;
+
+                    if (mCurrentPosition == TAB_INDEX_DIALER) {
+                        sendFragmentVisibilityChange(TAB_INDEX_DIALER, false);
+                        sendFragmentVisibilityChange(TAB_INDEX_CALL_LOG, true);
+                        invalidateOptionsMenu();
+                    }
+                    break;
+                }
+                case ViewPager.SCROLL_STATE_SETTLING: {
+                    if (DEBUG) Log.d(TAG, "onPageScrollStateChanged() with SCROLL_STATE_SETTLING");
+                    mDuringSwipe = true;
+                    mUserTabClick = false;
+                    break;
+                }
                 default:
                     break;
             }
@@ -230,10 +280,26 @@
     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 (mDialpadFragment != null) {
+                    if (DEBUG) Log.d(TAG, "Immediately hide fake buttons for tab selection case");
+                    mDialpadFragment.updateFakeMenuButtonsVisibility(false);
+                }
+                mUserTabClick = true;
+            }
+
             if (mViewPager.getCurrentItem() != tab.getPosition()) {
                 mViewPager.setCurrentItem(tab.getPosition(), true);
             }
@@ -249,6 +315,7 @@
 
         @Override
         public void onTabReselected(Tab tab, FragmentTransaction ft) {
+            if (DEBUG) Log.d(TAG, "onTabReselected");
         }
     };
 
@@ -436,6 +503,12 @@
         if (mSearchFragment != null) {
             mSearchFragment.setFilter(mContactListFilterController.getFilter());
         }
+
+        if (mDuringSwipe || mUserTabClick) {
+            if (DEBUG) Log.d(TAG, "reset buggy flag state..");
+            mDuringSwipe = false;
+            mUserTabClick = false;
+        }
     }
 
     @Override
@@ -659,6 +732,8 @@
 
         // Restore to the previous manual selection
         mLastManuallySelectedFragment = savedTabIndex;
+        mDuringSwipe = false;
+        mUserTabClick = false;
     }
 
     @Override
@@ -776,6 +851,7 @@
         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 fakeMenuItem = menu.findItem(R.id.fake_menu_item);
         Tab tab = getActionBar().getSelectedTab();
         if (mInSearchUi) {
             searchMenuItem.setVisible(false);
@@ -792,17 +868,33 @@
                 addContactOptionMenuItem.setVisible(false);
             }
             callSettingsMenuItem.setVisible(false);
+            fakeMenuItem.setVisible(false);
         } else {
             final boolean showCallSettingsMenu;
             if (tab != null && tab.getPosition() == TAB_INDEX_DIALER) {
-                searchMenuItem.setVisible(false);
-                // When permanent menu key is _not_ available, the call settings menu should be
-                // available via DialpadFragment.
-                showCallSettingsMenu = ViewConfiguration.get(this).hasPermanentMenuKey();
+                if (DEBUG) {
+                    Log.d(TAG, "onPrepareOptionsMenu(dialer). swipe: " + mDuringSwipe
+                            + ", user tab click: " + mUserTabClick);
+                }
+                if (mDuringSwipe || mUserTabClick) {
+                    // During horizontal movement, we just show real ActionBar menu items.
+                    searchMenuItem.setVisible(true);
+                    searchMenuItem.setOnMenuItemClickListener(mSearchMenuItemClickListener);
+                    showCallSettingsMenu = true;
+
+                    fakeMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
+                } else {
+                    searchMenuItem.setVisible(false);
+                    // When permanent menu key is _not_ available, the call settings menu should be
+                    // available via DialpadFragment.
+                    showCallSettingsMenu = ViewConfiguration.get(this).hasPermanentMenuKey();
+                    fakeMenuItem.setVisible(false);
+                }
             } else {
                 searchMenuItem.setVisible(true);
                 searchMenuItem.setOnMenuItemClickListener(mSearchMenuItemClickListener);
                 showCallSettingsMenu = true;
+                fakeMenuItem.setVisible(ViewConfiguration.get(this).hasPermanentMenuKey());
             }
             if (tab != null && tab.getPosition() == TAB_INDEX_FAVORITES) {
                 filterOptionMenuItem.setVisible(true);
@@ -932,6 +1024,10 @@
 
         sendFragmentVisibilityChange(mViewPager.getCurrentItem(), true);
 
+        // Before exiting the search screen, reset swipe state.
+        mDuringSwipe = false;
+        mUserTabClick = false;
+
         mViewPager.setVisibility(View.VISIBLE);
 
         hideInputMethod(getCurrentFocus());
diff --git a/src/com/android/contacts/dialpad/DialpadFragment.java b/src/com/android/contacts/dialpad/DialpadFragment.java
index 793717d..cdba30b 100644
--- a/src/com/android/contacts/dialpad/DialpadFragment.java
+++ b/src/com/android/contacts/dialpad/DialpadFragment.java
@@ -16,16 +16,6 @@
 
 package com.android.contacts.dialpad;
 
-import com.android.contacts.ContactsUtils;
-import com.android.contacts.R;
-import com.android.contacts.SpecialCharSequenceMgr;
-import com.android.contacts.activities.DialtactsActivity;
-import com.android.contacts.activities.DialtactsActivity.ViewPagerVisibilityListener;
-import com.android.contacts.util.PhoneNumberFormatter;
-import com.android.internal.telephony.ITelephony;
-import com.android.phone.CallLogAsync;
-import com.android.phone.HapticFeedback;
-
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
@@ -57,6 +47,7 @@
 import android.text.TextUtils;
 import android.text.TextWatcher;
 import android.text.method.DialerKeyListener;
+import android.util.DisplayMetrics;
 import android.util.Log;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -64,20 +55,25 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
-import android.view.View.OnClickListener;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
-import android.widget.Button;
 import android.widget.EditText;
 import android.widget.ImageView;
 import android.widget.ListView;
 import android.widget.PopupMenu;
 import android.widget.TextView;
 
-import java.util.HashSet;
-import java.util.Set;
+import com.android.contacts.ContactsUtils;
+import com.android.contacts.R;
+import com.android.contacts.SpecialCharSequenceMgr;
+import com.android.contacts.activities.DialtactsActivity;
+import com.android.contacts.activities.DialtactsActivity.ViewPagerVisibilityListener;
+import com.android.contacts.util.PhoneNumberFormatter;
+import com.android.internal.telephony.ITelephony;
+import com.android.phone.CallLogAsync;
+import com.android.phone.HapticFeedback;
 
 /**
  * Fragment that displays a twelve-key phone dialpad.
@@ -90,6 +86,8 @@
         ViewPagerVisibilityListener {
     private static final String TAG = DialpadFragment.class.getSimpleName();
 
+    private static final boolean DEBUG = false;
+
     private static final String EMPTY_NUMBER = "";
 
     /** The length of DTMF tones in milliseconds */
@@ -116,11 +114,12 @@
     private ToneGenerator mToneGenerator;
     private Object mToneGeneratorLock = new Object();
     private View mDialpad;
-    private View mAdditionalButtonsRow;
 
     private View mSearchButton;
+    private View mMenuButton;
     private Listener mListener;
 
+    private View mDialButtonContainer;
     private View mDialButton;
     private ListView mDialpadChooser;
     private DialpadChooserAdapter mDialpadChooserAdapter;
@@ -253,15 +252,28 @@
 
         PhoneNumberFormatter.setPhoneNumberFormattingTextWatcher(getActivity(), mDigits);
 
+        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;
+        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.
-        final View overflowMenuButton = fragmentView.findViewById(R.id.overflow_menu);
-        if (overflowMenuButton != null) {
+        mMenuButton = fragmentView.findViewById(R.id.overflow_menu);
+        if (mMenuButton != null) {
+            mMenuButton.setMinimumWidth(fakeMenuItemWidth);
             if (ViewConfiguration.get(getActivity()).hasPermanentMenuKey()) {
-                overflowMenuButton.setVisibility(View.GONE);
+                // This is required for dialpad button's layout, so must not use GONE here.
+                mMenuButton.setVisibility(View.INVISIBLE);
             } else {
-                overflowMenuButton.setOnClickListener(this);
+                mMenuButton.setOnClickListener(this);
             }
         }
+        mSearchButton = fragmentView.findViewById(R.id.searchButton);
+        if (mSearchButton != null) {
+            mSearchButton.setMinimumWidth(fakeMenuItemWidth);
+            mSearchButton.setOnClickListener(this);
+        }
 
         // Check for the presence of the keypad
         View oneButton = fragmentView.findViewById(R.id.one);
@@ -269,16 +281,8 @@
             setupKeypad(fragmentView);
         }
 
-        mAdditionalButtonsRow = fragmentView.findViewById(R.id.dialpadAdditionalButtons);
-
-        mSearchButton = mAdditionalButtonsRow.findViewById(R.id.searchButton);
-        if (mSearchButton != null) {
-            mSearchButton.setOnClickListener(this);
-        }
-
-        // Check whether we should show the onscreen "Dial" button.
-        mDialButton = mAdditionalButtonsRow.findViewById(R.id.dialButton);
-
+        mDialButtonContainer = fragmentView.findViewById(R.id.dialButtonContainer);
+        mDialButton = fragmentView.findViewById(R.id.dialButton);
         if (r.getBoolean(R.bool.config_show_onscreen_dial_button)) {
             mDialButton.setOnClickListener(this);
         } else {
@@ -286,9 +290,11 @@
             mDialButton = null;
         }
 
-        mDelete = mAdditionalButtonsRow.findViewById(R.id.deleteButton);
-        mDelete.setOnClickListener(this);
-        mDelete.setOnLongClickListener(this);
+        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.
 
@@ -305,6 +311,8 @@
 
         configureScreenFromIntent(getActivity().getIntent());
 
+        updateFakeMenuButtonsVisibility(mShowOptionsMenu);
+
         return fragmentView;
     }
 
@@ -1040,7 +1048,8 @@
                 mDigits.setVisibility(View.GONE);
             }
             if (mDialpad != null) mDialpad.setVisibility(View.GONE);
-            mAdditionalButtonsRow.setVisibility(View.GONE);
+            if (mDialButtonContainer != null) mDialButtonContainer.setVisibility(View.GONE);
+
             mDialpadChooser.setVisibility(View.VISIBLE);
 
             // Instantiate the DialpadChooserAdapter and hook it up to the
@@ -1057,7 +1066,7 @@
                 mDigits.setVisibility(View.VISIBLE);
             }
             if (mDialpad != null) mDialpad.setVisibility(View.VISIBLE);
-            mAdditionalButtonsRow.setVisibility(View.VISIBLE);
+            if (mDialButtonContainer != null) mDialButtonContainer.setVisibility(View.VISIBLE);
             mDialpadChooser.setVisibility(View.GONE);
         }
     }
@@ -1446,7 +1455,34 @@
     }
 
     @Override
-    public void onVisibilityChanged(boolean visible) {
-        mShowOptionsMenu = visible;
+    public void onVisibilityChanged(boolean fragmentVisible) {
+        mShowOptionsMenu = fragmentVisible;
+        updateFakeMenuButtonsVisibility(fragmentVisible);
+    }
+
+    /**
+     * Update visibility of the search button and menu button at the bottom of dialer screen, which
+     * should be invisible when bottom ActionBar's real items are available and be visible
+     * otherwise.
+     *
+     * @param visible True when visible.
+     */
+    public void updateFakeMenuButtonsVisibility(boolean visible) {
+        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(getActivity()).hasPermanentMenuKey()) {
+                mMenuButton.setVisibility(View.VISIBLE);
+            } else {
+                mMenuButton.setVisibility(View.INVISIBLE);
+            }
+        }
     }
 }
diff --git a/src/com/android/contacts/list/PhoneFavoriteFragment.java b/src/com/android/contacts/list/PhoneFavoriteFragment.java
index b6e8dd6..7073a57 100644
--- a/src/com/android/contacts/list/PhoneFavoriteFragment.java
+++ b/src/com/android/contacts/list/PhoneFavoriteFragment.java
@@ -239,7 +239,8 @@
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
             Bundle savedInstanceState) {
-        final View listLayout = inflater.inflate(R.layout.contact_tile_list, container, false);
+        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);