Merge "Set primaryColorDark in Dialer's theme"
diff --git a/res/drawable-hdpi/ic_dial_action_delete.png b/res/drawable-hdpi/ic_dial_action_delete.png
deleted file mode 100644
index ebf692a..0000000
--- a/res/drawable-hdpi/ic_dial_action_delete.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_dial_action_vm.png b/res/drawable-hdpi/ic_dial_action_vm.png
deleted file mode 100644
index f424304..0000000
--- a/res/drawable-hdpi/ic_dial_action_vm.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_dial_action_delete.png b/res/drawable-mdpi/ic_dial_action_delete.png
deleted file mode 100644
index e1394c5..0000000
--- a/res/drawable-mdpi/ic_dial_action_delete.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_dial_action_vm.png b/res/drawable-mdpi/ic_dial_action_vm.png
deleted file mode 100644
index fbcf378..0000000
--- a/res/drawable-mdpi/ic_dial_action_vm.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dial_action_delete.png b/res/drawable-xhdpi/ic_dial_action_delete.png
deleted file mode 100644
index 6788669..0000000
--- a/res/drawable-xhdpi/ic_dial_action_delete.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_dial_action_vm.png b/res/drawable-xhdpi/ic_dial_action_vm.png
deleted file mode 100644
index 2919bbd..0000000
--- a/res/drawable-xhdpi/ic_dial_action_vm.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_dial_action_delete.png b/res/drawable-xxhdpi/ic_dial_action_delete.png
deleted file mode 100644
index ca91a72..0000000
--- a/res/drawable-xxhdpi/ic_dial_action_delete.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_dial_action_vm.png b/res/drawable-xxhdpi/ic_dial_action_vm.png
deleted file mode 100644
index acac8d8..0000000
--- a/res/drawable-xxhdpi/ic_dial_action_vm.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/dialpad_key_colors.xml b/res/drawable/dialpad_key_colors.xml
deleted file mode 100644
index 27b4d4f..0000000
--- a/res/drawable/dialpad_key_colors.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2014 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item
-        android:state_pressed="true"
-        android:drawable="@color/background_dialpad_pressed" />
-    <item android:drawable="@color/background_dialpad" />
-</selector>
diff --git a/res/layout/dialpad.xml b/res/layout/dialpad.xml
deleted file mode 100644
index df6f527..0000000
--- a/res/layout/dialpad.xml
+++ /dev/null
@@ -1,139 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2006 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<!-- Dialpad in the Phone app. -->
-<TableLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/dialpad"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:paddingLeft="5dp"
-    android:paddingRight="5dp"
-    android:stretchColumns="*"
-    android:layoutDirection="ltr" >
-
-    <TableRow>
-        <com.android.dialer.dialpad.DialpadKeyButton
-            android:id="@+id/one"
-            style="@style/DialpadKeyButtonStyle">
-            <LinearLayout
-                style="@style/DialpadKeyInternalLayoutStyle">
-                <TextView
-                    android:id="@+id/dialpad_key_number"
-                    style="@style/DialpadKeyNumberStyle"/>
-                <ImageView
-                    android:id="@+id/dialpad_key_voicemail"
-                    style="@style/DialpadKeyLettersStyle"
-                    android:src="@drawable/ic_dial_action_vm"
-                    android:scaleType="fitStart"
-                    android:baselineAlignBottom="true" />
-            </LinearLayout>
-        </com.android.dialer.dialpad.DialpadKeyButton>
-        <include layout="@layout/dialpad_key"
-            android:id="@+id/two"
-            style="@style/DialpadKeyButtonStyle" />
-        <include layout="@layout/dialpad_key"
-            android:id="@+id/three"
-            style="@style/DialpadKeyButtonStyle" />
-    </TableRow>
-
-    <TableRow>
-        <include layout="@layout/dialpad_key"
-            android:id="@+id/four"
-            style="@style/DialpadKeyButtonStyle" />
-        <include layout="@layout/dialpad_key"
-            android:id="@+id/five"
-            style="@style/DialpadKeyButtonStyle" />
-        <include layout="@layout/dialpad_key"
-            android:id="@+id/six"
-            style="@style/DialpadKeyButtonStyle" />
-    </TableRow>
-
-    <TableRow>
-        <include layout="@layout/dialpad_key"
-            android:id="@+id/seven"
-            style="@style/DialpadKeyButtonStyle" />
-        <include layout="@layout/dialpad_key"
-            android:id="@+id/eight"
-            style="@style/DialpadKeyButtonStyle" />
-        <include layout="@layout/dialpad_key"
-            android:id="@+id/nine"
-            style="@style/DialpadKeyButtonStyle" />
-    </TableRow>
-
-    <TableRow>
-        <com.android.dialer.dialpad.DialpadKeyButton
-            android:id="@+id/star"
-            style="@style/DialpadKeyButtonStyle">
-            <LinearLayout
-                style="@style/DialpadKeyInternalLayoutStyle">
-                <TextView
-                    android:id="@id/dialpad_key_number"
-                    style="@style/DialpadKeyStarPoundStyle" />
-                <View
-                    android:layout_height="match_parent"
-                    android:layout_width="@dimen/dialpad_key_letters_width" />
-            </LinearLayout>
-        </com.android.dialer.dialpad.DialpadKeyButton>
-        <include layout="@layout/dialpad_key"
-            android:id="@+id/zero"
-            style="@style/DialpadKeyButtonStyle" />
-        <com.android.dialer.dialpad.DialpadKeyButton
-            android:id="@+id/pound"
-            style="@style/DialpadKeyButtonStyle">
-            <LinearLayout
-                style="@style/DialpadKeyInternalLayoutStyle">
-                <TextView
-                    android:id="@id/dialpad_key_number"
-                    style="@style/DialpadKeyStarPoundStyle" />
-                <View
-                    android:layout_height="match_parent"
-                    android:layout_width="@dimen/dialpad_key_letters_width" />
-            </LinearLayout>
-        </com.android.dialer.dialpad.DialpadKeyButton>
-    </TableRow>
-
-    <TableRow>
-        <FrameLayout
-            android:id="@+id/dialpad_add_contact"
-            android:contentDescription="@string/description_add_contact"
-            style="@style/DialpadBottomKeyButtonStyle"
-            android:visibility="invisible"
-            >
-            <ImageView
-                android:src="@drawable/ic_add_person_dk"
-                android:importantForAccessibility="no"
-                android:paddingRight="@dimen/dialpad_key_letters_width"
-                style="@style/DialpadKeyInternalLayoutStyle"
-                />
-        </FrameLayout>
-        <Space
-            style="@style/DialpadBottomKeyButtonStyle"
-            />
-        <FrameLayout
-            android:id="@+id/dialpad_overflow"
-            android:contentDescription="@string/description_dialpad_overflow"
-            style="@style/DialpadBottomKeyButtonStyle"
-            >
-            <ImageView
-                android:src="@drawable/ic_overflow_menu"
-                android:importantForAccessibility="no"
-                android:paddingRight="@dimen/dialpad_key_letters_width"
-                style="@style/DialpadKeyInternalLayoutStyle"
-                />
-        </FrameLayout>
-    </TableRow>
-</TableLayout>
diff --git a/res/layout/dialpad_fragment.xml b/res/layout/dialpad_fragment.xml
index 9d3c620..33324d1 100644
--- a/res/layout/dialpad_fragment.xml
+++ b/res/layout/dialpad_fragment.xml
@@ -30,47 +30,14 @@
         android:layout_width="match_parent"
         android:layout_height="3dp"
         android:background="@drawable/shadow_fade_up" />
