Updating Dialpad animation in InCallUI.

Dialpad now saves orientation state.
Animation now matches duration and direction in Dialtacts.

Bug: 15386162

Change-Id: I6b8f23147c9be956d16c758a6a51a9fa3bb47ec6
diff --git a/InCallUI/res/anim/incall_dialpad_slide_in.xml b/InCallUI/res/anim/incall_dialpad_slide_in.xml
deleted file mode 100644
index 9885e81..0000000
--- a/InCallUI/res/anim/incall_dialpad_slide_in.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.
--->
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@interpolator/ease_in_interpolator"
-    android:valueFrom="1.0"
-    android:valueTo="0"
-    android:valueType="floatType"
-    android:propertyName="yFraction"
-    android:duration="532" />
\ No newline at end of file
diff --git a/InCallUI/res/anim/incall_dialpad_slide_out.xml b/InCallUI/res/anim/incall_dialpad_slide_out.xml
deleted file mode 100644
index 5e1dc8e..0000000
--- a/InCallUI/res/anim/incall_dialpad_slide_out.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.
--->
-<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
-    android:interpolator="@interpolator/ease_in_interpolator"
-    android:valueFrom="0"
-    android:valueTo="1.0"
-    android:valueType="floatType"
-    android:propertyName="yFraction"
-    android:duration="257" />
\ No newline at end of file
diff --git a/InCallUI/src/com/android/incallui/CallButtonFragment.java b/InCallUI/src/com/android/incallui/CallButtonFragment.java
index 76055f2..20d2aa7 100644
--- a/InCallUI/src/com/android/incallui/CallButtonFragment.java
+++ b/InCallUI/src/com/android/incallui/CallButtonFragment.java
@@ -493,10 +493,10 @@
     }
 
     @Override
-    public void displayDialpad(boolean value) {
+    public void displayDialpad(boolean value, boolean animate) {
         mShowDialpadButton.setSelected(value);
         if (getActivity() != null && getActivity() instanceof InCallActivity) {
-            ((InCallActivity) getActivity()).displayDialpad(value);
+            ((InCallActivity) getActivity()).displayDialpad(value, animate);
         }
     }
 
diff --git a/InCallUI/src/com/android/incallui/CallButtonPresenter.java b/InCallUI/src/com/android/incallui/CallButtonPresenter.java
index b7d8565..e899bf6 100644
--- a/InCallUI/src/com/android/incallui/CallButtonPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallButtonPresenter.java
@@ -100,12 +100,12 @@
                 if (mPreviousState == InCallState.OUTGOING && mCall != null
                         && TelephonyManagerUtils.isVoiceMailNumber(mCall.getNumber(),
                                 callButtonFragment.getActivity())) {
-                    ui.displayDialpad(true);
+                    ui.displayDialpad(true /* show */, true /* animate */);
                 }
             }
         } else if (state == InCallState.INCOMING) {
             if (ui != null) {
-                ui.displayDialpad(false);
+                ui.displayDialpad(false /* show */, true /* animate */);
             }
             mCall = null;
         } else {
@@ -230,7 +230,7 @@
 
     public void showDialpadClicked(boolean checked) {
         Log.v(this, "Show dialpad " + String.valueOf(checked));
-        getUi().displayDialpad(checked);
+        getUi().displayDialpad(checked /* show */, true /* animate */);
         updateExtraButtonRow();
     }
 
@@ -385,7 +385,7 @@
         void showSwap(boolean show);
         void showAddCall(boolean show);
         void enableAddCall(boolean enabled);
-        void displayDialpad(boolean on);
+        void displayDialpad(boolean on, boolean animate);
         boolean isDialpadVisible();
         void setAudio(int mode);
         void setSupportedAudio(int mask);
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index 3be517b..7cd8c90 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -168,27 +168,25 @@
                 R.dimen.floating_action_button_width);
         mFloatingActionButtonController = new FloatingActionButtonController(getActivity(),
                 mFloatingActionButtonContainer);
