Fix 2209086: Make animation/decline transition much smoother in PhoneApp.
This fix makes hideIncomingCallWidget() re-entrant such that repeatedly calling it while
the incoming call widget is being hidden is OK. This fixes a problem where we might try to
hide the incoming call widget a second time in the case where updateState() is called again
based on some async event.
Tested: Answer/Decline call on CDMA and GSM device.
diff --git a/src/com/android/phone/InCallTouchUi.java b/src/com/android/phone/InCallTouchUi.java
index 1494478..0359b22 100644
--- a/src/com/android/phone/InCallTouchUi.java
+++ b/src/com/android/phone/InCallTouchUi.java
@@ -272,7 +272,13 @@
throw new IllegalStateException(
"'Incoming' and 'in-call' touch controls visible at the same time!");
}
- mIncomingCallWidget.setVisibility(showIncomingCallControls ? View.VISIBLE : View.GONE);
+
+ if (showIncomingCallControls) {
+ showIncomingCallWidget();
+ } else {
+ hideIncomingCallWidget();
+ }
+
mInCallControls.setVisibility(showInCallControls ? View.VISIBLE : View.GONE);
// TODO: As an optimization, also consider setting the visibility
@@ -551,18 +557,14 @@
/**
* Apply an animation to hide the incoming call widget.
- *
- * NOTE: in addition to this fadeout animation, the {@link #mIncomingCallWidget}
- * will get hidden by the updateState() method if a phone state change event comes
- * in and the phone isn't in the RINGING state any more. So there's basically a race
- * condition between this animation, and the telephony layer actually answering
- * the incoming call.
- *
- * In practice, 250ms should be short enough to avoid this condition, but this should
- * probably be cleaned up post-eclair.
*/
private void hideIncomingCallWidget() {
- // Transition from the incoming call UI
+ if (mIncomingCallWidget.getVisibility() != View.VISIBLE
+ || mIncomingCallWidget.getAnimation() != null) {
+ // Widget is already hidden or in the process of being hidden
+ return;
+ }
+ // Hide the incoming call screen with a transition
AlphaAnimation anim = new AlphaAnimation(1.0f, 0.0f);
anim.setDuration(IN_CALL_WIDGET_TRANSITION_TIME);
anim.setAnimationListener(new AnimationListener() {
@@ -577,6 +579,7 @@
public void onAnimationEnd(Animation animation) {
// hide the incoming call UI.
+ mIncomingCallWidget.clearAnimation();
mIncomingCallWidget.setVisibility(View.GONE);
}
});
@@ -584,6 +587,18 @@
}
/**
+ * Shows the incoming call widget and cancels any animation that may be fading it out.
+ */
+ private void showIncomingCallWidget() {
+ Animation anim = mIncomingCallWidget.getAnimation();
+ if (anim != null) {
+ anim.reset();
+ mIncomingCallWidget.clearAnimation();
+ }
+ mIncomingCallWidget.setVisibility(View.VISIBLE);
+ }
+
+ /**
* Handles state changes of the SlidingTabSelector widget. While the user
* is dragging one of the handles, we display an onscreen hint; see
* CallCard.getRotateWidgetHint().