-    <view class="com.android.dialer.dialpad.DialpadFragment$HoverIgnoringLinearLayout"
-        android:id="@+id/top"
-        android:layout_height="wrap_content"
-        android:layout_width="match_parent"
-        android:layout_gravity="bottom"
-        android:orientation="vertical"
-        android:layoutDirection="ltr"
-        android:background="@color/background_dialpad"
-        android:clickable="true">
-
-        <Space
-            android:layout_width="match_parent"
-            android:layout_height="2dp"
-            android:background="@color/dialpad_separator_line_color" />
-
-        <Space
-            android:layout_width="match_parent"
-            android:layout_height="5dp" />
-
-        <include layout="@layout/dialpad_digits" />
-
-        <Space
-            android:layout_width="match_parent"
-            android:layout_height="4dp" />
-
-        <include layout="@layout/dialpad" />
-
-        <Space
-            android:layout_width="match_parent"
-            android:layout_height="2dp"
-            android:background="@color/dialpad_separator_line_color" />
-
-        <!-- "Dialpad chooser" UI, shown only when the user brings up the
+    <include layout="@layout/dialpad_view" />
+    <!-- "Dialpad chooser" UI, shown only when the user brings up the
              Dialer while a call is already in progress.
              When this UI is visible, the other Dialer elements
              (the textfield/button and the dialpad) are hidden. -->
