Merge "Update comments on createAdjacentPageAnimForTaskLaunch" into main
diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig
index aafa1f6..fca1647 100644
--- a/aconfig/launcher.aconfig
+++ b/aconfig/launcher.aconfig
@@ -471,3 +471,17 @@
description: "Shows filtered set of widgets by default and an option to show all widgets in the widget picker"
bug: "356127021"
}
+
+flag {
+ name: "show_taskbar_pinning_popup_from_anywhere"
+ namespace: "launcher"
+ description: "Shows the pinning popup view after long-pressing or right-clicking anywhere on the pinned taskbar"
+ bug: "297325541"
+}
+
+flag {
+ name: "enable_launcher_overview_in_window"
+ namespace: "launcher"
+ description: "Enables launcher recents opening inside of a window instead of being hosted in launcher activity."
+ bug: "292269949"
+}
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 8957e0d..9836172 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -424,6 +424,7 @@
<!--- Taskbar Pinning -->
<dimen name="taskbar_pinning_popup_menu_width">300dp</dimen>
<dimen name="taskbar_pinning_popup_menu_vertical_margin">16dp</dimen>
+ <dimen name="taskbar_pinning_popup_menu_min_padding_from_screen_edge">16dp</dimen>
<!--- Floating Ime Inset height-->
<dimen name="floating_ime_inset_height">60dp</dimen>
diff --git a/quickstep/res/values/ids.xml b/quickstep/res/values/ids.xml
index 3091d9e..c71bb76 100644
--- a/quickstep/res/values/ids.xml
+++ b/quickstep/res/values/ids.xml
@@ -19,4 +19,6 @@
<item type="id" name="action_move_left" />
<item type="id" name="action_move_right" />
<item type="id" name="action_dismiss_all" />
+
+ <item type="id" name="bubble_bar_flyout_view" />
</resources>
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 12be99d..f3741b2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -1704,7 +1704,7 @@
duration);
View allAppsButton = mControllers.taskbarViewController.getAllAppsButtonView();
- if (allAppsButton != null && !FeatureFlags.enableAllAppsButtonInHotseat()) {
+ if (!FeatureFlags.enableAllAppsButtonInHotseat()) {
ValueAnimator alphaOverride = ValueAnimator.ofFloat(0, 1);
alphaOverride.setDuration(duration);
alphaOverride.addUpdateListener(a -> {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
index b5a3314..69bc6bd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
@@ -31,21 +31,21 @@
import android.widget.Switch
import androidx.core.view.postDelayed
import com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE
+import com.android.launcher3.Flags
import com.android.launcher3.R
import com.android.launcher3.popup.ArrowPopup
import com.android.launcher3.popup.RoundedArrowDrawable
import com.android.launcher3.util.DisplayController
import com.android.launcher3.util.Themes
import com.android.launcher3.views.ActivityContext
+import kotlin.math.max
+import kotlin.math.min
/** Popup view with arrow for taskbar pinning */
class TaskbarDividerPopupView<T : TaskbarActivityContext>
@JvmOverloads
-constructor(
- context: Context,
- attrs: AttributeSet? = null,
- defStyleAttr: Int = 0,
-) : ArrowPopup<T>(context, attrs, defStyleAttr) {
+constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
+ ArrowPopup<T>(context, attrs, defStyleAttr) {
companion object {
private const val TAG = "TaskbarDividerPopupView"
private const val DIVIDER_POPUP_CLOSING_DELAY = 333L
@@ -55,24 +55,28 @@
fun createAndPopulate(
view: View,
taskbarActivityContext: TaskbarActivityContext,
+ horizontalPosition: Float,
): TaskbarDividerPopupView<*> {
val taskMenuViewWithArrow =
taskbarActivityContext.layoutInflater.inflate(
R.layout.taskbar_divider_popup_menu,
taskbarActivityContext.dragLayer,
- false
+ false,
) as TaskbarDividerPopupView<*>
- return taskMenuViewWithArrow.populateForView(view)
+ return taskMenuViewWithArrow.populateForView(view, horizontalPosition)
}
}
private lateinit var dividerView: View
+ private var horizontalPosition = 0.0f
private val popupCornerRadius = Themes.getDialogCornerRadius(context)
private val arrowWidth = resources.getDimension(R.dimen.popup_arrow_width)
private val arrowHeight = resources.getDimension(R.dimen.popup_arrow_height)
private val arrowPointRadius = resources.getDimension(R.dimen.popup_arrow_corner_radius)
+ private val minPaddingFromScreenEdge =
+ resources.getDimension(R.dimen.taskbar_pinning_popup_menu_min_padding_from_screen_edge)
private var alwaysShowTaskbarOn = !DisplayController.isTransientTaskbar(context)
private var didPreferenceChange = false
@@ -128,7 +132,15 @@
/** Orient object as usual and then center object horizontally. */
override fun orientAboutObject() {
super.orientAboutObject()
- x = mTempRect.centerX() - measuredWidth / 2f
+ x =
+ if (Flags.showTaskbarPinningPopupFromAnywhere()) {
+ min(
+ max(minPaddingFromScreenEdge, horizontalPosition - measuredWidth / 2f),
+ popupContainer.getWidth() - measuredWidth - minPaddingFromScreenEdge,
+ )
+ } else {
+ mTempRect.centerX() - measuredWidth / 2f
+ }
}
override fun onControllerInterceptTouchEvent(ev: MotionEvent?): Boolean {
@@ -142,8 +154,9 @@
return false
}
- private fun populateForView(view: View): TaskbarDividerPopupView<*> {
+ private fun populateForView(view: View, horizontalPosition: Float): TaskbarDividerPopupView<*> {
dividerView = view
+ this@TaskbarDividerPopupView.horizontalPosition = horizontalPosition
tryUpdateBackground()
return this
}
@@ -169,15 +182,21 @@
override fun addArrow() {
super.addArrow()
- val location = IntArray(2)
- popupContainer.getLocationInDragLayer(dividerView, location)
- val dividerViewX = location[0].toFloat()
- // Change arrow location to the middle of popup.
- mArrow.x = (dividerViewX + dividerView.width / 2) - (mArrowWidth / 2)
+ if (Flags.showTaskbarPinningPopupFromAnywhere()) {
+ mArrow.x = horizontalPosition - mArrowWidth / 2
+ } else {
+ val location = IntArray(2)
+ popupContainer.getLocationInDragLayer(dividerView, location)
+ val dividerViewX = location[0].toFloat()
+ // Change arrow location to the middle of popup.
+ mArrow.x = (dividerViewX + dividerView.width / 2) - (mArrowWidth / 2)
+ }
}
override fun updateArrowColor() {
- if (!Gravity.isVertical(mGravity)) {
+ if (Flags.showTaskbarPinningPopupFromAnywhere()) {
+ super.updateArrowColor()
+ } else if (!Gravity.isVertical(mGravity)) {
mArrow.background =
RoundedArrowDrawable(
arrowWidth,
@@ -227,13 +246,13 @@
ObjectAnimator.ofFloat(
this,
TRANSLATION_Y,
- *floatArrayOf(this.translationY, this.translationY + translateYValue)
+ *floatArrayOf(this.translationY, this.translationY + translateYValue),
)
val arrowTranslateY =
ObjectAnimator.ofFloat(
mArrow,
TRANSLATION_Y,
- *floatArrayOf(mArrow.translationY, mArrow.translationY + translateYValue)
+ *floatArrayOf(mArrow.translationY, mArrow.translationY + translateYValue),
)
val animatorSet = AnimatorSet()
animatorSet.playTogether(alpha, arrowAlpha, translateY, arrowTranslateY)
@@ -243,7 +262,7 @@
private fun getAnimatorOfFloat(
view: View,
property: Property<View, Float>,
- vararg values: Float
+ vararg values: Float,
): Animator {
val animator: Animator = ObjectAnimator.ofFloat(view, property, *values)
animator.setDuration(DIVIDER_POPUP_CLOSING_ANIMATION_DURATION)
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt
index 1867cd0..7848b7e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPinningController.kt
@@ -76,10 +76,10 @@
}
}
- fun showPinningView(view: View) {
+ fun showPinningView(view: View, horizontalPosition: Float = -1f) {
context.isTaskbarWindowFullscreen = true
view.post {
- val popupView = getPopupView(view)
+ val popupView = getPopupView(view, horizontalPosition)
popupView.requestFocus()
popupView.onCloseCallback = onCloseCallback
context.onPopupVisibilityChanged(true)
@@ -89,8 +89,8 @@
}
@VisibleForTesting
- fun getPopupView(view: View): TaskbarDividerPopupView<*> {
- return createAndPopulate(view, context)
+ fun getPopupView(view: View, horizontalPosition: Float = -1f): TaskbarDividerPopupView<*> {
+ return createAndPopulate(view, context, horizontalPosition)
}
@VisibleForTesting
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index d757180..c0891a9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -100,7 +100,7 @@
@Nullable private FolderIcon mLeaveBehindFolderIcon;
// Only non-null when device supports having an All Apps button.
- @Nullable private final TaskbarAllAppsButtonContainer mAllAppsButtonContainer;
+ private final TaskbarAllAppsButtonContainer mAllAppsButtonContainer;
// Only non-null when device supports having a Divider button.
@Nullable private TaskbarDividerContainer mTaskbarDividerContainer;
@@ -217,16 +217,14 @@
// All apps icon takes less space compared to normal icon size, reserve space for the icon
// separately.
- if (mAllAppsButtonContainer != null) {
- boolean forceTransientTaskbarSize =
- enableTaskbarPinning() && !mActivityContext.isThreeButtonNav();
- availableWidth -= iconSize - (int) getResources().getDimension(
- mAllAppsButtonContainer.getAllAppsButtonTranslationXOffset(
- forceTransientTaskbarSize || (
- DisplayController.isTransientTaskbar(mActivityContext)
- && !mActivityContext.isPhoneMode())));
- ++additionalIcons;
- }
+ boolean forceTransientTaskbarSize =
+ enableTaskbarPinning() && !mActivityContext.isThreeButtonNav();
+ availableWidth -= iconSize - (int) getResources().getDimension(
+ mAllAppsButtonContainer.getAllAppsButtonTranslationXOffset(
+ forceTransientTaskbarSize || (
+ DisplayController.isTransientTaskbar(mActivityContext)
+ && !mActivityContext.isPhoneMode())));
+ ++additionalIcons;
return Math.floorDiv(availableWidth, iconSize) + additionalIcons;
}
@@ -313,10 +311,9 @@
mIconClickListener = mControllerCallbacks.getIconOnClickListener();
mIconLongClickListener = mControllerCallbacks.getIconOnLongClickListener();
- if (mAllAppsButtonContainer != null) {
- mAllAppsButtonContainer.setUpCallbacks(callbacks);
- }
- if (mTaskbarDividerContainer != null && callbacks.supportsDividerLongPress()) {
+ mAllAppsButtonContainer.setUpCallbacks(callbacks);
+ if (mTaskbarDividerContainer != null
+ && mActivityContext.getTaskbarFeatureEvaluator().getSupportsPinningPopup()) {
mTaskbarDividerContainer.setUpCallbacks(callbacks);
}
if (mTaskbarOverflowView != null) {
@@ -325,6 +322,10 @@
mTaskbarOverflowView.setOnLongClickListener(
mControllerCallbacks.getOverflowOnLongClickListener());
}
+ if (Flags.showTaskbarPinningPopupFromAnywhere()
+ && mActivityContext.getTaskbarFeatureEvaluator().getSupportsPinningPopup()) {
+ setOnTouchListener(mControllerCallbacks.getTaskbarTouchListener());
+ }
}
private void removeAndRecycle(View view) {
@@ -345,12 +346,10 @@
int numViewsAnimated = 0;
mAddedDividerForRecents = false;
- if (mAllAppsButtonContainer != null) {
- removeView(mAllAppsButtonContainer);
+ removeView(mAllAppsButtonContainer);
- if (mTaskbarDividerContainer != null) {
- removeView(mTaskbarDividerContainer);
- }
+ if (mTaskbarDividerContainer != null) {
+ removeView(mTaskbarDividerContainer);
}
if (mTaskbarOverflowView != null) {
removeView(mTaskbarOverflowView);
@@ -527,17 +526,16 @@
removeAndRecycle(getChildAt(nextViewIndex));
}
- if (mAllAppsButtonContainer != null) {
- addView(mAllAppsButtonContainer, mIsRtl ? hotseatItemInfos.length : 0);
+ addView(mAllAppsButtonContainer, mIsRtl ? hotseatItemInfos.length : 0);
- // If there are no recent tasks, add divider after All Apps (unless it's the only view).
- if (!mAddedDividerForRecents
- && mTaskbarDividerContainer != null
- && getChildCount() > 1) {
- addView(mTaskbarDividerContainer, mIsRtl ? (getChildCount() - 1) : 1);
- }
+ // If there are no recent tasks, add divider after All Apps (unless it's the only view).
+ if (!mAddedDividerForRecents
+ && mTaskbarDividerContainer != null
+ && getChildCount() > 1) {
+ addView(mTaskbarDividerContainer, mIsRtl ? (getChildCount() - 1) : 1);
}
+
if (mActivityContext.getDeviceProfile().isQsbInline) {
addView(mQsb, mIsRtl ? getChildCount() : 0);
// Always set QSB to invisible after re-adding.
@@ -774,7 +772,6 @@
/**
* Returns the all apps button in the taskbar.
*/
- @Nullable
public TaskbarAllAppsButtonContainer getAllAppsButtonContainer() {
return mAllAppsButtonContainer;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
index 8bc1e12..4591f9b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
@@ -19,15 +19,19 @@
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_LONG_PRESS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP;
+import android.annotation.SuppressLint;
import android.content.Context;
+import android.view.GestureDetector;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.View;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.internal.jank.Cuj;
import com.android.launcher3.taskbar.bubbles.BubbleBarViewController;
+import com.android.launcher3.util.DisplayController;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.wm.shell.Flags;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
@@ -40,12 +44,14 @@
private final TaskbarActivityContext mActivity;
private final TaskbarControllers mControllers;
private final TaskbarView mTaskbarView;
+ private final GestureDetector mGestureDetector;
public TaskbarViewCallbacks(TaskbarActivityContext activity, TaskbarControllers controllers,
TaskbarView taskbarView) {
mActivity = activity;
mControllers = controllers;
mTaskbarView = taskbarView;
+ mGestureDetector = new GestureDetector(activity, new TaskbarViewGestureListener());
}
public View.OnClickListener getIconOnClickListener() {
@@ -70,23 +76,23 @@
return false;
}
- public View.OnLongClickListener getTaskbarDividerLongClickListener() {
- return v -> {
- mControllers.taskbarPinningController.showPinningView(v);
- return true;
- };
+ @SuppressLint("ClickableViewAccessibility")
+ public View.OnTouchListener getTaskbarTouchListener() {
+ return (view, event) -> mGestureDetector.onTouchEvent(event);
}
- /** Check to see if we support long press on taskbar divider */
- public boolean supportsDividerLongPress() {
- return !mActivity.isThreeButtonNav();
+ public View.OnLongClickListener getTaskbarDividerLongClickListener() {
+ return v -> {
+ mControllers.taskbarPinningController.showPinningView(v, getDividerCenterX());
+ return true;
+ };
}
public View.OnTouchListener getTaskbarDividerRightClickListener() {
return (v, event) -> {
if (event.isFromSource(InputDevice.SOURCE_MOUSE)
&& event.getButtonState() == MotionEvent.BUTTON_SECONDARY) {
- mControllers.taskbarPinningController.showPinningView(v);
+ mControllers.taskbarPinningController.showPinningView(v, getDividerCenterX());
return true;
}
return false;
@@ -159,4 +165,32 @@
}
};
}
+
+ private float getDividerCenterX() {
+ View divider = mTaskbarView.getTaskbarDividerViewContainer();
+ if (divider == null) {
+ return 0.0f;
+ }
+ return divider.getX() + (float) divider.getWidth() / 2;
+ }
+
+ private class TaskbarViewGestureListener extends GestureDetector.SimpleOnGestureListener {
+ @Override
+ public boolean onDown(@NonNull MotionEvent event) {
+ return true;
+ }
+
+ @Override
+ public boolean onSingleTapUp(@NonNull MotionEvent event) {
+ return true;
+ }
+
+ @Override
+ public void onLongPress(MotionEvent event) {
+ if (DisplayController.isPinnedTaskbar(mActivity)) {
+ mControllers.taskbarPinningController.showPinningView(mTaskbarView,
+ event.getRawX());
+ }
+ }
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index e9458ff..253d025 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -367,7 +367,6 @@
return mTaskbarView.getIconViews();
}
- @Nullable
public View getAllAppsButtonView() {
return mTaskbarView.getAllAppsButtonContainer();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index 51e09ab..b22fd6f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -377,8 +377,6 @@
// Updates mean the dot state may have changed; any other changes were updated in
// the populateBubble step.
BubbleBarBubble bb = mBubbles.get(update.updatedBubble.getKey());
- // If we're not stashed, we're visible so animate
- bb.getView().updateDotVisibility(!mBubbleStashController.isStashed() /* animate */);
mBubbleBarViewController.animateBubbleNotification(
bb, /* isExpanding= */ false, /* isUpdate= */ true);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index 63f101f..76d3606 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -148,7 +148,8 @@
mBubbleBarFlyoutController = new BubbleBarFlyoutController(
mBubbleBarContainer, createFlyoutPositioner(), createFlyoutTopBoundaryListener());
mBubbleBarViewAnimator = new BubbleBarViewAnimator(
- mBarView, mBubbleStashController, mBubbleBarController::showExpandedView);
+ mBarView, mBubbleStashController, mBubbleBarFlyoutController,
+ mBubbleBarController::showExpandedView);
mTaskbarViewPropertiesProvider = taskbarViewPropertiesProvider;
onBubbleBarConfigurationChanged(/* animate= */ false);
mActivity.addOnDeviceProfileChangeListener(
@@ -781,6 +782,11 @@
/** Animates the bubble bar to notify the user about a bubble change. */
public void animateBubbleNotification(BubbleBarBubble bubble, boolean isExpanding,
boolean isUpdate) {
+ // if we're expanded, don't animate the bubble bar. just show the notification dot.
+ if (isExpanded()) {
+ bubble.getView().updateDotVisibility(/* animate= */ true);
+ return;
+ }
boolean isInApp = mTaskbarStashController.isInApp();
// if this is the first bubble, animate to the initial state.
if (mBarView.getBubbleChildCount() == 1 && !isUpdate) {
@@ -789,13 +795,12 @@
}
boolean persistentTaskbarOrOnHome = mBubbleStashController.isBubblesShowingOnHome()
|| !mBubbleStashController.isTransientTaskBar();
- if (persistentTaskbarOrOnHome && !isExpanded()) {
+ if (persistentTaskbarOrOnHome) {
mBubbleBarViewAnimator.animateBubbleBarForCollapsed(bubble, isExpanding);
return;
}
- // only animate the new bubble if we're in an app, have handle view and not auto expanding
- if (isInApp && mBubbleStashController.getHasHandleView() && !isExpanded()) {
+ if (isInApp && mBubbleStashController.getHasHandleView()) {
mBubbleBarViewAnimator.animateBubbleInForStashed(bubble, isExpanding);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
index 707655c..4f3e1ae 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
@@ -301,7 +301,7 @@
void updateDotVisibility(boolean animate) {
if (mDotSuppressedForBubbleUpdate) {
- // if the dot is suppressed for
+ // if the dot is suppressed for an update, there's nothing to do
return;
}
final float targetScale = hasUnseenContent() ? 1f : 0f;
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
index 6a955d9..8a52ca9 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
@@ -27,6 +27,8 @@
import com.android.launcher3.taskbar.bubbles.BubbleBarBubble
import com.android.launcher3.taskbar.bubbles.BubbleBarView
import com.android.launcher3.taskbar.bubbles.BubbleView
+import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutController
+import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutMessage
import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController
import com.android.wm.shell.shared.animation.PhysicsAnimator
@@ -36,8 +38,9 @@
constructor(
private val bubbleBarView: BubbleBarView,
private val bubbleStashController: BubbleStashController,
+ private val bubbleBarFlyoutController: BubbleBarFlyoutController,
private val onExpanded: Runnable,
- private val scheduler: Scheduler = HandlerScheduler(bubbleBarView)
+ private val scheduler: Scheduler = HandlerScheduler(bubbleBarView),
) {
private var animatingBubble: AnimatingBubble? = null
@@ -54,7 +57,7 @@
private companion object {
/** The time to show the flyout. */
- const val FLYOUT_DELAY_MS: Long = 2500
+ const val FLYOUT_DELAY_MS: Long = 3000
/** The initial scale Y value that the new bubble is set to before the animation starts. */
const val BUBBLE_ANIMATION_INITIAL_SCALE_Y = 0.3f
/** The minimum alpha value to make the bubble bar touchable. */
@@ -69,7 +72,7 @@
val showAnimation: Runnable,
val hideAnimation: Runnable,
val expand: Boolean,
- val state: State = State.CREATED
+ val state: State = State.CREATED,
) {
/**
@@ -91,7 +94,7 @@
/** The bubble notification is now fully showing and waiting to be hidden. */
IN,
/** The bubble notification is animating out. */
- ANIMATING_OUT
+ ANIMATING_OUT,
}
}
@@ -127,7 +130,7 @@
private val springConfig =
PhysicsAnimator.SpringConfig(
stiffness = SpringForce.STIFFNESS_LOW,
- dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY
+ dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY,
)
/** Animates a bubble for the state where the bubble bar is stashed. */
@@ -137,8 +140,9 @@
val bubbleView = b.view
val animator = PhysicsAnimator.getInstance(bubbleView)
if (animator.isRunning()) animator.cancel()
- // the animation of a new bubble is divided into 2 parts. The first part shows the bubble
- // and the second part hides it after a delay.
+ // the animation of a new bubble is divided into 2 parts. The first part transforms the
+ // handle to the bubble bar and then shows the flyout. The second part hides the flyout and
+ // transforms the bubble bar back to the handle.
val showAnimation = buildHandleToBubbleBarAnimation()
val hideAnimation = if (isExpanding) Runnable {} else buildBubbleBarToHandleAnimation()
animatingBubble =
@@ -243,7 +247,8 @@
cancelHideAnimation()
return@addEndListener
}
- moveToState(AnimatingBubble.State.IN)
+ setupAndShowFlyout()
+
// the bubble bar is now fully settled in. update taskbar touch region so it's touchable
bubbleStashController.updateTaskbarTouchRegion()
}
@@ -316,7 +321,17 @@
bubbleBarView.scaleY = 1f
bubbleStashController.updateTaskbarTouchRegion()
}
- animator.start()
+
+ val bubble = animatingBubble?.bubbleView?.bubble as? BubbleBarBubble
+ val flyout = bubble?.flyoutMessage
+ if (flyout != null) {
+ bubbleBarFlyoutController.collapseFlyout {
+ onFlyoutRemoved(bubble.view)
+ animator.start()
+ }
+ } else {
+ animator.start()
+ }
}
/** Animates to the initial state of the bubble bar, when there are no previous bubbles. */
@@ -326,16 +341,16 @@
val bubbleView = b.view
val animator = PhysicsAnimator.getInstance(bubbleView)
if (animator.isRunning()) animator.cancel()
- // the animation of a new bubble is divided into 2 parts. The first part shows the bubble
- // and the second part hides it after a delay if we are in an app.
+ // the animation of a new bubble is divided into 2 parts. The first part slides in the
+ // bubble bar and shows the flyout. The second part hides the flyout and transforms the
+ // bubble bar to the handle if we're in an app.
val showAnimation = buildBubbleBarSpringInAnimation()
val hideAnimation =
if (isInApp && !isExpanding) {
buildBubbleBarToHandleAnimation()
} else {
- // in this case the bubble bar remains visible so not much to do. once we implement
- // the flyout we'll update this runnable to hide it.
Runnable {
+ bubbleBarFlyoutController.collapseFlyout { onFlyoutRemoved(bubbleView) }
animatingBubble = null
bubbleStashController.showBubbleBarImmediate()
bubbleStashController.updateTaskbarTouchRegion()
@@ -370,7 +385,7 @@
if (animatingBubble?.expand == true) {
cancelHideAnimation()
} else {
- moveToState(AnimatingBubble.State.IN)
+ setupAndShowFlyout()
}
// the bubble bar is now fully settled in. update taskbar touch region so it's touchable
bubbleStashController.updateTaskbarTouchRegion()
@@ -384,8 +399,10 @@
val bubbleView = b.view
val animator = PhysicsAnimator.getInstance(bubbleView)
if (animator.isRunning()) animator.cancel()
+ // first bounce the bubble bar and show the flyout. Then hide the flyout.
val showAnimation = buildBubbleBarBounceAnimation()
val hideAnimation = Runnable {
+ bubbleBarFlyoutController.collapseFlyout { onFlyoutRemoved(bubbleView) }
animatingBubble = null
bubbleStashController.showBubbleBarImmediate()
bubbleStashController.updateTaskbarTouchRegion()
@@ -413,7 +430,7 @@
expandBubbleBar()
cancelHideAnimation()
} else {
- moveToState(AnimatingBubble.State.IN)
+ setupAndShowFlyout()
}
}
@@ -427,10 +444,38 @@
.start()
}
+ private fun setupAndShowFlyout() {
+ val bubbleView = animatingBubble?.bubbleView
+ val bubble = bubbleView?.bubble as? BubbleBarBubble
+ val flyout = bubble?.flyoutMessage
+ if (flyout != null) {
+ bubbleView.suppressDotForBubbleUpdate(true)
+ bubbleBarFlyoutController.setUpAndShowFlyout(
+ BubbleBarFlyoutMessage(flyout.icon, flyout.title, flyout.message)
+ ) {
+ moveToState(AnimatingBubble.State.IN)
+ bubbleStashController.updateTaskbarTouchRegion()
+ }
+ } else {
+ moveToState(AnimatingBubble.State.IN)
+ }
+ }
+
+ private fun cancelFlyout() {
+ val bubbleView = animatingBubble?.bubbleView
+ bubbleBarFlyoutController.cancelFlyout { onFlyoutRemoved(bubbleView) }
+ }
+
+ private fun onFlyoutRemoved(bubbleView: BubbleView?) {
+ bubbleView?.suppressDotForBubbleUpdate(false)
+ bubbleStashController.updateTaskbarTouchRegion()
+ }
+
/** Handles touching the animating bubble bar. */
fun onBubbleBarTouchedWhileAnimating() {
PhysicsAnimator.getInstance(bubbleBarView).cancelIfRunning()
bubbleStashController.getStashedHandlePhysicsAnimator().cancelIfRunning()
+ cancelFlyout()
val hideAnimation = animatingBubble?.hideAnimation ?: return
scheduler.cancel(hideAnimation)
bubbleBarView.relativePivotY = 1f
@@ -439,6 +484,7 @@
/** Notifies the animator that the taskbar area was touched during an animation. */
fun onStashStateChangingWhileAnimating() {
+ cancelFlyout()
val hideAnimation = animatingBubble?.hideAnimation ?: return
scheduler.cancel(hideAnimation)
animatingBubble = null
@@ -446,7 +492,7 @@
bubbleBarView.relativePivotY = 1f
bubbleStashController.onNewBubbleAnimationInterrupted(
/* isStashed= */ bubbleBarView.alpha == 0f,
- bubbleBarView.translationY
+ bubbleBarView.translationY,
)
}
@@ -455,6 +501,7 @@
this.animatingBubble = animatingBubble.copy(expand = true)
// if we're fully in and waiting to hide, cancel the hide animation and clean up
if (animatingBubble.state == AnimatingBubble.State.IN) {
+ cancelFlyout()
expandBubbleBar()
cancelHideAnimation()
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt
index c431deb..d6400bb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt
@@ -21,8 +21,8 @@
import android.widget.FrameLayout
import androidx.core.animation.ValueAnimator
import com.android.launcher3.R
+import com.android.systemui.util.addListener
import com.android.systemui.util.doOnEnd
-import com.android.systemui.util.doOnStart
/** Creates and manages the visibility of the [BubbleBarFlyoutView]. */
class BubbleBarFlyoutController
@@ -35,14 +35,19 @@
) {
private companion object {
- const val EXPAND_COLLAPSE_ANIMATION_DURATION_MS = 250L
+ const val ANIMATION_DURATION_MS = 250L
}
private var flyout: BubbleBarFlyoutView? = null
private val horizontalMargin =
container.context.resources.getDimensionPixelSize(R.dimen.transient_taskbar_bottom_margin)
- fun setUpFlyout(message: BubbleBarFlyoutMessage) {
+ private enum class AnimationType {
+ COLLAPSE,
+ FADE,
+ }
+
+ fun setUpAndShowFlyout(message: BubbleBarFlyoutMessage, onEnd: () -> Unit) {
flyout?.let(container::removeView)
val flyout = BubbleBarFlyoutView(container.context, positioner, flyoutScheduler)
@@ -58,27 +63,42 @@
lp.marginEnd = horizontalMargin
container.addView(flyout, lp)
- val animator =
- ValueAnimator.ofFloat(0f, 1f).setDuration(EXPAND_COLLAPSE_ANIMATION_DURATION_MS)
+ val animator = ValueAnimator.ofFloat(0f, 1f).setDuration(ANIMATION_DURATION_MS)
animator.addUpdateListener { _ ->
flyout.updateExpansionProgress(animator.animatedValue as Float)
}
- animator.doOnStart {
- val flyoutTop = flyout.top + flyout.translationY
- // If the top position of the flyout is negative, then it's bleeding over the
- // top boundary of its parent view
- if (flyoutTop < 0) topBoundaryListener.extendTopBoundary(space = -flyoutTop.toInt())
- }
+ animator.addListener(
+ onStart = {
+ val flyoutTop = flyout.top + flyout.translationY
+ // If the top position of the flyout is negative, then it's bleeding over the
+ // top boundary of its parent view
+ if (flyoutTop < 0) topBoundaryListener.extendTopBoundary(space = -flyoutTop.toInt())
+ },
+ onEnd = { onEnd() },
+ )
flyout.showFromCollapsed(message) { animator.start() }
this.flyout = flyout
}
- fun hideFlyout(endAction: () -> Unit) {
+ fun cancelFlyout(endAction: () -> Unit) {
+ hideFlyout(AnimationType.FADE, endAction)
+ }
+
+ fun collapseFlyout(endAction: () -> Unit) {
+ hideFlyout(AnimationType.COLLAPSE, endAction)
+ }
+
+ private fun hideFlyout(animationType: AnimationType, endAction: () -> Unit) {
+ // TODO: b/277815200 - stop the current animation if it's running
val flyout = this.flyout ?: return
- val animator =
- ValueAnimator.ofFloat(1f, 0f).setDuration(EXPAND_COLLAPSE_ANIMATION_DURATION_MS)
- animator.addUpdateListener { _ ->
- flyout.updateExpansionProgress(animator.animatedValue as Float)
+ val animator = ValueAnimator.ofFloat(1f, 0f).setDuration(ANIMATION_DURATION_MS)
+ when (animationType) {
+ AnimationType.FADE ->
+ animator.addUpdateListener { _ -> flyout.alpha = animator.animatedValue as Float }
+ AnimationType.COLLAPSE ->
+ animator.addUpdateListener { _ ->
+ flyout.updateExpansionProgress(animator.animatedValue as Float)
+ }
}
animator.doOnEnd {
container.removeView(flyout)
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutView.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutView.kt
index c60fba2..6903c87 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutView.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutView.kt
@@ -140,6 +140,7 @@
init {
LayoutInflater.from(context).inflate(R.layout.bubblebar_flyout, this, true)
+ id = R.id.bubble_bar_flyout_view
val ta = context.obtainStyledAttributes(intArrayOf(android.R.attr.dialogCornerRadius))
cornerRadius = ta.getDimensionPixelSize(0, 0).toFloat()
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
index 7739a0e..f130d29 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
@@ -23,9 +23,7 @@
/** Evaluates all the features taskbar can have. */
class TaskbarFeatureEvaluator
-private constructor(
- private val taskbarActivityContext: TaskbarActivityContext,
-) {
+private constructor(private val taskbarActivityContext: TaskbarActivityContext) {
val hasAllApps = true
val hasAppIcons = true
val hasBubbles = false
@@ -43,6 +41,9 @@
val isLandscape: Boolean
get() = taskbarActivityContext.deviceProfile.isLandscape
+ val supportsPinningPopup: Boolean
+ get() = !hasNavButtons
+
fun onDestroy() {
taskbarFeatureEvaluator = null
}
@@ -51,9 +52,7 @@
@Volatile private var taskbarFeatureEvaluator: TaskbarFeatureEvaluator? = null
@JvmStatic
- fun getInstance(
- taskbarActivityContext: TaskbarActivityContext,
- ): TaskbarFeatureEvaluator {
+ fun getInstance(taskbarActivityContext: TaskbarActivityContext): TaskbarFeatureEvaluator {
synchronized(this) {
if (taskbarFeatureEvaluator == null) {
taskbarFeatureEvaluator = TaskbarFeatureEvaluator(taskbarActivityContext)
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 41a8a31..1481ef2 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -607,6 +607,9 @@
this::createFallbackSwipeHandler;
private final AbsSwipeUpHandler.Factory mRecentsWindowSwipeHandlerFactory =
this::createRecentsWindowSwipeHandler;
+ // This needs to be a member to be queued and potentially removed later if the service is
+ // destroyed before the user is unlocked
+ private final Runnable mUserUnlockedRunnable = this::onUserUnlocked;
private final ScreenOnTracker.ScreenOnListener mScreenOnListener = this::onScreenOnChanged;
@@ -678,8 +681,7 @@
mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
// Call runOnUserUnlocked() before any other callbacks to ensure everything is initialized.
- LockedUserState.get(this).runOnUserUnlocked(this::onUserUnlocked);
- LockedUserState.get(this).runOnUserUnlocked(mTaskbarManager::onUserUnlocked);
+ LockedUserState.get(this).runOnUserUnlocked(mUserUnlockedRunnable);
mDeviceState.addNavigationModeChangedCallback(this::onNavigationModeChanged);
sConnected = true;
@@ -746,6 +748,8 @@
mOverviewComponentObserver.setOverviewChangeListener(this::onOverviewTargetChange);
onOverviewTargetChange(mOverviewComponentObserver.isHomeAndOverviewSame());
+
+ mTaskbarManager.onUserUnlocked();
}
public OverviewCommandHelper getOverviewCommandHelper() {
@@ -836,6 +840,7 @@
mDesktopVisibilityController.onDestroy();
sConnected = false;
+ LockedUserState.get(this).removeOnUserUnlockedRunnable(mUserUnlockedRunnable);
ScreenOnTracker.INSTANCE.get(this).removeListener(mScreenOnListener);
super.onDestroy();
}
diff --git a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java
index 34b3d74..4f9d837 100644
--- a/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/fallback/window/RecentsWindowSwipeHandler.java
@@ -27,7 +27,6 @@
import static com.android.launcher3.GestureNavContract.EXTRA_REMOTE_CALLBACK;
import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
-import android.animation.ObjectAnimator;
import android.app.ActivityManager.RunningTaskInfo;
import android.content.Context;
import android.content.Intent;
@@ -62,16 +61,15 @@
import com.android.launcher3.util.DisplayController;
import com.android.quickstep.AbsSwipeUpHandler;
import com.android.quickstep.GestureState;
+import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.RecentsAnimationDeviceState;
-import com.android.quickstep.RemoteAnimationTargets;
+import com.android.quickstep.RecentsAnimationTargets;
import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.fallback.FallbackRecentsView;
import com.android.quickstep.fallback.RecentsState;
-import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.RectFSpringAnim;
import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
import com.android.quickstep.util.TransformParams;
-import com.android.quickstep.util.TransformParams.BuilderProxy;
import com.android.quickstep.views.TaskView;
import com.android.systemui.shared.recents.model.Task.TaskKey;
import com.android.systemui.shared.system.InputConsumerController;
@@ -115,12 +113,25 @@
mRunningOverHome = mGestureState.getRunningTask() != null
&& mGestureState.getRunningTask().isHomeTask();
- if (mRunningOverHome) {
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
- RecentsWindowSwipeHandler.
- this::updateHomeActivityTransformDuringSwipeUp));
+
+ initTransformParams();
+ }
+
+ @Override
+ public void onRecentsAnimationStart(RecentsAnimationController controller,
+ RecentsAnimationTargets targets) {
+ super.onRecentsAnimationStart(controller, targets);
+ initTransformParams();
+ }
+
+ private void initTransformParams() {
+ if (mActiveAnimationFactory != null) {
+ mActiveAnimationFactory.initTransformParams();
+ return;
}
+ runActionOnRemoteHandles(remoteTargetHandle ->
+ remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
+ RecentsWindowSwipeHandler.this::updateHomeActivityTransformDuringSwipeUp));
}
@Override
@@ -135,12 +146,17 @@
private void updateHomeActivityTransformDuringSwipeUp(SurfaceProperties builder,
RemoteAnimationTarget app, TransformParams params) {
- setHomeScaleAndAlpha(builder, app, mCurrentShift.value,
- Utilities.boundToRange(1 - mCurrentShift.value, 0, 1));
+ if (mActiveAnimationFactory != null) {
+ return;
+ }
+ setHomeScaleAndAlpha(builder, app, mCurrentShift.value, 0);
}
private void setHomeScaleAndAlpha(SurfaceProperties builder,
RemoteAnimationTarget app, float verticalShift, float alpha) {
+ if (app.windowConfiguration.getActivityType() != ACTIVITY_TYPE_HOME) {
+ return;
+ }
float scale = Utilities.mapRange(verticalShift, 1, mMaxLauncherScale);
mTmpMatrix.setScale(scale, scale,
app.localBounds.exactCenterX(), app.localBounds.exactCenterY());
@@ -163,25 +179,13 @@
mActiveAnimationFactory = new FallbackHomeAnimationFactory(duration);
//todo: b/368410893 follow up on this as its intent focused and seems to cut immediately
Intent intent = new Intent(mGestureState.getHomeIntent());
- if (mActiveAnimationFactory != null && runningTaskTarget != null) {
+ if (runningTaskTarget != null) {
mActiveAnimationFactory.addGestureContract(intent, runningTaskTarget.taskInfo);
}
return mActiveAnimationFactory;
}
@Override
- protected boolean handleTaskAppeared(@NonNull RemoteAnimationTarget[] appearedTaskTargets,
- @NonNull ActiveGestureLog.CompoundString failureReason) {
- if (mActiveAnimationFactory != null
- && mActiveAnimationFactory.handleHomeTaskAppeared(appearedTaskTargets)) {
- mActiveAnimationFactory = null;
- return false;
- }
-
- return super.handleTaskAppeared(appearedTaskTargets, failureReason);
- }
-
- @Override
protected void finishRecentsControllerToHome(Runnable callback) {
final Runnable recentsCallback;
if (mAppCanEnterPip) {
@@ -236,11 +240,12 @@
private class FallbackHomeAnimationFactory extends HomeAnimationFactory
implements Consumer<Message> {
private final Rect mTempRect = new Rect();
- private final TransformParams mHomeAlphaParams = new TransformParams();
- private final AnimatedFloat mHomeAlpha;
- private final AnimatedFloat mVerticalShiftForScale = new AnimatedFloat();
- private final AnimatedFloat mRecentsAlpha = new AnimatedFloat();
+ private final TransformParams mTransformParams = new TransformParams();
+ private final AnimatedFloat mHomeAlpha = new AnimatedFloat(this::updateAppTransforms);
+ private final AnimatedFloat mVerticalShiftForScale =
+ new AnimatedFloat(this::updateAppTransforms);
+ private final AnimatedFloat mRecentsAlpha = new AnimatedFloat(this:: updateAppTransforms);
private final RectF mTargetRect = new RectF();
private SurfaceControl mSurfaceControl;
@@ -255,25 +260,12 @@
mDuration = duration;
if (mRunningOverHome) {
- mHomeAlpha = new AnimatedFloat();
- mHomeAlpha.value = Utilities.boundToRange(1 - mCurrentShift.value, 0, 1);
mVerticalShiftForScale.value = mCurrentShift.value;
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
- FallbackHomeAnimationFactory.this
- ::updateHomeActivityTransformDuringHomeAnim));
- } else {
- mHomeAlpha = new AnimatedFloat(this::updateHomeAlpha);
- mHomeAlpha.value = 0;
- mHomeAlphaParams.setHomeBuilderProxy(
- this::updateHomeActivityTransformDuringHomeAnim);
}
-
mRecentsAlpha.value = 1;
- runActionOnRemoteHandles(remoteTargetHandle ->
- remoteTargetHandle.getTransformParams().setBaseBuilderProxy(
- FallbackHomeAnimationFactory.this
- ::updateRecentsActivityTransformDuringHomeAnim));
+ mHomeAlpha.value = 0;
+
+ initTransformParams();
}
@NonNull
@@ -285,63 +277,30 @@
return mTargetRect;
}
- private void updateRecentsActivityTransformDuringHomeAnim(SurfaceProperties builder,
- RemoteAnimationTarget app, TransformParams params) {
- builder.setAlpha(mRecentsAlpha.value);
- }
-
- private void updateHomeActivityTransformDuringHomeAnim(SurfaceProperties builder,
- RemoteAnimationTarget app, TransformParams params) {
- setHomeScaleAndAlpha(builder, app, mVerticalShiftForScale.value, mHomeAlpha.value);
- }
-
@NonNull
@Override
public AnimatorPlaybackController createActivityAnimationToHome() {
PendingAnimation pa = new PendingAnimation(mDuration);
pa.setFloat(mRecentsAlpha, AnimatedFloat.VALUE, 0, ACCELERATE);
+ pa.setFloat(mHomeAlpha, AnimatedFloat.VALUE, 1, ACCELERATE);
return pa.createPlaybackController();
}
- private void updateHomeAlpha() {
- if (mHomeAlphaParams.getTargetSet() != null) {
- mHomeAlphaParams.applySurfaceParams(
- mHomeAlphaParams.createSurfaceParams(BuilderProxy.NO_OP));
- }
- }
-
- public boolean handleHomeTaskAppeared(RemoteAnimationTarget[] appearedTaskTargets) {
- RemoteAnimationTarget appearedTaskTarget = appearedTaskTargets[0];
- if (appearedTaskTarget.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME) {
- RemoteAnimationTargets targets = new RemoteAnimationTargets(
- new RemoteAnimationTarget[] {appearedTaskTarget},
- new RemoteAnimationTarget[0], new RemoteAnimationTarget[0],
- appearedTaskTarget.mode);
- mHomeAlphaParams.setTargetSet(targets);
- updateHomeAlpha();
- return true;
- }
- return false;
- }
-
@Override
public void playAtomicAnimation(float velocity) {
- ObjectAnimator alphaAnim = mHomeAlpha.animateToValue(mHomeAlpha.value, 1);
- alphaAnim.setDuration(mDuration).setInterpolator(ACCELERATE);
- alphaAnim.start();
-
- if (mRunningOverHome) {
- // Spring back launcher scale
- new SpringAnimationBuilder(mContext)
- .setStartValue(mVerticalShiftForScale.value)
- .setEndValue(0)
- .setStartVelocity(-velocity / mTransitionDragLength)
- .setMinimumVisibleChange(1f / mDp.heightPx)
- .setDampingRatio(0.6f)
- .setStiffness(800)
- .build(mVerticalShiftForScale, AnimatedFloat.VALUE)
- .start();
+ if (!mRunningOverHome) {
+ return;
}
+ // Spring back launcher scale
+ new SpringAnimationBuilder(mContext)
+ .setStartValue(mVerticalShiftForScale.value)
+ .setEndValue(0)
+ .setStartVelocity(-velocity / mTransitionDragLength)
+ .setMinimumVisibleChange(1f / mDp.heightPx)
+ .setDampingRatio(0.6f)
+ .setStiffness(800)
+ .build(mVerticalShiftForScale, AnimatedFloat.VALUE)
+ .start();
}
@Override
@@ -350,6 +309,34 @@
mSpringAnim.addAnimatorListener(forEndCallback(this::onRectAnimationEnd));
}
+ private void initTransformParams() {
+ runActionOnRemoteHandles(remoteTargetHandle ->
+ remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
+ FallbackHomeAnimationFactory.this
+ ::updateHomeActivityTransformDuringHomeAnim));
+
+ mTransformParams.setTargetSet(mRecentsAnimationTargets);
+ }
+
+ private void updateRecentsActivityTransformDuringHomeAnim(SurfaceProperties builder,
+ RemoteAnimationTarget app, TransformParams params) {
+ if (app.mode != mRecentsAnimationTargets.targetMode) {
+ return;
+ }
+ builder.setAlpha(mRecentsAlpha.value);
+ }
+
+ private void updateAppTransforms() {
+ mTransformParams.applySurfaceParams(
+ mTransformParams.createSurfaceParams(FallbackHomeAnimationFactory.this
+ ::updateRecentsActivityTransformDuringHomeAnim));
+ }
+
+ private void updateHomeActivityTransformDuringHomeAnim(SurfaceProperties builder,
+ RemoteAnimationTarget app, TransformParams params) {
+ setHomeScaleAndAlpha(builder, app, mVerticalShiftForScale.value, mHomeAlpha.value);
+ }
+
private void onRectAnimationEnd() {
mAnimationFinished = true;
maybeSendEndMessage();
diff --git a/quickstep/src/com/android/quickstep/util/TransformParams.java b/quickstep/src/com/android/quickstep/util/TransformParams.java
index ebcef30..401eccc 100644
--- a/quickstep/src/com/android/quickstep/util/TransformParams.java
+++ b/quickstep/src/com/android/quickstep/util/TransformParams.java
@@ -143,18 +143,15 @@
for (int i = 0; i < targets.unfilteredApps.length; i++) {
RemoteAnimationTarget app = targets.unfilteredApps[i];
SurfaceProperties builder = transaction.forSurface(app.leash);
+ BuilderProxy targetProxy =
+ app.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME
+ ? mHomeBuilderProxy
+ : (app.mode == targets.targetMode ? proxy : mBaseBuilderProxy);
if (app.mode == targets.targetMode) {
- int activityType = app.windowConfiguration.getActivityType();
- if (activityType == ACTIVITY_TYPE_HOME) {
- mHomeBuilderProxy.onBuildTargetParams(builder, app, this);
- } else {
- builder.setAlpha(getTargetAlpha());
- proxy.onBuildTargetParams(builder, app, this);
- }
- } else {
- mBaseBuilderProxy.onBuildTargetParams(builder, app, this);
+ builder.setAlpha(getTargetAlpha());
}
+ targetProxy.onBuildTargetParams(builder, app, this);
}
// always put wallpaper layer to bottom.
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarEduTooltipControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarEduTooltipControllerTest.kt
index e60717b..3c80352 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarEduTooltipControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/TaskbarEduTooltipControllerTest.kt
@@ -16,7 +16,6 @@
package com.android.launcher3.taskbar
-import android.util.Log
import com.android.launcher3.Utilities
import com.android.launcher3.taskbar.TaskbarControllerTestUtil.asProperty
import com.android.launcher3.taskbar.TaskbarControllerTestUtil.runOnMainSync
@@ -34,14 +33,12 @@
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
-import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(LauncherMultivalentJUnit::class)
@EmulatedDevices(["pixelFoldable2023", "pixelTablet2023"])
-@Ignore
class TaskbarEduTooltipControllerTest {
@get:Rule(order = 0) val context = TaskbarWindowSandboxContext.create()
@@ -62,7 +59,6 @@
@Before
fun setUp() {
- Log.e("Taskbar", "TaskbarEduTooltipControllerTest test started")
Utilities.disableRunningInTestHarnessForTests()
}
@@ -71,7 +67,6 @@
if (wasInTestHarness) {
Utilities.enableRunningInTestHarnessForTests()
}
- Log.e("Taskbar", "TaskbarEduTooltipControllerTest test completed")
}
@Test
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
index 7eee4de..b37048a 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
@@ -19,6 +19,7 @@
import android.content.Context
import android.graphics.Color
import android.graphics.Path
+import android.graphics.PointF
import android.graphics.drawable.ColorDrawable
import android.view.LayoutInflater
import android.view.View
@@ -36,6 +37,10 @@
import com.android.launcher3.taskbar.bubbles.BubbleBarOverflow
import com.android.launcher3.taskbar.bubbles.BubbleBarView
import com.android.launcher3.taskbar.bubbles.BubbleView
+import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutController
+import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutMessage
+import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutPositioner
+import com.android.launcher3.taskbar.bubbles.flyout.FlyoutScheduler
import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController
import com.android.wm.shell.shared.animation.PhysicsAnimator
import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils
@@ -63,13 +68,19 @@
private lateinit var bubbleView: BubbleView
private lateinit var bubble: BubbleBarBubble
private lateinit var bubbleBarView: BubbleBarView
+ private lateinit var flyoutContainer: FrameLayout
private lateinit var bubbleStashController: BubbleStashController
+ private lateinit var flyoutController: BubbleBarFlyoutController
private val onExpandedNoOp = Runnable {}
+ private val flyoutView: View?
+ get() = flyoutContainer.findViewById(R.id.bubble_bar_flyout_view)
+
@Before
fun setUp() {
animatorScheduler = TestBubbleBarViewAnimatorScheduler()
PhysicsAnimatorTestUtils.prepareForTest()
+ setupFlyoutController()
}
@Test
@@ -85,6 +96,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -106,10 +118,14 @@
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_TASKBAR)
assertThat(animator.isAnimating).isTrue()
+ waitForFlyoutToShow()
+
// execute the hide bubble animation
assertThat(animatorScheduler.delayedBlock).isNotNull()
InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
+ waitForFlyoutToHide()
+
// let the animation start and wait for it to complete
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
@@ -134,6 +150,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -157,10 +174,16 @@
verify(bubbleStashController, atLeastOnce()).updateTaskbarTouchRegion()
+ waitForFlyoutToShow()
+
// verify the hide bubble animation is pending
assertThat(animatorScheduler.delayedBlock).isNotNull()
- animator.onBubbleBarTouchedWhileAnimating()
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ animator.onBubbleBarTouchedWhileAnimating()
+ }
+
+ waitForFlyoutToHide()
assertThat(animatorScheduler.delayedBlock).isNull()
assertThat(bubbleBarView.alpha).isEqualTo(1)
@@ -182,6 +205,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -227,6 +251,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -239,10 +264,14 @@
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
+ waitForFlyoutToShow()
+
// execute the hide bubble animation
assertThat(animatorScheduler.delayedBlock).isNotNull()
InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
+ waitForFlyoutToHide()
+
// wait for the hide animation to start
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
handleAnimator.assertIsRunning()
@@ -273,6 +302,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -310,6 +340,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -354,6 +385,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -404,6 +436,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -418,6 +451,9 @@
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
assertThat(animator.isAnimating).isTrue()
+
+ waitForFlyoutToShow()
+
// verify the hide bubble animation is pending
assertThat(animatorScheduler.delayedBlock).isNotNull()
@@ -428,6 +464,8 @@
// verify that the hide animation was canceled
assertThat(animatorScheduler.delayedBlock).isNull()
+ waitForFlyoutToHide()
+
assertThat(handle.alpha).isEqualTo(0)
assertThat(handle.translationY)
.isEqualTo(DIFF_BETWEEN_HANDLE_AND_BAR_CENTERS + BAR_TRANSLATION_Y_FOR_TASKBAR)
@@ -453,6 +491,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -469,9 +508,13 @@
assertThat(bubbleBarView.alpha).isEqualTo(1)
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_TASKBAR)
+ waitForFlyoutToShow()
+
assertThat(animatorScheduler.delayedBlock).isNotNull()
InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
+ waitForFlyoutToHide()
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
@@ -503,6 +546,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -537,6 +581,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -553,9 +598,13 @@
assertThat(bubbleBarView.alpha).isEqualTo(1)
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_HOTSEAT)
+ waitForFlyoutToShow()
+
assertThat(animatorScheduler.delayedBlock).isNotNull()
InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
+ waitForFlyoutToHide()
+
assertThat(animator.isAnimating).isFalse()
assertThat(bubbleBarView.alpha).isEqualTo(1)
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_HOTSEAT)
@@ -576,6 +625,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -624,6 +674,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -636,6 +687,8 @@
InstrumentationRegistry.getInstrumentation().runOnMainSync {}
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
+ waitForFlyoutToShow()
+
assertThat(animator.isAnimating).isTrue()
// verify the hide bubble animation is pending
assertThat(animatorScheduler.delayedBlock).isNotNull()
@@ -644,6 +697,8 @@
animator.expandedWhileAnimating()
}
+ waitForFlyoutToHide()
+
// verify that the hide animation was canceled
assertThat(animatorScheduler.delayedBlock).isNull()
@@ -665,6 +720,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpandedNoOp,
animatorScheduler,
)
@@ -687,9 +743,13 @@
barAnimator.assertIsRunning()
PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Y)
+ waitForFlyoutToShow()
+
assertThat(animatorScheduler.delayedBlock).isNotNull()
InstrumentationRegistry.getInstrumentation().runOnMainSync(animatorScheduler.delayedBlock!!)
+ waitForFlyoutToHide()
+
assertThat(animator.isAnimating).isFalse()
// the bubble bar translation y should be back to its initial value
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_HOTSEAT)
@@ -712,6 +772,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -759,6 +820,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -817,6 +879,7 @@
BubbleBarViewAnimator(
bubbleBarView,
bubbleStashController,
+ flyoutController,
onExpanded,
animatorScheduler,
)
@@ -843,6 +906,8 @@
assertThat(animatorScheduler.delayedBlock).isNotNull()
assertThat(animator.isAnimating).isTrue()
+ waitForFlyoutToShow()
+
InstrumentationRegistry.getInstrumentation().runOnMainSync {
animator.expandedWhileAnimating()
}
@@ -850,6 +915,8 @@
// verify that the hide animation was canceled
assertThat(animatorScheduler.delayedBlock).isNull()
+ waitForFlyoutToHide()
+
assertThat(animator.isAnimating).isFalse()
assertThat(bubbleBarView.translationY).isEqualTo(BAR_TRANSLATION_Y_FOR_HOTSEAT)
assertThat(bubbleBarView.isExpanded).isTrue()
@@ -894,7 +961,7 @@
Color.WHITE,
Path(),
"",
- null,
+ BubbleBarFlyoutMessage(icon = null, title = "title", message = "message"),
)
bubbleView.setBubble(bubble)
bubbleBarView.addView(bubbleView)
@@ -913,6 +980,34 @@
.thenReturn(BAR_TRANSLATION_Y_FOR_TASKBAR)
}
+ private fun setupFlyoutController() {
+ flyoutContainer = FrameLayout(context)
+ val flyoutPositioner =
+ object : BubbleBarFlyoutPositioner {
+ override val isOnLeft = true
+ override val targetTy = 100f
+ override val distanceToCollapsedPosition = PointF(0f, 0f)
+ override val collapsedSize = 30f
+ override val collapsedColor = Color.BLUE
+ override val collapsedElevation = 1f
+ override val distanceToRevealTriangle = 10f
+ }
+ val topBoundaryListener =
+ object : BubbleBarFlyoutController.TopBoundaryListener {
+ override fun extendTopBoundary(space: Int) {}
+
+ override fun resetTopBoundary() {}
+ }
+ val flyoutScheduler = FlyoutScheduler { block -> block.invoke() }
+ flyoutController =
+ BubbleBarFlyoutController(
+ flyoutContainer,
+ flyoutPositioner,
+ topBoundaryListener,
+ flyoutScheduler,
+ )
+ }
+
private fun verifyBubbleBarIsExpandedWithTranslation(ty: Float) {
assertThat(bubbleBarView.visibility).isEqualTo(VISIBLE)
assertThat(bubbleBarView.scaleX).isEqualTo(1)
@@ -921,6 +1016,20 @@
assertThat(bubbleBarView.isExpanded).isTrue()
}
+ private fun waitForFlyoutToShow() {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ animatorTestRule.advanceTimeBy(300)
+ }
+ assertThat(flyoutView).isNotNull()
+ }
+
+ private fun waitForFlyoutToHide() {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ animatorTestRule.advanceTimeBy(300)
+ }
+ assertThat(flyoutView).isNull()
+ }
+
private fun <T> PhysicsAnimator<T>.assertIsRunning() {
InstrumentationRegistry.getInstrumentation().runOnMainSync {
assertThat(isRunning()).isTrue()
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt
index 3dd7689..527bdaa 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt
@@ -20,6 +20,7 @@
import android.graphics.Color
import android.graphics.PointF
import android.view.Gravity
+import android.view.View
import android.widget.FrameLayout
import android.widget.TextView
import androidx.core.animation.AnimatorTestRule
@@ -80,7 +81,7 @@
@Test
fun flyoutPosition_left() {
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
val flyout = flyoutContainer.getChildAt(0)
val lp = flyout.layoutParams as FrameLayout.LayoutParams
@@ -93,7 +94,7 @@
fun flyoutPosition_right() {
onLeft = false
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
val flyout = flyoutContainer.getChildAt(0)
val lp = flyout.layoutParams as FrameLayout.LayoutParams
@@ -105,7 +106,7 @@
@Test
fun flyoutMessage() {
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
val flyout = flyoutContainer.getChildAt(0)
val sender = flyout.findViewById<TextView>(R.id.bubble_flyout_title)
@@ -118,9 +119,9 @@
@Test
fun hideFlyout_removedFromContainer() {
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
- flyoutController.hideFlyout {}
+ flyoutController.collapseFlyout {}
animatorTestRule.advanceTimeBy(300)
}
assertThat(flyoutContainer.childCount).isEqualTo(0)
@@ -132,7 +133,7 @@
// boundary
flyoutTy = -50f
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
}
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
@@ -145,7 +146,7 @@
@Test
fun showFlyout_withinBoundary() {
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
}
InstrumentationRegistry.getInstrumentation().waitForIdleSync()
@@ -156,16 +157,30 @@
}
@Test
- fun hideFlyout_resetsTopBoundary() {
+ fun collapseFlyout_resetsTopBoundary() {
InstrumentationRegistry.getInstrumentation().runOnMainSync {
- flyoutController.setUpFlyout(flyoutMessage)
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
assertThat(flyoutContainer.childCount).isEqualTo(1)
- flyoutController.hideFlyout {}
+ flyoutController.collapseFlyout {}
animatorTestRule.advanceTimeBy(300)
}
assertThat(topBoundaryListener.topBoundaryReset).isTrue()
}
+ @Test
+ fun cancelFlyout_fadesOutFlyout() {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+ assertThat(flyoutContainer.childCount).isEqualTo(1)
+ val flyoutView = flyoutContainer.findViewById<View>(R.id.bubble_bar_flyout_view)
+ assertThat(flyoutView.alpha).isEqualTo(1f)
+ flyoutController.cancelFlyout {}
+ animatorTestRule.advanceTimeBy(300)
+ assertThat(flyoutView.alpha).isEqualTo(0f)
+ }
+ assertThat(topBoundaryListener.topBoundaryReset).isTrue()
+ }
+
class FakeTopBoundaryListener : BubbleBarFlyoutController.TopBoundaryListener {
var topBoundaryExtendedSpace = 0
diff --git a/res/drawable/bg_letter_list_text.xml b/res/drawable/bg_letter_list_text.xml
index 427702b..bfdd35c 100644
--- a/res/drawable/bg_letter_list_text.xml
+++ b/res/drawable/bg_letter_list_text.xml
@@ -15,7 +15,7 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
- <solid android:color="?attr/materialColorSurfaceContainer" />
+ <solid android:color="?attr/materialColorSurface" />
<corners android:radius="100dp"/>
<size
android:width="@dimen/bg_letter_list_text_size"
diff --git a/src/com/android/launcher3/allapps/LetterListTextView.java b/src/com/android/launcher3/allapps/LetterListTextView.java
index 433a7f2..8586078 100644
--- a/src/com/android/launcher3/allapps/LetterListTextView.java
+++ b/src/com/android/launcher3/allapps/LetterListTextView.java
@@ -42,8 +42,6 @@
private final Drawable mLetterBackground;
private final int mLetterListTextWidthAndHeight;
private final int mTextColor;
- private final int mBackgroundColor;
- private final int mSelectedColor;
public LetterListTextView(Context context) {
this(context, null, 0);
@@ -59,8 +57,6 @@
mLetterListTextWidthAndHeight = context.getResources().getDimensionPixelSize(
R.dimen.fastscroll_list_letter_size);
mTextColor = Themes.getAttrColor(context, R.attr.materialColorOnSurface);
- mBackgroundColor = Themes.getAttrColor(context, R.attr.materialColorSurfaceContainer);
- mSelectedColor = Themes.getAttrColor(context, R.attr.materialColorOnSecondary);
}
@Override
@@ -101,26 +97,11 @@
float cutOffMin = currentFingerY - (getHeight() * 2);
float cutOffMax = currentFingerY + (getHeight() * 2);
float cutOffDistance = cutOffMax - cutOffMin;
- // Update the background blend color
boolean isWithinAnimationBounds = getY() < cutOffMax && getY() > cutOffMin;
- if (isWithinAnimationBounds) {
- getBackground().setColorFilter(new PorterDuffColorFilter(
- getBlendColorBasedOnYPosition(currentFingerY, cutOffDistance),
- PorterDuff.Mode.MULTIPLY));
- } else {
- getBackground().setColorFilter(new PorterDuffColorFilter(
- mBackgroundColor, PorterDuff.Mode.MULTIPLY));
- }
translateBasedOnYPosition(currentFingerY, cutOffDistance, isWithinAnimationBounds);
scaleBasedOnYPosition(currentFingerY, cutOffDistance, isWithinAnimationBounds);
}
- private int getBlendColorBasedOnYPosition(int y, float cutOffDistance) {
- float raisedCosineBlend = (float) Math.cos(((y - getY()) / (cutOffDistance)) * Math.PI);
- float blendRatio = Utilities.boundToRange(raisedCosineBlend, 0f, 1f);
- return ColorUtils.blendARGB(mBackgroundColor, mSelectedColor, blendRatio);
- }
-
private void scaleBasedOnYPosition(int y, float cutOffDistance,
boolean isWithinAnimationBounds) {
float raisedCosineScale = (float) Math.cos(((y - getY()) / (cutOffDistance)) * Math.PI)
diff --git a/src/com/android/launcher3/util/LockedUserState.kt b/src/com/android/launcher3/util/LockedUserState.kt
index 10559f3..c8d86d4 100644
--- a/src/com/android/launcher3/util/LockedUserState.kt
+++ b/src/com/android/launcher3/util/LockedUserState.kt
@@ -88,6 +88,13 @@
mUserUnlockedActions.add(action)
}
+ /**
+ * Removes a previously queued `Runnable` to be run when the user is unlocked.
+ */
+ fun removeOnUserUnlockedRunnable(action: Runnable) {
+ mUserUnlockedActions.remove(action)
+ }
+
companion object {
@VisibleForTesting
@JvmField