New appearance and look and feel for dialpad.

http://b/13189041

Change-Id: I91028c8fdee31c1f76610573a4396eb979c30170
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index 5989e52..4542137 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -28,7 +28,6 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -40,11 +39,8 @@
 import android.speech.RecognizerIntent;
 import android.telephony.TelephonyManager;
 import android.text.Editable;
-import android.text.Spannable;
-import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
 import android.text.TextWatcher;
-import android.text.style.ImageSpan;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -88,13 +84,13 @@
 public class DialtactsActivity extends TransactionSafeActivity implements View.OnClickListener,
         DialpadFragment.OnDialpadQueryChangedListener, PopupMenu.OnMenuItemClickListener,
         OnListFragmentScrolledListener,
-        DialpadFragment.OnDialpadFragmentStartedListener,
+        DialpadFragment.HostInterface,
         PhoneFavoriteFragment.OnShowAllContactsListener,
         PhoneFavoriteFragment.HostInterface,
-        OnDragDropListener {
+        OnDragDropListener, View.OnLongClickListener {
     private static final String TAG = "DialtactsActivity";
 
-    public static final boolean DEBUG = false;
+    public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
     public static final String SHARED_PREFS_NAME = "com.android.dialer_preferences";
 
@@ -121,8 +117,6 @@
      */
     private static final String ACTION_TOUCH_DIALER = "com.android.phone.action.TOUCH_DIALER";
 
-    private static final int SUBACTIVITY_ACCOUNT_FILTER = 1;
-
     private static final int ACTIVITY_REQUEST_CODE_VOICE_SEARCH = 1;
 
     private static final int FADE_ANIMATION_DURATION = 200;
@@ -150,14 +144,14 @@
     private SmartDialSearchFragment mSmartDialSearchFragment;
 
     private View mMenuButton;
+    private View mFakeActionBar;
     private View mCallHistoryButton;
     private View mDialpadButton;
+    private View mDialButton;
     private PopupMenu mOverflowMenu;
 
     // Padding view used to shift the fragments up when the dialpad is shown.
-    private View mBottomPaddingView;
     private View mFragmentsFrame;
-    private View mActionBar;
 
     private boolean mInDialpadSearch;
     private boolean mInRegularSearch;
@@ -302,12 +296,10 @@
         // Add the favorites fragment, and the dialpad fragment, but only if savedInstanceState
         // is null. Otherwise the fragment manager takes care of recreating these fragments.
         if (savedInstanceState == null) {
-            final PhoneFavoriteFragment phoneFavoriteFragment = new PhoneFavoriteFragment();
-
-            final FragmentTransaction ft = getFragmentManager().beginTransaction();
-            ft.add(R.id.dialtacts_frame, phoneFavoriteFragment, TAG_FAVORITES_FRAGMENT);
-            ft.add(R.id.dialtacts_container, new DialpadFragment(), TAG_DIALPAD_FRAGMENT);
-            ft.commit();
+            getFragmentManager().beginTransaction()
+                    .add(R.id.dialtacts_frame, new PhoneFavoriteFragment(), TAG_FAVORITES_FRAGMENT)
+                    .add(R.id.dialtacts_container, new DialpadFragment(), TAG_DIALPAD_FRAGMENT)
+                    .commit();
         } else {
             mSearchQuery = savedInstanceState.getString(KEY_SEARCH_QUERY);
             mInRegularSearch = savedInstanceState.getBoolean(KEY_IN_REGULAR_SEARCH_UI);
@@ -315,9 +307,8 @@
             mFirstLaunch = savedInstanceState.getBoolean(KEY_FIRST_LAUNCH);
         }
 
-        mBottomPaddingView = findViewById(R.id.dialtacts_bottom_padding);
         mFragmentsFrame = findViewById(R.id.dialtacts_frame);
-        mActionBar = findViewById(R.id.fake_action_bar);
+
         mRemoveViewContainer = (RemoveView) findViewById(R.id.remove_view_container);
         prepareSearchView();
 
@@ -326,6 +317,7 @@
             setupFilterText(intent);
         }
 
+        hideDialpadFragment(false, false);
         setupFakeActionBarItems();
 
         mDialerDatabaseHelper = DatabaseHelperManager.getDatabaseHelper(this);
@@ -432,7 +424,11 @@
     public void onClick(View view) {
         switch (view.getId()) {
             case R.id.overflow_menu: {
-                mOverflowMenu.show();
+                if (isDialpadShowing()) {
+                    mDialpadFragment.optionsMenuInvoked(view);
+                } else {
+                    mOverflowMenu.show();
+                }
                 break;
             }
             case R.id.dialpad_button:
@@ -443,7 +439,10 @@
                 mInCallDialpadUp = false;
                 showDialpadFragment(true);
                 break;
-            case R.id.call_history_on_dialpad_button:
+            case R.id.dial_button:
+                // Dial button was pressed; tell the Dialpad fragment
+                mDialpadFragment.dialButtonPressed();
+                break;
             case R.id.call_history_button:
                 // Use explicit CallLogActivity intent instead of ACTION_VIEW +
                 // CONTENT_TYPE, so that we always open our call log from our dialer
@@ -474,6 +473,22 @@
     }
 
     @Override
+    public boolean onLongClick(View view) {
+        switch (view.getId()) {
+            case R.id.dial_button: {
+                // Dial button was pressed; tell the Dialpad fragment
+                mDialpadFragment.dialButtonPressed();
+                return true;  // Consume the event
+            }
+            default: {
+                Log.wtf(TAG, "Unexpected onClick event from " + view);
+                break;
+            }
+        }
+        return false;
+    }
+
+    @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == ACTIVITY_REQUEST_CODE_VOICE_SEARCH) {
             if (resultCode == RESULT_OK) {
@@ -502,6 +517,8 @@
         }
         ft.show(mDialpadFragment);
         ft.commit();
+        mDialButton.setVisibility(shouldShowOnscreenDialButton() ? View.VISIBLE : View.GONE);
+        mDialpadButton.setVisibility(View.GONE);
     }
 
     public void hideDialpadFragment(boolean animate, boolean clearDialpad) {
@@ -517,6 +534,8 @@
         }
         ft.hide(mDialpadFragment);
         ft.commit();
+        mDialButton.setVisibility(View.GONE);
+        mDialpadButton.setVisibility(View.VISIBLE);
     }
 
     private void prepareSearchView() {
@@ -580,14 +599,11 @@
                     new AnimatorListenerAdapter() {
                         @Override
                         public void onAnimationEnd(Animator animation) {
-                            mBottomPaddingView.setVisibility(View.VISIBLE);
                             mFragmentsFrame.setTranslationY(0);
-                            mActionBar.setVisibility(View.INVISIBLE);
                         }
                     });
         } else {
             mSearchViewContainer.setTranslationY(-mSearchView.getHeight());
-            mActionBar.setVisibility(View.INVISIBLE);
         }
     }
 