-        <ListView android:id="@+id/dialpadChooser"
+    <ListView android:id="@+id/dialpadChooser"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_weight="1"
+            android:background="@color/background_dialer_light"
             android:visibility="gone" />
-
-    </view>
 </view>
diff --git a/res/layout/dialpad_key.xml b/res/layout/dialpad_key.xml
deleted file mode 100644
index abbe4f9..0000000
--- a/res/layout/dialpad_key.xml
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 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.
--->
-
-<!-- A layout representing a single key in the dialpad -->
-<com.android.dialer.dialpad.DialpadKeyButton
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/DialpadKeyButtonStyle" >
-
-    <LinearLayout style="@style/DialpadKeyInternalLayoutStyle">
-
-        <!-- Note in the referenced styles that we assign hard widths to these components
-             because we want them to line up vertically when we arrange them in an MxN grid -->
-
-        <TextView
-            android:id="@+id/dialpad_key_number"
-            style="@style/DialpadKeyNumberStyle" />
-
-        <TextView
-            android:id="@+id/dialpad_key_letters"
-            style="@style/DialpadKeyLettersStyle" />
-    </LinearLayout>
-</com.android.dialer.dialpad.DialpadKeyButton>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index b159246..49b122e 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -20,19 +20,6 @@
     <!-- Secondary text color in the Dialer -->
     <color name="dialtacts_secondary_text_color">#888888</color>
 