-        if (savedInstanceState != null) {
-            final ViewGroup parent = (ViewGroup) mPrimaryCallCardContainer.getParent();
-            final ViewTreeObserver observer = getView().getViewTreeObserver();
-            observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
-                @Override
-                public void onGlobalLayout() {
-                    final ViewTreeObserver observer = getView().getViewTreeObserver();
-                    if (!observer.isAlive()) {
-                        return;
-                    }
-                    observer.removeOnGlobalLayoutListener(this);
-                    mFloatingActionButtonController.setScreenWidth(parent.getWidth());
-                    mFloatingActionButtonController.align(
-                            mIsLandscape ? FloatingActionButtonController.ALIGN_QUARTER_RIGHT
-                                : FloatingActionButtonController.ALIGN_MIDDLE,
-                            0 /* offsetX */,
-                            0 /* offsetY */,
-                            false);
+        final ViewGroup parent = (ViewGroup) mPrimaryCallCardContainer.getParent();
+        final ViewTreeObserver observer = getView().getViewTreeObserver();
+        observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                final ViewTreeObserver observer = getView().getViewTreeObserver();
+                if (!observer.isAlive()) {
+                    return;
                 }
-            });
-        }
+                observer.removeOnGlobalLayoutListener(this);
+                mFloatingActionButtonController.setScreenWidth(parent.getWidth());
+                mFloatingActionButtonController.align(
+                        mIsLandscape ? FloatingActionButtonController.ALIGN_QUARTER_RIGHT
+                            : FloatingActionButtonController.ALIGN_MIDDLE,
+                        0 /* offsetX */,
+                        0 /* offsetY */,
+                        false);
+            }
+        });
 
         mHandoffButton = (ImageButton) view.findViewById(R.id.handoffButton);
         mHandoffButton.setOnClickListener(new View.OnClickListener() {
diff --git a/InCallUI/src/com/android/incallui/DialpadFragment.java b/InCallUI/src/com/android/incallui/DialpadFragment.java
index f36e25b..d0d2d7f 100644
--- a/InCallUI/src/com/android/incallui/DialpadFragment.java
+++ b/InCallUI/src/com/android/incallui/DialpadFragment.java
@@ -449,28 +449,6 @@
             configureKeypadListeners(mDialpadView);
         }
 
-        final ViewTreeObserver vto = parent.getViewTreeObserver();
-        // Adjust the translation of the DialpadFragment in a preDrawListener instead of in
-        // DialtactsActivity, because at the point in time when the DialpadFragment is added,
-        // its views have not been laid out yet.
-        final ViewTreeObserver.OnPreDrawListener
-                preDrawListener = new ViewTreeObserver.OnPreDrawListener() {
-            @Override
-            public boolean onPreDraw() {
-                if (isHidden()) return true;
-                if (parent.getTranslationY() == 0) {
-                    ((DialpadSlidingLinearLayout) parent)
-                            .setYFraction(DIALPAD_SLIDE_FRACTION);
-                }
-                final ViewTreeObserver vto = parent.getViewTreeObserver();
-                vto.removeOnPreDrawListener(this);
-                return true;
-            }
-
-        };
-
-        vto.addOnPreDrawListener(preDrawListener);
-
         return parent;
     }
 
diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java
index c699126..b37bdcb 100644
--- a/InCallUI/src/com/android/incallui/InCallActivity.java
+++ b/InCallUI/src/com/android/incallui/InCallActivity.java
@@ -26,6 +26,8 @@
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.telephony.DisconnectCause;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.Window;
@@ -33,6 +35,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.Toast;
 