@@ -600,7 +616,6 @@
                     @Override
                     public void onAnimationStart(Animator animation) {
                         mSearchViewContainer.setVisibility(View.VISIBLE);
-                        mActionBar.setVisibility(View.VISIBLE);
                     }
                 });
 
@@ -610,7 +625,6 @@
                         new AnimatorListenerAdapter() {
                             @Override
                             public void onAnimationStart(Animator animation) {
-                                mBottomPaddingView.setVisibility(View.GONE);
                             }
                         });
     }
@@ -628,20 +642,21 @@
             mMenuButton.setOnTouchListener(mOverflowMenu.getDragToOpenListener());
         }
 
+        mFakeActionBar = findViewById(R.id.fake_action_bar);
+
         mCallHistoryButton = findViewById(R.id.call_history_button);
         // mCallHistoryButton.setMinimumWidth(fakeMenuItemWidth);
         mCallHistoryButton.setOnClickListener(this);
 
+        mDialButton = findViewById(R.id.dial_button);
+        mDialButton.setOnClickListener(this);
+        mDialButton.setOnLongClickListener(this);
+
         mDialpadButton = findViewById(R.id.dialpad_button);
         // DialpadButton.setMinimumWidth(fakeMenuItemWidth);
         mDialpadButton.setOnClickListener(this);
     }
 
