Merge "Suppress IME show-up on search mode."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 95edf0f..aeec2b2 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -53,17 +53,6 @@
         android:hardwareAccelerated="true"
     >
 
-        <!-- A virtual 12 key dialer -->
-        <activity android:name=".activities.DialpadActivity"
-            android:launchMode="singleTop"
-        >
-            <intent-filter>
-                <action android:name="com.android.phone.action.TOUCH_DIALER" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.TAB" />
-            </intent-filter>
-        </activity>
-
         <!-- A list of recent calls -->
         <activity android:name=".activities.CallLogActivity"
             android:label="@string/recentCallsIconLabel"
@@ -181,6 +170,13 @@
                 <category android:name="android.intent.category.DEFAULT" />
                 <category android:name="android.intent.category.BROWSABLE" />
             </intent-filter>
+            <!-- This was never intended to be public, but is here for backward
+                 compatibility.  Use Intent.ACTION_DIAL instead. -->
+            <intent-filter>
+                <action android:name="com.android.phone.action.TOUCH_DIALER" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.TAB" />
+            </intent-filter>
         </activity>
 
         <!-- The main Contacts activity with the contact list, favorites, and groups. -->
diff --git a/res/menu/dialpad_options.xml b/res/menu/dialpad_options.xml
index 77da9cb..4dc62a8 100644
--- a/res/menu/dialpad_options.xml
+++ b/res/menu/dialpad_options.xml
@@ -30,4 +30,10 @@
         android:icon="@drawable/ic_menu_wait"
         android:title="@string/add_wait"
         android:showAsAction="withText" />
+
+    <item
+        android:id="@+id/menu_call_settings_dialpad"
+        android:title="@string/call_settings"
+        android:icon="@drawable/ic_menu_settings_holo_light"
+        android:showAsAction="withText" />
 </menu>
diff --git a/src/com/android/contacts/activities/DialpadActivity.java b/src/com/android/contacts/activities/DialpadActivity.java
deleted file mode 100644
index 1221068..0000000
--- a/src/com/android/contacts/activities/DialpadActivity.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.contacts.activities;
-
-import com.android.contacts.ContactsSearchManager;
-import com.android.contacts.R;
-import com.android.contacts.dialpad.DialpadFragment;
-
-import android.app.Activity;
-import android.content.ActivityNotFoundException;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.KeyEvent;
-import android.view.ViewConfiguration;
-import android.view.Window;
-import android.view.inputmethod.InputMethodManager;
-
-/**
- * Activity that displays a twelve-key phone dialpad.
- * This is just a simple container around DialpadFragment.
- * @see DialpadFragment
- */
-public class DialpadActivity extends Activity {
-    private static final String TAG = "DialpadActivity";
-
-    private DialpadFragment mFragment;
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        setContentView(R.layout.dialpad_activity);
-
-        Resources r = getResources();
-        // Do not show title in the case the device is in carmode.
-        if ((r.getConfiguration().uiMode & Configuration.UI_MODE_TYPE_MASK) ==
-                Configuration.UI_MODE_TYPE_CAR) {
-            requestWindowFeature(Window.FEATURE_NO_TITLE);
-        }
-
-        mFragment = (DialpadFragment) getFragmentManager().findFragmentById(
-                R.id.dialpad_fragment);
-    }
-
-    @Override
-    protected void onNewIntent(Intent newIntent) {
-        setIntent(newIntent);
-        mFragment.configureScreenFromIntent(newIntent);
-    }
-
-    public DialpadFragment getFragment() {
-        return mFragment;
-    }
-
-    @Override
-    public void onWindowFocusChanged(boolean hasFocus) {
-        if (hasFocus) {
-            // Hide soft keyboard, if visible (it's fugly over button dialer).
-            // The only known case where this will be true is when launching the dialer with
-            // ACTION_DIAL via a soft keyboard.  we dismiss it here because we don't
-            // have a window token yet in onCreate / onNewIntent
-            InputMethodManager inputMethodManager = (InputMethodManager)
-                    getSystemService(Context.INPUT_METHOD_SERVICE);
-            inputMethodManager.hideSoftInputFromWindow(
-                    mFragment.getDigitsWidget().getWindowToken(), 0);
-        }
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_CALL: {
-                long callPressDiff = SystemClock.uptimeMillis() - event.getDownTime();
-                if (callPressDiff >= ViewConfiguration.getLongPressTimeout()) {
-                    // Launch voice dialer
-                    Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
-                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-                    try {
-                        startActivity(intent);
-                    } catch (ActivityNotFoundException e) {
-                        Log.w(TAG, "Failed to launch voice dialer: " + e);
-                    }
-                }
-                return true;
-            }
-            case KeyEvent.KEYCODE_1: {
-                long timeDiff = SystemClock.uptimeMillis() - event.getDownTime();
-                if (timeDiff >= ViewConfiguration.getLongPressTimeout()) {
-                    // Long press detected, call voice mail
-                    mFragment.callVoicemail();
-                }
-                return true;
-            }
-        }
-        return super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_CALL: {
-                mFragment.dialButtonPressed();
-                return true;
-            }
-        }
-        return super.onKeyUp(keyCode, event);
-    }
-
-    @Override
-    public void startSearch(String initialQuery, boolean selectInitialQuery, Bundle appSearchData,
-            boolean globalSearch) {
-        if (globalSearch) {
-            super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
-        } else {
-            ContactsSearchManager.startSearch(this, initialQuery);
-        }
-    }
-}
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index a51b267..3fd1558 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -58,6 +58,7 @@
 import android.view.MenuItem.OnMenuItemClickListener;
 import android.view.View;
 import android.view.View.OnAttachStateChangeListener;