-    <!-- Background color of dialpad -->
-    <color name="background_dialpad">#ffffff</color>
-    <!-- Pressed color of dialpad buttons -->
-    <color name="background_dialpad_pressed">#ececec</color>
-    <!-- Primary color of dialpad text, including the call button -->
-    <color name="dialpad_primary_text_color">#3B77E7</color>
-    <!-- Secondary color of dialpad text (used for the letters corresponding to each digit -->
-    <color name="dialpad_secondary_text_color">#8b8b8b</color>
-    <!-- Color of dialpad digits -->
-    <color name="dialpad_digits_text_color">#000000</color>
-    <!-- Color for dialpad separator lines -->
-    <color name="dialpad_separator_line_color">#dadada</color>
-
     <!-- Color of the text describing an unconsumed missed call. -->
     <color name="call_log_missed_call_highlight_color">#FF0000</color>
 
@@ -57,10 +44,6 @@
     <!-- Background color of dialer list items (contacts, call log entries) -->
     <color name="background_dialer_list_items">#ffffff</color>
 
-    <!-- Background color of action bars. Ensure this stays in sync with packages/Telephony
-         actionbar_background_color. -->
-    <color name="actionbar_background_color">#00afcc</color>
-
     <!-- Dark variant of the action bar color. -->
     <color name="actionbar_background_color_dark">#008aa1</color>
 
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 5095cdd..76de677 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -44,24 +44,6 @@
          the main area of a call log entry and the secondary action button. -->
     <dimen name="call_log_list_item_vertical_divider_width">1dp</dimen>
 
-    <!-- Text dimensions for dialpad keys -->
-    <dimen name="dialpad_key_numbers_size">40sp</dimen>
-    <dimen name="dialpad_key_letters_size">13sp</dimen>
-    <dimen name="dialpad_key_star_pound_size">26sp</dimen>
-    <dimen name="dialpad_key_numbers_width">30dp</dimen>
-    <dimen name="dialpad_key_letters_width">50dp</dimen>
-    <dimen name="dialpad_key_height">56sp</dimen>
-    <!-- The bottom row of the dialpad is slightly taller to account for the dial button -->
-    <dimen name="dialpad_bottom_key_height">70dp</dimen>
-    <dimen name="dialpad_key_plus_size">18sp</dimen>
-    <dimen name="dialpad_number_to_letters_padding">11dp</dimen>
-    <dimen name="dialpad_horizontal_padding">5dp</dimen>
-    <dimen name="dialpad_digits_text_size">33sp</dimen>
-    <dimen name="dialpad_digits_height">55dp</dimen>
-    <dimen name="dialpad_digits_padding">16dp</dimen>
-    <dimen name="dialpad_digits_margin_bottom">0px</dimen>
-    <dimen name="dialpad_center_margin">3dp</dimen>
-    <dimen name="dialpad_button_margin">2dp</dimen>
     <!-- Match call_button_height to Phone's dimens/in_call_end_button_height -->
     <dimen name="call_button_height">74dp</dimen>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 2575a0b..945f6f9 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -290,12 +290,6 @@
     -->
     <string name="description_dial_button">dial</string>
 
-    <!-- String describing the Delete/Backspace ImageButton
-
-         Used by AccessibilityService to announce the purpose of the button.
-    -->
-    <string name="description_delete_button">backspace</string>
-
     <!-- String describing the digits text box containing the number to dial.
 
          Used by AccessibilityService to announce the purpose of the view.
@@ -420,16 +414,6 @@
     -->
     <string name="description_call_log_voicemail">Voicemail</string>
 
-    <!-- String describing the button to add a contact for the current number.
-
-        Note: AccessibilityServices use this attribute to announce what the view represents.
-              This is especially valuable for views without textual representation like ImageView.
-    -->
-    <string name="description_add_contact">Add contact</string>
-
-    <!-- String describing the overflow menu button in the dialpad -->
-    <string name="description_dialpad_overflow">More options</string>
-
     <!-- String describing the button to view the contact for the current number.
 
         Note: AccessibilityServices use this attribute to announce what the view represents.
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 771cd92..3dbfbe5 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -113,52 +113,6 @@
         <item name="call_log_voicemail_status_action_text_color">#33b5e5</item>
     </style>
 
-    <style name="DialpadKeyNumberStyle">
-        <item name="android:textColor">@color/actionbar_background_color</item>
-        <item name="android:textSize">@dimen/dialpad_key_numbers_size</item>
-        <item name="android:fontFamily">sans-serif-light</item>
-        <item name="android:layout_width">@dimen/dialpad_key_numbers_width</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:gravity">center</item>
-    </style>
-
-    <style name="DialpadKeyStarPoundStyle">
-        <item name="android:textColor">@color/dialpad_secondary_text_color</item>
-        <item name="android:textSize">@dimen/dialpad_key_star_pound_size</item>
-        <item name="android:fontFamily">sans-serif-light</item>
-        <item name="android:layout_width">@dimen/dialpad_key_numbers_width</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:gravity">center</item>
-    </style>
-
-    <style name="DialpadKeyLettersStyle">
-        <item name="android:textColor">@color/dialpad_secondary_text_color</item>
-        <item name="android:textSize">@dimen/dialpad_key_letters_size</item>
-        <item name="android:fontFamily">sans-serif-light</item>
-        <item name="android:layout_width">@dimen/dialpad_key_letters_width</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:paddingLeft">@dimen/dialpad_number_to_letters_padding</item>
-    </style>
-
-    <style name="DialpadKeyButtonStyle">
-        <item name="android:soundEffectsEnabled">false</item>
-        <item name="android:clickable">true</item>
-        <item name="android:layout_width">fill_parent</item>
-        <item name="android:layout_height">@dimen/dialpad_key_height</item>
-        <item name="android:background">@drawable/dialpad_key_colors</item>
-        <item name="android:focusable">true</item>
-    </style>
-
-    <style name="DialpadBottomKeyButtonStyle" parent="DialpadKeyButtonStyle">
-        <item name="android:layout_height">@dimen/dialpad_bottom_key_height</item>
-    </style>
-
-    <style name="DialpadKeyInternalLayoutStyle">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">wrap_content</item>
-        <item name="android:layout_gravity">center</item>
-    </style>
-
     <style name="DialtactsActionBarStyle" parent="android:Widget.Quantum.ActionBar">
         <item name="android:background">@color/actionbar_background_color</item>
         <item name="android:backgroundStacked">#ffffff</item>
diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java
index 0ca26e9..5de9ffd 100644
--- a/src/com/android/dialer/dialpad/DialpadFragment.java
+++ b/src/com/android/dialer/dialpad/DialpadFragment.java
@@ -142,30 +142,6 @@
         }
     }
 