-    public void setupFakeActionBarItemsForDialpadFragment() {
-        final View callhistoryButton = findViewById(R.id.call_history_on_dialpad_button);
-        callhistoryButton.setOnClickListener(this);
-    }
-
     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
@@ -937,8 +952,13 @@
     }
 
     @Override
-    public void onDialpadFragmentStarted() {
-        setupFakeActionBarItemsForDialpadFragment();
+    public void setDialButtonEnabled(boolean enabled) {
+        mDialButton.setEnabled(enabled);
+    }
+
+    @Override
+    public void setDialButtonContainerVisible(boolean visible) {
+        mFakeActionBar.setVisibility(visible ? View.VISIBLE : View.GONE);
     }
 
     private boolean phoneIsInUse() {
@@ -960,12 +980,6 @@
         return intent;
     }
 
-    public static Intent getInsertContactWithNameIntent(CharSequence text) {
-        final Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
-        intent.putExtra(Intents.Insert.NAME, text);
-        return intent;
-    }
-
     private boolean canIntentBeHandled(Intent intent) {
         final PackageManager packageManager = getPackageManager();
         final List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent,
@@ -1016,4 +1030,8 @@
         fadeIn.animate().alpha(1).setDuration(FADE_ANIMATION_DURATION)
                 .setListener(null);
     }
+
+    private boolean shouldShowOnscreenDialButton() {
+        return getResources().getBoolean(R.bool.config_show_onscreen_dial_button);
+    }
 }
diff --git a/src/com/android/dialer/dialpad/DialpadFragment.java b/src/com/android/dialer/dialpad/DialpadFragment.java
index 0d23378..ae9700f 100644
--- a/src/com/android/dialer/dialpad/DialpadFragment.java
+++ b/src/com/android/dialer/dialpad/DialpadFragment.java
@@ -35,11 +35,9 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.provider.ContactsContract.Contacts;
 import android.provider.Contacts.People;
 import android.provider.Contacts.Phones;
 import android.provider.Contacts.PhonesColumns;
-import android.provider.ContactsContract.Intents;
 import android.provider.Settings;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.PhoneStateListener;
@@ -50,17 +48,13 @@
 import android.text.TextWatcher;
 import android.text.style.RelativeSizeSpan;
 import android.util.AttributeSet;
-import android.util.DisplayMetrics;
 import android.util.Log;
-import android.util.TypedValue;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.Menu;
-import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewConfiguration;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
 import android.view.ViewTreeObserver.OnPreDrawListener;
@@ -76,17 +70,12 @@
 
 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.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;
@@ -105,8 +94,19 @@
         DialpadKeyButton.OnPressedListener {
     private static final String TAG = DialpadFragment.class.getSimpleName();
 
-    public interface OnDialpadFragmentStartedListener {
-        public void onDialpadFragmentStarted();
+    /**
+     * This interface allows the DialpadFragment to tell its hosting Activity when and when not
+     * to display the "dial" button. While this is logically part of the DialpadFragment, the
+     * need to have a particular kind of slick animation puts the "dial" button in the parent.
+     *
+     * The parent calls dialButtonPressed() and optionsMenuInvoked() on the dialpad fragment
+     * when appropriate.
+     *
+     * TODO: Refactor the app so this interchange is a bit cleaner.
+     */
+    public interface HostInterface {
+        void setDialButtonEnabled(boolean enabled);
+        void setDialButtonContainerVisible(boolean visible);
     }
 
     /**
@@ -210,8 +210,6 @@
      */
     private final HashSet<View> mPressedDialpadKeys = new HashSet<View>(12);
 
-    private View mDialButtonContainer;
-    private View mDialButton;
     private ListView mDialpadChooser;
     private DialpadChooserAdapter mDialpadChooserAdapter;
 
@@ -396,7 +394,6 @@
         // Load up the resources for the text field.
         Resources r = getResources();
 
-        mDialButtonContainer = fragmentView.findViewById(R.id.dialButtonContainer);
         mDigitsContainer = fragmentView.findViewById(R.id.digits_container);
         mDigits = (EditText) fragmentView.findViewById(R.id.digits);
         mDigits.setKeyListener(UnicodeDialerKeyListener.INSTANCE);
@@ -411,15 +408,6 @@
             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);
@@ -457,18 +445,6 @@
     @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() {
@@ -654,10 +630,6 @@
             dialpadKey.setContentDescription(numberString);
             if (lettersView != null) {
                 lettersView.setText(resources.getString(letterIds[i]));
-                if (buttonIds[i] == R.id.zero) {
-                    lettersView.setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(
-                            R.dimen.dialpad_key_plus_size));
-                }
             }
         }
 