+import android.view.ViewConfiguration;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.SearchView;
 import android.widget.SearchView.OnCloseListener;
@@ -78,6 +79,11 @@
     private static final String CALL_SETTINGS_CLASS_NAME =
             "com.android.phone.CallFeaturesSetting";
 
+    /**
+     * 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;
@@ -579,7 +585,7 @@
     /** 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)) {
+        if (Intent.ACTION_DIAL.equals(action) || ACTION_TOUCH_DIALER.equals(action)) {
             return true;
         }
         if (Intent.ACTION_VIEW.equals(action)) {
@@ -674,15 +680,25 @@
                     mFilterOptionsMenuItemClickListener);
             callSettingsMenuItem.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();
             } else {
                 searchMenuItem.setVisible(true);
                 searchMenuItem.setOnMenuItemClickListener(mSearchMenuItemClickListener);
+                showCallSettingsMenu = true;
             }
             filterOptionMenuItem.setVisible(false);
-            callSettingsMenuItem.setVisible(true);
-            callSettingsMenuItem.setIntent(DialtactsActivity.getCallSettingsIntent());
+
+            if (showCallSettingsMenu) {
+                callSettingsMenuItem.setVisible(true);
+                callSettingsMenuItem.setIntent(DialtactsActivity.getCallSettingsIntent());
+            } else {
+                callSettingsMenuItem.setVisible(false);
+            }
         }
 
         return true;
diff --git a/src/com/android/contacts/dialpad/DialpadFragment.java b/src/com/android/contacts/dialpad/DialpadFragment.java
index 62ba95e..93bd3e9 100644
--- a/src/com/android/contacts/dialpad/DialpadFragment.java
+++ b/src/com/android/contacts/dialpad/DialpadFragment.java
@@ -571,10 +571,20 @@
     }
 
     private void setupMenuItems(Menu menu) {
+        final MenuItem callSettingsMenuItem = menu.findItem(R.id.menu_call_settings_dialpad);
         final MenuItem addToContactMenuItem = menu.findItem(R.id.menu_add_contacts);
         final MenuItem twoSecPauseMenuItem = menu.findItem(R.id.menu_2s_pause);
         final MenuItem waitMenuItem = menu.findItem(R.id.menu_add_wait);
 
+        final Activity activity = getActivity();
+        if (activity != null && ViewConfiguration.get(activity).hasPermanentMenuKey()) {
+            // Call settings should be available via its parent Activity.
+            callSettingsMenuItem.setVisible(false);
+        } else {
+            callSettingsMenuItem.setVisible(true);
+            callSettingsMenuItem.setIntent(DialtactsActivity.getCallSettingsIntent());
+        }
+
         // We show "add to contacts", "2sec pause", and "add wait" menus only when the user is
         // seeing usual dialpads and has typed at least one digit.
         // We never show a menu if the "choose dialpad" UI is up.
diff --git a/src/com/android/contacts/model/AccountTypeWithDataSet.java b/src/com/android/contacts/model/AccountTypeWithDataSet.java
index d5cdbdd..f1b2344 100644
--- a/src/com/android/contacts/model/AccountTypeWithDataSet.java
+++ b/src/com/android/contacts/model/AccountTypeWithDataSet.java
@@ -25,16 +25,14 @@
  * Encapsulates an "account type" string and a "data set" string.
  */
 public class AccountTypeWithDataSet {
-    /** account type will never be null. */
+    /** account type.  Can be null for fallback type. */
     public final String accountType;
 
     /** dataSet may be null, but never be "". */
     public final String dataSet;
 
     private AccountTypeWithDataSet(String accountType, String dataSet) {
-        if (accountType == null) throw new NullPointerException();
-
-        this.accountType = accountType;
+        this.accountType = TextUtils.isEmpty(accountType) ? null : accountType;
         this.dataSet = TextUtils.isEmpty(dataSet) ? null : dataSet;
     }
 
@@ -53,7 +51,8 @@
 
     @Override
     public int hashCode() {
-        return Objects.hashCode(accountType) ^ (dataSet == null ? 0 : Objects.hashCode(dataSet));
+        return (accountType == null ? 0 : accountType.hashCode())
+                ^ (dataSet == null ? 0 : dataSet.hashCode());
     }
 
     @Override