Loading packages/SystemUI/res/values/ids.xml +6 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,12 @@ <item type="id" name="action_snooze_assistant_suggestion_1"/> <item type="id" name="action_snooze"/> <!-- Accessibility actions for bubbles. --> <item type="id" name="action_move_top_left"/> <item type="id" name="action_move_top_right"/> <item type="id" name="action_move_bottom_left"/> <item type="id" name="action_move_bottom_right"/> <!-- For StatusIconContainer to tag its icon views --> <item type="id" name="status_bar_view_state_tag" /> Loading packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +51 −13 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.WindowManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.FrameLayout; import android.widget.TextView; Loading Loading @@ -391,11 +392,34 @@ public class BubbleStackView extends FrameLayout { @Override public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfoInternal(info); info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS); // Custom actions. AccessibilityAction moveTopLeft = new AccessibilityAction(R.id.action_move_top_left, getContext().getResources() .getString(R.string.bubble_accessibility_action_move_top_left)); info.addAction(moveTopLeft); AccessibilityAction moveTopRight = new AccessibilityAction(R.id.action_move_top_right, getContext().getResources() .getString(R.string.bubble_accessibility_action_move_top_right)); info.addAction(moveTopRight); AccessibilityAction moveBottomLeft = new AccessibilityAction(R.id.action_move_bottom_left, getContext().getResources() .getString(R.string.bubble_accessibility_action_move_bottom_left)); info.addAction(moveBottomLeft); AccessibilityAction moveBottomRight = new AccessibilityAction(R.id.action_move_bottom_right, getContext().getResources() .getString(R.string.bubble_accessibility_action_move_bottom_right)); info.addAction(moveBottomRight); // Default actions. info.addAction(AccessibilityAction.ACTION_DISMISS); if (mIsExpanded) { info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE); info.addAction(AccessibilityAction.ACTION_COLLAPSE); } else { info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND); info.addAction(AccessibilityAction.ACTION_EXPAND); } } Loading @@ -404,16 +428,30 @@ public class BubbleStackView extends FrameLayout { if (super.performAccessibilityActionInternal(action, arguments)) { return true; } switch (action) { case AccessibilityNodeInfo.ACTION_DISMISS: final RectF stackBounds = mStackAnimationController.getAllowableStackPositionRegion(); // R constants are not final so we cannot use switch-case here. if (action == AccessibilityNodeInfo.ACTION_DISMISS) { mBubbleData.dismissAll(BubbleController.DISMISS_ACCESSIBILITY_ACTION); return true; case AccessibilityNodeInfo.ACTION_COLLAPSE: } else if (action == AccessibilityNodeInfo.ACTION_COLLAPSE) { mBubbleData.setExpanded(false); return true; case AccessibilityNodeInfo.ACTION_EXPAND: } else if (action == AccessibilityNodeInfo.ACTION_EXPAND) { mBubbleData.setExpanded(true); return true; } else if (action == R.id.action_move_top_left) { mStackAnimationController.springStack(stackBounds.left, stackBounds.top); return true; } else if (action == R.id.action_move_top_right) { mStackAnimationController.springStack(stackBounds.right, stackBounds.top); return true; } else if (action == R.id.action_move_bottom_left) { mStackAnimationController.springStack(stackBounds.left, stackBounds.bottom); return true; } else if (action == R.id.action_move_bottom_right) { mStackAnimationController.springStack(stackBounds.right, stackBounds.bottom); return true; } return false; } Loading packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java +26 −3 Original line number Diff line number Diff line Loading @@ -175,11 +175,33 @@ public class StackAnimationController extends /** Whether the stack is on the left side of the screen. */ public boolean isStackOnLeftSide() { if (mLayout != null) { return mStackPosition.x - mIndividualBubbleSize / 2 < mLayout.getWidth() / 2; } else { if (mLayout == null) { return false; } float stackCenter = mStackPosition.x + mIndividualBubbleSize / 2; float screenCenter = mLayout.getWidth() / 2; return stackCenter < screenCenter; } /** * Fling stack to given corner, within allowable screen bounds. * Note that we need new SpringForce instances per animation despite identical configs because * SpringAnimation uses SpringForce's internal (changing) velocity while the animation runs. */ public void springStack(float destinationX, float destinationY) { springFirstBubbleWithStackFollowing(DynamicAnimation.TRANSLATION_X, new SpringForce() .setStiffness(SPRING_AFTER_FLING_STIFFNESS) .setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO), 0 /* startXVelocity */, destinationX); springFirstBubbleWithStackFollowing(DynamicAnimation.TRANSLATION_Y, new SpringForce() .setStiffness(SPRING_AFTER_FLING_STIFFNESS) .setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO), 0 /* startYVelocity */, destinationY); } /** Loading Loading @@ -352,6 +374,7 @@ public class StackAnimationController extends float destinationY = Float.MIN_VALUE; if (imeVisible) { // Stack is lower than it should be and overlaps the now-visible IME. if (mStackPosition.y > maxBubbleY && mPreImeY == Float.MIN_VALUE) { mPreImeY = mStackPosition.y; destinationY = maxBubbleY; Loading Loading
packages/SystemUI/res/values/ids.xml +6 −0 Original line number Diff line number Diff line Loading @@ -103,6 +103,12 @@ <item type="id" name="action_snooze_assistant_suggestion_1"/> <item type="id" name="action_snooze"/> <!-- Accessibility actions for bubbles. --> <item type="id" name="action_move_top_left"/> <item type="id" name="action_move_top_right"/> <item type="id" name="action_move_bottom_left"/> <item type="id" name="action_move_bottom_right"/> <!-- For StatusIconContainer to tag its icon views --> <item type="id" name="status_bar_view_state_tag" /> Loading
packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java +51 −13 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.view.ViewTreeObserver; import android.view.WindowInsets; import android.view.WindowManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.FrameLayout; import android.widget.TextView; Loading Loading @@ -391,11 +392,34 @@ public class BubbleStackView extends FrameLayout { @Override public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfoInternal(info); info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS); // Custom actions. AccessibilityAction moveTopLeft = new AccessibilityAction(R.id.action_move_top_left, getContext().getResources() .getString(R.string.bubble_accessibility_action_move_top_left)); info.addAction(moveTopLeft); AccessibilityAction moveTopRight = new AccessibilityAction(R.id.action_move_top_right, getContext().getResources() .getString(R.string.bubble_accessibility_action_move_top_right)); info.addAction(moveTopRight); AccessibilityAction moveBottomLeft = new AccessibilityAction(R.id.action_move_bottom_left, getContext().getResources() .getString(R.string.bubble_accessibility_action_move_bottom_left)); info.addAction(moveBottomLeft); AccessibilityAction moveBottomRight = new AccessibilityAction(R.id.action_move_bottom_right, getContext().getResources() .getString(R.string.bubble_accessibility_action_move_bottom_right)); info.addAction(moveBottomRight); // Default actions. info.addAction(AccessibilityAction.ACTION_DISMISS); if (mIsExpanded) { info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE); info.addAction(AccessibilityAction.ACTION_COLLAPSE); } else { info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND); info.addAction(AccessibilityAction.ACTION_EXPAND); } } Loading @@ -404,16 +428,30 @@ public class BubbleStackView extends FrameLayout { if (super.performAccessibilityActionInternal(action, arguments)) { return true; } switch (action) { case AccessibilityNodeInfo.ACTION_DISMISS: final RectF stackBounds = mStackAnimationController.getAllowableStackPositionRegion(); // R constants are not final so we cannot use switch-case here. if (action == AccessibilityNodeInfo.ACTION_DISMISS) { mBubbleData.dismissAll(BubbleController.DISMISS_ACCESSIBILITY_ACTION); return true; case AccessibilityNodeInfo.ACTION_COLLAPSE: } else if (action == AccessibilityNodeInfo.ACTION_COLLAPSE) { mBubbleData.setExpanded(false); return true; case AccessibilityNodeInfo.ACTION_EXPAND: } else if (action == AccessibilityNodeInfo.ACTION_EXPAND) { mBubbleData.setExpanded(true); return true; } else if (action == R.id.action_move_top_left) { mStackAnimationController.springStack(stackBounds.left, stackBounds.top); return true; } else if (action == R.id.action_move_top_right) { mStackAnimationController.springStack(stackBounds.right, stackBounds.top); return true; } else if (action == R.id.action_move_bottom_left) { mStackAnimationController.springStack(stackBounds.left, stackBounds.bottom); return true; } else if (action == R.id.action_move_bottom_right) { mStackAnimationController.springStack(stackBounds.right, stackBounds.bottom); return true; } return false; } Loading
packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java +26 −3 Original line number Diff line number Diff line Loading @@ -175,11 +175,33 @@ public class StackAnimationController extends /** Whether the stack is on the left side of the screen. */ public boolean isStackOnLeftSide() { if (mLayout != null) { return mStackPosition.x - mIndividualBubbleSize / 2 < mLayout.getWidth() / 2; } else { if (mLayout == null) { return false; } float stackCenter = mStackPosition.x + mIndividualBubbleSize / 2; float screenCenter = mLayout.getWidth() / 2; return stackCenter < screenCenter; } /** * Fling stack to given corner, within allowable screen bounds. * Note that we need new SpringForce instances per animation despite identical configs because * SpringAnimation uses SpringForce's internal (changing) velocity while the animation runs. */ public void springStack(float destinationX, float destinationY) { springFirstBubbleWithStackFollowing(DynamicAnimation.TRANSLATION_X, new SpringForce() .setStiffness(SPRING_AFTER_FLING_STIFFNESS) .setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO), 0 /* startXVelocity */, destinationX); springFirstBubbleWithStackFollowing(DynamicAnimation.TRANSLATION_Y, new SpringForce() .setStiffness(SPRING_AFTER_FLING_STIFFNESS) .setDampingRatio(SPRING_AFTER_FLING_DAMPING_RATIO), 0 /* startYVelocity */, destinationY); } /** Loading Loading @@ -352,6 +374,7 @@ public class StackAnimationController extends float destinationY = Float.MIN_VALUE; if (imeVisible) { // Stack is lower than it should be and overlaps the now-visible IME. if (mStackPosition.y > maxBubbleY && mPreImeY == Float.MIN_VALUE) { mPreImeY = mStackPosition.y; destinationY = maxBubbleY; Loading