@@ -881,7 +853,7 @@
         switch (view.getId()) {
             case R.id.digits:
                 if (keyCode == KeyEvent.KEYCODE_ENTER) {
-                    dialButtonPressed();
+                    handleDialButtonPressed();
                     return true;
                 }
                 break;
@@ -963,27 +935,37 @@
         }
     }
 
+    /**
+     * Called by the containing Activity to tell this Fragment that the gesture to display the
+     * "options" menu has been invoked.
+     *
+     * @param invoker the View that invoked the options menu, to act as an anchor location.
+     */
+    public void optionsMenuInvoked(View invoker) {
+        final PopupMenu popupMenu = new PopupMenu(getActivity(), invoker);
+        final Menu menu = popupMenu.getMenu();
+        popupMenu.inflate(R.menu.dialpad_options);
+        popupMenu.setOnMenuItemClickListener(this);
+        setupMenuItems(menu);
+        popupMenu.show();
+    }
+
+    /**
+     * Called by the containing Activity to tell this Fragment that the dial button has been
+     * pressed.
+     */
+    public void dialButtonPressed() {
+        mHaptic.vibrate();
+        handleDialButtonPressed();
+    }
+
     @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);
-                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);
@@ -1058,16 +1040,6 @@
                 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;
     }
@@ -1160,7 +1132,7 @@
      * user needs to press the dial button again, to dial it (general
      * case described above).
      */
-    public void dialButtonPressed() {
+    private void handleDialButtonPressed() {
         if (isDigitsEmpty()) { // No number entered.
             handleDialButtonClickWithEmptyDigits();
         } else {
@@ -1330,7 +1302,7 @@
                 mDigits.setVisibility(View.GONE);
             }
             if (mDialpad != null) mDialpad.setVisibility(View.GONE);
-            if (mDialButtonContainer != null) mDialButtonContainer.setVisibility(View.GONE);
+            ((HostInterface) getActivity()).setDialButtonContainerVisible(false);
 
             mDialpadChooser.setVisibility(View.VISIBLE);
 
@@ -1348,7 +1320,7 @@
                 mDigits.setVisibility(View.VISIBLE);
             }
             if (mDialpad != null) mDialpad.setVisibility(View.VISIBLE);
-            if (mDialButtonContainer != null) mDialButtonContainer.setVisibility(View.VISIBLE);
+            ((HostInterface) getActivity()).setDialButtonContainerVisible(true);
             mDialpadChooser.setVisibility(View.GONE);
         }
     }
@@ -1597,23 +1569,18 @@
      */
     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);
+        // 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()) {
+            ((HostInterface) getActivity()).setDialButtonEnabled(true);
+        } else {
+            // Common case: GSM, or CDMA but not on a call. Enable the Dial button if something
+            // has been entered into the digits field, or if there is a last dialed number that
+            // could be redialed.
+            ((HostInterface) getActivity()).setDialButtonEnabled(
+                    digitsNotEmpty || !TextUtils.isEmpty(mLastNumberDialed));
+        }
     }
 
     /**