+import com.android.contacts.common.animation.AnimationListenerAdapter;
 import com.android.incallui.Call.State;
 
 /**
@@ -61,6 +64,16 @@
     private String mShowPostCharWaitDialogCallId;
     private String mShowPostCharWaitDialogChars;
 
+    private boolean mIsLandscape;
+    private Animation mSlideIn;
+    private Animation mSlideOut;
+    AnimationListenerAdapter mSlideOutListener = new AnimationListenerAdapter() {
+        @Override
+        public void onAnimationEnd(Animation animation) {
+            showDialpad(false);
+        }
+    };
+
     @Override
     protected void onCreate(Bundle icicle) {
         Log.d(this, "onCreate()...  this = " + this);
@@ -86,10 +99,29 @@
         initializeInCall();
 
         internalResolveIntent(getIntent());
+
+        mIsLandscape = getResources().getConfiguration().orientation
+                == Configuration.ORIENTATION_LANDSCAPE;
+        mSlideIn = AnimationUtils.loadAnimation(this,
+                mIsLandscape ? R.anim.dialpad_slide_in_right : R.anim.dialpad_slide_in_bottom);
+        mSlideOut = AnimationUtils.loadAnimation(this,
+                mIsLandscape ? R.anim.dialpad_slide_out_right : R.anim.dialpad_slide_out_bottom);
+
+        mSlideOut.setAnimationListener(mSlideOutListener);
+        if (icicle != null) {
+            if (icicle.getBoolean(SHOW_DIALPAD_EXTRA)) {
+                mCallButtonFragment.displayDialpad(true /* show */, false /* animate */);
+            }
+        }
         Log.d(this, "onCreate(): exit");
     }
 
     @Override
+    protected void onSaveInstanceState(Bundle out) {
+        out.putBoolean(SHOW_DIALPAD_EXTRA, mCallButtonFragment.isDialpadVisible());
+    }
+
+    @Override
     protected void onStart() {
         Log.d(this, "onStart()...");
         super.onStart();
@@ -107,7 +139,7 @@
         InCallPresenter.getInstance().onUiShowing(true);
 
         if (mShowDialpadRequested) {
-            mCallButtonFragment.displayDialpad(true);
+            mCallButtonFragment.displayDialpad(true /* show */, true /* animate */);
             mShowDialpadRequested = false;
         }
 
@@ -209,7 +241,7 @@
         // in-call UI:
 
         if (mDialpadFragment.isVisible()) {
-            mCallButtonFragment.displayDialpad(false);  // do the "closing" animation
+            mCallButtonFragment.displayDialpad(false /* show */, true /* animate */);
             return;
         } else if (mConferenceManagerFragment.isVisible()) {
             mConferenceManagerFragment.setVisible(false);
@@ -408,7 +440,7 @@
      * update the checked state of the dialpad button, and update the proximity sensor state.
      */
     public void hideDialpadForDisconnect() {
-        mCallButtonFragment.displayDialpad(false);
+        mCallButtonFragment.displayDialpad(false /* show */, true /* animate */);
     }
 
     public void dismissKeyguard(boolean dismiss) {
@@ -419,16 +451,31 @@
         }
     }
 
-    public void displayDialpad(boolean showDialpad) {
+    private void showDialpad(boolean showDialpad) {
         final FragmentTransaction ft = getFragmentManager().beginTransaction();
         if (showDialpad) {
-            ft.setCustomAnimations(R.anim.incall_dialpad_slide_in, 0);
             ft.show(mDialpadFragment);
         } else {
-            ft.setCustomAnimations(0, R.anim.incall_dialpad_slide_out);
             ft.hide(mDialpadFragment);
         }
         ft.commitAllowingStateLoss();
+    }
+
+    public void displayDialpad(boolean showDialpad, boolean animate) {
+        // If the dialpad is already visible, don't animate in. If it's gone, don't animate out.
+        if ((showDialpad && isDialpadVisible()) || (!showDialpad && !isDialpadVisible())) {
+            return;
+        }
+        // We don't do a FragmentTransaction on the hide case because it will be dealt with when
+        // the listener is fired after an animation finishes.
+        if (!animate) {
+            showDialpad(showDialpad);
+        } else {
+            if (showDialpad) {
+                showDialpad(true);
+            }
+            mDialpadFragment.getView().startAnimation(showDialpad ? mSlideIn : mSlideOut);
+        }
 
         InCallPresenter.getInstance().getProximitySensor().onDialpadVisible(showDialpad);
     }