summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java79
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java73
3 files changed, 116 insertions, 45 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index bb572191fe3c..c5639ea6fcde 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -84,6 +84,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dumpable;
+import com.android.systemui.bubbles.animation.StackAnimationController;
import com.android.systemui.bubbles.dagger.BubbleModule;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.model.SysUiState;
@@ -173,6 +174,12 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
@Nullable private BubbleStackView mStackView;
private BubbleIconFactory mBubbleIconFactory;
+ /**
+ * The relative position of the stack when we removed it and nulled it out. If the stack is
+ * re-created, it will re-appear at this position.
+ */
+ @Nullable private BubbleStackView.RelativeStackPosition mPositionFromRemovedStack;
+
// Tracks the id of the current (foreground) user.
private int mCurrentUserId;
// Saves notification keys of active bubbles when users are switched.
@@ -736,6 +743,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
mContext, mBubbleData, mSurfaceSynchronizer, mFloatingContentCoordinator,
mSysUiState, this::onAllBubblesAnimatedOut, this::onImeVisibilityChanged,
this::hideCurrentInputMethod);
+ mStackView.setStackStartPosition(mPositionFromRemovedStack);
mStackView.addView(mBubbleScrim);
if (mExpandListener != null) {
mStackView.setExpandListener(mExpandListener);
@@ -806,6 +814,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
try {
mAddedToWindowManager = false;
if (mStackView != null) {
+ mPositionFromRemovedStack = mStackView.getRelativeStackPosition();
mWindowManager.removeView(mStackView);
mStackView.removeView(mBubbleScrim);
mStackView = null;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index b3fbfd6a0f30..ec9644af7013 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -253,13 +253,8 @@ public class BubbleStackView extends FrameLayout
/** Layout change listener that moves the stack to the nearest valid position on rotation. */
private OnLayoutChangeListener mOrientationChangedListener;
- /** Whether the stack was on the left side of the screen prior to rotation. */
- private boolean mWasOnLeftBeforeRotation = false;
- /**
- * How far down the screen the stack was before rotation, in terms of percentage of the way down
- * the allowable region. Defaults to -1 if not set.
- */
- private float mVerticalPosPercentBeforeRotation = -1;
+
+ @Nullable private RelativeStackPosition mRelativeStackPositionBeforeRotation;
private int mMaxBubbles;
private int mBubbleSize;
@@ -940,9 +935,10 @@ public class BubbleStackView extends FrameLayout
mExpandedViewContainer.setTranslationY(getExpandedViewY());
mExpandedViewContainer.setAlpha(1f);
}
- if (mVerticalPosPercentBeforeRotation >= 0) {
- mStackAnimationController.moveStackToSimilarPositionAfterRotation(
- mWasOnLeftBeforeRotation, mVerticalPosPercentBeforeRotation);
+ if (mRelativeStackPositionBeforeRotation != null) {
+ mStackAnimationController.setStackPosition(
+ mRelativeStackPositionBeforeRotation);
+ mRelativeStackPositionBeforeRotation = null;
}
removeOnLayoutChangeListener(mOrientationChangedListener);
};
@@ -1189,13 +1185,7 @@ public class BubbleStackView extends FrameLayout
com.android.internal.R.dimen.status_bar_height);
mBubblePaddingTop = res.getDimensionPixelSize(R.dimen.bubble_padding_top);
- final RectF allowablePos = mStackAnimationController.getAllowableStackPositionRegion();
- mWasOnLeftBeforeRotation = mStackAnimationController.isStackOnLeftSide();
- mVerticalPosPercentBeforeRotation =
- (mStackAnimationController.getStackPosition().y - allowablePos.top)
- / (allowablePos.bottom - allowablePos.top);
- mVerticalPosPercentBeforeRotation =
- Math.max(0f, Math.min(1f, mVerticalPosPercentBeforeRotation));
+ mRelativeStackPositionBeforeRotation = mStackAnimationController.getRelativeStackPosition();
addOnLayoutChangeListener(mOrientationChangedListener);
hideFlyoutImmediate();
@@ -1459,7 +1449,7 @@ public class BubbleStackView extends FrameLayout
if (getBubbleCount() == 0 && mShouldShowUserEducation) {
// Override the default stack position if we're showing user education.
mStackAnimationController.setStackPosition(
- mStackAnimationController.getDefaultStartPosition());
+ mStackAnimationController.getStartPosition());
}
if (getBubbleCount() == 0) {
@@ -1674,7 +1664,7 @@ public class BubbleStackView extends FrameLayout
// Post so we have height of mUserEducationView
mUserEducationView.post(() -> {
final int viewHeight = mUserEducationView.getHeight();
- PointF stackPosition = mStackAnimationController.getDefaultStartPosition();
+ PointF stackPosition = mStackAnimationController.getStartPosition();
final float translationY = stackPosition.y + (mBubbleSize / 2) - (viewHeight / 2);
mUserEducationView.setTranslationY(translationY);
mUserEducationView.animate()
@@ -2740,10 +2730,18 @@ public class BubbleStackView extends FrameLayout
.floatValue();
}
+ public void setStackStartPosition(RelativeStackPosition position) {
+ mStackAnimationController.setStackStartPosition(position);
+ }
+
public PointF getStackPosition() {
return mStackAnimationController.getStackPosition();
}
+ public RelativeStackPosition getRelativeStackPosition() {
+ return mStackAnimationController.getRelativeStackPosition();
+ }
+
/**
* Logs the bubble UI event.
*
@@ -2797,4 +2795,47 @@ public class BubbleStackView extends FrameLayout
}
return bubbles;
}
+
+ /**
+ * Representation of stack position that uses relative properties rather than absolute
+ * coordinates. This is used to maintain similar stack positions across configuration changes.
+ */
+ public static class RelativeStackPosition {
+ /** Whether to place the stack at the leftmost allowed position. */
+ private boolean mOnLeft;
+
+ /**
+ * How far down the vertically allowed region to place the stack. For example, if the stack
+ * allowed region is between y = 100 and y = 1100 and this is 0.2f, we'll place the stack at
+ * 100 + (0.2f * 1000) = 300.
+ */
+ private float mVerticalOffsetPercent;
+
+ public RelativeStackPosition(boolean onLeft, float verticalOffsetPercent) {
+ mOnLeft = onLeft;
+ mVerticalOffsetPercent = clampVerticalOffsetPercent(verticalOffsetPercent);
+ }
+
+ /** Constructs a relative position given a region and a point in that region. */
+ public RelativeStackPosition(PointF position, RectF region) {
+ mOnLeft = position.x < region.width() / 2;
+ mVerticalOffsetPercent =
+ clampVerticalOffsetPercent((position.y - region.top) / region.height());
+ }
+
+ /** Ensures that the offset percent is between 0f and 1f. */
+ private float clampVerticalOffsetPercent(float offsetPercent) {
+ return Math.max(0f, Math.min(1f, offsetPercent));
+ }
+
+ /**
+ * Given an allowable stack position region, returns the point within that region
+ * represented by this relative position.
+ */
+ public PointF getAbsolutePositionInRegion(RectF region) {
+ return new PointF(
+ mOnLeft ? region.left : region.right,
+ region.top + mVerticalOffsetPercent * region.height());
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
index b378469c4c98..e835ea206e59 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
@@ -35,6 +35,7 @@ import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
import com.android.systemui.R;
+import com.android.systemui.bubbles.BubbleStackView;
import com.android.systemui.util.FloatingContentCoordinator;
import com.android.systemui.util.animation.PhysicsAnimator;
import com.android.systemui.util.magnetictarget.MagnetizedObject;
@@ -125,6 +126,9 @@ public class StackAnimationController extends
*/
private Rect mAnimatingToBounds = new Rect();
+ /** Initial starting location for the stack. */
+ @Nullable private BubbleStackView.RelativeStackPosition mStackStartPosition;
+
/** Whether or not the stack's start position has been set. */
private boolean mStackMovedToStartPosition = false;
@@ -431,21 +435,6 @@ public class StackAnimationController extends
return stackPos;
}
- /**
- * Moves the stack in response to rotation. We keep it in the most similar position by keeping
- * it on the same side, and positioning it the same percentage of the way down the screen
- * (taking status bar/nav bar into account by using the allowable region's height).
- */
- public void moveStackToSimilarPositionAfterRotation(boolean wasOnLeft, float verticalPercent) {
- final RectF allowablePos = getAllowableStackPositionRegion();
- final float allowableRegionHeight = allowablePos.bottom - allowablePos.top;
-
- final float x = wasOnLeft ? allowablePos.left : allowablePos.right;
- final float y = (allowableRegionHeight * verticalPercent) + allowablePos.top;
-
- setStackPosition(new PointF(x, y));
- }
-
/** Description of current animation controller state. */
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("StackAnimationController state:");
@@ -815,7 +804,7 @@ public class StackAnimationController extends
} else {
// When all children are removed ensure stack position is sane
setStackPosition(mRestingStackPosition == null
- ? getDefaultStartPosition()
+ ? getStartPosition()
: mRestingStackPosition);
// Remove the stack from the coordinator since we don't have any bubbles and aren't
@@ -868,7 +857,7 @@ public class StackAnimationController extends
mLayout.setVisibility(View.INVISIBLE);
mLayout.post(() -> {
setStackPosition(mRestingStackPosition == null
- ? getDefaultStartPosition()
+ ? getStartPosition()
: mRestingStackPosition);
mStackMovedToStartPosition = true;
mLayout.setVisibility(View.VISIBLE);
@@ -938,15 +927,47 @@ public class StackAnimationController extends
}
}
- /** Returns the default stack position, which is on the top left. */
- public PointF getDefaultStartPosition() {
- boolean isRtl = mLayout != null
- && mLayout.getResources().getConfiguration().getLayoutDirection()
- == View.LAYOUT_DIRECTION_RTL;
- return new PointF(isRtl
- ? getAllowableStackPositionRegion().right
- : getAllowableStackPositionRegion().left,
- getAllowableStackPositionRegion().top + mStackStartingVerticalOffset);
+ public void setStackPosition(BubbleStackView.RelativeStackPosition position) {
+ setStackPosition(position.getAbsolutePositionInRegion(getAllowableStackPositionRegion()));
+ }
+
+ public BubbleStackView.RelativeStackPosition getRelativeStackPosition() {
+ return new BubbleStackView.RelativeStackPosition(
+ mStackPosition, getAllowableStackPositionRegion());
+ }
+
+ /**
+ * Sets the starting position for the stack, where it will be located when the first bubble is
+ * added.
+ */
+ public void setStackStartPosition(BubbleStackView.RelativeStackPosition position) {
+ mStackStartPosition = position;
+ }
+
+ /**
+ * Returns the starting stack position. If {@link #setStackStartPosition} was called, this will
+ * return that position - otherwise, a reasonable default will be returned.
+ */
+ @Nullable public PointF getStartPosition() {
+ if (mLayout == null) {
+ return null;
+ }
+
+ if (mStackStartPosition == null) {
+ // Start on the left if we're in LTR, right otherwise.
+ final boolean startOnLeft =
+ mLayout.getResources().getConfiguration().getLayoutDirection()
+ != View.LAYOUT_DIRECTION_RTL;
+
+ final float startingVerticalOffset = mLayout.getResources().getDimensionPixelOffset(
+ R.dimen.bubble_stack_starting_offset_y);
+
+ mStackStartPosition = new BubbleStackView.RelativeStackPosition(
+ startOnLeft,
+ startingVerticalOffset / getAllowableStackPositionRegion().height());
+ }
+
+ return mStackStartPosition.getAbsolutePositionInRegion(getAllowableStackPositionRegion());
}
private boolean isStackPositionSet() {