-    /**
-     * LinearLayout that always returns true for onHoverEvent callbacks, to fix
-     * problems with accessibility due to the dialpad overlaying other fragments.
-     */
-    public static class HoverIgnoringLinearLayout extends LinearLayout {
-
-        public HoverIgnoringLinearLayout(Context context) {
-            super(context);
-        }
-
-        public HoverIgnoringLinearLayout(Context context, AttributeSet attrs) {
-            super(context, attrs);
-        }
-
-        public HoverIgnoringLinearLayout(Context context, AttributeSet attrs, int defStyle) {
-            super(context, attrs, defStyle);
-        }
-
-        @Override
-        public boolean onHoverEvent(MotionEvent event) {
-            return true;
-        }
-    }
-
     public interface OnDialpadQueryChangedListener {
         void onDialpadQueryChanged(String query);
     }
@@ -191,11 +167,7 @@
 
     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 DialpadView mDialpadView;
     private EditText mDigits;
 
     /** Remembers if we need to clear digits field when the screen is completely gone. */
@@ -206,7 +178,6 @@
     private View mDelete;
     private ToneGenerator mToneGenerator;
     private final Object mToneGeneratorLock = new Object();
-    private View mDialpad;
     private View mSpacer;
 
     /**
@@ -338,7 +309,7 @@
             mDigitsFilledByIntent = false;
             mDigits.setCursorVisible(false);
             mAddContactButton.setVisibility(View.INVISIBLE);
-        } else {
+        } else if (mDialpadView.canDigitsBeEdited()){
             mAddContactButton.setVisibility(View.VISIBLE);
         }
 
@@ -398,8 +369,10 @@
 
         vto.addOnPreDrawListener(preDrawListener);
 
-        mDigitsContainer = fragmentView.findViewById(R.id.digits_container);
-        mDigits = (EditText) fragmentView.findViewById(R.id.digits);
+        Resources r = getResources();
+
+        mDialpadView = (DialpadView) fragmentView.findViewById(R.id.dialpad_view);
+        mDigits = mDialpadView.getDigits();
         mDigits.setKeyListener(UnicodeDialerKeyListener.INSTANCE);
         mDigits.setOnClickListener(this);
         mDigits.setOnKeyListener(this);
@@ -410,10 +383,11 @@
         // Check for the presence of the keypad
         View oneButton = fragmentView.findViewById(R.id.one);
         if (oneButton != null) {
-            setupKeypad(fragmentView);
+            configureKeypadListeners(fragmentView);
         }
 
-        mDelete = fragmentView.findViewById(R.id.deleteButton);
+        mDelete = mDialpadView.getDeleteButton();
+
         if (mDelete != null) {
             mDelete.setOnClickListener(this);
             mDelete.setOnLongClickListener(this);
@@ -431,14 +405,7 @@
             }
         });
 
-        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);
-        }
+        mDigits.setCursorVisible(false);
 
         // Set up the "dialpad chooser" UI; see showDialpadChooser().
         mDialpadChooser = (ListView) fragmentView.findViewById(R.id.dialpadChooser);
@@ -596,53 +563,23 @@
         }
     }
 
-    private void setupKeypad(View fragmentView) {
+    private void configureKeypadListeners(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};
-
-        final Resources resources = getResources();
-
         DialpadKeyButton dialpadKey;
-        TextView numberView;
-        TextView lettersView;
 
         for (int i = 0; i < buttonIds.length; i++) {
             dialpadKey = (DialpadKeyButton) fragmentView.findViewById(buttonIds[i]);
             dialpadKey.setOnPressedListener(this);
-            numberView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_number);
-            lettersView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_letters);
-            final String numberString = resources.getString(numberIds[i]);
-            numberView.setText(numberString);
-            numberView.setElegantTextHeight(false);
-            dialpadKey.setContentDescription(numberString);
-            if (lettersView != null) {
-                lettersView.setText(resources.getString(letterIds[i]));
-            }
         }
 
         // Long-pressing one button will initiate Voicemail.
         final DialpadKeyButton one = (DialpadKeyButton) fragmentView.findViewById(R.id.one);
         one.setOnLongClickListener(this);
-        one.setLongHoverContentDescription(
-                resources.getText(R.string.description_voicemail_button));
 
         // Long-pressing zero button will enter '+' instead.
         final DialpadKeyButton zero = (DialpadKeyButton) fragmentView.findViewById(R.id.zero);
         zero.setOnLongClickListener(this);
-        zero.setLongHoverContentDescription(
-                resources.getText(R.string.description_image_button_plus));
 
         mAddContactButton = fragmentView.findViewById(R.id.dialpad_add_contact);
         mAddContactButton.setOnClickListener(this);
@@ -984,10 +921,6 @@
         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: {
@@ -1149,7 +1082,7 @@
                 }
 
                 // Clear the digits just in case.
-                mDigits.getText().clear();
+                clearDialpad();
             } else {
                 final Intent intent = CallUtil.getCallIntent(number,
                         (getActivity() instanceof DialtactsActivity ?
@@ -1287,13 +1220,9 @@
 
         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 (mDialpadView != null) {
+                mDialpadView.setVisibility(View.GONE);
             }
-            if (mDialpad != null) mDialpad.setVisibility(View.GONE);
             ((HostInterface) getActivity()).setDialButtonContainerVisible(false);
 
             mDialpadChooser.setVisibility(View.VISIBLE);
@@ -1306,12 +1235,11 @@
             mDialpadChooser.setAdapter(mDialpadChooserAdapter);
         } else {
             // Log.i(TAG, "Displaying normal Dialer UI.");
-            if (mDigitsContainer != null) {
-                mDigitsContainer.setVisibility(View.VISIBLE);
+            if (mDialpadView != null) {
+                mDialpadView.setVisibility(View.VISIBLE);
             } else {
                 mDigits.setVisibility(View.VISIBLE);
             }
-            if (mDialpad != null) mDialpad.setVisibility(View.VISIBLE);
             ((HostInterface) getActivity()).setDialButtonContainerVisible(true);
             mDialpadChooser.setVisibility(View.GONE);
         }
diff --git a/src/com/android/dialer/dialpad/DialpadView.java b/src/com/android/dialer/dialpad/DialpadView.java
new file mode 100644
index 0000000..a8b1e79
--- /dev/null
+++ b/src/com/android/dialer/dialpad/DialpadView.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.dialer.dialpad;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.EditText;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+import android.widget.TableRow;
+import android.widget.TextView;
+
+import com.android.dialer.R;
+
+/**
+ * View that displays a twelve-key phone dialpad.
+ */
+public class DialpadView extends LinearLayout {
+    private static final String TAG = DialpadView.class.getSimpleName();
+
+    private EditText mDigits;
+    private ImageButton mDelete;
+
+    private boolean mCanDigitsBeEdited;
+
+    public DialpadView(Context context) {
+        this(context, null);
+    }
+
+    public DialpadView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public DialpadView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        setupKeypad();
+        mDigits = (EditText) findViewById(R.id.digits);
+        mDelete = (ImageButton) findViewById(R.id.deleteButton);
+    }
+
+    private void setupKeypad() {
+        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};
+
+        final Resources resources = getContext().getResources();
+
+        DialpadKeyButton dialpadKey;
+        TextView numberView;
+        TextView lettersView;
+
+        for (int i = 0; i < buttonIds.length; i++) {
+            dialpadKey = (DialpadKeyButton) findViewById(buttonIds[i]);
+            numberView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_number);
+            lettersView = (TextView) dialpadKey.findViewById(R.id.dialpad_key_letters);
+            final String numberString = resources.getString(numberIds[i]);
+            numberView.setText(numberString);
+            numberView.setElegantTextHeight(false);
+            dialpadKey.setContentDescription(numberString);
+            if (lettersView != null) {
+                lettersView.setText(resources.getString(letterIds[i]));
+            }
+        }
+
+        final DialpadKeyButton one = (DialpadKeyButton) findViewById(R.id.one);
+        one.setLongHoverContentDescription(
+                resources.getText(R.string.description_voicemail_button));
+
+        final DialpadKeyButton zero = (DialpadKeyButton) findViewById(R.id.zero);
+        zero.setLongHoverContentDescription(
+                resources.getText(R.string.description_image_button_plus));
+
+    }
+
+    public void setShowVoicemailButton(boolean show) {
+        View view = findViewById(R.id.dialpad_key_voicemail);
+        if (view != null) {
+            view.setVisibility(show ? View.VISIBLE : View.INVISIBLE);
+        }
+    }
+
+    /**
+     * Whether or not the digits above the dialer can be edited.
+     *
+     * @param canBeEdited If true, the backspace button will be shown and the digits EditText
+     *         will be configured to allow text manipulation.
+     */
+    public void setCanDigitsBeEdited(boolean canBeEdited) {
+        View deleteButton = findViewById(R.id.deleteButton);
+        deleteButton.setVisibility(canBeEdited ? View.VISIBLE : View.GONE);
+
+        EditText digits = (EditText) findViewById(R.id.digits);
+        digits.setClickable(canBeEdited);
+        digits.setLongClickable(canBeEdited);
+        digits.setFocusableInTouchMode(canBeEdited);
+        digits.setCursorVisible(false);
+
+        View overflowMenuButton = findViewById(R.id.dialpad_overflow);
+        overflowMenuButton.setVisibility(canBeEdited ? View.VISIBLE : View.GONE);
+
+        View addContactButton = findViewById(R.id.dialpad_add_contact);
+        addContactButton.setVisibility(canBeEdited ? View.VISIBLE : View.GONE);
+        mCanDigitsBeEdited = canBeEdited;
+    }
+
+    public boolean canDigitsBeEdited() {
+        return mCanDigitsBeEdited;
+    }
+
+    /**
+     * Always returns true for onHoverEvent callbacks, to fix problems with accessibility due to
+     * the dialpad overlaying other fragments.
+     */
+    @Override
+    public boolean onHoverEvent(MotionEvent event) {
+        return true;
+    }
+
+    public EditText getDigits() {
+        return mDigits;
+    }
+
+    public ImageButton getDeleteButton() {
+        return mDelete;
+    }
+}