summaryrefslogtreecommitdiff
path: root/java/com/android/dialershared/bubble/Bubble.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialershared/bubble/Bubble.java')
-rw-r--r--java/com/android/dialershared/bubble/Bubble.java124
1 files changed, 81 insertions, 43 deletions
diff --git a/java/com/android/dialershared/bubble/Bubble.java b/java/com/android/dialershared/bubble/Bubble.java
index f2ba117d8..9606f5be6 100644
--- a/java/com/android/dialershared/bubble/Bubble.java
+++ b/java/com/android/dialershared/bubble/Bubble.java
@@ -61,6 +61,8 @@ import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.ViewAnimator;
+import com.android.dialer.logging.DialerImpression;
+import com.android.dialer.logging.Logger;
import com.android.dialershared.bubble.BubbleInfo.Action;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -87,6 +89,8 @@ public class Bubble {
private final Context context;
private final WindowManager windowManager;
+ private final Handler handler = new Handler();
+
private LayoutParams windowParams;
// Initialized in factory method
@@ -100,9 +104,7 @@ public class Bubble {
private boolean hideAfterText;
private int collapseEndAction;
- private final Handler handler = new Handler();
-
- private ViewHolder viewHolder;
+ @VisibleForTesting ViewHolder viewHolder;
private ViewPropertyAnimator collapseAnimation;
private Integer overrideGravity;
private ViewPropertyAnimator exitAnimator;
@@ -238,47 +240,22 @@ public class Bubble {
updatePrimaryIconAnimation();
}
- /**
- * Hide the button if visible. Will run a short exit animation before hiding. If the bubble is
- * currently showing text, will hide after the text is done displaying. If the bubble is not
- * visible this method does nothing.
- */
+ /** Hide the bubble. */
public void hide() {
- if (visibility == Visibility.HIDDEN || visibility == Visibility.EXITING) {
- return;
- }
-
- if (textShowing) {
- hideAfterText = true;
- return;
- }
-
- if (collapseAnimation != null) {
- collapseEndAction = CollapseEnd.HIDE;
- return;
- }
-
- if (expanded) {
- startCollapse(CollapseEnd.HIDE);
+ if (hideAfterText) {
+ // hideAndReset() will be called after showing text, do nothing here.
return;
}
+ hideHelper(this::defaultAfterHidingAnimation);
+ }
- visibility = Visibility.EXITING;
- exitAnimator =
- viewHolder
- .getPrimaryButton()
- .animate()
- .setInterpolator(new AnticipateInterpolator())
- .scaleX(0)
- .scaleY(0)
- .withEndAction(
- () -> {
- exitAnimator = null;
- windowManager.removeView(viewHolder.getRoot());
- visibility = Visibility.HIDDEN;
- updatePrimaryIconAnimation();
- });
- exitAnimator.start();
+ /** Hide the bubble and reset {@viewHolder} to initial state */
+ public void hideAndReset() {
+ hideHelper(
+ () -> {
+ defaultAfterHidingAnimation();
+ reset();
+ });
}
/** Returns whether the bubble is currently visible */
@@ -350,8 +327,15 @@ public class Bubble {
public boolean onPreDraw() {
primaryButton.getViewTreeObserver().removeOnPreDrawListener(this);
- // Prepare and capture end values
+ // Prepare and capture end values, always use the size of primaryText since
+ // its invisibility makes primaryButton smaller than expected
TransitionValues endValues = new TransitionValues();
+ endValues.values.put(
+ ChangeOnScreenBounds.PROPNAME_WIDTH,
+ viewHolder.getPrimaryText().getWidth());
+ endValues.values.put(
+ ChangeOnScreenBounds.PROPNAME_HEIGHT,
+ viewHolder.getPrimaryText().getHeight());
endValues.view = primaryButton;
transition.addTarget(endValues.view);
transition.captureEndValues(endValues);
@@ -377,7 +361,8 @@ public class Bubble {
() -> {
textShowing = false;
if (hideAfterText) {
- hide();
+ // Always reset here since text shouldn't keep showing.
+ hideAndReset();
} else {
doResize(
() -> viewHolder.getPrimaryButton().setDisplayedChild(ViewHolder.CHILD_INDEX_ICON));
@@ -411,6 +396,7 @@ public class Bubble {
void primaryButtonClick() {
if (expanded || textShowing || currentInfo.getActions().isEmpty()) {
+ Logger.get(context).logImpression(DialerImpression.Type.BUBBLE_PRIMARY_BUTTON_RETURN_TO_CALL);
try {
currentInfo.getPrimaryIntent().send();
} catch (CanceledException e) {
@@ -419,6 +405,7 @@ public class Bubble {
return;
}
+ Logger.get(context).logImpression(DialerImpression.Type.BUBBLE_PRIMARY_BUTTON_EXPAND);
doResize(
() -> {
onLeftRightSwitch(isDrawingFromRight());
@@ -478,6 +465,48 @@ public class Bubble {
return viewHolder.getRoot();
}
+ /**
+ * Hide the bubble if visible. Will run a short exit animation and before hiding, and {@code
+ * afterHiding} after hiding. If the bubble is currently showing text, will hide after the text is
+ * done displaying. If the bubble is not visible this method does nothing.
+ */
+ private void hideHelper(Runnable afterHiding) {
+ if (visibility == Visibility.HIDDEN || visibility == Visibility.EXITING) {
+ return;
+ }
+
+ if (textShowing) {
+ hideAfterText = true;
+ return;
+ }
+
+ if (collapseAnimation != null) {
+ collapseEndAction = CollapseEnd.HIDE;
+ return;
+ }
+
+ if (expanded) {
+ startCollapse(CollapseEnd.HIDE);
+ return;
+ }
+
+ visibility = Visibility.EXITING;
+ exitAnimator =
+ viewHolder
+ .getPrimaryButton()
+ .animate()
+ .setInterpolator(new AnticipateInterpolator())
+ .scaleX(0)
+ .scaleY(0)
+ .withEndAction(afterHiding);
+ exitAnimator.start();
+ }
+
+ private void reset() {
+ viewHolder = new ViewHolder(viewHolder.getRoot().getContext());
+ update();
+ }
+
private void update() {
RippleDrawable backgroundRipple =
(RippleDrawable)
@@ -681,7 +710,16 @@ public class Bubble {
windowManager.updateViewLayout(getRootView(), windowParams);
}
- private class ViewHolder {
+ private void defaultAfterHidingAnimation() {
+ exitAnimator = null;
+ windowManager.removeView(viewHolder.getRoot());
+ visibility = Visibility.HIDDEN;
+
+ updatePrimaryIconAnimation();
+ }
+
+ @VisibleForTesting
+ class ViewHolder {
public static final int CHILD_INDEX_ICON = 0;
public static final int CHILD_INDEX_TEXT = 1;