viewOrder) {
- if (isExpanded() || (mWidthAnimator != null && mWidthAnimator.isRunning())) {
+ if (isExpanded() || mWidthAnimator.isRunning()) {
mReorderRunnable = () -> doReorder(viewOrder);
} else {
doReorder(viewOrder);
@@ -1200,7 +1192,7 @@ public class BubbleBarView extends FrameLayout {
mUpdateSelectedBubbleAfterCollapse = updateSelectedBubbleAfterCollapse;
}
- public void setController(Controller controller) {
+ void setController(Controller controller) {
mController = controller;
}
@@ -1318,38 +1310,20 @@ public class BubbleBarView extends FrameLayout {
}
/**
- * Update bubble bar expanded state.
+ * Sets whether the bubble bar is expanded or collapsed.
*/
public void setExpanded(boolean isBarExpanded) {
- setExpandedInternal(isBarExpanded, false);
- }
-
- /**
- * Update bubble bar expanded state with animation.
- *
- * Also triggers a talkback announcement for accessibility.
- */
- public void animateExpanded(boolean isBarExpanded) {
- setExpandedInternal(isBarExpanded, true);
- }
-
- private void setExpandedInternal(boolean isBarExpanded, boolean animate) {
- if (mIsBarExpanded == isBarExpanded) return;
- mIsBarExpanded = isBarExpanded;
- updateArrowForSelected(/* shouldAnimate= */ false);
- setOrUnsetClickListener();
- if (animate) {
+ if (mIsBarExpanded != isBarExpanded) {
+ mIsBarExpanded = isBarExpanded;
+ updateArrowForSelected(/* shouldAnimate= */ false);
+ setOrUnsetClickListener();
mWidthAnimator = createExpansionAnimator(isBarExpanded);
mWidthAnimator.start();
+ updateBubbleAccessibilityStates();
announceExpandedStateChange();
- } else {
- onExpandedChanged();
}
- updateBubbleAccessibilityStates();
- mController.onBubbleBarExpandedStateChanged(mIsBarExpanded);
}
-
/**
* Returns whether the bubble bar is expanded.
*/
@@ -1361,7 +1335,7 @@ public class BubbleBarView extends FrameLayout {
* Returns whether the bubble bar is expanding.
*/
public boolean isExpanding() {
- return mWidthAnimator != null && mWidthAnimator.isRunning() && mIsBarExpanded;
+ return mWidthAnimator.isRunning() && mIsBarExpanded;
}
/**
@@ -1610,7 +1584,26 @@ public class BubbleBarView extends FrameLayout {
animator.setInterpolator(Interpolators.EMPHASIZED);
addAnimationCallBacks(animator,
/* onStart= */ () -> mBubbleBarBackground.showArrow(true),
- /* onEnd= */ this::onExpandedChanged,
+ /* onEnd= */ () -> {
+ mBubbleBarBackground.showArrow(mIsBarExpanded);
+ if (!mIsBarExpanded && mReorderRunnable != null) {
+ mReorderRunnable.run();
+ mReorderRunnable = null;
+ }
+ // If the bar was just collapsed and the overflow was the last bubble that was
+ // selected, set the first bubble as selected.
+ if (!mIsBarExpanded && mUpdateSelectedBubbleAfterCollapse != null
+ && mSelectedBubbleView != null
+ && mSelectedBubbleView.getBubble() instanceof BubbleBarOverflow) {
+ BubbleView firstBubble = (BubbleView) getChildAt(0);
+ mUpdateSelectedBubbleAfterCollapse.accept(firstBubble.getBubble().getKey());
+ }
+ // If the bar was just expanded, remove the dot from the selected bubble.
+ if (mIsBarExpanded && mSelectedBubbleView != null) {
+ mSelectedBubbleView.markSeen();
+ }
+ updateLayoutParams();
+ },
/* onUpdate= */ anim -> {
updateBubblesLayoutProperties(mBubbleBarLocation);
invalidate();
@@ -1618,27 +1611,6 @@ public class BubbleBarView extends FrameLayout {
return animator;
}
- private void onExpandedChanged() {
- mBubbleBarBackground.showArrow(mIsBarExpanded);
- if (!mIsBarExpanded && mReorderRunnable != null) {
- mReorderRunnable.run();
- mReorderRunnable = null;
- }
- // If the bar was just collapsed and the overflow was the last bubble that was
- // selected, set the first bubble as selected.
- if (!mIsBarExpanded && mUpdateSelectedBubbleAfterCollapse != null
- && mSelectedBubbleView != null
- && mSelectedBubbleView.getBubble() instanceof BubbleBarOverflow) {
- BubbleView firstBubble = (BubbleView) getChildAt(0);
- mUpdateSelectedBubbleAfterCollapse.accept(firstBubble.getBubble().getKey());
- }
- // If the bar was just expanded, remove the dot from the selected bubble.
- if (mIsBarExpanded && mSelectedBubbleView != null) {
- mSelectedBubbleView.markSeen();
- }
- updateLayoutParams();
- }
-
/**
* Returns the distance between the top left corner of the bubble bar to the center of the dot
* of the selected bubble.
@@ -1672,7 +1644,7 @@ public class BubbleBarView extends FrameLayout {
}
/** Interface for BubbleBarView to communicate with its controller. */
- public interface Controller {
+ interface Controller {
/** Returns the translation Y that the bubble bar should have. */
float getBubbleBarTranslationY();
@@ -1692,8 +1664,5 @@ public class BubbleBarView extends FrameLayout {
/** Notifies the controller that bubble bar is being dragged */
void setIsDragging(boolean dragging);
-
- /** Notifies the controller that bubble bar expanded state changed */
- void onBubbleBarExpandedStateChanged(boolean expanded);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index 648ad9f2a2..2ed72d7824 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -43,25 +43,33 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.app.animation.Interpolators;
+import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
+
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
+import com.android.launcher3.dragndrop.DragController;
+import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.taskbar.TaskbarActivityContext;
import com.android.launcher3.taskbar.TaskbarControllers;
import com.android.launcher3.taskbar.TaskbarInsetsController;
import com.android.launcher3.taskbar.TaskbarSharedState;
import com.android.launcher3.taskbar.TaskbarStashController;
+import com.android.launcher3.taskbar.bubbles.BubbleBarLocationDropTarget.BubbleBarDragListener;
import com.android.launcher3.taskbar.bubbles.animation.BubbleBarViewAnimator;
import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutController;
import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutPositioner;
import com.android.launcher3.taskbar.bubbles.flyout.FlyoutCallbacks;
import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.quickstep.SystemUiProxy;
import com.android.wm.shell.Flags;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
+import com.android.wm.shell.shared.bubbles.DeviceConfig;
import java.io.PrintWriter;
import java.util.List;
@@ -120,6 +128,60 @@ public class BubbleBarViewController {
updateTranslationY();
setBubbleBarScaleAndPadding(pinningProgress);
});
+ private final BubbleBarDragListener mDragListener = new BubbleBarDragListener() {
+
+ @Override
+ public void getBubbleBarLocationHitRect(@NonNull BubbleBarLocation bubbleBarLocation,
+ Rect outRect) {
+ Point screenSize = DisplayController.INSTANCE.get(mActivity).getInfo().currentSize;
+ outRect.top = screenSize.y - mBubbleBarDropTargetSize;
+ outRect.bottom = screenSize.y;
+ if (bubbleBarLocation.isOnLeft(mBarView.isLayoutRtl())) {
+ outRect.left = 0;
+ outRect.right = mBubbleBarDropTargetSize;
+ } else {
+ outRect.left = screenSize.x - mBubbleBarDropTargetSize;
+ outRect.right = screenSize.x;
+ }
+ }
+
+ @Override
+ public void onLauncherItemDroppedOverBubbleBarDragZone(@NonNull BubbleBarLocation location,
+ @NonNull ItemInfo itemInfo) {
+ AbstractFloatingView.closeAllOpenViews(mActivity);
+ if (itemInfo instanceof WorkspaceItemInfo) {
+ ShortcutInfo shortcutInfo = ((WorkspaceItemInfo) itemInfo).getDeepShortcutInfo();
+ if (shortcutInfo != null) {
+ mSystemUiProxy.showShortcutBubble(shortcutInfo, location);
+ return;
+ }
+ }
+ Intent itemIntent = itemInfo.getIntent();
+ if (itemIntent != null && itemIntent.getComponent() != null) {
+ itemIntent.setPackage(itemIntent.getComponent().getPackageName());
+ mSystemUiProxy.showAppBubble(itemIntent, itemInfo.user, location);
+ }
+ }
+
+ @Override
+ public void onLauncherItemDraggedOutsideBubbleBarDropZone() {
+ onItemDraggedOutsideBubbleBarDropZone();
+ mSystemUiProxy.showBubbleDropTarget(/* show = */ false);
+ }
+
+ @Override
+ public void onLauncherItemDraggedOverBubbleBarDragZone(
+ @NonNull BubbleBarLocation location) {
+ onDragItemOverBubbleBarDragZone(location);
+ mSystemUiProxy.showBubbleDropTarget(/* show = */ true, location);
+ }
+
+ @NonNull
+ @Override
+ public View getDropView() {
+ return mBarView;
+ }
+ };
// Modified when swipe up is happening on the bubble bar or task bar.
private float mBubbleBarSwipeUpTranslationY;
@@ -145,8 +207,11 @@ public class BubbleBarViewController {
private BubbleBarFlyoutController mBubbleBarFlyoutController;
private BubbleBarPinController mBubbleBarPinController;
private TaskbarSharedState mTaskbarSharedState;
+ private final BubbleBarLocationDropTarget mBubbleBarLeftDropTarget;
+ private final BubbleBarLocationDropTarget mBubbleBarRightDropTarget;
private final TimeSource mTimeSource = System::currentTimeMillis;
private final int mTaskbarTranslationDelta;
+ private final int mBubbleBarDropTargetSize;
@Nullable
private BubbleBarBoundsChangeListener mBoundsChangeListener;
@@ -164,6 +229,15 @@ public class BubbleBarViewController {
R.dimen.bubblebar_transient_taskbar_min_distance);
mDragElevation = res.getDimensionPixelSize(R.dimen.dragged_bubble_elevation);
mTaskbarTranslationDelta = getBubbleBarTranslationDeltaForTaskbar(activity);
+ if (DeviceConfig.isSmallTablet(mActivity)) {
+ mBubbleBarDropTargetSize = res.getDimensionPixelSize(com.android.wm.shell.R.dimen.drag_zone_bubble_fold);
+ } else {
+ mBubbleBarDropTargetSize = res.getDimensionPixelSize(com.android.wm.shell.R.dimen.drag_zone_bubble_tablet);
+ }
+ mBubbleBarLeftDropTarget = new BubbleBarLocationDropTarget(BubbleBarLocation.LEFT,
+ mDragListener);
+ mBubbleBarRightDropTarget = new BubbleBarLocationDropTarget(BubbleBarLocation.RIGHT,
+ mDragListener);
}
/** Initializes controller. */
@@ -196,7 +270,7 @@ public class BubbleBarViewController {
if (!mBubbleStashController.isTransientTaskBar()) {
// TODO(b/380274085) for transient taskbar mode, the click is also handled by the input
// consumer. This check can be removed once b/380274085 is fixed.
- mBarView.setOnClickListener(v -> animateExpanded(!mBarView.isExpanded()));
+ mBarView.setOnClickListener(v -> setExpanded(!mBarView.isExpanded()));
}
mBarView.addOnLayoutChangeListener(
(v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
@@ -212,7 +286,7 @@ public class BubbleBarViewController {
mBarView.setController(new BubbleBarView.Controller() {
@Override
public float getBubbleBarTranslationY() {
- return mBubbleStashController.getTargetTranslationYForState();
+ return mBubbleStashController.getBubbleBarTranslationY();
}
@Override
@@ -224,7 +298,7 @@ public class BubbleBarViewController {
@Override
public void expandBubbleBar() {
- BubbleBarViewController.this.animateExpanded(
+ BubbleBarViewController.this.setExpanded(
/* isExpanded= */ true, /* maybeShowEdu*/ true);
}
@@ -243,14 +317,6 @@ public class BubbleBarViewController {
public void setIsDragging(boolean dragging) {
mBubbleBarContainer.setElevation(dragging ? mDragElevation : 0);
}
-
- @Override
- public void onBubbleBarExpandedStateChanged(boolean expanded) {
- if (expanded && !mTaskbarStashController.isStashed()) {
- mTaskbarStashController.updateAndAnimateTransientTaskbar(true /* stash */,
- false /* shouldBubblesFollow */);
- }
- }
});
mBubbleViewController = new BubbleView.Controller() {
@@ -280,6 +346,18 @@ public class BubbleBarViewController {
};
}
+ /** Adds bubble bar locations drop zones to the drag controller. */
+ public void addBubbleBarDropTargets(DragController> dragController) {
+ dragController.addDropTarget(mBubbleBarLeftDropTarget);
+ dragController.addDropTarget(mBubbleBarRightDropTarget);
+ }
+
+ /** Removes bubble bar locations drop zones to the drag controller. */
+ public void removeBubbleBarDropTargets(DragController> dragController) {
+ dragController.removeDropTarget(mBubbleBarLeftDropTarget);
+ dragController.removeDropTarget(mBubbleBarRightDropTarget);
+ }
+
/** Returns animated float property responsible for pinning transition animation. */
public AnimatedFloat getBubbleBarPinning() {
return mBubbleBarPinning;
@@ -346,7 +424,7 @@ public class BubbleBarViewController {
@Override
public void flyoutClicked() {
interruptAnimationForTouch();
- animateExpanded(/* isExpanded= */ true, /* maybeShowEdu*/ true);
+ setExpanded(/* isExpanded= */ true, /* maybeShowEdu*/ true);
}
};
}
@@ -360,11 +438,6 @@ public class BubbleBarViewController {
};
}
- /** Returns the overflow bubble. */
- public BubbleBarOverflow getOverflowBubble() {
- return mOverflowBubble;
- }
-
private void onBubbleClicked(BubbleView bubbleView) {
if (mBubbleBarPinning.isAnimating()) return;
bubbleView.markSeen();
@@ -389,7 +462,7 @@ public class BubbleBarViewController {
}
private void collapseBubbleBar() {
- animateExpanded(false);
+ setExpanded(false);
mBubbleStashController.stashBubbleBar();
}
@@ -564,12 +637,6 @@ public class BubbleBarViewController {
return mBarView.isShowingDropTarget();
}
- /** Tells bubble bar view if it should show the drop target. */
- public void setShowingDropTarget(boolean showingDropTarget) {
- mBarView.showDropTarget(showingDropTarget);
- }
-
- //TODO(b/411505605) remove unused IPC calls and code
/**
* Notifies the controller that a drag event is over the Bubble Bar drop zone. The controller
* will display the appropriate drop target and enter drop target mode. The controller will also
@@ -665,8 +732,7 @@ public class BubbleBarViewController {
public boolean isEventOverBubbleBar(MotionEvent event) {
if (!isBubbleBarVisible()) return false;
final Rect bounds = getBubbleBarBounds();
- final int bubbleBarTopOnScreen =
- mActivity.getScreenSize().y - mBarView.getTopToScreenBottom();
+ final int bubbleBarTopOnScreen = mBarView.getRestingTopPositionOnScreen();
final float x = event.getX();
return event.getRawY() >= bubbleBarTopOnScreen && x >= bounds.left && x <= bounds.right;
}
@@ -741,7 +807,7 @@ public class BubbleBarViewController {
if (hidden) {
mBarView.dismiss(() -> {
updateVisibilityForStateChange();
- mBarView.animateExpanded(false);
+ mBarView.setExpanded(false);
adjustTaskbarAndHotseatToBubbleBarState(/* isBubbleBarExpanded= */ false);
mActivity.bubbleBarVisibilityChanged(/* isVisible= */ false);
});
@@ -864,7 +930,7 @@ public class BubbleBarViewController {
float mediumIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
APP_ICON_MEDIUM_DP, dm);
float smallMediumThreshold = (smallIconSize + mediumIconSize) / 2f;
- int taskbarIconSize = deviceProfile.getTaskbarProfile().getIconSize();
+ int taskbarIconSize = deviceProfile.taskbarIconSize;
return taskbarIconSize <= smallMediumThreshold
? res.getDimensionPixelSize(R.dimen.bubblebar_icon_size_small) :
res.getDimensionPixelSize(R.dimen.bubblebar_icon_size);
@@ -882,7 +948,7 @@ public class BubbleBarViewController {
float largeIconSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
APP_ICON_LARGE_DP, dm);
float mediumLargeThreshold = (mediumIconSize + largeIconSize) / 2f;
- return deviceProfile.getTaskbarProfile().getIconSize() >= mediumLargeThreshold
+ return deviceProfile.taskbarIconSize >= mediumLargeThreshold
? res.getDimensionPixelSize(R.dimen.bubblebar_icon_spacing_large) :
res.getDimensionPixelSize(R.dimen.bubblebar_icon_spacing);
}
@@ -959,11 +1025,9 @@ public class BubbleBarViewController {
int persistentSpacingSize = res
.getDimensionPixelSize(R.dimen.bubblebar_icon_spacing_persistent_taskbar);
int persistentBubbleBarSize = persistentBubbleSize + persistentSpacingSize * 2;
- int persistentTaskbarHeight =
- activity.getPersistentTaskbarDeviceProfile().getTaskbarProfile().getHeight();
+ int persistentTaskbarHeight = activity.getPersistentTaskbarDeviceProfile().taskbarHeight;
int persistentBubbleBarY = (persistentTaskbarHeight - persistentBubbleBarSize) / 2;
- int transientBubbleBarY =
- activity.getTransientTaskbarDeviceProfile().getTaskbarProfile().getBottomMargin();
+ int transientBubbleBarY = activity.getTransientTaskbarDeviceProfile().taskbarBottomMargin;
return transientBubbleBarY - persistentBubbleBarY;
}
@@ -1037,7 +1101,7 @@ public class BubbleBarViewController {
if (mOverflowAdded == showOverflow) return;
mOverflowAdded = showOverflow;
if (mOverflowAdded) {
- mBarView.addBubble(mOverflowBubble.getView(), /* suppressAnimation= */ true);
+ mBarView.addBubble(mOverflowBubble.getView());
mOverflowBubble.getView().setOnClickListener(mBubbleClickListener);
mOverflowBubble.getView().setController(mBubbleViewController);
} else {
@@ -1084,7 +1148,10 @@ public class BubbleBarViewController {
if (b != null) {
BubbleView bubbleToSelectView =
bubbleToSelect == null ? null : bubbleToSelect.getView();
- addBubbleView(b.getView(), suppressAnimation, bubbleToSelectView);
+ mBarView.addBubble(b.getView(), bubbleToSelectView);
+ b.getView().setOnClickListener(mBubbleClickListener);
+ mBubbleDragController.setupBubbleView(b.getView());
+ b.getView().setController(mBubbleViewController);
if (suppressAnimation || !(b instanceof BubbleBarBubble bubble)) {
// the bubble bar and handle are initialized as part of the first bubble animation.
@@ -1092,8 +1159,7 @@ public class BubbleBarViewController {
// ensure they've been initialized.
if (mTaskbarStashController.isInApp()
&& mBubbleStashController.isTransientTaskBar()
- && mTaskbarStashController.isStashed()
- && !isExpanded()) {
+ && mTaskbarStashController.isStashed()) {
mBubbleStashController.stashBubbleBarImmediate();
} else {
mBubbleStashController.showBubbleBarImmediate();
@@ -1106,21 +1172,6 @@ public class BubbleBarViewController {
}
}
- private void addBubbleView(BubbleView bubbleView, boolean suppressAnimation,
- BubbleView selectedBubbleView) {
- mBarView.addBubble(bubbleView, selectedBubbleView, suppressAnimation);
- bubbleView.setOnClickListener(mBubbleClickListener);
- mBubbleDragController.setupBubbleView(bubbleView);
- bubbleView.setController(mBubbleViewController);
- }
-
- /**
- * Restore a previous bubble that is stored in {@link TaskbarSharedState}.
- */
- public void restoreBubble(BubbleBarItem b) {
- addBubbleView(b.getView(), /* suppressAnimation= */ true, /* bubbleToSelectView= */ null);
- }
-
/** Animates the bubble bar to notify the user about a bubble change. */
public void animateBubbleNotification(BubbleBarBubble bubble, boolean isExpanding,
boolean isUpdate) {
@@ -1174,32 +1225,34 @@ public class BubbleBarViewController {
mBarView.setSelectedBubble(newlySelected.getView());
}
- /** @see #animateExpanded(boolean, boolean) */
- public void animateExpanded(boolean isExpanded) {
- animateExpanded(isExpanded, /* maybeShowEdu= */ false);
+ /** @see #setExpanded(boolean, boolean) */
+ public void setExpanded(boolean isExpanded) {
+ setExpanded(isExpanded, /* maybeShowEdu= */ false);
}
/**
- * Sets whether the bubble bar should be animated to expanded state (not unstashed, but have
- * the contents within it expanded). This method notifies SystemUI that the bubble bar is
- * expanded and showing a selected bubble. This method should ONLY be called from UI events
- * originating from Launcher.
+ * Sets whether the bubble bar should be expanded (not unstashed, but have the contents
+ * within it expanded). This method notifies SystemUI that the bubble bar is expanded and
+ * showing a selected bubble. This method should ONLY be called from UI events originating
+ * from Launcher.
*
* @param isExpanded whether the bar should be expanded
* @param maybeShowEdu whether we should show the edu view before expanding
*/
- public void animateExpanded(boolean isExpanded, boolean maybeShowEdu) {
+ public void setExpanded(boolean isExpanded, boolean maybeShowEdu) {
// if we're trying to expand try showing the edu view instead
if (maybeShowEdu && isExpanded && !mBarView.isExpanded() && maybeShowEduView()) {
return;
}
if (!mBubbleBarPinning.isAnimating() && isExpanded != mBarView.isExpanded()) {
- mBarView.animateExpanded(isExpanded);
+ mBarView.setExpanded(isExpanded);
adjustTaskbarAndHotseatToBubbleBarState(isExpanded);
if (!isExpanded) {
mSystemUiProxy.collapseBubbles();
} else {
mBubbleBarController.showSelectedBubble();
+ mTaskbarStashController.updateAndAnimateTransientTaskbar(true /* stash */,
+ false /* shouldBubblesFollow */);
}
}
}
@@ -1238,25 +1291,15 @@ public class BubbleBarViewController {
* Sets whether the bubble bar should be expanded. This method is used in response to UI events
* from SystemUI.
*/
- public void setExpandedFromSysui(boolean isExpanded, boolean animate) {
+ public void setExpandedFromSysui(boolean isExpanded) {
if (isNewBubbleAnimationRunningOrPending() && isExpanded) {
mBubbleBarViewAnimator.expandedWhileAnimating();
return;
}
- if (animate) {
- if (!isExpanded) {
- mBubbleStashController.stashBubbleBar();
- } else {
- mBubbleStashController.showBubbleBar(true /* expand the bubbles */);
- }
+ if (!isExpanded) {
+ mBubbleStashController.stashBubbleBar();
} else {
- if (!isExpanded) {
- mBubbleStashController.stashBubbleBarImmediate();
- } else {
- mBubbleStashController.showBubbleBarImmediate();
- mBarView.setExpanded(true);
- adjustTaskbarAndHotseatToBubbleBarState(true);
- }
+ mBubbleStashController.showBubbleBar(true /* expand the bubbles */);
}
}
@@ -1286,7 +1329,7 @@ public class BubbleBarViewController {
* Notifies SystemUI to expand the selected bubble when the bubble is released.
*/
public void onBubbleDragRelease(BubbleBarLocation location) {
- mSystemUiProxy.stopBubbleDrag(location, mBarView.getTopToScreenBottom());
+ mSystemUiProxy.stopBubbleDrag(location, mBarView.getRestingTopPositionOnScreen());
}
/** Handle given bubble being dismissed */
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java
index 083829bd57..c2118404e4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleControllers.java
@@ -27,8 +27,6 @@ import com.android.launcher3.taskbar.bubbles.stashing.BubbleBarLocationOnDemandL
import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.RunnableList;
-import com.android.quickstep.SystemUiProxy;
-import com.android.wm.shell.shared.bubbles.DragZoneFactory;
import java.io.PrintWriter;
import java.util.Optional;
@@ -46,7 +44,6 @@ public class BubbleControllers {
public final BubblePinController bubblePinController;
public final Optional bubbleBarSwipeController;
public final BubbleCreator bubbleCreator;
- public final DragToBubbleController dragToBubbleController;
private final RunnableList mPostInitRunnables = new RunnableList();
@@ -65,7 +62,6 @@ public class BubbleControllers {
BubbleBarPinController bubbleBarPinController,
BubblePinController bubblePinController,
Optional bubbleBarSwipeController,
- DragToBubbleController dragToBubbleController,
BubbleCreator bubbleCreator) {
this.bubbleBarController = bubbleBarController;
this.bubbleBarViewController = bubbleBarViewController;
@@ -77,7 +73,6 @@ public class BubbleControllers {
this.bubblePinController = bubblePinController;
this.bubbleBarSwipeController = bubbleBarSwipeController;
this.bubbleCreator = bubbleCreator;
- this.dragToBubbleController = dragToBubbleController;
}
/**
@@ -120,30 +115,12 @@ public class BubbleControllers {
.get(ALPHA_INDEX_BUBBLE_BAR);
}
});
- bubbleDragController.init(/* bubbleControllers = */ this, bubbleBarLocationListeners);
+ bubbleDragController.init(/* bubbleControllers = */ this);
bubbleDismissController.init(/* bubbleControllers = */ this);
bubbleBarPinController.init(this, bubbleBarLocationListeners);
bubblePinController.init(this);
bubbleBarSwipeController.ifPresent(c -> c.init(this));
- dragToBubbleController.init(bubbleBarViewController,
- new DragZoneFactory.BubbleBarPropertiesProvider() {
- @Override
- public int getHeight() {
- return (int) bubbleBarViewController.getBubbleBarCollapsedHeight();
- }
- @Override
- public int getWidth() {
- return (int) bubbleBarViewController.getBubbleBarCollapsedWidth();
- }
-
- @Override
- public int getBottomPadding() {
- return -(int) bubbleStashController.getBubbleBarTranslationY();
- }
- },
- bubbleBarLocationListeners,
- SystemUiProxy.INSTANCE.get(taskbarControllers.taskbarActivityContext));
mPostInitRunnables.executeAllAndDestroy();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDismissViewExt.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDismissViewExt.kt
index 27b30a1f3d..fdc9fb0b40 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDismissViewExt.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDismissViewExt.kt
@@ -18,7 +18,7 @@
package com.android.launcher3.taskbar.bubbles
import com.android.launcher3.R
-import com.android.wm.shell.R as SharedR // WM and WMShared are "shared" or linked together.
+import com.android.wm.shell.R as SharedR
import com.android.wm.shell.shared.bubbles.DismissView
/**
@@ -39,7 +39,6 @@ fun DismissView.setup() {
floatingGradientColorResId = android.R.color.system_neutral1_900,
backgroundResId = SharedR.drawable.floating_dismiss_background,
iconResId = SharedR.drawable.floating_dismiss_ic_close,
- applyMarginOverNavBarInset = false,
)
)
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
index 7535d366cc..3df10c0ce0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleDragController.java
@@ -30,14 +30,12 @@ import androidx.annotation.Nullable;
import androidx.dynamicanimation.animation.FloatPropertyCompat;
import com.android.launcher3.taskbar.TaskbarActivityContext;
-import com.android.launcher3.taskbar.bubbles.BubbleBarController.BubbleBarLocationListener;
import com.android.wm.shell.shared.bubbles.BaseBubblePinController.LocationChangeListener;
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.bubbles.DeviceConfig;
import com.android.wm.shell.shared.bubbles.DragZone;
import com.android.wm.shell.shared.bubbles.DragZoneFactory;
-import com.android.wm.shell.shared.bubbles.DragZoneFactory.BubbleBarPropertiesProvider;
import com.android.wm.shell.shared.bubbles.DragZoneFactory.DesktopWindowModeChecker;
import com.android.wm.shell.shared.bubbles.DragZoneFactory.SplitScreenModeChecker;
import com.android.wm.shell.shared.bubbles.DraggedObject;
@@ -90,7 +88,6 @@ public class BubbleDragController {
private BubbleDismissController mBubbleDismissController;
private BubbleBarPinController mBubbleBarPinController;
private BubblePinController mBubblePinController;
- private BubbleBarLocationListener mBubbleBarLocationListener;
private final DropTargetManager mDropTargetManager;
private final DragZoneFactory mDragZoneFactory;
private final BubbleDragZoneChangedListener mBubbleDragZoneChangedListener;
@@ -116,25 +113,8 @@ public class BubbleDragController {
return false;
}
};
- BubbleBarPropertiesProvider bubbleBarPropertiesProvider =
- new BubbleBarPropertiesProvider() {
- @Override
- public int getHeight() {
- return (int) mBubbleBarViewController.getBubbleBarCollapsedHeight();
- }
-
- @Override
- public int getWidth() {
- return (int) mBubbleBarViewController.getBubbleBarCollapsedWidth();
- }
-
- @Override
- public int getBottomPadding() {
- return (int) -mBubbleBarViewController.getBubbleBarTranslationY().value;
- }
- };
mDragZoneFactory = new DragZoneFactory(mActivity.getApplicationContext(), deviceConfig,
- splitScreenModeChecker, desktopWindowModeChecker, bubbleBarPropertiesProvider);
+ splitScreenModeChecker, desktopWindowModeChecker);
mBubbleDragZoneChangedListener = new BubbleDragZoneChangedListener();
mDropTargetManager = new DropTargetManager(mActivity.getApplicationContext(),
dropTargetParent, mBubbleDragZoneChangedListener);
@@ -145,14 +125,12 @@ public class BubbleDragController {
* Should be careful to only access things that were created in constructors for now, as some
* controllers may still be waiting for init().
*/
- public void init(@NonNull BubbleControllers bubbleControllers,
- BubbleBarLocationListener bubbleBarLocationListener) {
+ public void init(@NonNull BubbleControllers bubbleControllers) {
mBubbleBarController = bubbleControllers.bubbleBarController;
mBubbleBarViewController = bubbleControllers.bubbleBarViewController;
mBubbleDismissController = bubbleControllers.bubbleDismissController;
mBubbleBarPinController = bubbleControllers.bubbleBarPinController;
mBubblePinController = bubbleControllers.bubblePinController;
- mBubbleBarLocationListener = bubbleBarLocationListener;
mBubbleDismissController.setListener(
stuck -> {
if (stuck) {
@@ -216,7 +194,9 @@ public class BubbleDragController {
protected void onDragUpdate(float x, float y, float newTx, float newTy) {
bubbleView.setDragTranslationX(newTx);
bubbleView.setTranslationY(newTy);
- if (!BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+ if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+ mDropTargetManager.onDragUpdated((int) x, (int) y);
+ } else {
mBubblePinController.onDragUpdate(x, y);
}
}
@@ -325,7 +305,9 @@ public class BubbleDragController {
protected void onDragUpdate(float x, float y, float newTx, float newTy) {
bubbleBarView.setTranslationX(newTx);
bubbleBarView.setTranslationY(newTy);
- if (!BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+ if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+ mDropTargetManager.onDragUpdated((int) x, (int) y);
+ } else {
mBubbleBarPinController.onDragUpdate(x, y);
}
}
@@ -588,17 +570,7 @@ public class BubbleDragController {
private void drag(@NonNull View view, @NonNull MotionEvent event, float dx, float dy,
float x, float y) {
- if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
- // notify drop target manager about the new drag location regardless of whether we
- // are in the dismiss zone so that it can keep track of the current zone and update
- // the drop target view
- mDropTargetManager.onDragUpdated((int) x, (int) y);
- }
- if (mBubbleDismissController.handleTouchEvent(event)) {
- // if we're dragging within the dismiss target, return immediately; the dragged
- // object is manipulated by the dismiss target
- return;
- }
+ if (mBubbleDismissController.handleTouchEvent(event)) return;
final float newTx = mViewInitialPosition.x + dx;
final float newTy = mViewInitialPosition.y + dy;
onDragUpdate(x, y, newTx, newTy);
@@ -626,7 +598,7 @@ public class BubbleDragController {
}
} else {
mAnimator.animateToRestingState(getRestingPosition(), getCurrentVelocity(),
- onComplete);
+ onComplete);
}
}
mBubbleDismissController.hideDismissView();
@@ -678,7 +650,7 @@ public class BubbleDragController {
}
@Override
- public void onInitialDragZoneSet(@Nullable DragZone dragZone) {
+ public void onInitialDragZoneSet(@NonNull DragZone dragZone) {
mDragZone = dragZone;
if (dragZone instanceof DragZone.Bubble.Left) {
mBubbleBarLocation = BubbleBarLocation.LEFT;
@@ -688,31 +660,25 @@ public class BubbleDragController {
}
@Override
- public void onDragZoneChanged(@NonNull DraggedObject draggedObject, @Nullable DragZone from,
- @Nullable DragZone to) {
+ public void onDragZoneChanged(@NonNull DraggedObject draggedObject, @NonNull DragZone from,
+ @NonNull DragZone to) {
mDragZone = to;
if (to instanceof DragZone.Bubble.Left
&& mBubbleBarLocation != BubbleBarLocation.LEFT) {
if (draggedObject instanceof DraggedObject.Bubble) {
- // listener will be notified by BubbleBarController
mBubbleBarController.animateBubbleBarLocation(BubbleBarLocation.LEFT);
- } else {
- // otherwise notify listener manually
- mBubbleBarLocationListener.onBubbleBarLocationAnimated(BubbleBarLocation.LEFT);
}
mBubbleBarLocation = BubbleBarLocation.LEFT;
} else if (to instanceof DragZone.Bubble.Right
&& mBubbleBarLocation != BubbleBarLocation.RIGHT) {
if (draggedObject instanceof DraggedObject.Bubble) {
mBubbleBarController.animateBubbleBarLocation(BubbleBarLocation.RIGHT);
- } else {
- mBubbleBarLocationListener.onBubbleBarLocationAnimated(BubbleBarLocation.RIGHT);
}
mBubbleBarLocation = BubbleBarLocation.RIGHT;
}
}
@Override
- public void onDragEnded(@Nullable DragZone zone) {}
+ public void onDragEnded(@NonNull DragZone zone) {}
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
index 7e2b139f2b..ec540e0088 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
@@ -85,6 +85,7 @@ public class BubbleStashedHandleViewController {
mActivity = activity;
mStashedHandleView = stashedHandleView;
mStashedHandleAlpha = new MultiValueAlpha(mStashedHandleView, 1);
+ mStashedHandleAlpha.setUpdateVisibility(true);
}
/** Initialize controller. */
@@ -104,7 +105,7 @@ public class BubbleStashedHandleViewController {
// Use values directly from device profile to avoid referencing other bubble controllers
// during init flow.
int maxTy = Math.max(deviceProfile.hotseatBarBottomSpacePx,
- deviceProfile.getTaskbarProfile().getBottomMargin());
+ deviceProfile.taskbarBottomMargin);
// Adjust handle view size to accommodate the handle morphing into the bubble bar
mStashedHandleView.getLayoutParams().height = barSize + maxTy;
@@ -348,7 +349,7 @@ public class BubbleStashedHandleViewController {
// the bounds of the handle only include the visible part, so we check that the Y coordinate
// is anywhere within the stashed height of bubble bar (same as taskbar stashed height).
- final int top = mActivity.getDeviceProfile().getDeviceProperties().getHeightPx() - mStashedBubbleBarHeight;
+ final int top = mActivity.getDeviceProfile().heightPx - mStashedBubbleBarHeight;
final float x = ev.getRawX();
return ev.getRawY() >= top && x >= mStashedHandleBounds.left
&& x <= mStashedHandleBounds.right;
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 15fe35b3cc..622fea2928 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
@@ -728,7 +728,7 @@ constructor(
}
private fun expandBubbleBar() {
- bubbleBarView.animateExpanded(true)
+ bubbleBarView.isExpanded = true
onExpanded.run()
}
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 4a2f029fd5..fea40f9211 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt
@@ -64,7 +64,6 @@ constructor(
}
fun setUpAndShowFlyout(message: BubbleBarFlyoutMessage, onInit: () -> Unit, onEnd: () -> Unit) {
- animator?.cancel()
flyout?.let(container::removeView)
val flyout = BubbleBarFlyoutView(container.context, positioner, flyoutScheduler)
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt
index 56622020e8..ec272ac873 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt
@@ -186,14 +186,12 @@ interface BubbleStashController {
fun getHandleViewAlpha(): MultiPropertyFactory.MultiProperty? = null
/**
- * Default implementation only analyse [isBubblesShowingOnHome] and return value is equal to
- * [targetTranslationYForState].
+ * Returns bubble bar Y position according to [isBubblesShowingOnHome] and
+ * [isBubblesShowingOnOverview] values. Default implementation only analyse
+ * [isBubblesShowingOnHome] and return translationY to align with the hotseat vertical center.
+ * For Other cases align bubbles with the taskbar.
*/
val bubbleBarTranslationY: Float
- get() = targetTranslationYForState
-
- /** Returns bubble bar Y target position according to [isBubblesShowingOnHome] value. */
- val targetTranslationYForState: Float
get() =
if (isBubblesShowingOnHome) {
bubbleBarTranslationYForHotseat
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/DeviceProfileDimensionsProviderAdapter.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/DeviceProfileDimensionsProviderAdapter.kt
index 2408274c9f..886b9f02c2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/DeviceProfileDimensionsProviderAdapter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/DeviceProfileDimensionsProviderAdapter.kt
@@ -27,9 +27,9 @@ import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController.Task
class DeviceProfileDimensionsProviderAdapter(
private val taskbarActivityContext: TaskbarActivityContext
) : TaskbarHotseatDimensionsProvider {
- override fun getTaskbarBottomSpace(): Int = taskbarDp().taskbarProfile.bottomMargin
+ override fun getTaskbarBottomSpace(): Int = taskbarDp().taskbarBottomMargin
- override fun getTaskbarHeight(): Int = taskbarDp().taskbarProfile.height
+ override fun getTaskbarHeight(): Int = taskbarDp().taskbarHeight
private fun taskbarDp(): DeviceProfile = taskbarActivityContext.deviceProfile
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt
index 5c8746cb8b..9d8c0ed970 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt
@@ -60,10 +60,6 @@ class PersistentBubbleStashController(
// if there are no bubbles, there's nothing to show, so just return.
return
}
- if (transitionFromHome && inAppDisplayOverrideProgress != 0f) {
- // was on -1 page and leaving it, - reset the inAppDisplayOverrideProgress
- inAppDisplayOverrideProgress = 0f
- }
// If we're transitioning anywhere, bubble bar should be collapsed
updateExpandedState(expand = false)
if (transitionFromHome || field == BubbleLauncherState.HOME) {
@@ -104,10 +100,6 @@ class PersistentBubbleStashController(
return -bubbleBarVerticalCenterForHome + bubbleBarHeight / 2
}
- /**
- * Returns bubble bar Y target position according to [isBubblesShowingOnHome] value. Value could
- * be adjusted to the display override progress.
- */
override val bubbleBarTranslationY: Float
get() =
if (inAppDisplayOverrideProgress > 0f && launcherState == BubbleLauncherState.HOME) {
@@ -120,7 +112,7 @@ class PersistentBubbleStashController(
Interpolators.LINEAR,
)
} else {
- targetTranslationYForState
+ super.bubbleBarTranslationY
}
override var inAppDisplayOverrideProgress: Float = 0f
@@ -246,7 +238,7 @@ class PersistentBubbleStashController(
}
if (bubbleBarViewController.isExpanded != expand) {
val maybeShowEdu = expand && bubbleBarGesture
- bubbleBarViewController.animateExpanded(expand, maybeShowEdu)
+ bubbleBarViewController.setExpanded(expand, maybeShowEdu)
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
index 00e79029e2..82bb071bc3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
@@ -115,16 +115,7 @@ class TransientBubbleStashController(
}
// Only stash if we're in an app, otherwise we're in home or overview where we should
// be un-stashed
- val stash = field == BubbleLauncherState.IN_APP
- val expand =
- if (stash) {
- // Always collapse when we are stashing
- false
- } else {
- // If unstashing, keep the current state
- bubbleBarViewController.isExpanded
- }
- updateStashedAndExpandedState(stash, expand)
+ updateStashedAndExpandedState(field == BubbleLauncherState.IN_APP, expand = false)
}
override var isSysuiLocked: Boolean = false
@@ -477,7 +468,7 @@ class TransientBubbleStashController(
// reset stash translation
translationYDuringStash.updateValue(0f)
bubbleBarBubbleTranslationY.updateValue(0f)
- bubbleBarViewController.animateExpanded(false)
+ bubbleBarViewController.isExpanded = false
}
taskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
}
@@ -565,7 +556,6 @@ class TransientBubbleStashController(
) {
if (bubbleBarViewController.isHiddenForNoBubbles) {
// If there are no bubbles the bar and handle are invisible, nothing to do here.
- cancelAnimation()
return
}
val isStashed = stash && !isBubblesShowingOnHome && !isBubblesShowingOnOverview
@@ -587,7 +577,7 @@ class TransientBubbleStashController(
}
if (bubbleBarViewController.isExpanded != expand) {
val maybeShowEdu = expand && bubbleBarGesture
- bubbleBarViewController.animateExpanded(expand, maybeShowEdu)
+ bubbleBarViewController.setExpanded(expand, maybeShowEdu)
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarAllAppsButtonContainer.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarAllAppsButtonContainer.kt
index 2807668107..a1df21fa04 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarAllAppsButtonContainer.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarAllAppsButtonContainer.kt
@@ -49,15 +49,11 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
private var allAppsTouchTriggered = false
private var allAppsTouchRunnable: Runnable? = null
private var allAppsButtonTouchDelayMs: Long = ViewConfiguration.getLongPressTimeout().toLong()
- private var isTaskbarInMinimalState = false
private lateinit var taskbarViewCallbacks: TaskbarViewCallbacks
override val spaceNeeded: Int
get() {
- return dpToPx(
- activityContext.taskbarSpecsEvaluator.taskbarIconSize.size.toFloat(),
- activityContext,
- )
+ return dpToPx(activityContext.taskbarSpecsEvaluator.taskbarIconSize.size.toFloat())
}
init {
@@ -74,12 +70,7 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
backgroundTintList = ColorStateList.valueOf(TRANSPARENT)
setIconDrawable(drawable)
if (!activityContext.isTransientTaskbar) {
- setPadding(
- dpToPx(
- (activityContext.taskbarSpecsEvaluator.taskbarIconPadding).toFloat(),
- activityContext,
- )
- )
+ setPadding(dpToPx(activityContext.taskbarSpecsEvaluator.taskbarIconPadding.toFloat()))
}
setForegroundTint(activityContext.getColor(R.color.all_apps_button_color))
}
@@ -111,26 +102,29 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
return getAllAppsButtonForExpressiveTheme()
}
val shouldSelectTransientIcon =
- isTransientTaskbar ||
- (enableTaskbarPinning() &&
- activityContext.taskbarFeatureEvaluator.supportsTransitionToTransientTaskbar)
+ isTransientTaskbar || (enableTaskbarPinning() && !activityContext.isThreeButtonNav)
return if (shouldSelectTransientIcon) R.drawable.ic_transient_taskbar_all_apps_search_button
else R.drawable.ic_taskbar_all_apps_search_button
}
@DrawableRes
private fun getAllAppsButtonForExpressiveTheme(): Int {
- return if (isTaskbarInMinimalState) {
- R.drawable.ic_taskbar_minimal_state_all_apps_search_button_expressive_theme
+ return R.drawable.ic_taskbar_all_apps_search_button_expressive_theme
+ }
+
+ @DimenRes
+ fun getAllAppsButtonTranslationXOffsetForExpressiveTheme(isTransientTaskbar: Boolean): Int {
+ return if (isTransientTaskbar) {
+ R.dimen.transient_taskbar_all_apps_button_translation_x_offset_for_expressive_theme
} else {
- R.drawable.ic_taskbar_all_apps_search_button_expressive_theme
+ R.dimen.taskbar_all_apps_search_button_translation_x_offset_for_expressive_theme
}
}
@DimenRes
fun getAllAppsButtonTranslationXOffset(isTransientTaskbar: Boolean): Int {
if (Flags.enableGsf()) {
- return R.dimen.taskbar_all_apps_search_button_translation_x_offset_for_expressive_theme
+ return getAllAppsButtonTranslationXOffsetForExpressiveTheme(isTransientTaskbar)
}
return if (isTransientTaskbar) {
R.dimen.transient_taskbar_all_apps_button_translation_x_offset
@@ -139,14 +133,6 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
}
}
- /** Taskbar minimal state is that taskbar does not host anything other than all apps button. */
- fun updateTaskbarMinimalState(isInMinimalState: Boolean) {
- if (isTaskbarInMinimalState != isInMinimalState) {
- isTaskbarInMinimalState = isInMinimalState
- setUpIcon()
- }
- }
-
private fun onAllAppsButtonTouch(view: View, ev: MotionEvent): Boolean {
when (ev.action) {
MotionEvent.ACTION_DOWN -> {
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarDividerContainer.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarDividerContainer.kt
index 96dc5c8447..08a1b48acf 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarDividerContainer.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarDividerContainer.kt
@@ -40,10 +40,7 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
override val spaceNeeded: Int
get() {
- return dpToPx(
- activityContext.taskbarSpecsEvaluator.taskbarIconSize.size.toFloat(),
- activityContext,
- )
+ return dpToPx(activityContext.taskbarSpecsEvaluator.taskbarIconSize.size.toFloat())
}
init {
@@ -56,12 +53,7 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
val drawable = getTaskbarDividerIcon()
setIconDrawable(drawable)
if (!activityContext.isTransientTaskbar) {
- setPadding(
- dpToPx(
- activityContext.taskbarSpecsEvaluator.taskbarIconPadding.toFloat(),
- activityContext,
- )
- )
+ setPadding(dpToPx(activityContext.taskbarSpecsEvaluator.taskbarIconPadding.toFloat()))
}
}
@@ -75,8 +67,8 @@ constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
}
@SuppressLint("ClickableViewAccessibility")
- fun setUpCallbacks(callbacks: TaskbarViewCallbacks?) {
- setOnLongClickListener(callbacks?.taskbarDividerLongClickListener)
- setOnTouchListener(callbacks?.taskbarDividerRightClickListener)
+ fun setUpCallbacks(callbacks: TaskbarViewCallbacks) {
+ setOnLongClickListener(callbacks.taskbarDividerLongClickListener)
+ setOnTouchListener(callbacks.taskbarDividerRightClickListener)
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
index 2de143e979..a14c5a47e6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarFeatureEvaluator.kt
@@ -38,17 +38,11 @@ private constructor(private val taskbarActivityContext: TaskbarActivityContext)
get() = taskbarActivityContext.isTransientTaskbar
val isLandscape: Boolean
- get() = taskbarActivityContext.deviceProfile.deviceProperties.isLandscape
-
- val isTnMinimalState: Boolean
- get() = taskbarActivityContext.isTaskbarInMinimalState
+ get() = taskbarActivityContext.deviceProfile.isLandscape
val supportsPinningPopup: Boolean
get() = !hasNavButtons
- val supportsTransitionToTransientTaskbar: Boolean
- get() = !hasNavButtons && !taskbarActivityContext.showDesktopTaskbarForFreeformDisplay()
-
fun onDestroy() {
taskbarFeatureEvaluator = null
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt
index 13c878ee6f..f1ed6c5ea0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt
@@ -35,7 +35,7 @@ class TaskbarSpecsEvaluator(
val taskbarIconPadding: Int =
if (
TaskbarIconSpecs.transientOrPinnedTaskbarIconPaddingSize.size > taskbarIconSize.size &&
- taskbarFeatureEvaluator.supportsTransitionToTransientTaskbar
+ !taskbarFeatureEvaluator.hasNavButtons
) {
(TaskbarIconSpecs.iconSize52dp.size - taskbarIconSize.size) / 2
} else {
diff --git a/quickstep/src/com/android/launcher3/taskbar/growth/NudgeController.kt b/quickstep/src/com/android/launcher3/taskbar/growth/NudgeController.kt
index 5c5990eb24..04e41bc3bd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/growth/NudgeController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/growth/NudgeController.kt
@@ -16,34 +16,15 @@
package com.android.launcher3.taskbar.growth
import android.content.Context
-import android.os.Bundle
-import android.view.View
-import android.view.View.GONE
-import android.view.ViewGroup.LayoutParams.MATCH_PARENT
-import android.view.ViewGroup.MarginLayoutParams
-import android.view.accessibility.AccessibilityEvent
-import android.view.accessibility.AccessibilityNodeInfo
-import android.widget.Button
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.annotation.LayoutRes
-import androidx.core.view.updateLayoutParams
-import com.airbnb.lottie.LottieAnimationView
-import com.android.launcher3.R
import com.android.launcher3.Utilities
import com.android.launcher3.taskbar.TaskbarActivityContext
-import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_GROWTH_NUDGE_OPEN
import com.android.launcher3.taskbar.TaskbarControllers
import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController
+import com.android.launcher3.util.DisplayController
import com.android.launcher3.views.ActivityContext
-import com.android.quickstep.util.LottieAnimationColorUtils
import java.io.PrintWriter
-/**
- * Controls nudge lifecycles.
- *
- * TODO: b/413718172 - Refactor to reduce code duplication with [TaskbarEduTooltipController].
- */
+/** Controls nudge lifecycles. */
class NudgeController(context: Context) : LoggableTaskbarController {
protected val activityContext: TaskbarActivityContext = ActivityContext.lookupContext(context)
@@ -55,184 +36,26 @@ class NudgeController(context: Context) : LoggableTaskbarController {
!activityContext.isTinyTaskbar
}
- val isNudgeOpen: Boolean
- get() = nudgeView?.isOpen == true
-
private lateinit var controllers: TaskbarControllers
- private var nudgeView: NudgeView? = null
-
fun init(controllers: TaskbarControllers) {
this.controllers = controllers
}
- fun maybeShow(model: NudgePayload) {
- if (!isNudgeEnabled || !activityContext.isTransientTaskbar) {
+ fun maybeShow(payload: NudgePayload) {
+ if (!isNudgeEnabled || !DisplayController.isTransientTaskbar(activityContext)) {
return
}
-
- inflateNudgeContent(R.layout.growth_nudge)
- nudgeView?.run {
- allowTouchDismissal = false
-
- fun updateButton(button: Button, buttonPayload: ButtonPayload?) {
- if (buttonPayload != null) {
- button.apply {
- text = buttonPayload.label
- setOnClickListener {
- ActionPerformers.performActions(
- /*actions=*/ buttonPayload.actions,
- /*context=*/ activityContext,
- /*dismissCallback=*/ ::hide,
- )
- }
- }
- } else {
- button.visibility = GONE
- }
- }
-
- fun updateImage(image: Image?) {
- val imageView = requireViewById(R.id.image_view)
- when (image) {
- is Image.ResourceId -> {
- imageView.setImageDrawable(context.getDrawable(image.resId))
- }
- null -> imageView.visibility = GONE
- }
- }
-
- fun updateContent() {
- // Update content.
- val title = requireViewById(R.id.title)
- title.text = model.titleText
- val body = requireViewById(R.id.body)
- body.text = model.bodyText
- updateButton(requireViewById(R.id.primary_button), model.primaryButton)
- updateButton(requireViewById(R.id.secondary_button), model.secondaryButton)
- updateImage(model.image)
- }
-
- fun updateLayout() {
- content.updateLayoutParams { width = MATCH_PARENT }
- val sideSpacing =
- resources.getDimensionPixelSize(R.dimen.nudge_default_position_side_spacing)
- updateLayoutParams {
- if (Utilities.isRtl(context.getResources())) {
- rightMargin = sideSpacing
- } else {
- leftMargin = sideSpacing
- }
- width = resources.getDimensionPixelSize(R.dimen.nudge_width)
- }
- }
-
- updateContent()
- updateLayout()
- show()
- }
+ // TODO: b/398033012 - create and show nudge view based on the payload.
}
/** Closes the current [nudgeView]. */
fun hide() {
- nudgeView?.close(true)
+ // TODO: b/398033012 - hide the nudge view.
}
- /** Initializes [nudgeView] with content from [contentResId]. */
- private fun inflateNudgeContent(@LayoutRes contentResId: Int) {
- val overlayContext = controllers.taskbarOverlayController.requestWindow()
- val nudgeView =
- overlayContext.layoutInflater.inflate(
- R.layout.taskbar_nudge_container,
- overlayContext.dragLayer,
- false,
- ) as NudgeView
-
- controllers.taskbarAutohideSuspendController.updateFlag(
- FLAG_AUTOHIDE_SUSPEND_GROWTH_NUDGE_OPEN,
- true,
- )
-
- nudgeView.onCloseCallback = {
- this.nudgeView = null
- controllers.taskbarAutohideSuspendController.updateFlag(
- FLAG_AUTOHIDE_SUSPEND_GROWTH_NUDGE_OPEN,
- false,
- )
- controllers.taskbarStashController.updateAndAnimateTransientTaskbar(true)
- }
- nudgeView.accessibilityDelegate = createAccessibilityDelegate()
-
- overlayContext.layoutInflater.inflate(contentResId, nudgeView.content, true)
- this.nudgeView = nudgeView
- }
-
- private fun createAccessibilityDelegate() =
- object : View.AccessibilityDelegate() {
- override fun performAccessibilityAction(
- host: View,
- action: Int,
- args: Bundle?,
- ): Boolean {
- if (action == R.id.close) {
- hide()
- return true
- }
- return super.performAccessibilityAction(host, action, args)
- }
-
- override fun onPopulateAccessibilityEvent(host: View, event: AccessibilityEvent) {
- super.onPopulateAccessibilityEvent(host, event)
- if (event.eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
- event.text.add(host.context?.getText(R.string.nudge_a11y_title))
- }
- }
-
- override fun onInitializeAccessibilityNodeInfo(
- host: View,
- info: AccessibilityNodeInfo,
- ) {
- super.onInitializeAccessibilityNodeInfo(host, info)
- info.addAction(
- AccessibilityNodeInfo.AccessibilityAction(
- R.id.close,
- host.context?.getText(R.string.nudge_a11y_close),
- )
- )
- }
- }
-
override fun dumpLogs(prefix: String?, pw: PrintWriter?) {
pw?.println(prefix + "NudgeController:")
pw?.println("$prefix\tisNudgeEnabled=$isNudgeEnabled")
- pw?.println("$prefix\tisOpen=$isNudgeOpen")
}
}
-
-/**
- * Maps colors in the dark-themed Lottie assets to their light-themed equivalents.
- *
- * For instance, `".blue100" to R.color.lottie_blue400` means objects that are material blue100 in
- * dark theme should be changed to material blue400 in light theme.
- */
-private val DARK_TO_LIGHT_COLORS =
- mapOf(
- ".blue100" to R.color.lottie_blue400,
- ".blue400" to R.color.lottie_blue600,
- ".green100" to R.color.lottie_green400,
- ".green400" to R.color.lottie_green600,
- ".grey300" to R.color.lottie_grey600,
- ".grey400" to R.color.lottie_grey700,
- ".grey800" to R.color.lottie_grey200,
- ".red400" to R.color.lottie_red600,
- ".yellow100" to R.color.lottie_yellow400,
- ".yellow400" to R.color.lottie_yellow600,
- )
-
-private fun LottieAnimationView.supportLightTheme() {
- if (Utilities.isDarkTheme(context)) {
- return
- }
-
- LottieAnimationColorUtils.updateToColorResources(this, DARK_TO_LIGHT_COLORS, context.theme)
-}
diff --git a/quickstep/src/com/android/launcher3/taskbar/growth/NudgePayload.kt b/quickstep/src/com/android/launcher3/taskbar/growth/NudgePayload.kt
index 7c167b959d..7498cbc9b0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/growth/NudgePayload.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/growth/NudgePayload.kt
@@ -26,6 +26,8 @@ sealed interface Action {
sealed class Image {
data class ResourceId(val resId: Int) : Image()
+
+ data class Url(val url: String) : Image()
}
data class ButtonPayload(val label: String, val actions: List)
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt
index 918d5cf71e..3712a76eab 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt
@@ -90,7 +90,7 @@ abstract class AbstractNavButtonLayoutter(
resources.getDimensionPixelSize(R.dimen.taskbar_contextual_button_suw_margin)
nearestTouchFrameLayoutParams.marginStart = phoneOrPortraitSetupMargin
nearestTouchFrameLayoutParams.bottomMargin =
- if (!deviceProfile.deviceProperties.isLandscape) 0
+ if (!deviceProfile.isLandscape) 0
else
phoneOrPortraitSetupMargin -
resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size) / 2
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt
index 17e63e8bd3..a199dba0bd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt
@@ -90,7 +90,7 @@ class NavButtonLayoutFactory {
)
}
isPhoneNavMode -> {
- if (!deviceProfile.deviceProperties.isLandscape) {
+ if (!deviceProfile.isLandscape) {
navButtonsView.setIsVertical(false)
PhonePortraitNavLayoutter(
resources,
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt
index 00ba40c7f9..9f7f07e773 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt
@@ -25,7 +25,6 @@ import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Space
import com.android.launcher3.R
-import com.android.launcher3.Utilities
import com.android.launcher3.taskbar.TaskbarActivityContext
open class PhoneLandscapeNavLayoutter(
@@ -35,7 +34,7 @@ open class PhoneLandscapeNavLayoutter(
startContextualContainer: ViewGroup,
imeSwitcher: ImageView?,
a11yButton: ImageView?,
- space: Space?,
+ space: Space?
) :
AbstractNavButtonLayoutter(
resources,
@@ -44,11 +43,11 @@ open class PhoneLandscapeNavLayoutter(
startContextualContainer,
imeSwitcher,
a11yButton,
- space,
+ space
) {
override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) {
- val totalHeight = context.deviceProfile.deviceProperties.heightPx
+ val totalHeight = context.deviceProfile.heightPx
val homeButtonHeight =
resources.getDimensionPixelSize(R.dimen.taskbar_phone_home_button_size)
val roundedCornerContentMargin =
@@ -113,15 +112,9 @@ open class PhoneLandscapeNavLayoutter(
open fun addThreeButtons() {
// Swap recents and back button
- if (Utilities.isRtl(resources)) {
- navButtonContainer.addView(backButton)
- navButtonContainer.addView(homeButton)
- navButtonContainer.addView(recentsButton)
- } else {
- navButtonContainer.addView(recentsButton)
- navButtonContainer.addView(homeButton)
- navButtonContainer.addView(backButton)
- }
+ navButtonContainer.addView(recentsButton)
+ navButtonContainer.addView(homeButton)
+ navButtonContainer.addView(backButton)
}
open fun repositionContextualButtons(buttonSize: Int) {
@@ -136,14 +129,14 @@ open class PhoneLandscapeNavLayoutter(
buttonSize,
roundedCornerContentMargin + contentPadding,
0,
- Gravity.TOP,
+ Gravity.TOP
)
repositionContextualContainer(
endContextualContainer,
buttonSize,
0,
roundedCornerContentMargin + contentPadding,
- Gravity.BOTTOM,
+ Gravity.BOTTOM
)
if (imeSwitcher != null) {
@@ -162,7 +155,7 @@ open class PhoneLandscapeNavLayoutter(
buttonSize: Int,
barAxisMarginTop: Int,
barAxisMarginBottom: Int,
- gravity: Int,
+ gravity: Int
) {
val contextualContainerParams = FrameLayout.LayoutParams(MATCH_PARENT, buttonSize)
contextualContainerParams.apply {
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt
index 833a309e83..5b24ebfe1d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt
@@ -34,7 +34,7 @@ class PhonePortraitNavLayoutter(
startContextualContainer: ViewGroup,
imeSwitcher: ImageView?,
a11yButton: ImageView?,
- space: Space?,
+ space: Space?
) :
AbstractNavButtonLayoutter(
resources,
@@ -43,11 +43,11 @@ class PhonePortraitNavLayoutter(
startContextualContainer,
imeSwitcher,
a11yButton,
- space,
+ space
) {
override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) {
- val totalWidth = context.deviceProfile.deviceProperties.widthPx
+ val totalWidth = context.deviceProfile.widthPx
val homeButtonWidth =
resources.getDimensionPixelSize(R.dimen.taskbar_phone_home_button_size)
val roundedCornerContentMargin =
@@ -63,7 +63,7 @@ class PhonePortraitNavLayoutter(
val navContainerParams =
FrameLayout.LayoutParams(
navButtonContainerWidth.toInt(),
- ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
)
navContainerParams.apply {
topMargin = 0
@@ -120,14 +120,14 @@ class PhonePortraitNavLayoutter(
contextualButtonWidth.toInt(),
roundedCornerContentMargin + contentPadding,
0,
- Gravity.START,
+ Gravity.START
)
repositionContextualContainer(
endContextualContainer,
contextualButtonWidth.toInt(),
0,
roundedCornerContentMargin + contentPadding,
- Gravity.END,
+ Gravity.END
)
startContextualContainer.addView(space, MATCH_PARENT, MATCH_PARENT)
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneSeascapeNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneSeascapeNavLayoutter.kt
index cf6f89857a..f0b47f4caa 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneSeascapeNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneSeascapeNavLayoutter.kt
@@ -24,7 +24,6 @@ import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Space
import com.android.launcher3.R
-import com.android.launcher3.Utilities
class PhoneSeascapeNavLayoutter(
resources: Resources,
@@ -33,7 +32,7 @@ class PhoneSeascapeNavLayoutter(
startContextualContainer: ViewGroup,
imeSwitcher: ImageView?,
a11yButton: ImageView?,
- space: Space?,
+ space: Space?
) :
PhoneLandscapeNavLayoutter(
resources,
@@ -42,20 +41,14 @@ class PhoneSeascapeNavLayoutter(
startContextualContainer,
imeSwitcher,
a11yButton,
- space,
+ space
) {
override fun addThreeButtons() {
// Flip ordering of back and recents buttons
- if (Utilities.isRtl(resources)) {
- navButtonContainer.addView(recentsButton)
- navButtonContainer.addView(homeButton)
- navButtonContainer.addView(backButton)
- } else {
- navButtonContainer.addView(backButton)
- navButtonContainer.addView(homeButton)
- navButtonContainer.addView(recentsButton)
- }
+ navButtonContainer.addView(backButton)
+ navButtonContainer.addView(homeButton)
+ navButtonContainer.addView(recentsButton)
}
override fun repositionContextualButtons(buttonSize: Int) {
@@ -70,14 +63,14 @@ class PhoneSeascapeNavLayoutter(
buttonSize,
roundedCornerContentMargin + contentPadding,
0,
- Gravity.TOP,
+ Gravity.TOP
)
repositionContextualContainer(
endContextualContainer,
buttonSize,
0,
roundedCornerContentMargin + contentPadding,
- Gravity.BOTTOM,
+ Gravity.BOTTOM
)
startContextualContainer.addView(space, MATCH_PARENT, MATCH_PARENT)
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt
index 24998d4178..eb3fdeb99e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt
@@ -59,9 +59,7 @@ class SetupNavLayoutter(
override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) {
val SUWTheme = SystemProperties.get(SUW_THEME_SYSTEM_PROPERTY, "")
- val expressiveThemeEnabled =
- SUWTheme == GLIF_EXPRESSIVE_THEME || SUWTheme == GLIF_EXPRESSIVE_LIGHT_THEME
- if (expressiveThemeEnabled && !context.isSimpleViewEnabled) {
+ if (SUWTheme == GLIF_EXPRESSIVE_THEME || SUWTheme == GLIF_EXPRESSIVE_LIGHT_THEME) {
return
}
// Since setup wizard only has back button enabled, it looks strange to be
@@ -72,15 +70,15 @@ class SetupNavLayoutter(
val deviceProfile: DeviceProfile = context.deviceProfile
navButtonsLayoutParams.marginEnd = 0
- navButtonsLayoutParams.gravity = Gravity.START or Gravity.CENTER_VERTICAL
+ navButtonsLayoutParams.gravity = Gravity.START
context.setTaskbarWindowSize(context.setupWindowSize)
// If SUW is on a large screen device that is landscape (or has a square aspect
// ratio) the back button has to be placed accordingly
if (
- deviceProfile.deviceProperties.isTablet && deviceProfile.deviceProperties.isLandscape ||
- (deviceProfile.deviceProperties.aspectRatio > SQUARE_ASPECT_RATIO_BOTTOM_BOUND &&
- deviceProfile.deviceProperties.aspectRatio < SQUARE_ASPECT_RATIO_UPPER_BOUND)
+ deviceProfile.isTablet && deviceProfile.isLandscape ||
+ (deviceProfile.aspectRatio > SQUARE_ASPECT_RATIO_BOTTOM_BOUND &&
+ deviceProfile.aspectRatio < SQUARE_ASPECT_RATIO_UPPER_BOUND)
) {
navButtonsLayoutParams.marginStart =
resources.getDimensionPixelSize(R.dimen.taskbar_back_button_suw_start_margin)
diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt
index bef432e668..a59e8a847b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt
@@ -35,7 +35,7 @@ class TaskbarNavLayoutter(
startContextualContainer: ViewGroup,
imeSwitcher: ImageView?,
a11yButton: ImageView?,
- space: Space?,
+ space: Space?
) :
AbstractNavButtonLayoutter(
resources,
@@ -44,7 +44,7 @@ class TaskbarNavLayoutter(
startContextualContainer,
imeSwitcher,
a11yButton,
- space,
+ space
) {
override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) {
@@ -69,7 +69,7 @@ class TaskbarNavLayoutter(
val navButtonParams =
FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
)
navButtonParams.apply {
gravity = Gravity.END or Gravity.CENTER_VERTICAL
@@ -101,7 +101,7 @@ class TaskbarNavLayoutter(
endContextualContainer.removeAllViews()
startContextualContainer.removeAllViews()
- if (!context.deviceProfile.deviceProperties.isGestureMode) {
+ if (!context.deviceProfile.isGestureMode) {
val contextualMargin =
resources.getDimensionPixelSize(R.dimen.taskbar_contextual_button_padding)
repositionContextualContainer(endContextualContainer, WRAP_CONTENT, 0, 0, Gravity.END)
@@ -110,7 +110,7 @@ class TaskbarNavLayoutter(
WRAP_CONTENT,
contextualMargin,
contextualMargin,
- Gravity.START,
+ Gravity.START
)
if (imeSwitcher != null) {
@@ -122,7 +122,7 @@ class TaskbarNavLayoutter(
val imeSwitcherButtonParams =
FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT
)
imeSwitcherButtonParams.apply {
marginStart = imeStartMargin
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
index c964474912..6db300bf59 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
@@ -16,14 +16,12 @@
package com.android.launcher3.taskbar.overlay;
import android.content.Context;
-import android.graphics.Point;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Flags;
import com.android.launcher3.R;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.taskbar.BaseTaskbarContext;
@@ -59,14 +57,13 @@ public class TaskbarOverlayContext extends BaseTaskbarContext {
Context windowContext,
TaskbarActivityContext taskbarContext,
TaskbarControllers controllers) {
- super(windowContext, taskbarContext.getDisplayId(), taskbarContext.isPrimaryDisplay());
+ super(windowContext, taskbarContext.isPrimaryDisplay());
mTaskbarContext = taskbarContext;
mOverlayController = controllers.taskbarOverlayController;
mDragController = new TaskbarDragController(this);
mDragController.init(controllers);
mDragLayer = new TaskbarOverlayDragLayer(this);
mStashedTaskbarHeight = controllers.taskbarStashController.getStashedHeight();
- updateBlurStyle();
mUiController = controllers.uiController;
onViewCreated();
@@ -128,20 +125,6 @@ public class TaskbarOverlayContext extends BaseTaskbarContext {
return mDragLayer.findViewById(R.id.apps_view);
}
- @Override
- public boolean isAllAppsBackgroundBlurEnabled() {
- return Flags.allAppsBlur() && mOverlayController != null
- && mOverlayController.isBackgroundBlurEnabled();
- }
-
- /** Apply the blur or blur fallback style to the current theme. */
- private void updateBlurStyle() {
- if (!Flags.allAppsBlur()) {
- return;
- }
- getTheme().applyStyle(getAllAppsBlurStyleResId(), true);
- }
-
@Override
public View.OnClickListener getItemOnClickListener() {
return mTaskbarContext.getItemOnClickListener();
@@ -183,11 +166,6 @@ public class TaskbarOverlayContext extends BaseTaskbarContext {
return mTaskbarContext.isInDesktopMode();
}
- @Override
- public boolean isTaskbarShowingDesktopTasks() {
- return mTaskbarContext.isTaskbarShowingDesktopTasks();
- }
-
@Override
public boolean showLockedTaskbarOnHome() {
return mTaskbarContext.showLockedTaskbarOnHome();
@@ -199,18 +177,8 @@ public class TaskbarOverlayContext extends BaseTaskbarContext {
}
@Override
- public Point getScreenSize() {
- return mTaskbarContext.getScreenSize();
- }
-
- @Override
- public int getDisplayHeight() {
- return mTaskbarContext.getDisplayHeight();
- }
-
- @Override
- public void notifyConfigChanged() {
- mTaskbarContext.notifyConfigChanged();
+ public boolean isPrimaryDisplay() {
+ return mTaskbarContext.isPrimaryDisplay();
}
@Override
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
index 4905287356..178fe9d6b6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java
@@ -15,11 +15,9 @@
*/
package com.android.launcher3.taskbar.overlay;
-import static android.os.Trace.TRACE_TAG_APP;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_CONSUME_IME_INSETS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-import static android.window.DesktopModeFlags.ENABLE_TASKBAR_OVERFLOW;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
@@ -28,12 +26,8 @@ import static com.android.launcher3.LauncherState.ALL_APPS;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.PixelFormat;
-import android.gui.EarlyWakeupInfo;
-import android.os.Binder;
-import android.os.Trace;
import android.util.Log;
import android.view.AttachedSurfaceControl;
-import android.view.CrossWindowBlurListeners;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.SurfaceControl;
@@ -104,10 +98,6 @@ public final class TaskbarOverlayController {
private TaskbarControllers mControllers; // Initialized in init.
// True if we have alerted surface flinger of an expensive call for blur.
private boolean mInEarlyWakeUp;
- /**
- * Token for early wakeup requests to SurfaceFlinger.
- */
- private EarlyWakeupInfo mEarlyWakeupInfo = new EarlyWakeupInfo();
public TaskbarOverlayController(
TaskbarActivityContext taskbarContext, DeviceProfile launcherDeviceProfile) {
@@ -118,8 +108,6 @@ public final class TaskbarOverlayController {
mLauncherDeviceProfile = launcherDeviceProfile;
mMaxBlurRadius = mTaskbarContext.getResources().getDimensionPixelSize(
R.dimen.max_depth_blur_radius_enhanced);
- mEarlyWakeupInfo.token = new Binder();
- mEarlyWakeupInfo.trace = TaskbarOverlayController.class.getName();
}
/** Initialize the controller. */
@@ -133,7 +121,7 @@ public final class TaskbarOverlayController {
*/
public TaskbarOverlayContext requestWindow() {
if (mOverlayContext == null) {
- mOverlayContext = TaskbarOverlayContextFactory.newInstance(mWindowContext).create(
+ mOverlayContext = new TaskbarOverlayContext(
mWindowContext, mTaskbarContext, mControllers);
}
@@ -189,7 +177,7 @@ public final class TaskbarOverlayController {
return mLauncherDeviceProfile;
}
- /** Updates {@link deviceprofile} instance for Taskbar's overlay window. */
+ /** Updates {@link DeviceProfile} instance for Taskbar's overlay window. */
public void updateLauncherDeviceProfile(DeviceProfile dp) {
mLauncherDeviceProfile = dp;
Optional.ofNullable(mOverlayContext).ifPresent(c -> {
@@ -239,11 +227,6 @@ public final class TaskbarOverlayController {
radius = 0;
// intentionally falling through in case a non-0 blur was previously set.
}
- if (!CrossWindowBlurListeners.getInstance().isCrossWindowBlurEnabled()) {
- Log.d(TAG, "setBackgroundBlurRadius: disabled, setting to 0");
- radius = 0;
- // intentionally falling through in case a non-0 blur was previously set.
- }
if (mOverlayContext == null) {
Log.w(TAG, "setBackgroundBlurRadius: no overlay context");
return;
@@ -269,42 +252,31 @@ public final class TaskbarOverlayController {
return;
}
Log.v(TAG, "setBackgroundBlurRadius: " + radius);
- final SurfaceControl.Transaction transaction =
+ SurfaceControl.Transaction transaction =
new SurfaceControl.Transaction().setBackgroundBlurRadius(surfaceControl, radius);
- try (transaction) {
- // Set early wake-up flags when we know we're executing an expensive operation, this way
- // SurfaceFlinger will adjust its internal offsets to avoid jank.
- boolean wantsEarlyWakeUp = radius > 0 && radius < mMaxBlurRadius;
- if (wantsEarlyWakeUp && !mInEarlyWakeUp) {
- Log.d(TAG, "setBackgroundBlurRadius: setting early wakeup with token "
- + mEarlyWakeupInfo);
- Trace.instantForTrack(TRACE_TAG_APP, TAG, "notifyRendererForGpuLoadUp");
- dragLayerViewRoot.notifyRendererForGpuLoadUp("setBackgroundBlurRadius");
- try {
- transaction.setEarlyWakeupStart(mEarlyWakeupInfo);
- } catch (NoSuchMethodError e) {
- // LC-Ignored: wtf?
- }
- mInEarlyWakeUp = true;
- } else if (!wantsEarlyWakeUp && mInEarlyWakeUp) {
- Log.d(TAG, "setBackgroundBlurRadius: clearing early wakeup with token "
- + mEarlyWakeupInfo);
- try {
- transaction.setEarlyWakeupEnd(mEarlyWakeupInfo);
- } catch (NoSuchMethodError e) {
- // LC-Ignored: wtf?
- }
- mInEarlyWakeUp = false;
+ // Set early wake-up flags when we know we're executing an expensive operation, this way
+ // SurfaceFlinger will adjust its internal offsets to avoid jank.
+ boolean wantsEarlyWakeUp = radius > 0 && radius < mMaxBlurRadius;
+ if (wantsEarlyWakeUp && !mInEarlyWakeUp) {
+ Log.d(TAG, "setBackgroundBlurRadius: setting early wakeup");
+ try {
+ transaction.setEarlyWakeupStart();
+ } catch (NoSuchMethodError e) {
+ // LC-Ignored: wtf?
}
-
- rootSurfaceControl.applyTransactionOnDraw(transaction);
+ mInEarlyWakeUp = true;
+ } else if (!wantsEarlyWakeUp && mInEarlyWakeUp) {
+ Log.d(TAG, "setBackgroundBlurRadius: clearing early wakeup");
+ try {
+ transaction.setEarlyWakeupEnd();
+ } catch (NoSuchMethodError e) {
+ // LC-Ignored: wtf?
+ }
+ mInEarlyWakeUp = false;
}
- }
- boolean isBackgroundBlurEnabled() {
- return BlurUtils.supportsBlursOnWindows()
- && CrossWindowBlurListeners.getInstance().isCrossWindowBlurEnabled();
+ rootSurfaceControl.applyTransactionOnDraw(transaction);
}
/**
@@ -328,7 +300,7 @@ public final class TaskbarOverlayController {
@Override
protected void handleClose(boolean animate) {
if (!mIsOpen) return;
- if (ENABLE_TASKBAR_OVERFLOW.isTrue()) {
+ if (Flags.taskbarOverflow()) {
// Mark the view closed before attempting to remove it, so the drag layer does not
// schedule another call to close. Needed for taskbar overflow in case the KQS
// view shown for taskbar overflow needs to be reshown - delayed close call would
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
index 9ecffdc6b3..41694ecee5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java
@@ -71,7 +71,6 @@ public class TaskbarOverlayDragLayer extends
@Override
public void recreateControllers() {
- super.recreateControllers();
List controllers = new ArrayList<>();
controllers.add(mContainer.getDragController());
controllers.addAll(mTouchControllers);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index eec0009437..966ae8bff6 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -39,11 +39,14 @@ import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Log;
import android.util.Property;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
import androidx.core.graphics.ColorUtils;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Flags;
+import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.anim.AnimatorListeners;
@@ -91,7 +94,7 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
private final Paint mIconRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Path mRingPath = new Path();
private final int mNormalizedIconSize;
- private Path mShapePath;
+ private final Path mShapePath;
private final Matrix mTmpMatrix = new Matrix();
private final BlurMaskFilter mShadowFilter;
@@ -278,6 +281,16 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
invalidate();
}
+ /**
+ * prepares prediction icon for usage after bind
+ */
+ public void finishBinding(OnLongClickListener longClickListener) {
+ setOnLongClickListener(longClickListener);
+ ((CellLayoutLayoutParams) getLayoutParams()).canReorder = false;
+ setTextVisibility(false);
+ verifyHighRes();
+ }
+
@Override
public void getIconBounds(Rect outBounds) {
super.getIconBounds(outBounds);
@@ -326,9 +339,6 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
}
private void updateRingPath() {
- mShapePath = ThemeManager.INSTANCE.get(mContext)
- .getIconShape()
- .getPath(mNormalizedIconSize);
mRingPath.reset();
mTmpMatrix.reset();
mTmpMatrix.setTranslate(getOutlineOffsetX(), getOutlineOffsetY());
@@ -447,6 +457,19 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
};
}
+ /**
+ * Creates and returns a new instance of PredictedAppIcon from WorkspaceItemInfo
+ */
+ public static PredictedAppIcon createIcon(ViewGroup parent, WorkspaceItemInfo info) {
+ PredictedAppIcon icon = (PredictedAppIcon) LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.predicted_app_icon, parent, false);
+ icon.applyFromWorkspaceItem(info);
+ Launcher launcher = Launcher.getLauncher(parent.getContext());
+ icon.setOnClickListener(launcher.getItemOnClickListener());
+ icon.setOnFocusChangeListener(launcher.getFocusHandler());
+ return icon;
+ }
+
private class AnimColorHolder {
public final AnimatedFloat progress = new AnimatedFloat(this::onUpdate, 1);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 2b67c232be..acec8d6b5a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -16,7 +16,6 @@
package com.android.launcher3.uioverrides;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
-import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_OPTIMIZE_MEASURE;
import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY;
@@ -24,18 +23,15 @@ import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_WALLPAPER
import static com.android.app.animation.Interpolators.EMPHASIZED;
import static com.android.internal.jank.Cuj.CUJ_LAUNCHER_LAUNCH_APP_PAIR_FROM_WORKSPACE;
import static com.android.launcher3.Flags.enableExpressiveDismissTaskMotion;
-import static com.android.launcher3.Flags.enableOverviewBackgroundWallpaperBlur;
import static com.android.launcher3.Flags.enableUnfoldStateAnimation;
import static com.android.launcher3.LauncherConstants.SavedInstanceKeys.PENDING_SPLIT_SELECT_INFO;
import static com.android.launcher3.LauncherConstants.SavedInstanceKeys.RUNTIME_STATE;
import static com.android.launcher3.LauncherSettings.Animation.DEFAULT_NO_ICON;
import static com.android.launcher3.LauncherSettings.Animation.VIEW_BACKGROUND;
-import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
import static com.android.launcher3.LauncherState.ALL_APPS;
-import static com.android.launcher3.LauncherState.FLAG_SKIP_STATE_ANNOUNCEMENT;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.NO_OFFSET;
import static com.android.launcher3.LauncherState.OVERVIEW;
@@ -55,7 +51,6 @@ import static com.android.launcher3.popup.SystemShortcut.BUBBLE_SHORTCUT;
import static com.android.launcher3.popup.SystemShortcut.DONT_SUGGEST_APP;
import static com.android.launcher3.popup.SystemShortcut.INSTALL;
import static com.android.launcher3.popup.SystemShortcut.PRIVATE_PROFILE_INSTALL;
-import static com.android.launcher3.popup.SystemShortcut.REMOVE;
import static com.android.launcher3.popup.SystemShortcut.UNINSTALL_APP;
import static com.android.launcher3.popup.SystemShortcut.WIDGETS;
import static com.android.launcher3.taskbar.LauncherTaskbarUIController.ALL_APPS_PAGE_PROGRESS_INDEX;
@@ -71,7 +66,6 @@ import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.quickstep.util.AnimUtils.completeRunnableListCallback;
import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY;
-import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_50_50;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -87,12 +81,15 @@ import android.graphics.RectF;
import android.hardware.display.DisplayManager;
import android.media.permission.SafeCloseable;
import android.os.Build;
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.IRemoteCallback;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.AttributeSet;
+import android.view.Display;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.View;
@@ -113,7 +110,6 @@ import com.android.app.viewcapture.ViewCaptureFactory;
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Flags;
-import com.android.launcher3.GestureNavContract;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings.Favorites;
@@ -135,9 +131,9 @@ import com.android.launcher3.hybridhotseat.HotseatPredictionController;
import com.android.launcher3.logging.InstanceId;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
+import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.WellbeingModel;
import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.model.data.PredictedContainerInfo;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.proxy.ProxyActivityStarter;
import com.android.launcher3.statehandlers.DepthController;
@@ -167,7 +163,6 @@ import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.IntSet;
import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.ObjectWrapper;
-import com.android.launcher3.util.OverviewCommandHelperProtoLogProxy;
import com.android.launcher3.util.PendingRequestArgs;
import com.android.launcher3.util.PendingSplitSelectInfo;
import com.android.launcher3.util.RunnableList;
@@ -178,7 +173,6 @@ import com.android.launcher3.util.StableViewInfo;
import com.android.launcher3.util.StartActivityParams;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.views.FloatingIconView;
-import com.android.quickstep.LauncherActivityInterface;
import com.android.quickstep.OverviewCommandHelper;
import com.android.quickstep.OverviewComponentObserver;
import com.android.quickstep.OverviewComponentObserver.OverviewChangeListener;
@@ -186,8 +180,6 @@ import com.android.quickstep.RecentsModel;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.TaskUtils;
import com.android.quickstep.TouchInteractionService.TISBinder;
-import com.android.quickstep.fallback.window.RecentsWindowFlags;
-import com.android.quickstep.fallback.window.RecentsWindowManager;
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
import com.android.quickstep.util.AsyncClockEventDelegate;
import com.android.quickstep.util.LauncherUnfoldAnimationController;
@@ -206,7 +198,6 @@ import com.android.quickstep.views.RecentsViewContainer;
import com.android.quickstep.views.TaskView;
import com.android.systemui.animation.back.FlingOnBackAnimationCallback;
import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.unfold.RemoteUnfoldSharedComponent;
import com.android.systemui.unfold.UnfoldTransitionFactory;
import com.android.systemui.unfold.UnfoldTransitionProgressProvider;
@@ -218,7 +209,6 @@ import com.android.systemui.unfold.updates.RotationChangeProvider;
import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
import com.android.wm.shell.shared.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
-import com.android.wm.shell.shared.desktopmode.DesktopState;
import kotlin.Unit;
@@ -246,7 +236,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
protected static final String RING_APPEAR_ANIMATION_PREFIX = "RingAppearAnimation\t";
- private PredictedContainerInfo mAllAppsPredictions;
+ private FixedContainerItems mAllAppsPredictions;
private HotseatPredictionController mHotseatPredictionController;
private DepthController mDepthController;
private QuickstepTransitionManager mAppTransitionManager;
@@ -284,8 +274,6 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
private final OverviewChangeListener mOverviewChangeListener = this::onOverviewTargetChanged;
- private boolean mOverviewBlurEnabled;
-
private final TaskViewRecentsTouchContext mTaskViewRecentsTouchContext =
new TaskViewRecentsTouchContext() {
@Override
@@ -305,16 +293,17 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
}
};
+ public static QuickstepLauncher getLauncher(Context context) {
+ return fromContext(context);
+ }
+
@Override
protected void setupViews() {
getAppWidgetHolder().setOnViewCreationCallback(new QuickstepInteractionHandler(this));
- mDepthController = new DepthController(this);
- mOverviewBlurEnabled = isOverviewBackgroundBlurEnabled();
- getTheme().applyStyle(getOverviewBlurStyleResId(), true);
super.setupViews();
mActionsView = findViewById(R.id.overview_actions_view);
- RecentsView, LauncherState> overviewPanel = getOverviewPanel();
+ RecentsView,?> overviewPanel = getOverviewPanel();
SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(this);
mSplitSelectStateController =
new SplitSelectStateController(this, getStateManager(),
@@ -342,7 +331,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
}
mTISBindHelper = new TISBindHelper(this, this::onTISConnected);
-
+ mDepthController = new DepthController(this);
if (DesktopModeStatus.canEnterDesktopModeOrShowAppHandle(this)) {
mSplitSelectStateController.initSplitFromDesktopController(this);
}
@@ -371,16 +360,16 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
if (mAllAppsPredictions != null
&& (info.itemType == ITEM_TYPE_APPLICATION
|| info.itemType == ITEM_TYPE_DEEP_SHORTCUT)) {
- List items = mAllAppsPredictions.getContents();
- int count = items.size();
+ int count = mAllAppsPredictions.items.size();
for (int i = 0; i < count; i++) {
- ItemInfo targetInfo = items.get(i);
+ ItemInfo targetInfo = mAllAppsPredictions.items.get(i);
if (targetInfo.itemType == info.itemType
&& targetInfo.user.equals(info.user)
&& Objects.equals(targetInfo.getIntent(), info.getIntent())) {
logger.withRank(i);
break;
}
+
}
}
logger.log(LAUNCHER_APP_LAUNCH_TAP);
@@ -430,19 +419,31 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
@Override
public RunnableList startActivitySafely(View v, Intent intent, ItemInfo item) {
+ // Only pause is taskbar controller is not present until the transition (if it exists) ends
+ mHotseatPredictionController.setPauseUIUpdate(getTaskbarUIController() == null);
PredictionRowView> predictionRowView =
getAppsView().getFloatingHeaderView().findFixedRowByType(PredictionRowView.class);
// Pause the prediction row updates until the transition (if it exists) ends.
predictionRowView.setPredictionUiUpdatePaused(true);
RunnableList result = super.startActivitySafely(v, intent, item);
if (result == null) {
+ mHotseatPredictionController.setPauseUIUpdate(false);
predictionRowView.setPredictionUiUpdatePaused(false);
} else {
- result.add(() -> predictionRowView.setPredictionUiUpdatePaused(false));
+ result.add(() -> {
+ mHotseatPredictionController.setPauseUIUpdate(false);
+ predictionRowView.setPredictionUiUpdatePaused(false);
+ });
}
return result;
}
+ @Override
+ public void startBinding() {
+ super.startBinding();
+ mHotseatPredictionController.verifyUIUpdateNotPaused();
+ }
+
@Override
protected void onActivityFlagsChanged(int changeBits) {
if ((changeBits & ACTIVITY_STATE_STARTED) != 0) {
@@ -468,31 +469,6 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
super.showAllAppsFromIntent(alreadyOnHome);
}
- @Override
- public boolean isAllAppsBackgroundBlurEnabled() {
- return mDepthController != null && mDepthController.isCrossWindowBlursEnabled()
- && Flags.allAppsBlur();
- }
-
- @Override
- public boolean isOverviewBackgroundBlurEnabled() {
- return mDepthController != null && mDepthController.isCrossWindowBlursEnabled()
- && enableOverviewBackgroundWallpaperBlur();
- }
-
- /** Apply the blur or blur fallback style to the current theme. */
- public void updateBlurStyle() {
- if (enableOverviewBackgroundWallpaperBlur()) {
- if (isOverviewBackgroundBlurEnabled() != mOverviewBlurEnabled) {
- mWallpaperThemeManager.recreateToUpdateTheme();
- }
- } else if (Flags.allAppsBlur()) {
- // For all apps, we only need to update the scrim, which draws the panel. But if the
- // activity was recreated above, this is unnecessary.
- getAppsView().invalidateHeader();
- }
- }
-
protected void onItemClicked(View view) {
if (!mSplitToWorkspaceController.handleSecondAppSelectionForSplit(view)) {
super.getItemOnClickListener().onClick(view);
@@ -505,7 +481,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
}
@Override
- public Stream getSupportedShortcuts(int container) {
+ public Stream getSupportedShortcuts() {
// Order matters as it affects order of appearance in popup container
List shortcuts = new ArrayList(Arrays.asList(
APP_INFO, WellbeingModel.SHORTCUT_FACTORY, mHotseatPredictionController));
@@ -513,15 +489,12 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
shortcuts.addAll(getSplitShortcuts());
shortcuts.add(WIDGETS);
shortcuts.add(INSTALL);
- if (Flags.enableLongPressRemoveShortcut()
- && (container == CONTAINER_HOTSEAT || container == CONTAINER_DESKTOP
- || /* Folder */ container > 0)) {
- shortcuts.add(REMOVE);
- }
- shortcuts.add(DONT_SUGGEST_APP);
if (Flags.enablePrivateSpaceInstallShortcut()) {
shortcuts.add(PRIVATE_PROFILE_INSTALL);
}
+ if (Flags.enableShortcutDontSuggestApp()) {
+ shortcuts.add(DONT_SUGGEST_APP);
+ }
if (Flags.enablePrivateSpace()) {
shortcuts.add(UNINSTALL_APP);
}
@@ -532,7 +505,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
}
private List> getSplitShortcuts() {
- if (!mDeviceProfile.getDeviceProperties().isTablet() || mSplitSelectStateController.isSplitSelectActive()) {
+ if (!mDeviceProfile.isTablet || mSplitSelectStateController.isSplitSelectActive()) {
return Collections.emptyList();
}
RecentsView recentsView = getOverviewPanel();
@@ -574,20 +547,17 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
}
@Override
- public void bindPredictedContainerInfo(PredictedContainerInfo info) {
- super.bindPredictedContainerInfo(info);
- switch (info.id) {
- case Favorites.CONTAINER_ALL_APPS_PREDICTION:
- mAllAppsPredictions = info;
- getAppsView().getFloatingHeaderView().findFixedRowByType(
- PredictionRowView.class).setPredictedApps(info.getContents());
- break;
- case Favorites.CONTAINER_HOTSEAT_PREDICTION:
- mHotseatPredictionController.setPredictedItems(info);
- break;
- case Favorites.CONTAINER_WIDGETS_PREDICTION:
- getWidgetPickerDataProvider().setWidgetRecommendations(info.getContents());
- break;
+ public void bindExtraContainerItems(FixedContainerItems item) {
+ if (item.containerId == Favorites.CONTAINER_PREDICTION) {
+ mAllAppsPredictions = item;
+ PredictionRowView> predictionRowView =
+ getAppsView().getFloatingHeaderView().findFixedRowByType(
+ PredictionRowView.class);
+ predictionRowView.setPredictedApps(item.items);
+ } else if (item.containerId == Favorites.CONTAINER_HOTSEAT_PREDICTION) {
+ mHotseatPredictionController.setPredictedItems(item);
+ } else if (item.containerId == Favorites.CONTAINER_WIDGETS_PREDICTION) {
+ getWidgetPickerDataProvider().setWidgetRecommendations(item.items);
}
}
@@ -689,15 +659,6 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
}
}
- @Override
- protected void setTitle(@NonNull LauncherState state) {
- if (state.hasFlag(FLAG_SKIP_STATE_ANNOUNCEMENT)) {
- // Prevent accessibility title update announcement
- getWindow().getAttributes().accessibilityTitle = getString(state.getTitle());
- }
- super.setTitle(state);
- }
-
@Override
public TouchController[] createTouchControllers() {
NavigationMode mode = DisplayController.getNavigationMode(this);
@@ -732,9 +693,8 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
break;
}
- if (!getDeviceProfile().getDeviceProperties().isMultiWindowMode()) {
- list.add(new StatusBarTouchController(
- this, () -> this.isInState(LauncherState.NORMAL)));
+ if (!getDeviceProfile().isMultiWindowMode) {
+ list.add(new StatusBarTouchController(this));
}
if (enableExpressiveDismissTaskMotion()) {
@@ -914,26 +874,11 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
@Override
protected void onNewIntent(Intent intent) {
- boolean intentHasGnc = GestureNavContract.canBuildFromIntent(intent);
super.onNewIntent(intent);
OverviewCommandHelper overviewCommandHelper = mTISBindHelper.getOverviewCommandHelper();
if (overviewCommandHelper != null) {
overviewCommandHelper.clearPendingCommands();
}
- if (RecentsWindowFlags.getEnableOverviewInWindow() && !intentHasGnc) {
- RecentsWindowManager defaultRecentsWindowManager =
- RecentsWindowManager.REPOSITORY_INSTANCE.get(this).get(DEFAULT_DISPLAY);
- if (defaultRecentsWindowManager != null) {
- defaultRecentsWindowManager.cleanupRecentsWindow();
- }
- }
- }
-
- @Override
- protected void logOnNewIntent(boolean alreadyOnHome, boolean shouldMoveToDefaultScreen,
- String action, boolean internalStateHandled) {
- OverviewCommandHelperProtoLogProxy.logOnNewIntent(alreadyOnHome, shouldMoveToDefaultScreen,
- action, internalStateHandled);
}
public QuickstepTransitionManager getAppTransitionManager() {
@@ -952,9 +897,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
@Override
protected void handleGestureContract(Intent intent) {
- if (GestureNavContract.isContractEnabled(intent)
- && (FeatureFlags.SEPARATE_RECENTS_ACTIVITY.get()
- || RecentsWindowFlags.getEnableOverviewInWindow())) {
+ if (FeatureFlags.SEPARATE_RECENTS_ACTIVITY.get()) {
super.handleGestureContract(intent);
}
}
@@ -984,8 +927,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
onTaskbarInAppDisplayProgressUpdate(progress, WIDGETS_PAGE_PROGRESS_INDEX);
if (mEnableWidgetDepth) {
getDepthController().widgetDepth.setValue(Utilities.mapToRange(
- progress, 0f, 1f, 0f,
- getDeviceProfile().getBottomSheetProfile().getBottomSheetDepth(), EMPHASIZED));
+ progress, 0f, 1f, 0f, getDeviceProfile().bottomSheetDepth, EMPHASIZED));
}
}
@@ -1029,7 +971,6 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
mActiveOnBackAnimationCallback.onBackStarted(backEvent);
}
- @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
@Override
public void onBackInvokedCompat() {
// Recreate mActiveOnBackAnimationCallback if necessary to avoid NPE
@@ -1332,7 +1273,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
}
activityOptions.options.setLaunchDisplayId(
(v != null && v.getDisplay() != null) ? v.getDisplay().getDisplayId()
- : DEFAULT_DISPLAY);
+ : Display.DEFAULT_DISPLAY);
Utilities.allowBGLaunch(activityOptions.options);
return activityOptions;
}
@@ -1353,8 +1294,8 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
@Override
@BinderThread
- public void enterStageSplitFromRunningApp(boolean leftOrTop, int displayId) {
- mSplitWithKeyboardShortcutController.enterStageSplit(leftOrTop, displayId);
+ public void enterStageSplitFromRunningApp(boolean leftOrTop) {
+ mSplitWithKeyboardShortcutController.enterStageSplit(leftOrTop);
}
@Override
@@ -1443,11 +1384,6 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
.isInDesktopModeAndNotInOverview(getDisplayId());
}
- @Override
- public boolean shouldShowHomeBehindDesktop() {
- return DesktopState.fromContext(this).getShouldShowHomeBehindDesktop();
- }
-
@Override
public void dispatchDeviceProfileChanged() {
super.dispatchDeviceProfileChanged();
@@ -1470,9 +1406,7 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT,
/* callback= */ success -> mSplitSelectStateController.resetState(),
/* freezeTaskList= */ false,
- splitTask.getSplitBounds() == null
- ? SNAP_TO_2_50_50
- : splitTask.getSplitBounds().snapPosition,
+ splitTask.getSplitBounds().snapPosition,
remoteTransition);
}
@@ -1629,20 +1563,4 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer,
public void returnToHomescreen() {
getStateManager().goToState(LauncherState.NORMAL);
}
-
- @Override
- public int getOverviewBlurStyleResId() {
- return isOverviewBackgroundBlurEnabled() ? R.style.OverviewBlurStyle
- : R.style.OverviewBlurFallbackStyle;
- }
-
- @Override
- public LauncherActivityInterface getContainerInterface() {
- return LauncherActivityInterface.INSTANCE;
- }
-
- @Override
- public SplitSelectStateController getSplitSelectStateController() {
- return mSplitSelectStateController;
- }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
index 846c850a18..0d5ff2b67e 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepWidgetHolder.java
@@ -20,7 +20,6 @@ import static com.android.launcher3.uioverrides.QuickstepAppWidgetHostProvider.g
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.widget.ListenableAppWidgetHost.getWidgetHolderExecutor;
-import android.appwidget.AppWidgetEvent;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetProviderInfo;
@@ -45,8 +44,6 @@ import dagger.assisted.AssistedInject;
import java.util.Collections;
import java.util.Set;
import java.util.WeakHashMap;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
import java.util.function.BiConsumer;
/**
@@ -60,10 +57,6 @@ public final class QuickstepWidgetHolder extends LauncherWidgetHolder {
AppWidgetHostView::updateAppWidget;
private static final UpdateKey KEY_VIEW_DATA_CHANGED =
AppWidgetHostView::onViewDataChanged;
- private static final UpdateKey KEY_COLLECT_WIDGET_EVENT =
- (view, event) -> {
- event.merge(view.collectWidgetEvent());
- };
private static final SparseArray sListeners =
new SparseArray<>();
@@ -273,25 +266,6 @@ public final class QuickstepWidgetHolder extends LauncherWidgetHolder {
executeOnMainExecutor(KEY_VIEW_DATA_CHANGED, viewId);
}
- @Nullable
- @Override
- public AppWidgetEvent collectWidgetEvent() {
- if (!android.appwidget.flags.Flags.engagementMetrics()) return null;
-
- CompletableFuture future = new CompletableFuture<>();
- MAIN_EXECUTOR.execute(() -> {
- AppWidgetEvent.Builder event = new AppWidgetEvent.Builder();
- mListeningHolders.forEach(holder ->
- holder.onWidgetUpdate(mWidgetId, KEY_COLLECT_WIDGET_EVENT, event));
- future.complete(event.isEmpty() ? null : event.build());
- });
- try {
- return future.get();
- } catch (InterruptedException | ExecutionException e) {
- return null;
- }
- }
-
private void executeOnMainExecutor(UpdateKey key, T data) {
MAIN_EXECUTOR.execute(() -> mListeningHolders.forEach(holder ->
holder.onWidgetUpdate(mWidgetId, key, data)));
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.kt b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.kt
index 927d94c2f6..c9f791c6ee 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.kt
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.kt
@@ -21,6 +21,7 @@ import com.android.app.animation.Interpolators.FINAL_FRAME
import com.android.app.animation.Interpolators.INSTANT
import com.android.app.animation.Interpolators.LINEAR
import com.android.launcher3.Flags.enableDesktopExplodedView
+import com.android.launcher3.Flags.enableGridOnlyOverview
import com.android.launcher3.Flags.enableLargeDesktopWindowingTile
import com.android.launcher3.LauncherState
import com.android.launcher3.anim.AnimatedFloat
@@ -36,7 +37,6 @@ import com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_SCALE
import com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_X
import com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_TRANSLATE_Y
import com.android.launcher3.states.StateAnimationConfig.SKIP_OVERVIEW
-import com.android.launcher3.util.OverviewReleaseFlags.enableGridOnlyOverview
import com.android.quickstep.util.AnimUtils
import com.android.quickstep.views.AddDesktopButton
import com.android.quickstep.views.ClearAllButton
@@ -246,10 +246,7 @@ class RecentsViewStateController(private val launcher: QuickstepLauncher) :
launcher.deviceProfile,
)
- val timings =
- AnimUtils.getDeviceOverviewToSplitTimings(
- launcher.deviceProfile.getDeviceProperties().isTablet
- )
+ val timings = AnimUtils.getDeviceOverviewToSplitTimings(launcher.deviceProfile.isTablet)
if (!goingToOverviewFromWorkspaceContextual) {
// This animation is already done for the contextual case, don't redo it
recentsView.createSplitSelectInitAnimation(
diff --git a/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt b/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt
index abe0e23432..f8e873a851 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt
+++ b/quickstep/src/com/android/launcher3/uioverrides/SystemApiWrapper.kt
@@ -23,11 +23,10 @@ import android.content.IIntentReceiver
import android.content.IIntentSender
import android.content.Intent
import android.content.pm.ActivityInfo
+import android.content.pm.ApplicationInfo
import android.content.pm.LauncherActivityInfo
import android.content.pm.LauncherApps
import android.content.pm.ShortcutInfo
-import android.graphics.Bitmap
-import android.graphics.Rect
import android.os.Build
import android.os.Bundle
import android.os.Flags.allowPrivateProfile
@@ -35,26 +34,23 @@ import android.os.IBinder
import android.os.UserHandle
import android.os.UserManager
import android.util.ArrayMap
-import android.view.SurfaceControlViewHost
import android.widget.Toast
import android.window.RemoteTransition
-import android.window.ScreenCapture
-import com.android.launcher3.BaseActivity
import androidx.annotation.RequiresApi
import com.android.launcher3.Flags.enablePrivateSpace
+import com.android.launcher3.Flags.enablePrivateSpaceInstallShortcut
+import com.android.launcher3.Flags.privateSpaceAppInstallerButton
import com.android.launcher3.Flags.privateSpaceSysAppsSeparation
import com.android.launcher3.R
import com.android.launcher3.Utilities
import com.android.launcher3.dagger.ApplicationContext
import com.android.launcher3.dagger.LauncherAppSingleton
import com.android.launcher3.proxy.ProxyActivityStarter
-import com.android.launcher3.uioverrides.touchcontrollers.StatusBarTouchController
import com.android.launcher3.util.ApiWrapper
import com.android.launcher3.util.Executors
import com.android.launcher3.util.StartActivityParams
import com.android.launcher3.util.UserIconInfo
import com.android.quickstep.util.FadeOutRemoteTransition
-import java.util.function.Supplier
import javax.inject.Inject
import app.lawnchair.LawnchairApp
@@ -127,7 +123,10 @@ open class SystemApiWrapper @Inject constructor(@ApplicationContext context: Con
override fun getAppMarketActivityIntent(packageName: String, user: UserHandle): Intent {
return try {
- if (allowPrivateProfile() && enablePrivateSpace())
+ if (
+ enablePrivateSpace() &&
+ (privateSpaceAppInstallerButton() || enablePrivateSpaceInstallShortcut())
+ )
ProxyActivityStarter.getLaunchIntent(
mContext,
StartActivityParams(null as PendingIntent?, 0).apply {
@@ -153,7 +152,7 @@ open class SystemApiWrapper @Inject constructor(@ApplicationContext context: Con
/** Returns an intent which can be used to open Private Space Settings. */
override fun getPrivateSpaceSettingsIntent(): Intent? {
return try {
- if (allowPrivateProfile() && enablePrivateSpace())
+ if (enablePrivateSpace())
ProxyActivityStarter.getLaunchIntent(
mContext,
StartActivityParams(null as PendingIntent?, 0).apply {
@@ -242,24 +241,11 @@ open class SystemApiWrapper @Inject constructor(@ApplicationContext context: Con
}
}
- override fun createStatusBarTouchController(
- launcher: BaseActivity,
- isEnabledCheck: Supplier,
- ): StatusBarTouchController? {
- return StatusBarTouchController(launcher, isEnabledCheck)
- }
+ override fun getApplicationInfoHash(appInfo: ApplicationInfo): String =
+ (appInfo.sourceDir?.hashCode() ?: 0).toString() + " " + appInfo.longVersionCode
+
+ override fun getRoundIconRes(appInfo: ApplicationInfo) = appInfo.roundIconRes
override fun isFileDrawable(shortcutInfo: ShortcutInfo) =
shortcutInfo.hasIconFile() || shortcutInfo.hasIconUri()
-
- override fun captureSnapshot(host: SurfaceControlViewHost, width: Int, height: Int): Bitmap =
- ScreenCapture.captureLayers(
- ScreenCapture.LayerCaptureArgs.Builder(host.surfacePackage!!.surfaceControl)
- .setSourceCrop(Rect(0, 0, width, height))
- .setAllowProtected(true)
- .setHintForSeamlessTransition(true)
- .build()
- )
- .asBitmap()
- .copy(Bitmap.Config.ARGB_8888, true)
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
index e2a624d4ca..8a44f76c70 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java
@@ -20,7 +20,6 @@ import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_ALLAPPS;
import android.content.Context;
-import android.graphics.Color;
import com.android.internal.jank.Cuj;
import com.android.launcher3.DeviceProfile;
@@ -30,7 +29,6 @@ import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.views.ScrimColors;
import com.android.quickstep.util.BaseDepthController;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
@@ -139,7 +137,7 @@ public class AllAppsState extends LauncherState {
protected
float getDepthUnchecked(DEVICE_PROFILE_CONTEXT context) {
if (context.getDeviceProfile().shouldShowAllAppsOnSheet()) {
- return context.getDeviceProfile().getBottomSheetProfile().getBottomSheetDepth();
+ return context.getDeviceProfile().bottomSheetDepth;
} else {
// The scrim fades in at approximately 50% of the swipe gesture.
if (enableScalingRevealHomeAnimation()) {
@@ -153,11 +151,6 @@ public class AllAppsState extends LauncherState {
}
}
- @Override
- public boolean shouldBlurWorkspace(LauncherState targetState) {
- return targetState == ALL_APPS || targetState == NORMAL;
- }
-
@Override
public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) {
PageAlphaProvider superPageAlphaProvider = super.getWorkspacePageAlphaProvider(launcher);
@@ -181,7 +174,8 @@ public class AllAppsState extends LauncherState {
}
private static boolean isWorkspaceVisible(DeviceProfile deviceProfile) {
- return deviceProfile.getDeviceProperties().isTablet() || (Flags.allAppsSheetForHandheld() && Flags.allAppsBlur());
+ // Currently we hide the workspace with the all apps blur flag for simplicity.
+ return deviceProfile.isTablet && !Flags.allAppsBlur();
}
@Override
@@ -204,24 +198,26 @@ public class AllAppsState extends LauncherState {
@Override
public boolean shouldFloatingSearchBarUsePillWhenUnfocused(Launcher launcher) {
DeviceProfile dp = launcher.getDeviceProfile();
- return dp.getDeviceProperties().isPhone() && !dp.getDeviceProperties().isLandscape();
+ return dp.isPhone && !dp.isLandscape;
}
@Override
- public ScrimColors getWorkspaceScrimColor(Launcher launcher) {
- int backgroundColor;
+ public LauncherState getHistoryForState(LauncherState previousState) {
+ return previousState == BACKGROUND_APP ? QUICK_SWITCH_FROM_HOME
+ : previousState == OVERVIEW ? OVERVIEW : NORMAL;
+ }
+
+ @Override
+ public int getWorkspaceScrimColor(Launcher launcher) {
if (!launcher.getDeviceProfile().shouldShowAllAppsOnSheet()) {
- // Lawnchair-TODO-Colour: LawnchairUtilsKt.getAllAppsScrimColor(launcher) + materialColorSurfaceDim
- // Always use an opaque scrim if there's no sheet.
- backgroundColor = launcher.getResources().getColor(R.color.materialColorSurfaceDim);
- } else if (!Flags.allAppsBlur()) {
- // Lawnchair-TODO-Colour: LawnchairUtilsKt.getAllAppsScrimColor(launcher) + widgets_picker_scrim
- // If there's a sheet but no blur, use the old scrim color.
- backgroundColor = launcher.getResources().getColor(R.color.widgets_picker_scrim);
- } else {
// Lawnchair-TODO-Colour: LawnchairUtilsKt.getAllAppsScrimColor(launcher) + allAppsScrimColor
- backgroundColor = Themes.getAttrColor(launcher, R.attr.allAppsScrimColor);
+ return Themes.getAttrColor(launcher, R.attr.allAppsScrimColor);
}
- return new ScrimColors(backgroundColor, /* foregroundColor */ Color.TRANSPARENT);
+ if (Flags.allAppsBlur()) {
+ // Lawnchair-TODO-Colour: LawnchairUtilsKt.getAllAppsScrimColor(launcher) + allAppsScrimColorOverBlur
+ return Themes.getAttrColor(launcher, R.attr.allAppsScrimColorOverBlur);
+ }
+ // Lawnchair-TODO-Colour: LawnchairUtilsKt.getAllAppsScrimColor(launcher) + widgets_picker_scrim
+ return launcher.getResources().getColor(R.color.widgets_picker_scrim);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 508643afd7..a5b1ee7b53 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.uioverrides.states;
+import static com.android.launcher3.Flags.enableDesktopWindowingCarouselDetach;
import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
@@ -24,7 +25,6 @@ import android.graphics.Color;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.views.ScrimColors;
import com.android.quickstep.util.BaseDepthController;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
@@ -35,8 +35,7 @@ import com.android.quickstep.views.RecentsView;
public class BackgroundAppState extends OverviewState {
private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_RECENTS_VIEW_VISIBLE
- | FLAG_WORKSPACE_INACCESSIBLE | FLAG_NON_INTERACTIVE | FLAG_CLOSE_POPUPS
- | FLAG_SKIP_STATE_ANNOUNCEMENT;
+ | FLAG_WORKSPACE_INACCESSIBLE | FLAG_NON_INTERACTIVE | FLAG_CLOSE_POPUPS;
public BackgroundAppState(int id) {
this(id, LAUNCHER_STATE_BACKGROUND);
@@ -56,7 +55,7 @@ public class BackgroundAppState extends OverviewState {
launcher,
launcher.getDeviceProfile(),
recentsView.getPagedOrientationHandler(),
- recentsView.getContainerInterface());
+ recentsView.getSizeStrategy());
AllAppsTransitionController controller = launcher.getAllAppsController();
float scrollRange = Math.max(controller.getShiftRange(), 1);
float progressDelta = (transitionLength / scrollRange);
@@ -92,6 +91,11 @@ public class BackgroundAppState extends OverviewState {
return true;
}
+ @Override
+ public boolean detachDesktopCarousel() {
+ return enableDesktopWindowingCarouselDetach();
+ }
+
@Override
public boolean showExplodedDesktopView() {
return false;
@@ -110,10 +114,8 @@ public class BackgroundAppState extends OverviewState {
}
@Override
- public ScrimColors getWorkspaceScrimColor(Launcher launcher) {
- return new ScrimColors(
- /* backgroundColor= */ Color.TRANSPARENT,
- /* foregroundColor= */ Color.TRANSPARENT);
+ public int getWorkspaceScrimColor(Launcher launcher) {
+ return Color.TRANSPARENT;
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
index 7348fb2eda..ae82f82c01 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java
@@ -15,7 +15,7 @@
*/
package com.android.launcher3.uioverrides.states;
-import static com.android.launcher3.util.OverviewReleaseFlags.enableGridOnlyOverview;
+import static com.android.launcher3.Flags.enableGridOnlyOverview;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
import android.graphics.Rect;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
index 3cc9431cef..fe8ab36fe2 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java
@@ -17,6 +17,7 @@ package com.android.launcher3.uioverrides.states;
import static com.android.app.animation.Interpolators.DECELERATE_2;
import static com.android.launcher3.Flags.enableDesktopExplodedView;
+import static com.android.launcher3.Flags.enableOverviewBackgroundWallpaperBlur;
import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_OVERVIEW;
@@ -24,8 +25,6 @@ import android.content.Context;
import android.graphics.Rect;
import android.os.SystemProperties;
-import androidx.core.graphics.ColorUtils;
-
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
@@ -33,11 +32,11 @@ import com.android.launcher3.R;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.views.ScrimColors;
import com.android.quickstep.util.BaseDepthController;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.system.BlurUtils;
import app.lawnchair.preferences.PreferenceManager;
import app.lawnchair.theme.color.tokens.ColorTokens;
@@ -88,7 +87,7 @@ public class OverviewState extends LauncherState {
recentsView.getTaskSize(sTempRect);
float scale;
DeviceProfile deviceProfile = launcher.getDeviceProfile();
- if (deviceProfile.getDeviceProperties().isTwoPanels()) {
+ if (deviceProfile.isTwoPanels) {
// In two panel layout, width does not include both panels or space between them, so
// use height instead. We do not use height for handheld, as cell layout can be
// shorter than a task and we want the workspace to scale down to task size.
@@ -123,9 +122,9 @@ public class OverviewState extends LauncherState {
int elements = CLEAR_ALL_BUTTON | OVERVIEW_ACTIONS | ADD_DESK_BUTTON;
DeviceProfile dp = launcher.getDeviceProfile();
boolean showFloatingSearch;
- if (dp.getDeviceProperties().isPhone()) {
+ if (dp.isPhone) {
// Only show search in phone overview in portrait mode.
- showFloatingSearch = !dp.getDeviceProperties().isLandscape();
+ showFloatingSearch = !dp.isLandscape;
} else {
// Only show search in tablet overview if taskbar is not visible.
showFloatingSearch = !dp.isTaskbarPresent || isTaskbarStashed(launcher);
@@ -157,7 +156,7 @@ public class OverviewState extends LauncherState {
@Override
public boolean shouldFloatingSearchBarUsePillWhenUnfocused(Launcher launcher) {
DeviceProfile dp = launcher.getDeviceProfile();
- return dp.getDeviceProperties().isPhone() && !dp.getDeviceProperties().isLandscape();
+ return dp.isPhone && !dp.isLandscape;
}
@Override
@@ -166,19 +165,22 @@ public class OverviewState extends LauncherState {
}
@Override
- public ScrimColors getWorkspaceScrimColor(Launcher launcher) {
+ public int getWorkspaceScrimColor(Launcher launcher) {
// Lawnchair-TODO-Colour: LawnchairUtilsKt.getAllAppsScrimColor(launcher) + allAppsScrimColorOverBlur
// Lawnchair-TODO-Colour: LawnchairUtilsKt.getAllAppsScrimColor(launcher) + allAppsScrimColor
- return new ScrimColors(
- /* backgroundColor */ Themes.getAttrColor(launcher, R.attr.overviewScrimColor),
- /* foregroundColor */ ColorUtils.compositeColors(
- Themes.getAttrColor(launcher, R.attr.overviewScrimForegroundPrimary),
- Themes.getAttrColor(launcher, R.attr.overviewScrimForegroundSecondary)));
+ return enableOverviewBackgroundWallpaperBlur() && BlurUtils.supportsBlursOnWindows()
+ ? Themes.getAttrColor(launcher, R.attr.overviewScrimColorOverBlur)
+ : Themes.getAttrColor(launcher, R.attr.overviewScrimColor);
}
@Override
public boolean displayOverviewTasksAsGrid(DeviceProfile deviceProfile) {
- return deviceProfile.getDeviceProperties().isTablet();
+ return deviceProfile.isTablet;
+ }
+
+ @Override
+ public boolean detachDesktopCarousel() {
+ return false;
}
@Override
@@ -228,7 +230,7 @@ public class OverviewState extends LauncherState {
public void onBackInvoked(Launcher launcher) {
RecentsView recentsView = launcher.getOverviewPanel();
TaskView taskView = recentsView.getRunningTaskView();
- if (taskView != null && !taskView.isBeingDismissed()) {
+ if (taskView != null) {
if (recentsView.isTaskViewFullyVisible(taskView)) {
taskView.launchWithAnimation();
} else {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
index 4058b55637..dfad4096bc 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java
@@ -17,7 +17,12 @@ package com.android.launcher3.uioverrides.states;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
+import android.graphics.Color;
+
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.util.Themes;
/**
* State to indicate we are about to launch a recent task. Note that this state is only used when
@@ -38,6 +43,19 @@ public class QuickSwitchState extends BackgroundAppState {
return new ScaleAndTranslation(0.9f, 0, translationY);
}
+ @Override
+ public int getWorkspaceScrimColor(Launcher launcher) {
+ if (launcher.areDesktopTasksVisible()) {
+ // No scrim while desktop tasks are visible
+ return Color.TRANSPARENT;
+ }
+ DeviceProfile dp = launcher.getDeviceProfile();
+ if (dp.isTaskbarPresentInApps) {
+ return launcher.getColor(R.color.taskbar_background);
+ }
+ return Themes.getAttrColor(launcher, R.attr.overviewScrimColor);
+ }
+
@Override
public float getVerticalProgress(Launcher launcher) {
// Don't move all apps shelf while quick-switching (just let it fade).
@@ -58,9 +76,4 @@ public class QuickSwitchState extends BackgroundAppState {
public boolean isTaskbarAlignedWithHotseat(Launcher launcher) {
return false;
}
-
- @Override
- public boolean detachDesktopCarousel() {
- return true;
- }
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
index 3a6de197ac..44f8bf1e07 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java
@@ -220,7 +220,7 @@ public class QuickstepAtomicAnimationFactory extends
} else if (fromState == NORMAL && toState == ALL_APPS) {
AllAppsSwipeController.applyNormalToAllAppsAnimConfig(mContainer, config);
} else if (fromState == OVERVIEW && toState == OVERVIEW_SPLIT_SELECT) {
- SplitAnimationTimings timings = mContainer.getDeviceProfile().getDeviceProperties().isTablet()
+ SplitAnimationTimings timings = mContainer.getDeviceProfile().isTablet
? SplitAnimationTimings.TABLET_OVERVIEW_TO_SPLIT
: SplitAnimationTimings.PHONE_OVERVIEW_TO_SPLIT;
config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(LINEAR,
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java b/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
index c2ec17ab3f..2631fbf0b6 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/SplitScreenSelectState.java
@@ -43,7 +43,7 @@ public class SplitScreenSelectState extends OverviewState {
@Override
public int getTransitionDuration(ActivityContext context, boolean isToState) {
- if (isToState && context.getDeviceProfile().getDeviceProperties().isTablet()) {
+ if (isToState && context.getDeviceProfile().isTablet) {
return SplitAnimationTimings.TABLET_ENTER_DURATION;
} else if (isToState) {
return SplitAnimationTimings.PHONE_ENTER_DURATION;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
index dce158f63f..a4f8b8135c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java
@@ -28,7 +28,6 @@ import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS
import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE;
import static com.android.launcher3.util.NavigationMode.THREE_BUTTONS;
-import static com.android.launcher3.util.ScrollableLayoutManager.PREDICTIVE_BACK_MIN_SCALE;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import android.animation.AnimatorSet;
@@ -45,6 +44,7 @@ import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.compat.AccessibilityManagerCompat;
+import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
import com.android.launcher3.util.DisplayController;
@@ -136,7 +136,7 @@ public class NavBarToHomeTouchController implements TouchController,
}
private float getShiftRange() {
- return mLauncher.getDeviceProfile().getDeviceProperties().getHeightPx();
+ return mLauncher.getDeviceProfile().heightPx;
}
@Override
@@ -157,16 +157,10 @@ public class NavBarToHomeTouchController implements TouchController,
AbstractFloatingView.closeOpenContainer(mLauncher, AbstractFloatingView.TYPE_TASK_MENU);
} else if (mStartState == ALL_APPS) {
AllAppsTransitionController allAppsController = mLauncher.getAllAppsController();
- if (mLauncher.getDeviceProfile().shouldShowAllAppsOnSheet()) {
- allAppsController.setShouldScaleHeader(true);
- builder.addAnimatedFloat(allAppsController.getAllAppScale(), 1f,
- PREDICTIVE_BACK_MIN_SCALE, PULLBACK_INTERPOLATOR);
- } else {
- builder.setFloat(allAppsController, ALL_APPS_PULL_BACK_TRANSLATION,
- -mPullbackDistance, PULLBACK_INTERPOLATOR);
- builder.setFloat(allAppsController, ALL_APPS_PULL_BACK_ALPHA,
- 0.5f, PULLBACK_INTERPOLATOR);
- }
+ builder.setFloat(allAppsController, ALL_APPS_PULL_BACK_TRANSLATION,
+ -mPullbackDistance, PULLBACK_INTERPOLATOR);
+ builder.setFloat(allAppsController, ALL_APPS_PULL_BACK_ALPHA,
+ 0.5f, PULLBACK_INTERPOLATOR);
}
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mLauncher);
if (topView != null) {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
index 8d907f4183..ff726e65d4 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java
@@ -17,7 +17,7 @@
package com.android.launcher3.uioverrides.touchcontrollers;
import static com.android.app.animation.Interpolators.ACCELERATE_DECELERATE;
-import static com.android.launcher3.LauncherAnimUtils.SCRIM_COLORS;
+import static com.android.launcher3.LauncherAnimUtils.VIEW_BACKGROUND_COLOR;
import static com.android.launcher3.LauncherAnimUtils.newSingleUseCancelListener;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.HINT_STATE;
@@ -47,7 +47,6 @@ import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.VibratorWrapper;
-import com.android.launcher3.views.ScrimColorsEvaluator;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.MotionPauseDetector;
@@ -63,8 +62,6 @@ import java.util.function.BiConsumer;
* first home screen instead of to Overview.
*/
public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouchController {
-
- public static final String TAG = "NoButtonNavbarToOverviewTouchController";
private static final float ONE_HANDED_ACTIVATED_SLOP_MULTIPLIER = 2.5f;
// How much of the movement to use for translating overview after swipe and hold.
@@ -87,7 +84,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
private AnimatorPlaybackController mOverviewResistYAnim;
// Normal to Hint animation has flag SKIP_OVERVIEW, so we update this scrim with this animator.
- private ValueAnimator mNormalToHintOverviewScrimAnimator;
+ private ObjectAnimator mNormalToHintOverviewScrimAnimator;
private final QuickstepLauncher mLauncher;
private boolean mIsTrackpadSwipe;
@@ -137,7 +134,7 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
float progressMultiplier = super.initCurrentAnimation();
if (mToState == HINT_STATE) {
// Track the drag across the entire height of the screen.
- progressMultiplier = -1f / mLauncher.getDeviceProfile().getDeviceProperties().getHeightPx();
+ progressMultiplier = -1f / mLauncher.getDeviceProfile().heightPx;
}
return progressMultiplier;
}
@@ -164,10 +161,9 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
}
if (mFromState == NORMAL && mToState == HINT_STATE) {
- mNormalToHintOverviewScrimAnimator = ObjectAnimator.ofObject(
+ mNormalToHintOverviewScrimAnimator = ObjectAnimator.ofArgb(
mLauncher.getScrimView(),
- SCRIM_COLORS,
- ScrimColorsEvaluator.INSTANCE,
+ VIEW_BACKGROUND_COLOR,
mFromState.getWorkspaceScrimColor(mLauncher),
mToState.getWorkspaceScrimColor(mLauncher));
}
@@ -176,11 +172,6 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch
mOverviewResistYAnim = null;
}
- @Override
- public String dump() {
- return TAG;
- }
-
@Override
protected void updateProgress(float fraction) {
super.updateProgress(fraction);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
index 416c8ab4fd..58b274a47c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java
@@ -51,7 +51,6 @@ import static com.android.launcher3.util.VibratorWrapper.OVERVIEW_HAPTIC;
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import static com.android.quickstep.views.RecentsView.ADJACENT_PAGE_HORIZONTAL_OFFSET;
import static com.android.quickstep.views.RecentsView.CONTENT_ALPHA;
-import static com.android.quickstep.views.RecentsView.DESKTOP_CAROUSEL_DETACH_PROGRESS;
import static com.android.quickstep.views.RecentsView.FULLSCREEN_PROGRESS;
import static com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY;
import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION;
@@ -130,13 +129,13 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
mLauncher = launcher;
mSwipeDetector = new BothAxesSwipeDetector(mLauncher, this);
mRecentsView = mLauncher.getOverviewPanel();
- mXRange = mLauncher.getDeviceProfile().getDeviceProperties().getWidthPx() / 2f;
+ mXRange = mLauncher.getDeviceProfile().widthPx / 2f;
mYRange = LayoutUtils.getShelfTrackingDistance(
mLauncher,
mLauncher.getDeviceProfile(),
mRecentsView.getPagedOrientationHandler(),
- mRecentsView.getContainerInterface());
- mMaxYProgress = mLauncher.getDeviceProfile().getDeviceProperties().getHeightPx() / mYRange;
+ mRecentsView.getSizeStrategy());
+ mMaxYProgress = mLauncher.getDeviceProfile().heightPx / mYRange;
mMotionPauseDetector = new MotionPauseDetector(mLauncher);
mMotionPauseMinDisplacement = mLauncher.getResources().getDimension(
R.dimen.motion_pause_detector_min_displacement_from_app);
@@ -261,8 +260,6 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
RECENTS_SCALE_PROPERTY.set(mRecentsView, fromState.getOverviewScaleAndOffset(mLauncher)[0]);
ADJACENT_PAGE_HORIZONTAL_OFFSET.set(mRecentsView, 1f);
TASK_THUMBNAIL_SPLASH_ALPHA.set(mRecentsView, fromState.showTaskThumbnailSplash() ? 1f : 0);
- DESKTOP_CAROUSEL_DETACH_PROGRESS.set(mRecentsView,
- fromState.detachDesktopCarousel() ? 1f : 0);
mRecentsView.setContentAlpha(1);
mRecentsView.setFullscreenProgress(fromState.getOverviewFullscreenProgress());
mLauncher.getActionsView().getVisibilityAlpha().updateValue(
@@ -278,9 +275,8 @@ public class NoButtonQuickSwitchTouchController implements TouchController,
xAnim.setFloat(mRecentsView, ADJACENT_PAGE_HORIZONTAL_OFFSET, scaleAndOffset[1], LINEAR);
// Use QuickSwitchState instead of OverviewState to determine scrim color,
// since we need to take potential taskbar into account.
- xAnim.setScrimColors(mLauncher.getScrimView(),
- QUICK_SWITCH_FROM_HOME.getWorkspaceScrimColor(mLauncher),
- LINEAR);
+ xAnim.setViewBackgroundColor(mLauncher.getScrimView(),
+ QUICK_SWITCH_FROM_HOME.getWorkspaceScrimColor(mLauncher), LINEAR);
if (!mRecentsView.hasTaskViews()) {
xAnim.addFloat(mRecentsView, CONTENT_ALPHA, 0f, 1f, LINEAR);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
index 22055821fa..a74b350a64 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java
@@ -26,7 +26,6 @@ import android.view.MotionEvent;
import com.android.app.animation.Interpolators;
import com.android.internal.jank.Cuj;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Flags;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.allapps.AllAppsTransitionController;
@@ -34,7 +33,6 @@ import com.android.launcher3.states.StateAnimationConfig;
import com.android.launcher3.touch.AbstractStateChangeTouchController;
import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.touch.SingleAxisSwipeDetector;
-import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.uioverrides.states.OverviewState;
import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.LayoutUtils;
@@ -149,7 +147,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
mLauncher,
mLauncher.getDeviceProfile(),
recentsView.getPagedOrientationHandler(),
- recentsView.getContainerInterface());
+ recentsView.getSizeStrategy());
} else {
mCurrentAnimation = mLauncher.getStateManager()
.createAnimationToNewWorkspace(mToState, config);
@@ -218,11 +216,6 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
@Override
protected void onReinitToState(LauncherState newToState) {
super.onReinitToState(newToState);
- if (Flags.allAppsBlur() && mLauncher.isAllAppsBackgroundBlurEnabled()
- && newToState == ALL_APPS) {
- // About to start blurring during swipe to All Apps; prepare the renderer.
- ((QuickstepLauncher) mLauncher).getDepthController().setEarlyWakeup(true);
- }
if (newToState != ALL_APPS) {
InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_OPEN_ALL_APPS);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
index 14896e53c7..f582324f23 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/QuickSwitchTouchController.java
@@ -161,6 +161,6 @@ public class QuickSwitchTouchController extends AbstractStateChangeTouchControll
@Override
protected float getShiftRange() {
- return mLauncher.getDeviceProfile().getDeviceProperties().getWidthPx() / 2f;
+ return mLauncher.getDeviceProfile().widthPx / 2f;
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
index 9d501ed116..16647a90b7 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/StatusBarTouchController.java
@@ -24,25 +24,24 @@ import static android.view.MotionEvent.ACTION_UP;
import static android.view.WindowManager.LayoutParams.FLAG_SLIPPERY;
import static com.android.launcher3.MotionEventsUtils.isTrackpadScroll;
-import static com.android.launcher3.Utilities.shouldEnableMouseInteractionChanges;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPE_DOWN_WORKSPACE_NOTISHADE_OPEN;
import android.graphics.PointF;
import android.util.SparseArray;
-import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.view.Window;
import android.view.WindowManager;
import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.TouchController;
import com.android.quickstep.SystemUiProxy;
-import java.util.function.Supplier;
+import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import app.lawnchair.LawnchairAppKt;
@@ -57,30 +56,29 @@ public class StatusBarTouchController implements TouchController {
private static final String TAG = "StatusBarController";
- private final BaseActivity mLauncher;
+ private final Launcher mLauncher;
private final SystemUiProxy mSystemUiProxy;
private final float mTouchSlop;
private int mLastAction;
private final SparseArray mDownEvents;
- private final Supplier mIsEnabledCheck;
/* If {@code false}, this controller should not handle the input {@link MotionEvent}.*/
private boolean mCanIntercept;
- public StatusBarTouchController(BaseActivity l, Supplier isEnabledCheck) {
+ public StatusBarTouchController(Launcher l) {
mLauncher = l;
mSystemUiProxy = SystemUiProxy.INSTANCE.get(mLauncher);
// Guard against TAPs by increasing the touch slop.
mTouchSlop = 2 * ViewConfiguration.get(l).getScaledTouchSlop();
mDownEvents = new SparseArray<>();
- mIsEnabledCheck = isEnabledCheck;
}
@Override
- public String dump() {
- return "mCanIntercept:" + mCanIntercept
- + " , mLastAction:" + MotionEvent.actionToString(mLastAction)
- + " , mSysUiProxy available:" + SystemUiProxy.INSTANCE.get(mLauncher).isActive();
+ public void dump(String prefix, PrintWriter writer) {
+ writer.println(prefix + "mCanIntercept:" + mCanIntercept);
+ writer.println(prefix + "mLastAction:" + MotionEvent.actionToString(mLastAction));
+ writer.println(prefix + "mSysUiProxy available:"
+ + SystemUiProxy.INSTANCE.get(mLauncher).isActive());
}
private void dispatchTouchEvent(MotionEvent ev) {
@@ -167,11 +165,9 @@ public class StatusBarTouchController implements TouchController {
}
private boolean canInterceptTouch(MotionEvent ev) {
- if (isTrackpadScroll(ev) || !mIsEnabledCheck.get()
+ if (isTrackpadScroll(ev) || !mLauncher.isInState(LauncherState.NORMAL)
|| AbstractFloatingView.getTopOpenViewWithType(mLauncher,
- AbstractFloatingView.TYPE_STATUS_BAR_SWIPE_DOWN_DISALLOW) != null || (
- shouldEnableMouseInteractionChanges(mLauncher.asContext())
- && ev.getSource() == InputDevice.SOURCE_MOUSE)) {
+ AbstractFloatingView.TYPE_STATUS_BAR_SWIPE_DOWN_DISALLOW) != null) {
return false;
} else {
// For NORMAL state, only listen if the event originated above the navbar height
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewDismissTouchController.kt b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewDismissTouchController.kt
index a85f706f69..06e6734a37 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewDismissTouchController.kt
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewDismissTouchController.kt
@@ -28,41 +28,23 @@ import com.android.launcher3.Utilities.boundToRange
import com.android.launcher3.Utilities.debugLog
import com.android.launcher3.Utilities.isRtl
import com.android.launcher3.Utilities.mapToRange
-import com.android.launcher3.statemanager.BaseState
-import com.android.launcher3.statemanager.StateManager.StateListener
-import com.android.launcher3.statemanager.StatefulContainer
import com.android.launcher3.touch.SingleAxisSwipeDetector
import com.android.launcher3.util.MSDLPlayerWrapper
import com.android.launcher3.util.TouchController
-import com.android.mechanics.spec.Breakpoint
-import com.android.mechanics.spec.Breakpoint.Companion.maxLimit
-import com.android.mechanics.spec.Breakpoint.Companion.minLimit
-import com.android.mechanics.spec.BreakpointKey
-import com.android.mechanics.spec.DirectionalMotionSpec
-import com.android.mechanics.spec.Guarantee
-import com.android.mechanics.spec.InputDirection
-import com.android.mechanics.spec.Mapping
-import com.android.mechanics.spec.MotionSpec
-import com.android.mechanics.spring.SpringParameters
-import com.android.mechanics.view.DistanceGestureContext
-import com.android.mechanics.view.ViewMotionValue
-import com.android.quickstep.views.RecentsDismissUtils
import com.android.quickstep.views.RecentsView
import com.android.quickstep.views.RecentsView.RECENTS_SCALE_PROPERTY
import com.android.quickstep.views.RecentsViewContainer
import com.android.quickstep.views.TaskView
import com.google.android.msdl.data.model.MSDLToken
import kotlin.math.abs
-import kotlin.math.ceil
/** Touch controller for handling task view card dismiss swipes */
-class TaskViewDismissTouchController>(
+class TaskViewDismissTouchController(
private val container: CONTAINER,
private val taskViewRecentsTouchContext: TaskViewRecentsTouchContext,
) : TouchController, SingleAxisSwipeDetector.Listener where
CONTAINER : Context,
-CONTAINER : RecentsViewContainer,
-CONTAINER : StatefulContainer {
+CONTAINER : RecentsViewContainer {
private val recentsView: RecentsView<*, *> = container.getOverviewPanel()
private val detector: SingleAxisSwipeDetector =
SingleAxisSwipeDetector(
@@ -72,37 +54,17 @@ CONTAINER : StatefulContainer {
)
private val isRtl = isRtl(container.resources)
private val upDirection: Int = recentsView.pagedOrientationHandler.getUpDirection(isRtl)
- private val maxUndershoot =
- container.resources.getDimension(R.dimen.task_dismiss_max_undershoot)
- private val detachThreshold =
- container.resources.getDimension(R.dimen.task_dismiss_detach_threshold)
- private val stateListener =
- object : StateListener {
- override fun onStateTransitionStart(toState: T) {
- springAnimation?.cancel()
- clearState()
- }
- }
+
private val tempTaskThumbnailBounds = Rect()
private var taskBeingDragged: TaskView? = null
- private var taskDragDisplacementValue: ViewMotionValue? = null
- private var springAnimation: RecentsDismissUtils.SpringSet? = null
+ private var springAnimation: SpringAnimation? = null
private var dismissLength: Int = 0
private var verticalFactor: Int = 0
private var hasDismissThresholdHapticRun = false
private var initialDisplacement: Float = 0f
private var recentsScaleAnimation: SpringAnimation? = null
- private var canInterceptTouch = false
- private var isDismissing = false
-
- init {
- container.getStateManager().addStateListener(stateListener)
- }
-
- override fun onTouchControllerDestroyed() {
- container.getStateManager().removeStateListener(stateListener)
- }
+ private var isBlockedDuringDismissal = false
private fun canInterceptTouch(ev: MotionEvent): Boolean =
when {
@@ -128,12 +90,6 @@ CONTAINER : StatefulContainer {
false
}
- // Do not allow dismiss while recents is scrolling.
- !recentsView.scroller.isFinished -> {
- debugLog(TAG, "Not intercepting touch, recents scrolling.")
- false
- }
-
else ->
taskViewRecentsTouchContext.isRecentsInteractive.also { isRecentsInteractive ->
if (!isRecentsInteractive) {
@@ -143,22 +99,15 @@ CONTAINER : StatefulContainer {
}
override fun onControllerInterceptTouchEvent(ev: MotionEvent): Boolean {
- // On consecutive events, end animation early so user can dismiss next task.
- springAnimation?.speedUpSpringsToEnd()
-
if ((ev.action == MotionEvent.ACTION_UP || ev.action == MotionEvent.ACTION_CANCEL)) {
clearState()
}
if (ev.action == MotionEvent.ACTION_DOWN) {
- canInterceptTouch = onActionDown(ev)
- if (!canInterceptTouch) {
+ if (!onActionDown(ev)) {
return false
}
}
- // Ignore other actions if touch intercepting has not been enabled in an ACTION_DOWN event.
- if (!canInterceptTouch) {
- return false
- }
+
onControllerTouchEvent(ev)
val upDirectionIsPositive = upDirection == SingleAxisSwipeDetector.DIRECTION_POSITIVE
val wasInitialTouchUp =
@@ -170,87 +119,42 @@ CONTAINER : StatefulContainer {
override fun onControllerTouchEvent(ev: MotionEvent?): Boolean = detector.onTouchEvent(ev)
private fun onActionDown(ev: MotionEvent): Boolean {
+ springAnimation?.cancel()
+ recentsScaleAnimation?.cancel()
if (!canInterceptTouch(ev)) {
return false
}
taskBeingDragged =
- recentsView.taskViews.firstOrNull {
- recentsView.isTaskViewVisible(it) && container.dragLayer.isEventOverView(it, ev)
- }
- // If event is not over a taskView, check if it would have been either over the
- // currently dismissing task being dragged, or over where the next task will be.
- ?: recentsView.taskViews.firstOrNull { taskView ->
- if (!recentsView.isTaskViewVisible(taskView)) return@firstOrNull false
- container.dragLayer.getDescendantRectRelativeToSelf(
- taskView,
- tempTaskThumbnailBounds,
- )
- if (taskView == taskBeingDragged && !isDismissing) {
- val secondaryTranslation =
- -taskView.secondaryDismissTranslationProperty.get(taskView).toInt()
- recentsView.pagedOrientationHandler.extendRectForSecondaryTranslation(
- tempTaskThumbnailBounds,
- secondaryTranslation,
- )
- } else {
- val primaryTranslation =
- recentsView.taskViewsDismissPrimaryTranslations[taskView] ?: 0
- recentsView.pagedOrientationHandler.extendRectForPrimaryTranslation(
- tempTaskThumbnailBounds,
- primaryTranslation,
- )
- }
- tempTaskThumbnailBounds.contains(ev.x.toInt(), ev.y.toInt())
+ recentsView.taskViews
+ .firstOrNull {
+ recentsView.isTaskViewVisible(it) && container.dragLayer.isEventOverView(it, ev)
+ }
+ ?.also {
+ val secondaryLayerDimension =
+ recentsView.pagedOrientationHandler.getSecondaryDimension(
+ container.dragLayer
+ )
+ // Dismiss length as bottom of task so it is fully off screen when dismissed.
+ it.getThumbnailBounds(tempTaskThumbnailBounds, relativeToDragLayer = true)
+ dismissLength =
+ recentsView.pagedOrientationHandler.getTaskDismissLength(
+ secondaryLayerDimension,
+ tempTaskThumbnailBounds,
+ )
+ verticalFactor =
+ recentsView.pagedOrientationHandler.getTaskDismissVerticalDirection()
}
-
- if (taskBeingDragged == null) {
- debugLog(TAG, "Not intercepting touch, null dragged task.")
- return false
- }
- val secondaryLayerDimension =
- recentsView.pagedOrientationHandler.getSecondaryDimension(container.dragLayer)
- // Dismiss length as bottom of task so it is fully off screen when dismissed.
- // Take into account the recents scale when fully zoomed out on dismiss.
- taskBeingDragged?.getThumbnailBounds(tempTaskThumbnailBounds, relativeToDragLayer = true)
- dismissLength =
- ceil(
- recentsView.pagedOrientationHandler.getTaskDismissLength(
- secondaryLayerDimension,
- tempTaskThumbnailBounds,
- ) / RECENTS_SCALE_ON_DISMISS_SUCCESS
- )
- .toInt()
- verticalFactor = recentsView.pagedOrientationHandler.getTaskDismissVerticalDirection()
- taskBeingDragged?.isBeingDraggedForDismissal = true
-
detector.setDetectableScrollConditions(upDirection, /* ignoreSlop= */ false)
return true
}
override fun onDragStart(start: Boolean, startDisplacement: Float) {
+ if (isBlockedDuringDismissal) return
val taskBeingDragged = taskBeingDragged ?: return
debugLog(TAG, "Handling touch event.")
initialDisplacement =
taskBeingDragged.secondaryDismissTranslationProperty.get(taskBeingDragged)
- taskDragDisplacementValue =
- generateMotionValue(
- initialDisplacement,
- detachThreshold * verticalFactor,
- container.asContext(),
- ) { currentDisplacement ->
- taskBeingDragged.secondaryDismissTranslationProperty.setValue(
- taskBeingDragged,
- currentDisplacement,
- )
- if (taskBeingDragged.isRunningTask && recentsView.enableDrawingLiveTile) {
- recentsView.runActionOnRemoteHandles { remoteTargetHandle ->
- remoteTargetHandle.taskViewSimulator.taskSecondaryTranslation.value =
- currentDisplacement
- }
- recentsView.redrawLiveTile()
- }
- }
// Add a tiny bit of translation Z, so that it draws on top of other views. This is relevant
// (e.g.) when we dismiss a task by sliding it upward: if there is a row of icons above, we
@@ -259,26 +163,36 @@ CONTAINER : StatefulContainer {
}
override fun onDrag(displacement: Float): Boolean {
- taskBeingDragged ?: return false
+ if (isBlockedDuringDismissal) return true
+ val taskBeingDragged = taskBeingDragged ?: return false
val currentDisplacement = displacement + initialDisplacement
val boundedDisplacement =
boundToRange(abs(currentDisplacement), 0f, dismissLength.toFloat())
// When swiping below origin, allow slight undershoot to simulate resisting the movement.
- val isAboveOrigin =
- recentsView.pagedOrientationHandler.isGoingUp(currentDisplacement, isRtl)
val totalDisplacement =
- if (isAboveOrigin) boundedDisplacement * verticalFactor
+ if (recentsView.pagedOrientationHandler.isGoingUp(currentDisplacement, isRtl))
+ boundedDisplacement * verticalFactor
else
mapToRange(
boundedDisplacement,
0f,
dismissLength.toFloat(),
0f,
- maxUndershoot,
+ container.resources.getDimension(R.dimen.task_dismiss_max_undershoot),
DECELERATE,
) * -verticalFactor
+ taskBeingDragged.secondaryDismissTranslationProperty.setValue(
+ taskBeingDragged,
+ totalDisplacement,
+ )
+ if (taskBeingDragged.isRunningTask && recentsView.enableDrawingLiveTile) {
+ recentsView.runActionOnRemoteHandles { remoteTargetHandle ->
+ remoteTargetHandle.taskViewSimulator.taskSecondaryTranslation.value =
+ totalDisplacement
+ }
+ recentsView.redrawLiveTile()
+ }
val dismissFraction = displacement / (dismissLength * verticalFactor).toFloat()
- taskDragDisplacementValue?.input = totalDisplacement
RECENTS_SCALE_PROPERTY.setValue(recentsView, getRecentsScale(dismissFraction))
playDismissThresholdHaptic(displacement)
return true
@@ -305,9 +219,8 @@ CONTAINER : StatefulContainer {
}
override fun onDragEnd(velocity: Float) {
+ if (isBlockedDuringDismissal) return
val taskBeingDragged = taskBeingDragged ?: return
- taskDragDisplacementValue?.dispose()
- taskBeingDragged.isBeingDraggedForDismissal = false
val currentDisplacement =
taskBeingDragged.secondaryDismissTranslationProperty.get(taskBeingDragged)
@@ -316,23 +229,23 @@ CONTAINER : StatefulContainer {
val velocityIsGoingUp = recentsView.pagedOrientationHandler.isGoingUp(velocity, isRtl)
val isFlingingTowardsDismiss = detector.isFling(velocity) && velocityIsGoingUp
val isFlingingTowardsRestState = detector.isFling(velocity) && !velocityIsGoingUp
- isDismissing =
+ val isDismissing =
isFlingingTowardsDismiss || (isBeyondDismissThreshold && !isFlingingTowardsRestState)
- val dismissThreshold = (DISMISS_THRESHOLD_FRACTION * dismissLength * verticalFactor).toInt()
- val finalPosition = if (isDismissing) (dismissLength * verticalFactor).toFloat() else 0f
springAnimation =
- recentsView.runTaskDismissSettlingSpringAnimation(
- taskBeingDragged,
- isDismissing,
- RecentsDismissUtils.DismissedTaskData(
- startVelocity = velocity,
- dismissLength = dismissLength,
- finalPosition = finalPosition,
- dismissThreshold = dismissThreshold,
- ),
- /* shouldRemoveTaskView= */ isDismissing,
- /* isSplitSelection= */ false,
- )
+ recentsView
+ .createTaskDismissSettlingSpringAnimation(
+ taskBeingDragged,
+ velocity,
+ isDismissing,
+ dismissLength,
+ this::clearState,
+ )
+ .apply {
+ animateToFinalPosition(
+ if (isDismissing) (dismissLength * verticalFactor).toFloat() else 0f
+ )
+ }
+ isBlockedDuringDismissal = true
recentsScaleAnimation =
recentsView.animateRecentsScale(RECENTS_SCALE_DEFAULT).addEndListener { _, _, _, _ ->
recentsScaleAnimation = null
@@ -342,11 +255,10 @@ CONTAINER : StatefulContainer {
private fun clearState() {
detector.finishedScrolling()
detector.setDetectableScrollConditions(0, false)
- taskBeingDragged?.resetViewTransforms()
+ taskBeingDragged?.translationZ = 0f
taskBeingDragged = null
springAnimation = null
- taskDragDisplacementValue = null
- isDismissing = false
+ isBlockedDuringDismissal = false
}
private fun getRecentsScale(dismissFraction: Float): Float {
@@ -388,43 +300,6 @@ CONTAINER : StatefulContainer {
}
}
- private fun generateMotionValue(
- initialDisplacement: Float,
- detachThreshold: Float,
- context: Context,
- updateCallback: (Float) -> Unit,
- ): ViewMotionValue {
- val direction = if (initialDisplacement < 0) InputDirection.Max else InputDirection.Min
- val distanceGestureContext =
- DistanceGestureContext.create(context, initialDisplacement, direction)
- val viewMotionValue =
- ViewMotionValue(
- initialDisplacement,
- distanceGestureContext,
- generateMotionSpec(detachThreshold),
- label = "taskDismiss::displacement",
- )
-
- viewMotionValue.addUpdateCallback { motionValue -> updateCallback(motionValue.output) }
- return viewMotionValue
- }
-
- /** Motion spec for an initial magnetic detach. Track linearly otherwise. No reattach. */
- private fun generateMotionSpec(detachThreshold: Float): MotionSpec {
- val spring = SpringParameters(stiffness = 800f, dampingRatio = 0.95f)
- val detachKey = BreakpointKey("TaskDismiss::Detach")
- val breakpoints = mutableListOf()
- val mappings = mutableListOf()
-
- breakpoints.add(minLimit)
- mappings.add(Mapping.Identity)
- breakpoints.add(Breakpoint(detachKey, detachThreshold, spring, Guarantee.None))
- mappings.add(Mapping.Linear(MAGNETIC_DETACH_INTERPOLATION_FRACTION))
- breakpoints.add(maxLimit)
-
- return MotionSpec(DirectionalMotionSpec(breakpoints, mappings))
- }
-
companion object {
private const val TAG = "TaskViewDismissTouchController"
@@ -437,7 +312,5 @@ CONTAINER : StatefulContainer {
private const val RECENTS_SCALE_FIRST_THRESHOLD_FRACTION = 0.2f
private const val RECENTS_SCALE_DISMISS_THRESHOLD_FRACTION = 0.5f
private const val RECENTS_SCALE_SECOND_THRESHOLD_FRACTION = 0.575f
-
- private const val MAGNETIC_DETACH_INTERPOLATION_FRACTION = 0.35f
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewLaunchTouchController.kt b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewLaunchTouchController.kt
index 6225c47835..fe9cae55f9 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewLaunchTouchController.kt
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewLaunchTouchController.kt
@@ -60,7 +60,6 @@ CONTAINER : RecentsViewContainer {
private var launchEndDisplacement: Float = 0f
private var playbackController: AnimatorPlaybackController? = null
private var verticalFactor: Int = 0
- private var canInterceptTouch = false
private fun canTaskLaunchTaskView(taskView: TaskView?) =
taskView != null &&
@@ -93,12 +92,6 @@ CONTAINER : RecentsViewContainer {
false
}
- // Do not allow launch while recents is scrolling.
- !recentsView.scroller.isFinished -> {
- debugLog(TAG, "Not intercepting touch, recents scrolling.")
- false
- }
-
else ->
taskViewRecentsTouchContext.isRecentsInteractive.also { isRecentsInteractive ->
if (!isRecentsInteractive) {
@@ -115,16 +108,11 @@ CONTAINER : RecentsViewContainer {
clearState()
}
if (ev.action == MotionEvent.ACTION_DOWN) {
- canInterceptTouch = onActionDown(ev)
- if (!canInterceptTouch) {
+ if (!onActionDown(ev)) {
clearState()
return false
}
}
- // Ignore other actions if touch intercepting has not been enabled in an ACTION_DOWN event.
- if (!canInterceptTouch) {
- return false
- }
onControllerTouchEvent(ev)
val downDirectionIsNegative = downDirection == SingleAxisSwipeDetector.DIRECTION_NEGATIVE
val wasInitialTouchDown =
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchControllerDeprecated.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchControllerDeprecated.java
index d9b0366a40..c9d68a5e37 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchControllerDeprecated.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TaskViewTouchControllerDeprecated.java
@@ -246,7 +246,7 @@ public class TaskViewTouchControllerDeprecated<
pa = new PendingAnimation(maxDuration);
mRecentsView.createTaskDismissAnimation(pa, mTaskBeingDragged,
true /* animateTaskView */, true /* removeTask */, maxDuration,
- false /* dismissingForSplitSelection*/, null /* gridEndData */);
+ false /* dismissingForSplitSelection*/, false /* isExpressiveDismiss */);
mEndDisplacement = -secondaryTaskDimension;
} else {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TransposedQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TransposedQuickSwitchTouchController.java
index e7d2cd23c6..b70cabe76d 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TransposedQuickSwitchTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/TransposedQuickSwitchTouchController.java
@@ -39,6 +39,6 @@ public class TransposedQuickSwitchTouchController extends QuickSwitchTouchContro
@Override
protected float getShiftRange() {
- return mLauncher.getDeviceProfile().getDeviceProperties().getHeightPx() / 2f;
+ return mLauncher.getDeviceProfile().heightPx / 2f;
}
}
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index aa81afb759..d9b90f5c73 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -16,7 +16,6 @@
package com.android.quickstep;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
-import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.view.Surface.ROTATION_0;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
@@ -31,6 +30,7 @@ import static com.android.launcher3.BaseActivity.EVENT_DESTROYED;
import static com.android.launcher3.BaseActivity.EVENT_STARTED;
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_STATE_HANDLER;
import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
+import static com.android.launcher3.Flags.enableAdditionalHomeAnimations;
import static com.android.launcher3.Flags.enableGestureNavHorizontalTouchSlop;
import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation;
import static com.android.launcher3.Flags.msdlFeedback;
@@ -98,7 +98,6 @@ import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.view.WindowInsets;
import android.view.animation.Interpolator;
import android.widget.Toast;
-import android.window.DesktopExperienceFlags;
import android.window.DesktopModeFlags;
import android.window.PictureInPictureSurfaceTransaction;
import android.window.TransitionInfo;
@@ -137,7 +136,7 @@ import com.android.launcher3.util.VibratorWrapper;
import com.android.launcher3.util.WindowBounds;
import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
-import com.android.quickstep.fallback.window.RecentsWindowManager;
+import com.android.quickstep.fallback.window.RecentsWindowFlags;
import com.android.quickstep.util.ActiveGestureErrorDetector;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
@@ -169,10 +168,10 @@ import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
+import com.android.wm.shell.Flags;
import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.TransactionPool;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
-import com.android.wm.shell.shared.pip.PipFlags;
import com.android.wm.shell.shared.startingsurface.SplashScreenExitAnimationUtils;
import com.google.android.msdl.data.model.MSDLToken;
@@ -216,7 +215,6 @@ public abstract class AbsSwipeUpHandler<
protected @Nullable RECENTS_CONTAINER mContainer;
protected @Nullable RECENTS_VIEW mRecentsView;
protected Runnable mGestureEndCallback;
- protected Runnable mGestureAnimationEndCallback;
protected MultiStateCallback mStateCallback;
protected boolean mCanceled;
private boolean mRecentsViewScrollLinked = false;
@@ -349,7 +347,15 @@ public abstract class AbsSwipeUpHandler<
private final SwipePipToHomeAnimator[] mSwipePipToHomeAnimators =
new SwipePipToHomeAnimator[2];
- private final Runnable mLauncherOnDestroyCallback;
+ private final Runnable mLauncherOnDestroyCallback = () -> {
+ ActiveGestureProtoLogProxy.logLauncherDestroyed();
+ mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener);
+ mRecentsView = null;
+ mContainer = null;
+ mStateCallback.clearState(STATE_LAUNCHER_PRESENT);
+ mRecentsAnimationStartCallbacks.clear();
+ mTaskAnimationManager.onLauncherDestroyed();
+ };
// Interpolate RecentsView scale from start of quick switch scroll until this scroll threshold
private final float mQuickSwitchScaleScrollThreshold;
@@ -374,30 +380,16 @@ public abstract class AbsSwipeUpHandler<
private final MSDLPlayerWrapper mMSDLPlayerWrapper;
- private final RotationTouchHelper mRotationTouchHelper;
-
public AbsSwipeUpHandler(Context context,
- TaskAnimationManager taskAnimationManager, RecentsAnimationDeviceState deviceState,
- RotationTouchHelper rotationTouchHelper, GestureState gestureState,
+ TaskAnimationManager taskAnimationManager, GestureState gestureState,
long touchTimeMs, boolean continuingLastGesture,
InputConsumerController inputConsumer,
MSDLPlayerWrapper msdlPlayerWrapper) {
- super(context, gestureState, rotationTouchHelper);
+ super(context, gestureState);
+ mDeviceState = RecentsAnimationDeviceState.INSTANCE.get(mContext);
mContainerInterface = gestureState.getContainerInterface();
mContextInitListener =
mContainerInterface.createActivityInitListener(this::onActivityInit);
- mLauncherOnDestroyCallback = () -> {
- ActiveGestureProtoLogProxy.logLauncherDestroyed();
- mContextInitListener.unregister("AbsSwipeUpHandler.mLauncherOnDestroyCallback");
- if (mRecentsView != null) {
- mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener);
- mRecentsView = null;
- }
- mContainer = null;
- mStateCallback.clearState(STATE_LAUNCHER_PRESENT);
- mRecentsAnimationStartCallbacks.clear();
- mTaskAnimationManager.onLauncherDestroyed();
- };
mInputConsumerProxy =
new InputConsumerProxy(context, /* rotationSupplier = */ () -> {
if (mRecentsView == null) {
@@ -409,10 +401,8 @@ public abstract class AbsSwipeUpHandler<
endLauncherTransitionController();
}, new InputProxyHandlerFactory(mContainerInterface, mGestureState));
mTaskAnimationManager = taskAnimationManager;
- mDeviceState = deviceState;
mTouchTimeMs = touchTimeMs;
mContinuingLastGesture = continuingLastGesture;
- mRotationTouchHelper = rotationTouchHelper;
Resources res = context.getResources();
mQuickSwitchScaleScrollThreshold = res
@@ -598,7 +588,7 @@ public abstract class AbsSwipeUpHandler<
private void onLauncherStart() {
final RECENTS_CONTAINER container = mContainerInterface.getCreatedContainer();
- if (container == null || mContainer != container || mRecentsView == null) {
+ if (container == null || mContainer != container) {
return;
}
if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) {
@@ -680,9 +670,9 @@ public abstract class AbsSwipeUpHandler<
mGestureState.getContainerInterface().setOnDeferredActivityLaunchCallback(
mOnDeferredActivityLaunch);
- mGestureState.runOnceAtState(STATE_END_TARGET_SET,
- () -> mRotationTouchHelper.onEndTargetCalculated(mGestureState.getEndTarget(),
- mContainerInterface));
+ mGestureState.runOnceAtState(STATE_END_TARGET_SET, () ->
+ RotationTouchHelper.INSTANCE.get(mContext)
+ .onEndTargetCalculated(mGestureState.getEndTarget(), mContainerInterface));
notifyGestureStarted();
}
@@ -912,8 +902,7 @@ public abstract class AbsSwipeUpHandler<
public Intent getLaunchIntent() {
// todo differentiate intent based on if we are on home or in app for overview in window
- boolean useHomeIntentForWindow =
- mContainerInterface.getCreatedContainer() instanceof RecentsWindowManager;
+ boolean useHomeIntentForWindow = RecentsWindowFlags.getEnableOverviewInWindow();
return useHomeIntentForWindow ? getHomeIntent() : mGestureState.getOverviewIntent();
}
/**
@@ -973,21 +962,7 @@ public abstract class AbsSwipeUpHandler<
public void onRecentsAnimationStart(RecentsAnimationController controller,
RecentsAnimationTargets targets, @Nullable TransitionInfo transitionInfo) {
super.onRecentsAnimationStart(controller, targets, transitionInfo);
- boolean forDesktop;
- if (DesktopModeStatus.enableMultipleDesktops(mContext)) {
- GroupedTaskInfo groupedTaskInfo;
- if (mGestureState.getRunningTask() != null
- && (groupedTaskInfo =
- mGestureState.getRunningTask().getPlaceholderGroupedTaskInfo(
- /* splitTaskIds = */ null)) != null) {
- forDesktop = groupedTaskInfo.isBaseType(GroupedTaskInfo.TYPE_DESK);
- } else {
- forDesktop = false;
- }
- } else {
- forDesktop = targets.hasDesktopTasks(mContext);
- }
- if (forDesktop) {
+ if (targets.hasDesktopTasks(mContext)) {
mRemoteTargetHandles = mTargetGluer.assignTargetsForDesktop(targets, transitionInfo);
} else {
int untrimmedAppCount = mRemoteTargetHandles.length;
@@ -1018,11 +993,9 @@ public abstract class AbsSwipeUpHandler<
.getOrientationState();
DeviceProfile dp = orientationState.getLauncherDeviceProfile(
mGestureState.getDisplayId());
- Rect overviewStackBounds = mContainerInterface.getOverviewWindowBounds(
- targets.minimizedHomeBounds, primaryTaskTarget);
- if (overviewStackBounds != null
- && !overviewStackBounds.isEmpty()
- && primaryTaskTarget != null) {
+ if (targets.minimizedHomeBounds != null && primaryTaskTarget != null) {
+ Rect overviewStackBounds = mContainerInterface
+ .getOverviewWindowBounds(targets.minimizedHomeBounds, primaryTaskTarget);
dp = dp.getMultiWindowProfile(mContext,
new WindowBounds(overviewStackBounds, targets.homeContentInsets));
} else {
@@ -1031,7 +1004,7 @@ public abstract class AbsSwipeUpHandler<
}
dp.updateInsets(targets.homeContentInsets);
initTransitionEndpoints(dp);
- orientationState.setMultiWindowMode(dp.getDeviceProperties().isMultiWindowMode());
+ orientationState.setMultiWindowMode(dp.isMultiWindowMode);
}
// Notify when the animation starts
@@ -1073,10 +1046,12 @@ public abstract class AbsSwipeUpHandler<
}
mHandled = true;
- InteractionJankMonitorWrapper.begin(
- rv, Cuj.CUJ_LAUNCHER_QUICK_SWITCH, /* timeoutMs= */ 2000);
- InteractionJankMonitorWrapper.begin(rv, Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_HOME);
- InteractionJankMonitorWrapper.begin(rv, Cuj.CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS);
+ InteractionJankMonitorWrapper.begin(mRecentsView, Cuj.CUJ_LAUNCHER_QUICK_SWITCH,
+ 2000 /* ms timeout */);
+ InteractionJankMonitorWrapper.begin(mRecentsView,
+ Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_HOME);
+ InteractionJankMonitorWrapper.begin(mRecentsView,
+ Cuj.CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS);
rv.post(() -> rv.getViewTreeObserver().removeOnDrawListener(this));
}
@@ -1544,7 +1519,7 @@ public abstract class AbsSwipeUpHandler<
}
private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTaskView) {
- if (mDp == null || !mDp.getDeviceProperties().isGestureMode()) {
+ if (mDp == null || !mDp.isGestureMode) {
// We probably never received an animation controller, skip logging.
return;
}
@@ -1687,26 +1662,21 @@ public abstract class AbsSwipeUpHandler<
boolean hasValidLeash = runningTaskTarget != null
&& runningTaskTarget.leash != null
&& runningTaskTarget.leash.isValid();
- final boolean swipeUpInDesktopWindowing =
- DesktopExperienceFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue()
- && runningTaskTarget != null
- && runningTaskTarget.taskInfo.getWindowingMode()
- == WINDOWING_MODE_FREEFORM;
boolean appCanEnterPip = !mDeviceState.isPipActive()
&& hasValidLeash
&& runningTaskTarget.allowEnterPip
&& runningTaskTarget.taskInfo.pictureInPictureParams != null
- && runningTaskTarget.taskInfo.pictureInPictureParams.isAutoEnterEnabled()
- && !swipeUpInDesktopWindowing;
+ && runningTaskTarget.taskInfo.pictureInPictureParams.isAutoEnterEnabled();
HomeAnimationFactory homeAnimFactory = createHomeAnimationFactory(
cookies,
duration,
isTranslucent,
appCanEnterPip,
runningTaskTarget,
- mRecentsView == null
+ !enableAdditionalHomeAnimations()
+ || mRecentsView == null
|| mRecentsView.getCurrentPage() == mRecentsView.getRunningTaskIndex()
- ? null : mRecentsView.getCurrentPageTaskView());
+ ? null : mRecentsView.getCurrentPageTaskView());
SwipePipToHomeAnimator swipePipToHomeAnimator = !mIsSwipeForSplit && appCanEnterPip
? createWindowAnimationToPip(homeAnimFactory, runningTaskTarget, start)
: null;
@@ -1783,10 +1753,8 @@ public abstract class AbsSwipeUpHandler<
mLauncherTransitionController = null;
if (mRecentsView != null) {
- AnimatorSet animatorSet = new AnimatorSet();
- mRecentsView.onPrepareGestureEndAnimation(animatorSet, mGestureState.getEndTarget(),
- mRemoteTargetHandles, /* isHandlingAtomicEvent= */ true);
- animatorSet.setDuration(0).start();
+ mRecentsView.onPrepareGestureEndAnimation(null, mGestureState.getEndTarget(),
+ mRemoteTargetHandles);
}
} else {
AnimatorSet animatorSet = new AnimatorSet();
@@ -1828,10 +1796,9 @@ public abstract class AbsSwipeUpHandler<
animatorSet.play(windowAnim);
if (mRecentsView != null) {
mRecentsView.onPrepareGestureEndAnimation(
- animatorSet,
+ mGestureState.isHandlingAtomicEvent() ? null : animatorSet,
mGestureState.getEndTarget(),
- mRemoteTargetHandles,
- mGestureState.isHandlingAtomicEvent());
+ mRemoteTargetHandles);
}
animatorSet.setDuration(duration).setInterpolator(interpolator);
animatorSet.start();
@@ -1983,26 +1950,24 @@ public abstract class AbsSwipeUpHandler<
private Rect getKeepClearAreaForHotseat() {
Rect keepClearArea;
- final int heightPx = mDp.getDeviceProperties().getHeightPx();
- final int widthPx = mDp.getDeviceProperties().getWidthPx();
// the keep clear area in global screen coordinates, in pixels
- if (mDp.getDeviceProperties().isPhone()) {
+ if (mDp.isPhone) {
if (mDp.isSeascape()) {
// in seascape the Hotseat is on the left edge of the screen
- keepClearArea = new Rect(0, 0, mDp.hotseatBarSizePx, heightPx);
- } else if (mDp.getDeviceProperties().isLandscape()) {
+ keepClearArea = new Rect(0, 0, mDp.hotseatBarSizePx, mDp.heightPx);
+ } else if (mDp.isLandscape) {
// in landscape the Hotseat is on the right edge of the screen
- keepClearArea = new Rect(widthPx - mDp.hotseatBarSizePx, 0,
- widthPx, heightPx);
+ keepClearArea = new Rect(mDp.widthPx - mDp.hotseatBarSizePx, 0,
+ mDp.widthPx, mDp.heightPx);
} else {
// in portrait mode the Hotseat is at the bottom of the screen
- keepClearArea = new Rect(0, heightPx - mDp.hotseatBarSizePx,
- widthPx, heightPx);
+ keepClearArea = new Rect(0, mDp.heightPx - mDp.hotseatBarSizePx,
+ mDp.widthPx, mDp.heightPx);
}
} else {
// large screens have Hotseat always at the bottom of the screen
- keepClearArea = new Rect(0, heightPx - mDp.hotseatBarSizePx,
- widthPx, heightPx);
+ keepClearArea = new Rect(0, mDp.heightPx - mDp.hotseatBarSizePx,
+ mDp.widthPx, mDp.heightPx);
}
return keepClearArea;
}
@@ -2180,9 +2145,6 @@ public abstract class AbsSwipeUpHandler<
if (mRecentsView != null) {
mRecentsView.onGestureAnimationEnd();
}
- if (mGestureAnimationEndCallback != null) {
- mGestureAnimationEndCallback.run();
- }
resetLauncherListeners();
}
@@ -2343,7 +2305,7 @@ public abstract class AbsSwipeUpHandler<
mSwipePipToHomeAnimator.getFinishTransaction(),
mSwipePipToHomeAnimator.getContentOverlay());
mIsSwipingPipToHome = false;
- } else if (mIsSwipeForSplit && !PipFlags.isPip2ExperimentEnabled()) {
+ } else if (mIsSwipeForSplit && !Flags.enablePip2()) {
// Transaction to hide the task to avoid flicker for entering PiP from split-screen.
// Note: PiP2 handles entering differently, so skip if enable_pip2=true
PictureInPictureSurfaceTransaction tx =
@@ -2403,10 +2365,6 @@ public abstract class AbsSwipeUpHandler<
mGestureEndCallback = gestureEndCallback;
}
- public void setGestureAnimationEndCallback(Runnable gestureAnimationEndCallback) {
- mGestureAnimationEndCallback = gestureAnimationEndCallback;
- }
-
protected void linkRecentsViewScroll() {
if (mRecentsView == null) {
return;
@@ -2722,8 +2680,7 @@ public abstract class AbsSwipeUpHandler<
transaction.setAlpha(app.leash, 1f - fadeProgress);
transaction.setPosition(app.leash,
/* x= */ app.startBounds.left
- + (
- mContainer.getDeviceProfile().getOverviewProfile().getPageSpacing()
+ + (mContainer.getDeviceProfile().overviewPageSpacing
* (mRecentsView.isRtl() ? fadeProgress : -fadeProgress)),
/* y= */ 0f);
transaction.setScale(app.leash, 1f, 1f);
@@ -2774,7 +2731,7 @@ public abstract class AbsSwipeUpHandler<
// Scaling of RecentsView during quick switch based on amount of recents scroll
private float getScaleProgressDueToScroll() {
- if (mContainer == null || !mContainer.getDeviceProfile().getDeviceProperties().isTablet() || mRecentsView == null
+ if (mContainer == null || !mContainer.getDeviceProfile().isTablet || mRecentsView == null
|| !shouldLinkRecentsViewScroll()) {
return 0;
}
@@ -2809,11 +2766,7 @@ public abstract class AbsSwipeUpHandler<
*/
@Override
protected float overrideDisplacementForTransientTaskbar(float displacement) {
- boolean shouldReturnDisplacement = mContainerInterface.getTaskbarController() == null
- ? !mIsTransientTaskbar
- : !mContainerInterface.getTaskbarController().shouldAllowTaskbarToAutoStash();
-
- if (shouldReturnDisplacement) {
+ if (!mIsTransientTaskbar) {
return displacement;
}
@@ -2844,7 +2797,6 @@ public abstract class AbsSwipeUpHandler<
}
public interface Factory {
- @Nullable
- AbsSwipeUpHandler, ?, ?> newHandler(GestureState gestureState, long touchTimeMs);
+ AbsSwipeUpHandler newHandler(GestureState gestureState, long touchTimeMs);
}
}
diff --git a/quickstep/src/com/android/quickstep/AllAppsActionManager.kt b/quickstep/src/com/android/quickstep/AllAppsActionManager.kt
index 51a68d16da..b807a4bfe3 100644
--- a/quickstep/src/com/android/quickstep/AllAppsActionManager.kt
+++ b/quickstep/src/com/android/quickstep/AllAppsActionManager.kt
@@ -27,7 +27,6 @@ import android.view.accessibility.AccessibilityManager
import com.android.launcher3.R
import com.android.launcher3.util.SettingsCache
import com.android.launcher3.util.SettingsCache.OnChangeListener
-import com.android.quickstep.input.QuickstepKeyGestureEventsManager
import java.util.concurrent.Executor
private val USER_SETUP_COMPLETE_URI = Settings.Secure.getUriFor(USER_SETUP_COMPLETE)
@@ -42,7 +41,6 @@ private val USER_SETUP_COMPLETE_URI = Settings.Secure.getUriFor(USER_SETUP_COMPL
class AllAppsActionManager(
private val context: Context,
private val bgExecutor: Executor,
- private val quickstepKeyGestureEventsManager: QuickstepKeyGestureEventsManager,
private val createAllAppsPendingIntent: () -> PendingIntent,
) {
@@ -94,22 +92,17 @@ class AllAppsActionManager(
val accessibilityManager =
context.getSystemService(AccessibilityManager::class.java) ?: return@execute
if (shouldRegisterAction) {
- val allAppsPendingIntent = createAllAppsPendingIntent()
accessibilityManager.registerSystemAction(
RemoteAction(
Icon.createWithResource(context, R.drawable.ic_apps),
context.getString(R.string.all_apps_label),
context.getString(R.string.all_apps_label),
- allAppsPendingIntent,
+ createAllAppsPendingIntent(),
),
GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS,
)
- quickstepKeyGestureEventsManager.registerAllAppsKeyGestureEvent(
- allAppsPendingIntent
- )
} else {
accessibilityManager.unregisterSystemAction(GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS)
- quickstepKeyGestureEventsManager.unregisterAllAppsKeyGestureEvent()
}
}
}
@@ -119,7 +112,6 @@ class AllAppsActionManager(
context
.getSystemService(AccessibilityManager::class.java)
?.unregisterSystemAction(GLOBAL_ACTION_ACCESSIBILITY_ALL_APPS)
- quickstepKeyGestureEventsManager.unregisterAllAppsKeyGestureEvent()
SettingsCache.INSTANCE[context].unregister(
USER_SETUP_COMPLETE_URI,
onSettingsChangeListener,
diff --git a/quickstep/src/com/android/quickstep/AspectRatioSystemShortcut.kt b/quickstep/src/com/android/quickstep/AspectRatioSystemShortcut.kt
index 9013ff082b..68860ac91b 100644
--- a/quickstep/src/com/android/quickstep/AspectRatioSystemShortcut.kt
+++ b/quickstep/src/com/android/quickstep/AspectRatioSystemShortcut.kt
@@ -26,7 +26,7 @@ import com.android.launcher3.logging.StatsLogManager.LauncherEvent
import com.android.launcher3.popup.SystemShortcut
import com.android.quickstep.views.RecentsViewContainer
import com.android.quickstep.views.TaskContainer
-import com.android.window.flags2.Flags.universalResizableByDefault
+import com.android.window.flags.Flags.universalResizableByDefault
/**
* System shortcut to change the application's aspect ratio compatibility mode.
@@ -58,7 +58,8 @@ class AspectRatioSystemShortcut(
}
mTarget.startActivitySafely(view, intent, mItemInfo)
- mTarget.statsLogManager
+ mTarget
+ .statsLogManager
.logger()
.withItemInfo(mItemInfo)
.log(LauncherEvent.LAUNCHER_ASPECT_RATIO_SETTINGS_SYSTEM_SHORTCUT_TAP)
@@ -80,7 +81,7 @@ class AspectRatioSystemShortcut(
!universalResizableByDefault() -> null
// The option is only shown on sw600dp+ screens (checked by isTablet)
- !viewContainer.deviceProfile.deviceProperties.isTablet -> null
+ !viewContainer.deviceProfile.isTablet -> null
else -> {
listOf(
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index c387856245..549c2f8e34 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -18,7 +18,9 @@ package com.android.quickstep;
import static com.android.app.animation.Interpolators.ACCELERATE_2;
import static com.android.app.animation.Interpolators.INSTANT;
import static com.android.app.animation.Interpolators.LINEAR;
+import static com.android.launcher3.MotionEventsUtils.isTrackpadMultiFingerSwipe;
import static com.android.quickstep.AbsSwipeUpHandler.RECENTS_ATTACH_DURATION;
+import static com.android.quickstep.GestureState.GestureEndTarget.LAST_TASK;
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_ATTACHED_ALPHA_ANIM;
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_FADE_ANIM;
import static com.android.quickstep.util.RecentsAtomicAnimationFactory.INDEX_RECENTS_TRANSLATE_X_ANIM;
@@ -31,12 +33,14 @@ import static com.android.quickstep.views.RecentsView.TASK_SECONDARY_TRANSLATION
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
+import android.view.MotionEvent;
import androidx.annotation.Nullable;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.anim.PendingAnimation;
import com.android.launcher3.statehandlers.DepthController;
+import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulActivity;
import com.android.launcher3.taskbar.TaskbarUIController;
@@ -67,6 +71,37 @@ public abstract class BaseActivityInterface Float = ::compu
companion object {
// computeCornerRadius is used as cornerRadiusProvider, so
// QuickStepContract::getWindowCornerRadius can be mocked properly.
- fun computeCornerRadius(context: Context): Float =
+ private fun computeCornerRadius(context: Context): Float =
context.resources.getDimension(R.dimen.desktop_windowing_freeform_rounded_corner_radius)
}
}
diff --git a/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt b/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
index 4fe3944258..4280baf21d 100644
--- a/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
+++ b/quickstep/src/com/android/quickstep/DesktopSystemShortcut.kt
@@ -16,14 +16,12 @@
package com.android.quickstep
-import android.view.Display
import android.view.View
import com.android.internal.jank.Cuj
import com.android.launcher3.AbstractFloatingViewHelper
import com.android.launcher3.R
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
import com.android.launcher3.popup.SystemShortcut
-import com.android.quickstep.fallback.window.RecentsWindowFlags.enableDesktopMenuOnSecondaryDisplay
import com.android.quickstep.views.RecentsView
import com.android.quickstep.views.RecentsViewContainer
import com.android.quickstep.views.TaskContainer
@@ -67,9 +65,8 @@ class DesktopSystemShortcut(
@JvmOverloads
fun createFactory(
abstractFloatingViewHelper: AbstractFloatingViewHelper = AbstractFloatingViewHelper()
- ): TaskShortcutFactory =
- object : TaskShortcutFactory {
-
+ ): TaskShortcutFactory {
+ return object : TaskShortcutFactory {
override fun getShortcuts(
container: RecentsViewContainer,
taskContainer: TaskContainer,
@@ -77,28 +74,20 @@ class DesktopSystemShortcut(
val context = container.asContext()
val taskKey = taskContainer.task.key
val desktopModeCompatPolicy = DesktopModeCompatPolicy(context)
- val isShortcutSupported =
- enableDesktopMenuOnSecondaryDisplay ||
- context.displayId == Display.DEFAULT_DISPLAY
-
return when {
- !isShortcutSupported -> null
+ !DesktopModeStatus.canEnterDesktopMode(context) -> null
- !DesktopModeStatus.isDesktopModeSupportedOnDisplay(
- context,
- context.display,
- ) -> null
-
- desktopModeCompatPolicy.shouldDisableDesktopEntryPoints(
+ desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(
taskKey.baseActivity?.packageName,
taskKey.numActivities,
taskKey.isTopActivityNoDisplay,
taskKey.isActivityStackTransparent,
+ taskKey.userId,
) -> null
!taskContainer.task.isDockable -> null
- else ->
+ else -> {
listOf(
DesktopSystemShortcut(
container,
@@ -106,10 +95,12 @@ class DesktopSystemShortcut(
abstractFloatingViewHelper,
)
)
+ }
}
}
override fun showForGroupedTask() = true
}
+ }
}
}
diff --git a/quickstep/src/com/android/quickstep/DisplayModel.kt b/quickstep/src/com/android/quickstep/DisplayModel.kt
index af2a43898a..0b8af4045b 100644
--- a/quickstep/src/com/android/quickstep/DisplayModel.kt
+++ b/quickstep/src/com/android/quickstep/DisplayModel.kt
@@ -21,21 +21,15 @@ import android.hardware.display.DisplayManager
import android.util.Log
import android.util.SparseArray
import android.view.Display
-import android.window.DesktopExperienceFlags
import androidx.core.util.valueIterator
-import com.android.app.displaylib.DisplayDecorationListener
-import com.android.app.displaylib.DisplaysWithDecorationsRepositoryCompat
import com.android.quickstep.DisplayModel.DisplayResource
+import com.android.quickstep.SystemDecorationChangeObserver.Companion.INSTANCE
+import com.android.quickstep.SystemDecorationChangeObserver.DisplayDecorationListener
import java.io.PrintWriter
-import kotlinx.coroutines.CoroutineDispatcher
/** data model for managing resources with lifecycles that match that of the connected display */
-abstract class DisplayModel(
- val context: Context,
- private val systemDecorationChangeObserver: SystemDecorationChangeObserver,
- private val displaysWithDecorationsRepositoryCompat: DisplaysWithDecorationsRepositoryCompat,
- private val dispatcher: CoroutineDispatcher,
-) : DisplayDecorationListener {
+abstract class DisplayModel(val context: Context) :
+ DisplayDecorationListener {
companion object {
private const val TAG = "DisplayModel"
@@ -43,10 +37,8 @@ abstract class DisplayModel(
}
private val displayManager = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager
- private val displayResourceArray = SparseArray()
- private val useDisplayDecorationListener: Boolean =
- DesktopExperienceFlags.ENABLE_SYS_DECORS_CALLBACKS_VIA_WM.isTrue() &&
- DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()
+ private var systemDecorationChangeObserver: SystemDecorationChangeObserver? = null
+ protected val displayResourceArray = SparseArray()
override fun onDisplayAddSystemDecorations(displayId: Int) {
if (DEBUG) Log.d(TAG, "onDisplayAdded: displayId=$displayId")
@@ -66,25 +58,16 @@ abstract class DisplayModel(
protected abstract fun createDisplayResource(display: Display): RESOURCE_TYPE
protected fun initializeDisplays() {
- if (useDisplayDecorationListener) {
- displaysWithDecorationsRepositoryCompat.registerDisplayDecorationListener(
- this,
- dispatcher,
- )
- } else {
- systemDecorationChangeObserver.registerDisplayDecorationListener(this)
- }
+ systemDecorationChangeObserver = INSTANCE[context]
+ systemDecorationChangeObserver?.registerDisplayDecorationListener(this)
displayManager.displays
.filter { getDisplayResource(it.displayId) == null }
.forEach { storeDisplayResource(it.displayId) }
}
fun destroy() {
- if (useDisplayDecorationListener) {
- displaysWithDecorationsRepositoryCompat.unregisterDisplayDecorationListener(this)
- } else {
- systemDecorationChangeObserver.unregisterDisplayDecorationListener(this)
- }
+ systemDecorationChangeObserver?.unregisterDisplayDecorationListener(this)
+ systemDecorationChangeObserver = null
displayResourceArray.valueIterator().forEach { displayResource ->
displayResource.cleanup()
}
diff --git a/quickstep/src/com/android/quickstep/ExternalDisplaySystemShortcut.kt b/quickstep/src/com/android/quickstep/ExternalDisplaySystemShortcut.kt
index 3b20ae18b1..3b823f5e60 100644
--- a/quickstep/src/com/android/quickstep/ExternalDisplaySystemShortcut.kt
+++ b/quickstep/src/com/android/quickstep/ExternalDisplaySystemShortcut.kt
@@ -24,7 +24,7 @@ import com.android.launcher3.popup.SystemShortcut
import com.android.quickstep.views.RecentsView
import com.android.quickstep.views.RecentsViewContainer
import com.android.quickstep.views.TaskContainer
-import com.android.window.flags2.Flags
+import com.android.window.flags.Flags
import com.android.wm.shell.shared.desktopmode.DesktopModeCompatPolicy
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
@@ -75,11 +75,12 @@ class ExternalDisplaySystemShortcut(
!Flags.moveToExternalDisplayShortcut() -> null
- desktopModeCompatPolicy.shouldDisableDesktopEntryPoints(
+ desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(
taskKey.baseActivity?.packageName,
taskKey.numActivities,
taskKey.isTopActivityNoDisplay,
taskKey.isActivityStackTransparent,
+ taskKey.userId,
) -> null
else -> {
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 740e2d6647..7654471555 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -27,14 +27,12 @@ import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.RemoteAnimationTarget;
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.taskbar.FallbackTaskbarUIController;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.views.ScrimColors;
import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
@@ -65,9 +63,9 @@ public final class FallbackActivityInterface extends
RecentsPagedOrientationHandler orientationHandler) {
calculateTaskSize(context, dp, outRect, orientationHandler);
if (dp.isVerticalBarLayout() && DisplayController.getNavigationMode(context) != NO_BUTTON) {
- return dp.isSeascape() ? outRect.left : (dp.getDeviceProperties().getWidthPx() - outRect.right);
+ return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
} else {
- return dp.getDeviceProperties().getHeightPx() - outRect.bottom;
+ return dp.heightPx - outRect.bottom;
}
}
@@ -135,8 +133,7 @@ public final class FallbackActivityInterface extends
}
@Override
- public boolean deferStartingActivity(
- @NonNull RecentsAnimationDeviceState deviceState, MotionEvent ev) {
+ public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
// In non-gesture mode, user might be clicking on the home button which would directly
// start the home activity instead of going through recents. In that case, defer starting
// recents until we are sure it is a gesture.
@@ -228,8 +225,7 @@ public final class FallbackActivityInterface extends
}
@Override
- protected ScrimColors getOverviewScrimColorForState(RecentsActivity activity,
- RecentsState state) {
+ protected int getOverviewScrimColorForState(RecentsActivity activity, RecentsState state) {
return state.getScrimColor(activity);
}
}
diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
index d29a556155..fc37091f86 100644
--- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java
@@ -20,7 +20,6 @@ import static android.content.Intent.EXTRA_COMPONENT_NAME;
import static android.content.Intent.EXTRA_USER;
import static com.android.app.animation.Interpolators.ACCELERATE;
-import static com.android.launcher3.GestureNavContract.EXTRA_ENABLE_GESTURE_CONTRACT;
import static com.android.launcher3.GestureNavContract.EXTRA_GESTURE_CONTRACT;
import static com.android.launcher3.GestureNavContract.EXTRA_ICON_POSITION;
import static com.android.launcher3.GestureNavContract.EXTRA_ICON_SURFACE;
@@ -108,13 +107,12 @@ public class FallbackSwipeHandler extends
private boolean mAppCanEnterPip;
- public FallbackSwipeHandler(Context context, TaskAnimationManager taskAnimationManager,
- RecentsAnimationDeviceState deviceState, RotationTouchHelper rotationTouchHelper,
- GestureState gestureState, long touchTimeMs,
+ public FallbackSwipeHandler(Context context,
+ TaskAnimationManager taskAnimationManager, GestureState gestureState, long touchTimeMs,
boolean continuingLastGesture, InputConsumerController inputConsumer,
MSDLPlayerWrapper msdlPlayerWrapper) {
- super(context, taskAnimationManager, deviceState, rotationTouchHelper, gestureState,
- touchTimeMs, continuingLastGesture, inputConsumer, msdlPlayerWrapper);
+ super(context, taskAnimationManager, gestureState, touchTimeMs,
+ continuingLastGesture, inputConsumer, msdlPlayerWrapper);
mRunningOverHome = mGestureState.getRunningTask() != null
&& mGestureState.getRunningTask().isHomeTask();
@@ -205,9 +203,7 @@ public class FallbackSwipeHandler extends
} else {
recentsCallback = callback;
}
- if (mRecentsView != null) {
- mRecentsView.cleanupRemoteTargets();
- }
+ mRecentsView.cleanupRemoteTargets();
mRecentsAnimationController.finish(
mAppCanEnterPip /* toRecents */, recentsCallback, true /* sendUserLeaveHint */);
}
@@ -240,7 +236,7 @@ public class FallbackSwipeHandler extends
@Override
public AnimatorPlaybackController createActivityAnimationToHome() {
// copied from {@link LauncherSwipeHandlerV2.LauncherHomeAnimationFactory}
- long accuracy = 2 * Math.max(mDp.getDeviceProperties().getWidthPx(), mDp.getDeviceProperties().getHeightPx());
+ long accuracy = 2 * Math.max(mDp.widthPx, mDp.heightPx);
return mContainer.getStateManager().createAnimationToNewWorkspace(
RecentsState.HOME, accuracy, StateAnimationConfig.SKIP_ALL_ANIMATIONS);
}
@@ -349,7 +345,7 @@ public class FallbackSwipeHandler extends
.setStartValue(mVerticalShiftForScale.value)
.setEndValue(0)
.setStartVelocity(-velocity / mTransitionDragLength)
- .setMinimumVisibleChange(1f / mDp.getDeviceProperties().getHeightPx())
+ .setMinimumVisibleChange(1f / mDp.heightPx)
.setDampingRatio(0.6f)
.setStiffness(800)
.build(mVerticalShiftForScale, AnimatedFloat.VALUE)
@@ -423,7 +419,6 @@ public class FallbackSwipeHandler extends
}
Bundle gestureNavContract = new Bundle();
- gestureNavContract.putBoolean(EXTRA_ENABLE_GESTURE_CONTRACT, !mIsSwipeForSplit);
gestureNavContract.putParcelable(EXTRA_COMPONENT_NAME, key.getComponent());
gestureNavContract.putParcelable(EXTRA_USER, UserHandle.of(key.userId));
gestureNavContract.putParcelable(
diff --git a/quickstep/src/com/android/quickstep/FallbackWindowInterface.java b/quickstep/src/com/android/quickstep/FallbackWindowInterface.java
index 330f7f1730..143da34ae8 100644
--- a/quickstep/src/com/android/quickstep/FallbackWindowInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackWindowInterface.java
@@ -24,19 +24,16 @@ import android.animation.Animator;
import android.animation.AnimatorSet;
import android.content.Context;
import android.graphics.Rect;
+import android.view.MotionEvent;
import android.view.RemoteAnimationTarget;
import androidx.annotation.Nullable;
-import com.android.app.displaylib.PerDisplayRepository;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.statemanager.StateManager;
import com.android.launcher3.taskbar.TaskbarUIController;
-import com.android.launcher3.util.DaggerSingletonObject;
import com.android.launcher3.util.DisplayController;
-import com.android.launcher3.views.ScrimColors;
import com.android.quickstep.GestureState.GestureEndTarget;
-import com.android.quickstep.dagger.QuickstepBaseAppComponent;
import com.android.quickstep.fallback.RecentsState;
import com.android.quickstep.fallback.window.RecentsWindowManager;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
@@ -44,31 +41,20 @@ import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.ContextInitListener;
import com.android.quickstep.views.RecentsView;
-import dagger.assisted.AssistedInject;
-
import java.util.function.Consumer;
import java.util.function.Predicate;
-
/**
* {@link BaseWindowInterface} for recents when the default launcher is different than the
* currently running one and apps should interact with the {@link RecentsWindowManager} as opposed
* to the in-launcher one.
*/
-public final class FallbackWindowInterface extends BaseWindowInterface {
+public final class FallbackWindowInterface extends BaseWindowInterface{
- public static final DaggerSingletonObject>
- REPOSITORY_INSTANCE = new DaggerSingletonObject<>(
- QuickstepBaseAppComponent::getFallbackWindowInterfaceRepository);
+ private final RecentsWindowManager mRecentsWindowManager;
- @Nullable private RecentsWindowManager mRecentsWindowManager = null;
-
- @AssistedInject
- public FallbackWindowInterface() {
+ public FallbackWindowInterface(RecentsWindowManager recentsWindowManager) {
super(DEFAULT, BACKGROUND_APP);
- }
-
- public void setRecentsWindowManager(@Nullable RecentsWindowManager recentsWindowManager) {
mRecentsWindowManager = recentsWindowManager;
}
@@ -78,9 +64,9 @@ public final class FallbackWindowInterface extends BaseWindowInterface {
RecentsPagedOrientationHandler orientationHandler) {
calculateTaskSize(context, dp, outRect, orientationHandler);
if (dp.isVerticalBarLayout() && DisplayController.getNavigationMode(context) != NO_BUTTON) {
- return dp.isSeascape() ? outRect.left : (dp.getDeviceProperties().getWidthPx() - outRect.right);
+ return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
} else {
- return dp.getDeviceProperties().getHeightPx() - outRect.bottom;
+ return dp.heightPx - outRect.bottom;
}
}
@@ -133,8 +119,8 @@ public final class FallbackWindowInterface extends BaseWindowInterface {
@Override
public > T getVisibleRecentsView() {
RecentsWindowManager manager = getCreatedContainer();
- if (manager != null && (manager.isStarted() || isInLiveTileMode())) {
- return manager.getOverviewPanel();
+ if(manager.isStarted() || isInLiveTileMode()){
+ return getCreatedContainer().getOverviewPanel();
}
return null;
}
@@ -145,17 +131,26 @@ public final class FallbackWindowInterface extends BaseWindowInterface {
}
@Override
- protected ScrimColors getOverviewScrimColorForState(RecentsWindowManager container,
- RecentsState state) {
+ protected int getOverviewScrimColorForState(RecentsWindowManager container,
+ RecentsState state) {
return state.getScrimColor(container.asContext());
}
+ @Override
+ public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
+ // In non-gesture mode, user might be clicking on the home button which would directly
+ // start the home activity instead of going through recents. In that case, defer starting
+ // recents until we are sure it is a gesture.
+ return false;
+// return !deviceState.isFullyGesturalNavMode();
+// || super.deferStartingActivity(deviceState, ev);
+ }
+
@Override
public void onExitOverview(Runnable exitRunnable) {
- RecentsWindowManager windowManager = getCreatedContainer();
final StateManager stateManager =
- windowManager != null ? windowManager.getStateManager() : null;
- if (stateManager == null || stateManager.getState() == HOME) {
+ getCreatedContainer().getStateManager();
+ if (stateManager.getState() == HOME) {
exitRunnable.run();
notifyRecentsOfOrientation();
return;
@@ -208,11 +203,8 @@ public final class FallbackWindowInterface extends BaseWindowInterface {
}
private void notifyRecentsOfOrientation() {
- RecentsWindowManager recentsWindowManager = getCreatedContainer();
- if (recentsWindowManager != null) {
- // reset layout on swipe to home
- ((RecentsView) recentsWindowManager.getOverviewPanel()).reapplyActiveRotation();
- }
+ // reset layout on swipe to home
+ ((RecentsView) getCreatedContainer().getOverviewPanel()).reapplyActiveRotation();
}
@Override
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 2492ac3aa8..c4ba2d52bb 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -41,7 +41,7 @@ import androidx.annotation.Nullable;
import com.android.launcher3.statemanager.BaseState;
import com.android.launcher3.statemanager.StatefulContainer;
import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
-import com.android.quickstep.fallback.window.RecentsWindowManager;
+import com.android.quickstep.fallback.window.RecentsWindowFlags;
import com.android.quickstep.util.ActiveGestureErrorDetector;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
@@ -194,7 +194,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
public GestureState(OverviewComponentObserver componentObserver, int displayId, int gestureId) {
mDisplayId = displayId;
- mHomeIntent = componentObserver.getHomeIntent(displayId);
+ mHomeIntent = componentObserver.getHomeIntent();
mOverviewIntent = componentObserver.getOverviewIntent();
mContainerInterface = componentObserver.getContainerInterface(displayId);
mStateCallback = new MultiStateCallback(
@@ -323,7 +323,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
*/
public boolean useSyntheticRecentsTransition() {
return mRunningTask.isHomeTask()
- && mContainerInterface.getCreatedContainer() instanceof RecentsWindowManager;
+ && RecentsWindowFlags.Companion.getEnableOverviewInWindow();
}
/**
@@ -361,8 +361,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL
* @return the single top-most running taskId for this gesture
*/
public int getTopRunningTaskId() {
- var taskIds = getRunningTaskIds(/* getMultipleTasks = */ false);
- return taskIds.length != 0 ? taskIds[0] : INVALID_TASK_ID;
+ return getRunningTaskIds(false /*getMultipleTasks*/)[0];
}
/**
diff --git a/quickstep/src/com/android/quickstep/HighResLoadingState.kt b/quickstep/src/com/android/quickstep/HighResLoadingState.kt
index aabaecfdfe..8a21c4f613 100644
--- a/quickstep/src/com/android/quickstep/HighResLoadingState.kt
+++ b/quickstep/src/com/android/quickstep/HighResLoadingState.kt
@@ -18,7 +18,6 @@ package com.android.quickstep
import android.content.res.Resources
import com.android.quickstep.recents.data.HighResLoadingStateNotifier
-import java.util.concurrent.CopyOnWriteArrayList
/** Determines when high res or low res thumbnails should be loaded. */
class HighResLoadingState : HighResLoadingStateNotifier {
@@ -39,7 +38,7 @@ class HighResLoadingState : HighResLoadingStateNotifier {
var isEnabled: Boolean = false
private set
- private val callbacks = CopyOnWriteArrayList()
+ private val callbacks = ArrayList()
interface HighResLoadingStateChangedCallback {
fun onHighResLoadingStateChanged(enabled: Boolean)
@@ -57,7 +56,7 @@ class HighResLoadingState : HighResLoadingStateNotifier {
val prevState = isEnabled
isEnabled = forceHighResThumbnails || (visible && !flingingFast)
if (prevState != isEnabled) {
- for (callback in callbacks) {
+ for (callback in callbacks.asReversed()) {
callback.onHighResLoadingStateChanged(isEnabled)
}
}
diff --git a/quickstep/src/com/android/quickstep/HomeVisibilityState.kt b/quickstep/src/com/android/quickstep/HomeVisibilityState.kt
index 253b434cb9..020b9e2fab 100644
--- a/quickstep/src/com/android/quickstep/HomeVisibilityState.kt
+++ b/quickstep/src/com/android/quickstep/HomeVisibilityState.kt
@@ -20,6 +20,7 @@ import android.os.RemoteException
import android.util.Log
import android.view.InsetsState
import android.view.WindowInsets
+
import com.android.launcher3.Utilities
import com.android.launcher3.config.FeatureFlags
import com.android.launcher3.util.Executors
@@ -46,25 +47,18 @@ class HomeVisibilityState {
transitions?.setHomeTransitionListener(
object : Stub() {
override fun onHomeVisibilityChanged(isVisible: Boolean) {
- Utilities.postAsyncCallback(Executors.MAIN_EXECUTOR.handler) {
- isHomeVisible = isVisible
- val copiedListeners = listeners.toSet()
- copiedListeners.forEach { it.onHomeVisibilityChanged(isVisible) }
- }
+ Utilities.postAsyncCallback(
+ Executors.MAIN_EXECUTOR.handler,
+ {
+ isHomeVisible = isVisible
+ listeners.forEach { it.onHomeVisibilityChanged(isVisible) }
+ },
+ )
}
-
override fun onDisplayInsetsChanged(insetsState: InsetsState) {
- val displayFrame = insetsState.displayFrame
- val bottomInset =
- insetsState
- .calculateInsets(
- displayFrame,
- displayFrame,
- WindowInsets.Type.navigationBars(),
- false,
- )
- .bottom
- navbarInsetPosition = displayFrame.bottom - bottomInset
+ val bottomInset = insetsState.calculateInsets(insetsState.displayFrame,
+ WindowInsets.Type.navigationBars(), false).bottom
+ navbarInsetPosition = insetsState.displayFrame.bottom - bottomInset
}
}
)
diff --git a/quickstep/src/com/android/quickstep/InputConsumerUtils.kt b/quickstep/src/com/android/quickstep/InputConsumerUtils.kt
index 549fffdfa5..89b5b291c6 100644
--- a/quickstep/src/com/android/quickstep/InputConsumerUtils.kt
+++ b/quickstep/src/com/android/quickstep/InputConsumerUtils.kt
@@ -23,7 +23,6 @@ import com.android.launcher3.statemanager.BaseState
import com.android.launcher3.statemanager.StatefulContainer
import com.android.launcher3.taskbar.TaskbarManager
import com.android.launcher3.util.LockedUserState.Companion.get
-import com.android.quickstep.fallback.window.RecentsWindowManager
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer
import com.android.quickstep.inputconsumers.AssistantInputConsumer
import com.android.quickstep.inputconsumers.BubbleBarInputConsumer
@@ -47,7 +46,6 @@ import com.android.quickstep.views.RecentsViewContainer
import com.android.systemui.shared.system.InputChannelCompat
import com.android.systemui.shared.system.InputMonitorCompat
import com.android.wm.shell.Flags
-import com.android.wm.shell.shared.desktopmode.DesktopState
import java.util.function.Consumer
import java.util.function.Function
@@ -73,9 +71,8 @@ object InputConsumerUtils {
swipeUpProxyProvider: Function,
overviewCommandHelper: OverviewCommandHelper,
event: MotionEvent,
- rotationTouchHelper: RotationTouchHelper,
): InputConsumer where T : RecentsViewContainer, T : StatefulContainer {
- val tac = taskbarManager.getCurrentActivityContext()
+ val tac = taskbarManager.currentActivityContext
val bubbleControllers = tac?.bubbleControllers
if (bubbleControllers != null && BubbleBarInputConsumer.isEventOnBubbles(tac, event)) {
val consumer: InputConsumer =
@@ -132,7 +129,6 @@ object InputConsumerUtils {
taskAnimationManager,
inputMonitorCompat,
reasonString.append("%scan start system gesture", SUBSTRING_PREFIX),
- rotationTouchHelper,
)
} else {
getDefaultInputConsumer(
@@ -174,7 +170,6 @@ object InputConsumerUtils {
inputEventReceiver,
event,
reasonString,
- rotationTouchHelper,
)
} else {
reasonString =
@@ -394,7 +389,6 @@ object InputConsumerUtils {
deviceState,
base,
inputMonitorCompat,
- rotationTouchHelper,
)
}
} else {
@@ -502,7 +496,6 @@ object InputConsumerUtils {
inputEventReceiver: InputChannelCompat.InputEventReceiver,
event: MotionEvent,
reasonString: CompoundString,
- rotationTouchHelper: RotationTouchHelper,
): InputConsumer where T : RecentsViewContainer, T : StatefulContainer {
if (deviceState.isKeyguardShowingOccluded) {
// This handles apps showing over the lockscreen (e.g. camera)
@@ -519,17 +512,15 @@ object InputConsumerUtils {
"trying to use device locked input consumer",
SUBSTRING_PREFIX,
),
- rotationTouchHelper,
)
}
reasonString.append("%skeyguard is not showing occluded", SUBSTRING_PREFIX)
val runningTask = gestureState.runningTask
- val containerInterface = gestureState.getContainerInterface()
// Use overview input consumer for sharesheets on top of home.
val forceOverviewInputConsumer =
- containerInterface.isStarted() &&
+ gestureState.getContainerInterface().isStarted() &&
runningTask != null &&
runningTask.isRootChooseActivity
@@ -551,21 +542,19 @@ object InputConsumerUtils {
deviceState.isPredictiveBackToHomeInProgress)
// with shell-transitions, home is resumed during recents animation, so
// explicitly check against recents animation too.
- // Home is always running and isn't resumed when home shows behind desktop.
val launcherResumedThroughShellTransition =
- containerInterface.isResumed() &&
- !previousGestureState.isRecentsAnimationRunning &&
- !DesktopState.fromContext(context).shouldShowHomeBehindDesktop
-
+ (gestureState.getContainerInterface().isResumed() &&
+ !previousGestureState.isRecentsAnimationRunning)
// If a task fragment within Launcher is resumed
val launcherChildActivityResumed =
- runningTask != null &&
+ (com.android.launcher3.Flags.useActivityOverlay() &&
+ runningTask != null &&
runningTask.isHomeTask &&
- !previousGestureState.isRecentsAnimationRunning &&
- overviewComponentObserver.isHomeAndOverviewSame &&
- containerInterface.isLauncherOverlayShowing
+ overviewComponentObserver.isHomeAndOverviewSameActivity &&
+ !launcherResumedThroughShellTransition &&
+ !previousGestureState.isRecentsAnimationRunning)
- return if (containerInterface.isInLiveTileMode()) {
+ return if (gestureState.getContainerInterface().isInLiveTileMode()) {
createOverviewInputConsumer(
userUnlocked,
taskAnimationManager,
@@ -602,18 +591,19 @@ object InputConsumerUtils {
previousGestureState,
gestureState,
event,
- reasonString
- .append(
- if (previousGestureAnimatedToLauncher)
- (if (previousGestureState.isRunningAnimationToLauncher)
- "%sprevious gesture is still animating to launcher"
- else "%spredictive back animation is still in progress")
- else if (launcherResumedThroughShellTransition)
- "%slauncher resumed through a shell transition"
- else "%sforceOverviewInputConsumer == true",
- SUBSTRING_PREFIX,
- )
- .append(", trying to use overview input consumer"),
+ reasonString.append(
+ if (previousGestureAnimatedToLauncher)
+ ("%sprevious gesture animated to launcher, " +
+ "trying to use overview input consumer")
+ else
+ (if (launcherResumedThroughShellTransition)
+ ("%slauncher resumed through a shell transition, " +
+ "trying to use overview input consumer")
+ else
+ ("%sforceOverviewInputConsumer == true, " +
+ "trying to use overview input consumer")),
+ SUBSTRING_PREFIX,
+ ),
)
} else if (deviceState.isGestureBlockedTask(runningTask) || launcherChildActivityResumed) {
getDefaultInputConsumer(
@@ -641,8 +631,6 @@ object InputConsumerUtils {
inputEventReceiver,
gestureState,
event,
- runningTask.isHomeTask,
- rotationTouchHelper,
)
}
}
@@ -656,7 +644,6 @@ object InputConsumerUtils {
taskAnimationManager: TaskAnimationManager,
inputMonitorCompat: InputMonitorCompat,
reasonString: CompoundString,
- rotationTouchHelper: RotationTouchHelper,
): InputConsumer {
return if (
(deviceState.isFullyGesturalNavMode || gestureState.isTrackpadGesture) &&
@@ -673,7 +660,6 @@ object InputConsumerUtils {
taskAnimationManager,
gestureState,
inputMonitorCompat,
- rotationTouchHelper,
)
} else {
getDefaultInputConsumer(
@@ -704,9 +690,8 @@ object InputConsumerUtils {
event: MotionEvent,
reasonString: CompoundString,
): InputConsumer where T : RecentsViewContainer, T : StatefulContainer {
- val containerInterface = gestureState.getContainerInterface()!!
val container: T =
- containerInterface.getCreatedContainer()
+ gestureState.getContainerInterface().getCreatedContainer()
?: return getDefaultInputConsumer(
gestureState.displayId,
userUnlocked,
@@ -723,16 +708,16 @@ object InputConsumerUtils {
val isPreviousGestureAnimatingToLauncher =
(previousGestureState.isRunningAnimationToLauncher ||
deviceState.isPredictiveBackToHomeInProgress)
- val isInLiveTileMode: Boolean = containerInterface.isInLiveTileMode()
+ val isInLiveTileMode: Boolean =
+ gestureState.getContainerInterface().isInLiveTileMode()
reasonString.append(
if (hasWindowFocus) "%sactivity has window focus"
- else if (isPreviousGestureAnimatingToLauncher)
- (if (previousGestureState.isRunningAnimationToLauncher)
+ else
+ (if (isPreviousGestureAnimatingToLauncher)
"%sprevious gesture is still animating to launcher"
- else "%spredictive back animation is still in progress")
- else if (isInLiveTileMode) "%sdevice is in live mode"
- else "%sall overview focus conditions failed",
+ else if (isInLiveTileMode) "%sdevice is in live mode"
+ else "%sall overview focus conditions failed"),
SUBSTRING_PREFIX,
)
return if (hasWindowFocus || isPreviousGestureAnimatingToLauncher || isInLiveTileMode) {
@@ -805,16 +790,13 @@ object InputConsumerUtils {
inputEventReceiver: InputChannelCompat.InputEventReceiver,
gestureState: GestureState,
event: MotionEvent,
- isHomeTask: Boolean,
- rotationTouchHelper: RotationTouchHelper,
): InputConsumer where T : RecentsViewContainer, T : StatefulContainer {
- val containerInterface = gestureState.getContainerInterface()
val shouldDefer =
(!overviewComponentObserver.isHomeAndOverviewSame ||
- containerInterface.deferStartingActivity(deviceState, event))
- val disableHorizontalSwipe =
- deviceState.isInExclusionRegion(event) &&
- (containerInterface.getCreatedContainer() !is RecentsWindowManager || !isHomeTask)
+ gestureState
+ .getContainerInterface()
+ .deferStartingActivity(deviceState, event))
+ val disableHorizontalSwipe = deviceState.isInExclusionRegion(event)
return OtherActivityInputConsumer(
/* base= */ context,
deviceState,
@@ -826,7 +808,6 @@ object InputConsumerUtils {
inputEventReceiver,
disableHorizontalSwipe,
swipeUpHandlerFactory,
- rotationTouchHelper,
)
}
diff --git a/quickstep/src/com/android/quickstep/InstantAppResolverImpl.java b/quickstep/src/com/android/quickstep/InstantAppResolverImpl.java
index bb208c49c7..33a2366157 100644
--- a/quickstep/src/com/android/quickstep/InstantAppResolverImpl.java
+++ b/quickstep/src/com/android/quickstep/InstantAppResolverImpl.java
@@ -24,12 +24,9 @@ import android.os.Process;
import android.os.UserHandle;
import android.util.Log;
-import com.android.launcher3.dagger.ApplicationContext;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.util.InstantAppResolver;
-import javax.inject.Inject;
-
/**
* Implementation of InstantAppResolver using platform APIs
*/
@@ -41,9 +38,7 @@ public class InstantAppResolverImpl extends InstantAppResolver {
private final PackageManager mPM;
- @Inject
- public InstantAppResolverImpl(@ApplicationContext Context context) {
- super();
+ public InstantAppResolverImpl(Context context) {
mPM = context.getPackageManager();
}
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index 4badf1007c..fa8e4846b3 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -27,6 +27,7 @@ import android.animation.Animator;
import android.animation.AnimatorSet;
import android.content.Context;
import android.graphics.Rect;
+import android.view.MotionEvent;
import android.view.RemoteAnimationTarget;
import androidx.annotation.Nullable;
@@ -44,14 +45,12 @@ import com.android.launcher3.taskbar.LauncherTaskbarUIController;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.NavigationMode;
-import com.android.launcher3.views.ScrimColors;
import com.android.quickstep.GestureState.GestureEndTarget;
import com.android.quickstep.orientation.RecentsPagedOrientationHandler;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.plugins.shared.LauncherOverlayManager;
-import com.android.wm.shell.shared.desktopmode.DesktopState;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -74,7 +73,7 @@ public final class LauncherActivityInterface extends
calculateTaskSize(context, dp, outRect, orientationHandler);
if (dp.isVerticalBarLayout()
&& DisplayController.getNavigationMode(context) != NavigationMode.NO_BUTTON) {
- return dp.isSeascape() ? outRect.left : (dp.getDeviceProperties().getWidthPx() - outRect.right);
+ return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
} else {
return LayoutUtils.getShelfTrackingDistance(context, dp, orientationHandler, this);
}
@@ -212,12 +211,6 @@ public final class LauncherActivityInterface extends
if (launcher == null) {
return false;
}
- if (DesktopState.fromContext(launcher.asContext()).getShouldShowHomeBehindDesktop()
- && !launcher.hasWindowFocus()) {
- // Home is always shown behind desktop, but it is currently not the top task, so treat
- // it as if it is not visible.
- return false;
- }
if (isInLiveTileMode()) {
RecentsView recentsView = getVisibleRecentsView();
if (recentsView == null) {
@@ -327,11 +320,29 @@ public final class LauncherActivityInterface extends
}
@Override
- protected ScrimColors getOverviewScrimColorForState(QuickstepLauncher activity,
- LauncherState state) {
+ protected int getOverviewScrimColorForState(QuickstepLauncher activity, LauncherState state) {
return state.getWorkspaceScrimColor(activity);
}
+ @Override
+ public boolean deferStartingActivity(RecentsAnimationDeviceState deviceState, MotionEvent ev) {
+ LauncherTaskbarUIController uiController = getTaskbarController();
+ if (uiController == null) {
+ return super.deferStartingActivity(deviceState, ev);
+ }
+ return uiController.isEventOverAnyTaskbarItem(ev)
+ || super.deferStartingActivity(deviceState, ev);
+ }
+
+ @Override
+ public boolean shouldCancelCurrentGesture() {
+ LauncherTaskbarUIController uiController = getTaskbarController();
+ if (uiController == null) {
+ return super.shouldCancelCurrentGesture();
+ }
+ return uiController.isDraggingItem();
+ }
+
@Override
public LauncherState stateFromGestureEndTarget(GestureEndTarget endTarget) {
switch (endTarget) {
@@ -347,11 +358,4 @@ public final class LauncherActivityInterface extends
return NORMAL;
}
}
-
- @Override
- public boolean isLauncherOverlayShowing() {
- Launcher launcher = Launcher.ACTIVITY_TRACKER.getCreatedContext();
-
- return launcher != null && launcher.getWorkspace().isOverlayShown();
- }
}
diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
index d545c47361..261ad9fb7c 100644
--- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
+++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java
@@ -25,9 +25,8 @@ import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
import static com.android.launcher3.BaseActivity.INVISIBLE_ALL;
import static com.android.launcher3.BaseActivity.INVISIBLE_BY_PENDING_FLAGS;
import static com.android.launcher3.BaseActivity.PENDING_INVISIBLE_BY_WALLPAPER_ANIMATION;
-import static com.android.launcher3.Flags.enableOverviewBackgroundWallpaperBlur;
-import static com.android.window.flags2.Flags.predictiveBackThreeButtonNav;
-import static com.android.window.flags2.Flags.removeDepartTargetFromMotion;
+import static com.android.window.flags.Flags.predictiveBackThreeButtonNav;
+import static com.android.window.flags.Flags.removeDepartTargetFromMotion;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -99,6 +98,7 @@ public class LauncherBackAnimationController {
Flags.predictiveBackToHomePolish() ? 0.75f : 0.85f;
private static final float MAX_SCRIM_ALPHA_DARK = 0.8f;
private static final float MAX_SCRIM_ALPHA_LIGHT = 0.2f;
+ private static final int MAX_BLUR_RADIUS = 20;
private static final int MIN_BLUR_RADIUS_PRE_COMMIT = 10;
private final QuickstepTransitionManager mQuickstepTransitionManager;
@@ -130,7 +130,6 @@ public class LauncherBackAnimationController {
private ValueAnimator mScrimAlphaAnimator;
private float mScrimAlpha;
private boolean mOverridingStatusBarFlags;
- private int mMaxBlurRadius;
private int mLastBlurRadius = 0;
private final ComponentCallbacks mComponentCallbacks = new ComponentCallbacks() {
@@ -424,7 +423,7 @@ public class LauncherBackAnimationController {
final float[] colorComponents = new float[] { 0f, 0f, 0f };
mScrimAlpha = (isDarkTheme)
? MAX_SCRIM_ALPHA_DARK : MAX_SCRIM_ALPHA_LIGHT;
- setBlur(mMaxBlurRadius);
+ setBlur(MAX_BLUR_RADIUS);
mTransaction
.setColor(mScrimLayer, colorComponents)
.setAlpha(mScrimLayer, mScrimAlpha)
@@ -452,7 +451,7 @@ public class LauncherBackAnimationController {
// Scrim hasn't been attached yet. Let's attach it.
addScrimLayer();
} else {
- mLastBlurRadius = (int) lerp(mMaxBlurRadius, MIN_BLUR_RADIUS_PRE_COMMIT, progress);
+ mLastBlurRadius = (int) lerp(MAX_BLUR_RADIUS, MIN_BLUR_RADIUS_PRE_COMMIT, progress);
setBlur(mLastBlurRadius);
}
float screenWidth = mStartRect.width();
@@ -612,7 +611,7 @@ public class LauncherBackAnimationController {
// Scrim hasn't been attached yet. Let's attach it.
addScrimLayer();
}
- mScrimAlphaAnimator = ValueAnimator.ofFloat(1, 0);
+ mScrimAlphaAnimator = new ValueAnimator().ofFloat(1, 0);
mScrimAlphaAnimator.addUpdateListener(animation -> {
float value = (Float) animation.getAnimatedValue();
if (mScrimLayer != null && mScrimLayer.isValid()) {
@@ -628,7 +627,7 @@ public class LauncherBackAnimationController {
}
});
mScrimAlphaAnimator.setDuration(SCRIM_FADE_DURATION).start();
- backAnim.start(mLauncher.getStateManager());
+ backAnim.start();
}
private void loadResources() {
@@ -638,14 +637,8 @@ public class LauncherBackAnimationController {
R.dimen.swipe_back_window_corner_radius)
: 0;
mWindowScaleStartCornerRadius = QuickStepContract.getWindowCornerRadius(mLauncher);
- // pE-TODO(QPR1): mStatusBarHeight is 24
- mStatusBarHeight = SystemBarUtils.getStatusBarHeight(mLauncher);
- if (Flags.allAppsBlur() || enableOverviewBackgroundWallpaperBlur()) {
- mMaxBlurRadius = mLauncher.getResources().getDimensionPixelSize(
- R.dimen.max_depth_blur_radius_enhanced);
- } else {
- mMaxBlurRadius = mLauncher.getResources().getInteger(R.integer.max_depth_blur_radius);
- }
+// mStatusBarHeight = SystemBarUtils.getStatusBarHeight(mLauncher);
+ mStatusBarHeight = 24;
}
/**
diff --git a/quickstep/src/com/android/quickstep/LauncherRestoreEventLoggerImpl.kt b/quickstep/src/com/android/quickstep/LauncherRestoreEventLoggerImpl.kt
index 8bb6e17b4b..e61f3792b0 100644
--- a/quickstep/src/com/android/quickstep/LauncherRestoreEventLoggerImpl.kt
+++ b/quickstep/src/com/android/quickstep/LauncherRestoreEventLoggerImpl.kt
@@ -10,17 +10,13 @@ import com.android.launcher3.Flags.enableLauncherBrMetricsFixed
import com.android.launcher3.LauncherSettings.Favorites
import com.android.launcher3.Utilities
import com.android.launcher3.backuprestore.LauncherRestoreEventLogger
-import com.android.launcher3.dagger.ApplicationContext
-import javax.inject.Inject
/**
* Concrete implementation for wrapper to log Restore event metrics for both success and failure to
* restore Launcher workspace from a backup. This implementation accesses SystemApis so is only
* available to QuickStep/NexusLauncher.
*/
-class LauncherRestoreEventLoggerImpl
-@Inject
-constructor(@ApplicationContext private val context: Context) : LauncherRestoreEventLogger() {
+class LauncherRestoreEventLoggerImpl(val context: Context) : LauncherRestoreEventLogger() {
companion object {
const val TAG = "LauncherRestoreEventLoggerImpl"
@@ -51,7 +47,7 @@ constructor(@ApplicationContext private val context: Context) : LauncherRestoreE
override fun logLauncherItemsRestoreFailed(
@BackupRestoreDataType dataType: String,
count: Int,
- @BackupRestoreError error: String?,
+ @BackupRestoreError error: String?
) {
if (enableLauncherBrMetricsFixed()) {
restoreEventLogger?.logItemsRestoreFailed(dataType, count, error)
@@ -101,7 +97,7 @@ constructor(@ApplicationContext private val context: Context) : LauncherRestoreE
*/
override fun logSingleFavoritesItemRestoreFailed(
favoritesId: Int,
- @BackupRestoreError error: String?,
+ @BackupRestoreError error: String?
) {
if (enableLauncherBrMetricsFixed()) {
restoreEventLogger?.logItemsRestoreFailed(favoritesIdToDataType(favoritesId), 1, error)
@@ -118,13 +114,13 @@ constructor(@ApplicationContext private val context: Context) : LauncherRestoreE
override fun logFavoritesItemsRestoreFailed(
favoritesId: Int,
count: Int,
- @BackupRestoreError error: String?,
+ @BackupRestoreError error: String?
) {
if (enableLauncherBrMetricsFixed()) {
restoreEventLogger?.logItemsRestoreFailed(
favoritesIdToDataType(favoritesId),
count,
- error,
+ error
)
}
}
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index 85a677f18b..4c56f35d90 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -36,7 +36,6 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import com.android.app.animation.Interpolators;
import com.android.launcher3.LauncherState;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.model.data.ItemInfo;
@@ -70,11 +69,10 @@ public class LauncherSwipeHandlerV2 extends AbsSwipeUpHandler<
QuickstepLauncher, RecentsView, LauncherState> {
public LauncherSwipeHandlerV2(Context context, TaskAnimationManager taskAnimationManager,
- RecentsAnimationDeviceState deviceState, RotationTouchHelper rotationTouchHelper,
GestureState gestureState, long touchTimeMs, boolean continuingLastGesture,
InputConsumerController inputConsumer, MSDLPlayerWrapper msdlPlayerWrapper) {
- super(context, taskAnimationManager, deviceState, rotationTouchHelper, gestureState,
- touchTimeMs, continuingLastGesture, inputConsumer, msdlPlayerWrapper);
+ super(context, taskAnimationManager, gestureState, touchTimeMs,
+ continuingLastGesture, inputConsumer, msdlPlayerWrapper);
}
@@ -87,13 +85,8 @@ public class LauncherSwipeHandlerV2 extends AbsSwipeUpHandler<
RemoteAnimationTarget runningTaskTarget,
@Nullable TaskView targetTaskView) {
if (mContainer == null) {
- mStateCallback.addChangeListener(
- STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
- isPresent -> {
- if (mRecentsView != null) {
- mRecentsView.startHome();
- }
- });
+ mStateCallback.addChangeListener(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
+ isPresent -> mRecentsView.startHome());
return new HomeAnimationFactory() {
@Override
public AnimatorPlaybackController createActivityAnimationToHome() {
@@ -147,7 +140,7 @@ public class LauncherSwipeHandlerV2 extends AbsSwipeUpHandler<
true /* hideOriginal */, iconLocation, false /* isOpening */);
// We want the window alpha to be 0 once this threshold is met, so that the
- // FloatingIconView can be seen morphing into the icon shape.
+ // FolderIconView can be seen morphing into the icon shape.
float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION;
return new FloatingViewHomeAnimationFactory(floatingIconView) {
@@ -195,11 +188,7 @@ public class LauncherSwipeHandlerV2 extends AbsSwipeUpHandler<
float progress,
float radius,
int overlayAlpha) {
- // We want the icon alpha to be 1 once this threshold is met, so that it can be
- // seen morphing into the icon shape. But before the threshold, we want to limit
- // the alpha to reduce the blur effect behind the window.
- float iconAlpha = Interpolators.clampToProgress(progress, 0f, windowAlphaThreshold);
- floatingIconView.update(iconAlpha, currentRect, progress, windowAlphaThreshold,
+ floatingIconView.update(1f /* alpha */, currentRect, progress, windowAlphaThreshold,
radius, false, overlayAlpha);
}
@@ -327,9 +316,7 @@ public class LauncherSwipeHandlerV2 extends AbsSwipeUpHandler<
@Override
protected void finishRecentsControllerToHome(Runnable callback) {
- if (mRecentsView != null) {
- mRecentsView.cleanupRemoteTargets();
- }
+ mRecentsView.cleanupRemoteTargets();
mRecentsAnimationController.finish(
true /* toRecents */, callback, true /* sendUserLeaveHint */);
}
@@ -373,7 +360,7 @@ public class LauncherSwipeHandlerV2 extends AbsSwipeUpHandler<
public AnimatorPlaybackController createActivityAnimationToHome() {
// Return an empty APC here since we have an non-user controlled animation
// to home.
- long accuracy = 2 * Math.max(mDp.getDeviceProperties().getWidthPx(), mDp.getDeviceProperties().getHeightPx());
+ long accuracy = 2 * Math.max(mDp.widthPx, mDp.heightPx);
return mContainer.getStateManager().createAnimationToNewWorkspace(
NORMAL, accuracy, StateAnimationConfig.SKIP_ALL_ANIMATIONS);
}
diff --git a/quickstep/src/com/android/quickstep/OWNERS b/quickstep/src/com/android/quickstep/OWNERS
index f0d0b2b442..868e0abf56 100644
--- a/quickstep/src/com/android/quickstep/OWNERS
+++ b/quickstep/src/com/android/quickstep/OWNERS
@@ -4,5 +4,6 @@ jonmiranda@google.com
jagrutdesai@google.com
randypfohl@google.com
saumyaprakash@google.com
+sukeshram@google.com
twickham@google.com
victortulias@google.com
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
index a010057324..b828903045 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
@@ -20,6 +20,7 @@ import android.animation.AnimatorListenerAdapter
import android.content.Intent
import android.graphics.PointF
import android.os.SystemClock
+import android.os.Trace
import android.util.Log
import android.view.Display.DEFAULT_DISPLAY
import android.view.View
@@ -27,10 +28,10 @@ import android.window.TransitionInfo
import androidx.annotation.BinderThread
import androidx.annotation.UiThread
import androidx.annotation.VisibleForTesting
-import com.android.app.displaylib.DisplayRepository
-import com.android.app.displaylib.PerDisplayRepository
import com.android.internal.jank.Cuj
-import com.android.launcher3.DeviceProfile
+import com.android.launcher3.Flags.enableAltTabKqsOnConnectedDisplays
+import com.android.launcher3.Flags.enableLargeDesktopWindowingTile
+import com.android.launcher3.Flags.enableOverviewCommandHelperTimeout
import com.android.launcher3.PagedView
import com.android.launcher3.logger.LauncherAtom
import com.android.launcher3.logging.StatsLogManager
@@ -39,29 +40,24 @@ import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVER
import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_SHORTCUT
import com.android.launcher3.taskbar.TaskbarManager
import com.android.launcher3.taskbar.TaskbarUIController
-import com.android.launcher3.util.OverviewCommandHelperProtoLogProxy
-import com.android.launcher3.util.OverviewReleaseFlags.enableGridOnlyOverview
+import com.android.launcher3.util.Executors
import com.android.launcher3.util.RunnableList
import com.android.launcher3.util.coroutines.DispatcherProvider
import com.android.launcher3.util.coroutines.ProductionDispatchers
import com.android.quickstep.OverviewCommandHelper.CommandInfo.CommandStatus
-import com.android.quickstep.OverviewCommandHelper.CommandType.HIDE_ALT_TAB
+import com.android.quickstep.OverviewCommandHelper.CommandType.HIDE
import com.android.quickstep.OverviewCommandHelper.CommandType.HOME
-import com.android.quickstep.OverviewCommandHelper.CommandType.SHOW_ALT_TAB
-import com.android.quickstep.OverviewCommandHelper.CommandType.SHOW_WITH_FOCUS
+import com.android.quickstep.OverviewCommandHelper.CommandType.KEYBOARD_INPUT
+import com.android.quickstep.OverviewCommandHelper.CommandType.SHOW
import com.android.quickstep.OverviewCommandHelper.CommandType.TOGGLE
-import com.android.quickstep.OverviewCommandHelper.CommandType.TOGGLE_OVERVIEW_PREVIOUS
-import com.android.quickstep.fallback.window.RecentsWindowManager
-import com.android.quickstep.util.ActiveGestureLog
-import com.android.quickstep.util.ActiveGestureProtoLogProxy
+import com.android.quickstep.fallback.window.RecentsDisplayModel
+import com.android.quickstep.fallback.window.RecentsWindowFlags.Companion.enableOverviewInWindow
import com.android.quickstep.views.RecentsView
import com.android.quickstep.views.TaskView
import com.android.systemui.shared.recents.model.ThumbnailData
import com.android.systemui.shared.system.InteractionJankMonitorWrapper
-import com.android.wm.shell.Flags.enableShellTopTaskTracking
import java.io.PrintWriter
import java.util.concurrent.ConcurrentLinkedDeque
-import java.util.concurrent.TimeUnit
import kotlin.coroutines.resume
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.SupervisorJob
@@ -77,13 +73,11 @@ constructor(
private val touchInteractionService: TouchInteractionService,
private val overviewComponentObserver: OverviewComponentObserver,
private val dispatcherProvider: DispatcherProvider = ProductionDispatchers,
- private val displayRepository: DisplayRepository,
+ private val recentsDisplayModel: RecentsDisplayModel,
+ private val focusState: FocusState,
private val taskbarManager: TaskbarManager,
- private val taskAnimationManagerRepository: PerDisplayRepository,
- private val elapsedRealtime: () -> Long = SystemClock::elapsedRealtime,
) {
- private val coroutineScope =
- CoroutineScope(SupervisorJob() + dispatcherProvider.lightweightBackground)
+ private val coroutineScope = CoroutineScope(SupervisorJob() + dispatcherProvider.background)
private val commandQueue = ConcurrentLinkedDeque()
@@ -94,13 +88,11 @@ constructor(
*/
private var keyboardTaskFocusIndex = -1
- private val lastToggleInfo = mutableMapOf()
-
private fun getContainerInterface(displayId: Int) =
overviewComponentObserver.getContainerInterface(displayId)
private fun getVisibleRecentsView(displayId: Int) =
- getContainerInterface(displayId)?.getVisibleRecentsView>()
+ getContainerInterface(displayId).getVisibleRecentsView>()
/**
* Adds a command to be executed next, after all pending tasks are completed. Max commands that
@@ -118,25 +110,23 @@ constructor(
isLastOfBatch: Boolean = true,
): CommandInfo? {
if (commandQueue.size >= MAX_QUEUE_SIZE) {
- OverviewCommandHelperProtoLogProxy.logCommandQueueFull(type, commandQueue)
+ Log.d(TAG, "command not added: $type - queue is full ($commandQueue).")
return null
}
- val command =
- CommandInfo(
- type,
- displayId = displayId,
- createTime = elapsedRealtime(),
- isLastOfBatch = isLastOfBatch,
- )
+ val command = CommandInfo(type, displayId = displayId, isLastOfBatch = isLastOfBatch)
commandQueue.add(command)
- OverviewCommandHelperProtoLogProxy.logCommandAdded(command)
+ Log.d(TAG, "command added: $command")
if (commandQueue.size == 1) {
- OverviewCommandHelperProtoLogProxy.logCommandExecuted(command, commandQueue.size)
- coroutineScope.launch(dispatcherProvider.main) { processNextCommand() }
+ Log.d(TAG, "execute: $command - queue size: ${commandQueue.size}")
+ if (enableOverviewCommandHelperTimeout()) {
+ coroutineScope.launch(dispatcherProvider.main) { processNextCommand() }
+ } else {
+ Executors.MAIN_EXECUTOR.execute { processNextCommand() }
+ }
} else {
- OverviewCommandHelperProtoLogProxy.logCommandNotExecuted(command, commandQueue.size)
+ Log.d(TAG, "not executed: $command - queue size: ${commandQueue.size}")
}
return command
@@ -154,25 +144,28 @@ constructor(
@BinderThread
fun addCommandsForAllDisplays(type: CommandType) =
- addCommandsForDisplays(type, displayRepository.displayIds.value.toIntArray())
+ addCommandsForDisplays(
+ type,
+ recentsDisplayModel.activeDisplayResources
+ .map { resource -> resource.displayId }
+ .toIntArray(),
+ )
@BinderThread
fun addCommandsForDisplaysExcept(type: CommandType, excludedDisplayId: Int) =
addCommandsForDisplays(
type,
- displayRepository.displayIds.value
+ recentsDisplayModel.activeDisplayResources
+ .map { resource -> resource.displayId }
.filter { displayId -> displayId != excludedDisplayId }
.toIntArray(),
)
- fun canStartHomeSafely(): Boolean =
- commandQueue.isEmpty() ||
- commandQueue.first().type == HOME ||
- commandQueue.first().type == TOGGLE_OVERVIEW_PREVIOUS
+ fun canStartHomeSafely(): Boolean = commandQueue.isEmpty() || commandQueue.first().type == HOME
/** Clear pending or completed commands from the queue */
fun clearPendingCommands() {
- OverviewCommandHelperProtoLogProxy.logClearPendingCommands(commandQueue)
+ Log.d(TAG, "clearing pending commands: $commandQueue")
commandQueue.removeAll { it.status != CommandStatus.PROCESSING }
}
@@ -185,19 +178,30 @@ constructor(
private fun processNextCommand() {
val command: CommandInfo? = commandQueue.firstOrNull()
if (command == null) {
- OverviewCommandHelperProtoLogProxy.logNoPendingCommands()
+ Log.d(TAG, "no pending commands to be executed.")
return
}
command.status = CommandStatus.PROCESSING
- OverviewCommandHelperProtoLogProxy.logExecutingCommand(command)
+ Log.d(TAG, "executing command: $command")
- coroutineScope.launch(dispatcherProvider.main) {
+ if (enableOverviewCommandHelperTimeout()) {
+ coroutineScope.launch(dispatcherProvider.main) {
withTimeout(QUEUE_WAIT_DURATION_IN_MS) {
executeCommandSuspended(command)
ensureActive()
onCommandFinished(command)
}
+ }
+ } else {
+ val result =
+ executeCommand(command, onCallbackResult = { onCommandFinished(command) })
+ Log.d(TAG, "command executed: $command with result: $result")
+ if (result) {
+ onCommandFinished(command)
+ } else {
+ Log.d(TAG, "waiting for command callback: $command")
+ }
}
}
@@ -208,7 +212,7 @@ constructor(
@VisibleForTesting
fun executeCommand(command: CommandInfo, onCallbackResult: () -> Unit): Boolean {
val recentsView = getVisibleRecentsView(command.displayId)
- OverviewCommandHelperProtoLogProxy.logExecutingCommand(command, recentsView)
+ Log.d(TAG, "executeCommand: $command - visibleRecentsView: $recentsView")
return if (recentsView != null) {
executeWhenRecentsIsVisible(command, recentsView, onCallbackResult)
} else {
@@ -223,14 +227,11 @@ constructor(
private suspend fun executeCommandSuspended(command: CommandInfo) =
suspendCancellableCoroutine { continuation ->
fun processResult(isCompleted: Boolean) {
- OverviewCommandHelperProtoLogProxy.logExecutedCommandWithResult(
- command,
- isCompleted,
- )
+ Log.d(TAG, "command executed: $command with result: $isCompleted")
if (isCompleted) {
continuation.resume(Unit)
} else {
- OverviewCommandHelperProtoLogProxy.logWaitingForCommandCallback(command)
+ Log.d(TAG, "waiting for command callback: $command")
}
}
@@ -246,9 +247,9 @@ constructor(
onCallbackResult: () -> Unit,
): Boolean =
when (command.type) {
- SHOW_WITH_FOCUS -> true // already visible
- SHOW_ALT_TAB,
- HIDE_ALT_TAB -> {
+ SHOW -> true // already visible
+ KEYBOARD_INPUT,
+ HIDE -> {
if (recentsView.isHandlingTouch) {
true
} else {
@@ -260,55 +261,38 @@ constructor(
}
TOGGLE -> {
- val runningTaskId = recentsView.runningTaskView?.taskIdSet
launchTask(
recentsView,
- getNextToggledTaskView(recentsView, command.displayId),
+ getNextToggledTaskView(recentsView),
command,
- ) {
- if (enableGridOnlyOverview() && runningTaskId != null) {
- lastToggleInfo[command.displayId] =
- ToggleInfo(command.createTime, runningTaskId)
- }
- onCallbackResult()
- }
- }
- TOGGLE_OVERVIEW_PREVIOUS -> {
- val taskView = recentsView.runningTaskView
- if (taskView == null) {
- recentsView.startHome()
- } else {
- taskView.launchWithAnimation()
- }
- true
+ onCallbackResult,
+ )
}
+
HOME -> {
recentsView.startHome()
true
}
}
- private fun getNextToggledTaskView(recentsView: RecentsView<*, *>, displayId: Int): TaskView? {
- val lastToggleInfo = lastToggleInfo[displayId]
- val lastToggleTaskView =
+ private fun getNextToggledTaskView(recentsView: RecentsView<*, *>): TaskView? {
+ // When running task view is null we return last large taskView - typically focusView when
+ // grid only is not enabled else last desktop task view.
+ return if (recentsView.runningTaskView == null) {
+ recentsView.lastLargeTaskView ?: recentsView.getFirstTaskView()
+ } else {
if (
- enableGridOnlyOverview() &&
- lastToggleInfo != null &&
- elapsedRealtime() - lastToggleInfo.createTime < TOGGLE_PREVIOUS_TIMEOUT_MS
+ enableLargeDesktopWindowingTile() &&
+ recentsView.getTaskViewCount() == recentsView.largeTilesCount &&
+ recentsView.runningTaskView === recentsView.lastLargeTaskView
) {
- recentsView.getTaskViewByTaskIds(lastToggleInfo.taskIds.toIntArray())
- } else null
- val runningTaskView = recentsView.runningTaskView
- return when {
- runningTaskView == null && !enableGridOnlyOverview() ->
- // When running task view is null we return last large taskView - typically
- // focusView or last desktop task view.
- recentsView.lastLargeTaskView ?: recentsView.firstTaskView
- runningTaskView == null ->
- recentsView.firstNonDesktopTaskView ?: recentsView.lastDesktopTaskView
- lastToggleTaskView != null && lastToggleTaskView != runningTaskView ->
- lastToggleTaskView
- else -> recentsView.nextTaskView ?: recentsView.previousTaskView ?: runningTaskView
+ // Enables the toggle when only large tiles are in recents view.
+ // We return previous because unlike small tiles, large tiles are always
+ // on the right hand side.
+ recentsView.previousTaskView ?: recentsView.runningTaskView
+ } else {
+ recentsView.nextTaskView ?: recentsView.runningTaskView
+ }
}
}
@@ -326,10 +310,10 @@ constructor(
if (callbackList != null) {
callbackList.add {
- OverviewCommandHelperProtoLogProxy.logLaunchingTaskCallback(command)
+ Log.d(TAG, "launching task callback: $command")
onCallbackResult()
}
- OverviewCommandHelperProtoLogProxy.logLaunchingTaskWaitingForCallback(command)
+ Log.d(TAG, "launching task - waiting for callback: $command")
return false
} else {
recents.startHome()
@@ -337,80 +321,85 @@ constructor(
}
}
- // Returns false if callbacks should be awaited, true otherwise.
private fun executeWhenRecentsIsNotVisible(
command: CommandInfo,
onCallbackResult: () -> Unit,
): Boolean {
- val containerInterface = getContainerInterface(command.displayId) ?: return true
+ val containerInterface = getContainerInterface(command.displayId)
val recentsViewContainer = containerInterface.getCreatedContainer()
val recentsView: RecentsView<*, *>? = recentsViewContainer?.getOverviewPanel()
val deviceProfile = recentsViewContainer?.getDeviceProfile()
- val taskbarUIController: TaskbarUIController? =
- if (
- command.displayId != DEFAULT_DISPLAY &&
- recentsViewContainer !is RecentsWindowManager
- ) {
- // When recentsViewContainer is not RecentsWindowManager, get TaskbarUiController
- // from TaskbarManager as a workaround.
- taskbarManager.getUIControllerForDisplay(command.displayId)
- } else {
- containerInterface.getTaskbarController()
- }
+ val uiController = containerInterface.getTaskbarController()
- val taskAnimationManager = taskAnimationManagerRepository[command.displayId]
- if (taskAnimationManager == null) {
- Log.e(TAG, "No TaskAnimationManager found for display ${command.displayId}")
- ActiveGestureProtoLogProxy.logOnTaskAnimationManagerNotAvailable(command.displayId)
- return false
- }
+ val focusedDisplayId = focusState.focusedDisplayId
+ val focusedDisplayUIController: TaskbarUIController? =
+ if (enableOverviewInWindow) {
+ Log.d(
+ TAG,
+ "Querying RecentsDisplayModel for TaskbarUIController for display: $focusedDisplayId",
+ )
+ recentsDisplayModel.getRecentsWindowManager(focusedDisplayId)?.taskbarUIController
+ } else {
+ Log.d(
+ TAG,
+ "Querying TaskbarManager for TaskbarUIController for display: $focusedDisplayId",
+ )
+ // TODO(b/395061396): Remove this path when overview in widow is enabled.
+ taskbarManager.getUIControllerForDisplay(focusedDisplayId)
+ }
+ Log.d(
+ TAG,
+ "TaskbarUIController for display $focusedDisplayId was" +
+ "${if (focusedDisplayUIController == null) " not" else ""} found",
+ )
when (command.type) {
- HIDE_ALT_TAB -> {
- if (
- taskbarUIController == null ||
- !shouldShowAltTabKqs(deviceProfile, command.displayId)
- ) {
- return true
- }
- keyboardTaskFocusIndex = taskbarUIController.launchFocusedTask()
+ HIDE -> {
+ if (uiController == null || deviceProfile?.isTablet == false) return true
+ keyboardTaskFocusIndex =
+ if (
+ enableAltTabKqsOnConnectedDisplays() && focusedDisplayUIController != null
+ ) {
+ focusedDisplayUIController.launchFocusedTask()
+ } else {
+ uiController.launchFocusedTask()
+ }
if (keyboardTaskFocusIndex == -1) return true
}
- SHOW_ALT_TAB ->
- if (
- taskbarUIController != null &&
- shouldShowAltTabKqs(deviceProfile, command.displayId)
- ) {
- taskbarUIController.openQuickSwitchView()
+ KEYBOARD_INPUT ->
+ if (uiController != null && deviceProfile?.isTablet == true) {
+ if (
+ enableAltTabKqsOnConnectedDisplays() && focusedDisplayUIController != null
+ ) {
+ focusedDisplayUIController.openQuickSwitchView()
+ } else {
+ uiController.openQuickSwitchView()
+ }
return true
} else {
keyboardTaskFocusIndex = 0
}
HOME -> {
- taskAnimationManager.maybeStartHomeAction {
- // Although IActivityTaskManager$Stub$Proxy.startActivity is a slow binder call,
- // we should still call it on main thread because launcher is waiting for
- // ActivityTaskManager to resume it. Also calling startActivity() on bg thread
- // could potentially delay resuming launcher. See b/348668521 for more details.
- touchInteractionService.startActivity(
- overviewComponentObserver.getHomeIntent(command.displayId)
- )
- }
+ //ActiveGestureProtoLogProxy.logExecuteHomeCommand()
+ // Although IActivityTaskManager$Stub$Proxy.startActivity is a slow binder call,
+ // we should still call it on main thread because launcher is waiting for
+ // ActivityTaskManager to resume it. Also calling startActivity() on bg thread
+ // could potentially delay resuming launcher. See b/348668521 for more details.
+ touchInteractionService.startActivity(overviewComponentObserver.homeIntent)
return true
}
- SHOW_WITH_FOCUS ->
+ SHOW ->
// When Recents is not currently visible, the command's type is SHOW
// when overview is triggered via the keyboard overview button or Action+Tab
// keys (Not Alt+Tab which is KQS). The overview button on-screen in 3-button
// nav is TYPE_TOGGLE.
keyboardTaskFocusIndex = 0
- TOGGLE,
- TOGGLE_OVERVIEW_PREVIOUS -> {}
+ TOGGLE -> {}
}
recentsView?.setKeyboardTaskFocusIndex(
@@ -422,68 +411,44 @@ constructor(
val animatorListener: Animator.AnimatorListener =
object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator) {
- OverviewCommandHelperProtoLogProxy.logSwitchingToOverviewStateStart(command)
+ Log.d(TAG, "switching to Overview state - onAnimationStart: $command")
super.onAnimationStart(animation)
updateRecentsViewFocus(command)
logShowOverviewFrom(command)
}
override fun onAnimationEnd(animation: Animator) {
- OverviewCommandHelperProtoLogProxy.logSwitchingToOverviewStateEnd(command)
+ Log.d(TAG, "switching to Overview state - onAnimationEnd: $command")
super.onAnimationEnd(animation)
onRecentsViewFocusUpdated(command)
onCallbackResult()
}
}
if (containerInterface.switchToRecentsIfVisible(animatorListener)) {
- OverviewCommandHelperProtoLogProxy.logSwitchingToOverviewStateWaiting(command)
+ Log.d(TAG, "switching to Overview state - waiting: $command")
// If successfully switched, wait until animation finishes
return false
}
- // If we get here then launcher is not the top visible task, so we should animate
- // that task.
-
- if (recentsViewContainer !is RecentsWindowManager) {
- recentsViewContainer?.rootView?.let { view ->
+ if (!enableOverviewInWindow) {
+ containerInterface.getCreatedContainer()?.rootView?.let { view ->
InteractionJankMonitorWrapper.begin(view, Cuj.CUJ_LAUNCHER_QUICK_SWITCH)
}
}
val gestureState =
- touchInteractionService
- .createGestureState(
- command.displayId,
- GestureState.DEFAULT_STATE,
- GestureState.TrackpadGestureType.NONE,
- )
- .apply {
- isHandlingAtomicEvent = true
- if (!enableShellTopTaskTracking()) {
- val runningTask = runningTask
- // In the case where we are in an excluded, translucent overlay, ignore it
- // and treat the running activity as the task behind the overlay.
- val otherVisibleTask = runningTask?.visibleNonExcludedTask
- if (otherVisibleTask != null) {
- ActiveGestureProtoLogProxy.logUpdateGestureStateRunningTask(
- otherVisibleTask.packageName ?: "MISSING",
- runningTask.packageName ?: "MISSING",
- )
- updateRunningTask(otherVisibleTask)
- }
- }
- }
+ touchInteractionService.createGestureState(
+ command.displayId,
+ GestureState.DEFAULT_STATE,
+ GestureState.TrackpadGestureType.NONE,
+ )
+ gestureState.isHandlingAtomicEvent = true
val interactionHandler =
touchInteractionService
- .getSwipeUpHandlerFactory(command.displayId)
+ // TODO(b/404757863): use command.displayId instead of focusedDisplayId.
+ .getSwipeUpHandlerFactory(focusedDisplayId)
.newHandler(gestureState, command.createTime)
- if (interactionHandler == null) {
- // Can happen e.g. when a display is disconnected, so try to handle gracefully.
- Log.d(TAG, "AbsSwipeUpHandler not available for displayId=${command.displayId})")
- ActiveGestureProtoLogProxy.logOnAbsSwipeUpHandlerNotAvailable(command.displayId)
- return true
- }
- interactionHandler.setGestureAnimationEndCallback {
+ interactionHandler.setGestureEndCallback {
onTransitionComplete(command, interactionHandler, onCallbackResult)
}
interactionHandler.initWhenReady("OverviewCommandHelper: command.type=${command.type}")
@@ -495,9 +460,9 @@ constructor(
targets: RecentsAnimationTargets,
transitionInfo: TransitionInfo?,
) {
- OverviewCommandHelperProtoLogProxy.logRecentsAnimStarted(command)
- if (recentsViewContainer is RecentsWindowManager) {
- recentsViewContainer.rootView?.let { view ->
+ Log.d(TAG, "recents animation started: $command")
+ if (enableOverviewInWindow) {
+ containerInterface.getCreatedContainer()?.rootView?.let { view ->
InteractionJankMonitorWrapper.begin(view, Cuj.CUJ_LAUNCHER_QUICK_SWITCH)
}
}
@@ -505,7 +470,7 @@ constructor(
updateRecentsViewFocus(command)
logShowOverviewFrom(command)
containerInterface.runOnInitBackgroundStateUI {
- OverviewCommandHelperProtoLogProxy.logOnInitBackgroundStateUI(command)
+ Log.d(TAG, "recents animation started - onInitBackgroundStateUI: $command")
interactionHandler.onGestureEnded(
0f,
PointF(),
@@ -518,7 +483,7 @@ constructor(
override fun onRecentsAnimationCanceled(
thumbnailDatas: HashMap
) {
- OverviewCommandHelperProtoLogProxy.logRecentsAnimCanceled(command)
+ Log.d(TAG, "recents animation canceled: $command")
interactionHandler.onGestureCancelled()
command.removeListener(this)
@@ -527,6 +492,15 @@ constructor(
}
}
+ val taskAnimationManager =
+ recentsDisplayModel.getTaskAnimationManager(command.displayId)
+ ?: run {
+ Log.e(TAG, "No TaskAnimationManager found for display ${command.displayId}")
+ //ActiveGestureProtoLogProxy.logOnTaskAnimationManagerNotAvailable(
+ // command.displayId
+ //)
+ return false
+ }
if (taskAnimationManager.isRecentsAnimationRunning) {
command.setAnimationCallbacks(
taskAnimationManager.continueRecentsAnimation(gestureState)
@@ -538,32 +512,29 @@ constructor(
command.addListener(recentAnimListener)
taskAnimationManager.notifyRecentsAnimationState(recentAnimListener)
} else {
+ // Lawnchair-TODO: What name to put in intent here?
val intent =
Intent(interactionHandler.getLaunchIntent())
- .putExtra(ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID, gestureState.gestureId)
+ .putExtra("Something", gestureState.gestureId)
command.setAnimationCallbacks(
taskAnimationManager.startRecentsAnimation(gestureState, intent, interactionHandler)
)
interactionHandler.onGestureStarted(false /*isLikelyToStartNewTask*/)
command.addListener(recentAnimListener)
}
- OverviewCommandHelperProtoLogProxy.logSwitchingViaRecentsAnim(command)
+ //Trace.beginAsyncSection(TRANSITION_NAME, 0)
+ Log.d(TAG, "switching via recents animation - onGestureStarted: $command")
return false
}
- private fun shouldShowAltTabKqs(deviceProfile: DeviceProfile?, displayId: Int): Boolean =
- // Alt+Tab KQS is always shown on tablets (large screen devices).
- deviceProfile?.deviceProperties?.isTablet == true ||
- // For small screen devices, it's only shown on connected displays.
- displayId != DEFAULT_DISPLAY
-
private fun onTransitionComplete(
command: CommandInfo,
handler: AbsSwipeUpHandler<*, *, *>,
onCommandResult: () -> Unit,
) {
- OverviewCommandHelperProtoLogProxy.logSwitchingViaRecentsAnimComplete(command)
+ Log.d(TAG, "switching via recents animation - onTransitionComplete: $command")
command.removeListener(handler)
+ Trace.endAsyncSection(TRANSITION_NAME, 0)
onRecentsViewFocusUpdated(command)
onCommandResult()
}
@@ -572,54 +543,42 @@ constructor(
private fun onCommandFinished(command: CommandInfo) {
command.status = CommandStatus.COMPLETED
if (commandQueue.firstOrNull() !== command) {
- OverviewCommandHelperProtoLogProxy.logCommandFinishedButNotScheduled(
- commandQueue.firstOrNull(),
- command,
+ Log.d(
+ TAG,
+ "next task not scheduled. First pending command type " +
+ "is ${commandQueue.firstOrNull()} - command type is: $command",
)
return
}
- OverviewCommandHelperProtoLogProxy.logCommandFinishedSuccessfully(command)
+ Log.d(TAG, "command executed successfully! $command")
commandQueue.remove(command)
processNextCommand()
}
private fun cancelCommand(command: CommandInfo, throwable: Throwable?) {
command.status = CommandStatus.CANCELED
- OverviewCommandHelperProtoLogProxy.logCommandCanceled(command, throwable)
+ Log.e(TAG, "command cancelled: $command - $throwable")
commandQueue.remove(command)
processNextCommand()
}
private fun updateRecentsViewFocus(command: CommandInfo) {
val recentsView: RecentsView<*, *> = getVisibleRecentsView(command.displayId) ?: return
- if (
- command.type != SHOW_ALT_TAB &&
- command.type != HIDE_ALT_TAB &&
- command.type != SHOW_WITH_FOCUS
- ) {
+ if (command.type != KEYBOARD_INPUT && command.type != HIDE && command.type != SHOW) {
return
}
+
// When the overview is launched via alt tab (command type is TYPE_KEYBOARD_INPUT),
// the touch mode somehow is not change to false by the Android framework.
// The subsequent tab to go through tasks in overview can only be dispatched to
// focuses views, while focus can only be requested in
// {@link View#requestFocusNoSearch(int, Rect)} when touch mode is false. To note,
// here we launch overview with live tile.
- if (recentsView.isAttachedToWindow) {
- recentsView.viewRootImpl.touchModeChanged(false)
- } else {
- recentsView.post { recentsView.viewRootImpl.touchModeChanged(false) }
- }
+ recentsView.viewRootImpl.touchModeChanged(false)
// Ensure that recents view has focus so that it receives the followup key inputs
// Stops requesting focused after first view gets focused.
- recentsView
- .getTaskViewAt(
- recentsView.indexOfChild(
- recentsView.taskViews.elementAtOrNull(keyboardTaskFocusIndex)
- )
- )
- .requestFocus() ||
+ recentsView.getTaskViewAt(keyboardTaskFocusIndex).requestFocus() ||
recentsView.nextTaskView.requestFocus() ||
recentsView.firstTaskView.requestFocus() ||
recentsView.requestFocus()
@@ -627,12 +586,11 @@ constructor(
private fun onRecentsViewFocusUpdated(command: CommandInfo) {
val recentsView: RecentsView<*, *> = getVisibleRecentsView(command.displayId) ?: return
- if (command.type != HIDE_ALT_TAB || keyboardTaskFocusIndex == PagedView.INVALID_PAGE) {
+ if (command.type != HIDE || keyboardTaskFocusIndex == PagedView.INVALID_PAGE) {
return
}
recentsView.setKeyboardTaskFocusIndex(PagedView.INVALID_PAGE)
- recentsView.currentPage =
- recentsView.indexOfChild(recentsView.taskViews.elementAtOrNull(keyboardTaskFocusIndex))
+ recentsView.currentPage = keyboardTaskFocusIndex
keyboardTaskFocusIndex = PagedView.INVALID_PAGE
}
@@ -646,12 +604,12 @@ constructor(
}
private fun logShowOverviewFrom(command: CommandInfo) {
- val containerInterface = getContainerInterface(command.displayId) ?: return
+ val containerInterface = getContainerInterface(command.displayId)
val container = containerInterface.getCreatedContainer() ?: return
val event =
when (command.type) {
- SHOW_WITH_FOCUS -> LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_SHORTCUT
- HIDE_ALT_TAB -> LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_QUICK_SWITCH
+ SHOW -> LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_SHORTCUT
+ HIDE -> LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_QUICK_SWITCH
TOGGLE -> LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_3_BUTTON
else -> return
}
@@ -680,7 +638,7 @@ constructor(
data class CommandInfo(
val type: CommandType,
var status: CommandStatus = CommandStatus.IDLE,
- val createTime: Long,
+ val createTime: Long = SystemClock.elapsedRealtime(),
private var animationCallbacks: RecentsAnimationCallbacks? = null,
val displayId: Int = DEFAULT_DISPLAY,
val isLastOfBatch: Boolean = true,
@@ -706,21 +664,13 @@ constructor(
}
enum class CommandType {
- SHOW_WITH_FOCUS,
- SHOW_ALT_TAB,
- HIDE_ALT_TAB,
- /** Toggle between overview and the next task */
+ SHOW,
+ KEYBOARD_INPUT,
+ HIDE,
TOGGLE, // Navigate to Overview
HOME, // Navigate to Home
- /**
- * Toggle between Overview and the previous screen before launching Overview, which can
- * either be a task or the home screen.
- */
- TOGGLE_OVERVIEW_PREVIOUS,
}
- data class ToggleInfo(val createTime: Long, val taskIds: Set)
-
companion object {
private const val TAG = "OverviewCommandHelper"
private const val TRANSITION_NAME = "Transition:toOverview"
@@ -731,6 +681,5 @@ constructor(
*/
private const val MAX_QUEUE_SIZE = 3
private const val QUEUE_WAIT_DURATION_IN_MS = 5000L
- @VisibleForTesting val TOGGLE_PREVIOUS_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5)
}
}
diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
index 2ae6a19164..1c2b1f01c7 100644
--- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
+++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java
@@ -21,11 +21,11 @@ import static android.content.Intent.ACTION_PACKAGE_CHANGED;
import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static android.view.Display.DEFAULT_DISPLAY;
+import static com.android.launcher3.Flags.enableOverviewOnConnectedDisplays;
import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.quickstep.fallback.window.RecentsWindowFlags.enableFallbackOverviewInWindow;
import static com.android.quickstep.fallback.window.RecentsWindowFlags.enableLauncherOverviewInWindow;
-import static com.android.quickstep.fallback.window.RecentsWindowFlags.enableOverviewOnConnectedDisplays;
import static com.android.systemui.shared.system.PackageManagerWrapper.ACTION_PREFERRED_ACTIVITY_CHANGED;
import android.content.ActivityNotFoundException;
@@ -43,7 +43,6 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
-import com.android.app.displaylib.PerDisplayRepository;
import com.android.launcher3.R;
import com.android.launcher3.dagger.ApplicationContext;
import com.android.launcher3.dagger.LauncherAppComponent;
@@ -51,7 +50,7 @@ import com.android.launcher3.dagger.LauncherAppSingleton;
import com.android.launcher3.util.DaggerSingletonObject;
import com.android.launcher3.util.DaggerSingletonTracker;
import com.android.launcher3.util.SimpleBroadcastReceiver;
-import com.android.quickstep.fallback.window.RecentsWindowManager;
+import com.android.quickstep.fallback.window.RecentsDisplayModel;
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
import com.android.systemui.shared.system.PackageManagerWrapper;
@@ -78,11 +77,10 @@ public final class OverviewComponentObserver {
private final SimpleBroadcastReceiver mUserPreferenceChangeReceiver;
private final SimpleBroadcastReceiver mOtherHomeAppUpdateReceiver;
- private final PerDisplayRepository mRecentsWindowManagerRepository;
+ private final RecentsDisplayModel mRecentsDisplayModel;
- private final Intent mCurrentPrimaryHomeIntent;
- private final Intent mSecondaryHomeIntent;
- private final Intent mMyPrimaryHomeIntent;
+ private final Intent mCurrentHomeIntent;
+ private final Intent mMyHomeIntent;
private final Intent mFallbackIntent;
private final SparseIntArray mConfigChangesMap = new SparseIntArray();
private final String mSetupWizardPkg;
@@ -100,32 +98,19 @@ public final class OverviewComponentObserver {
@Inject
public OverviewComponentObserver(
@ApplicationContext Context context,
- PerDisplayRepository recentsWindowManagerRepository,
+ RecentsDisplayModel recentsDisplayModel,
DaggerSingletonTracker lifecycleTracker) {
mUserPreferenceChangeReceiver =
new SimpleBroadcastReceiver(context, MAIN_EXECUTOR, this::updateOverviewTargets);
mOtherHomeAppUpdateReceiver =
new SimpleBroadcastReceiver(context, MAIN_EXECUTOR, this::updateOverviewTargets);
- mRecentsWindowManagerRepository = recentsWindowManagerRepository;
- // Set up primary intents
- mCurrentPrimaryHomeIntent = createHomeIntent();
- mMyPrimaryHomeIntent = new Intent(mCurrentPrimaryHomeIntent).setPackage(
- context.getPackageName());
- ResolveInfo info = context.getPackageManager().resolveActivity(mMyPrimaryHomeIntent, 0);
+ mRecentsDisplayModel = recentsDisplayModel;
+ mCurrentHomeIntent = createHomeIntent();
+ mMyHomeIntent = new Intent(mCurrentHomeIntent).setPackage(context.getPackageName());
+ ResolveInfo info = context.getPackageManager().resolveActivity(mMyHomeIntent, 0);
ComponentName myHomeComponent =
new ComponentName(context.getPackageName(), info.activityInfo.name);
- mMyPrimaryHomeIntent.setComponent(myHomeComponent);
- // Set up secondary home intent
- mSecondaryHomeIntent = createSecondaryHomeIntent().setPackage(
- context.getPackageName());
- ResolveInfo secondaryInfo = context.getPackageManager().resolveActivity(
- mSecondaryHomeIntent, 0);
- if (secondaryInfo != null) {
- ComponentName secondaryComponent = new ComponentName(context,
- secondaryInfo.activityInfo.name);
- mSecondaryHomeIntent.setComponent(secondaryComponent);
- }
-
+ mMyHomeIntent.setComponent(myHomeComponent);
mConfigChangesMap.append(myHomeComponent.hashCode(), info.activityInfo.configChanges);
mSetupWizardPkg = context.getString(R.string.setup_wizard_pkg);
@@ -187,7 +172,7 @@ public final class OverviewComponentObserver {
defaultHome = null;
}
- mIsDefaultHome = Objects.equals(mMyPrimaryHomeIntent.getComponent(), defaultHome);
+ mIsDefaultHome = Objects.equals(mMyHomeIntent.getComponent(), defaultHome);
// Set assistant visibility to 0 from launcher's perspective, ensures any elements that
// launcher made invisible become visible again before the new activity control helper
@@ -199,7 +184,7 @@ public final class OverviewComponentObserver {
if (SEPARATE_RECENTS_ACTIVITY.get()) {
mIsDefaultHome = false;
if (defaultHome == null) {
- defaultHome = mMyPrimaryHomeIntent.getComponent();
+ defaultHome = mMyHomeIntent.getComponent();
}
}
@@ -211,34 +196,28 @@ public final class OverviewComponentObserver {
if (!mIsHomeDisabled && (defaultHome == null || mIsDefaultHome)) {
// User default home is same as our home app. Use Overview integrated in Launcher.
if (enableLauncherOverviewInWindow) {
- RecentsWindowManager recentsWindowManager = mRecentsWindowManagerRepository.get(
- DEFAULT_DISPLAY);
mDefaultDisplayContainerInterface =
- recentsWindowManager != null ? recentsWindowManager.getContainerInterface()
- : null;
+ mRecentsDisplayModel.getFallbackWindowInterface(DEFAULT_DISPLAY);
} else {
mDefaultDisplayContainerInterface = LauncherActivityInterface.INSTANCE;
}
mIsHomeAndOverviewSame = true;
- mOverviewIntent = mMyPrimaryHomeIntent;
- mCurrentPrimaryHomeIntent.setComponent(mMyPrimaryHomeIntent.getComponent());
+ mOverviewIntent = mMyHomeIntent;
+ mCurrentHomeIntent.setComponent(mMyHomeIntent.getComponent());
// Remove any update listener as we don't care about other packages.
unregisterOtherHomeAppUpdateReceiver();
} else {
// The default home app is a different launcher. Use the fallback Overview instead.
if (enableFallbackOverviewInWindow) {
- RecentsWindowManager recentsWindowManager = mRecentsWindowManagerRepository.get(
- DEFAULT_DISPLAY);
mDefaultDisplayContainerInterface =
- recentsWindowManager != null ? recentsWindowManager.getContainerInterface()
- : null;
+ mRecentsDisplayModel.getFallbackWindowInterface(DEFAULT_DISPLAY);
} else {
mDefaultDisplayContainerInterface = FallbackActivityInterface.INSTANCE;
}
mIsHomeAndOverviewSame = false;
mOverviewIntent = mFallbackIntent;
- mCurrentPrimaryHomeIntent.setComponent(defaultHome);
+ mCurrentHomeIntent.setComponent(defaultHome);
// User's default home app can change as a result of package updates of this app (such
// as uninstalling the app or removing the "Launcher" feature in an update).
@@ -296,7 +275,7 @@ public final class OverviewComponentObserver {
* @return the overview intent
*/
public Intent getOverviewIntentIgnoreSysUiState() {
- return mIsDefaultHome ? mMyPrimaryHomeIntent : mOverviewIntent;
+ return mIsDefaultHome ? mMyHomeIntent : mOverviewIntent;
}
/**
@@ -311,12 +290,8 @@ public final class OverviewComponentObserver {
/**
* Get the current intent for going to the home activity.
*/
- public Intent getHomeIntent(int displayId) {
- if (displayId == DEFAULT_DISPLAY) {
- return mCurrentPrimaryHomeIntent;
- } else {
- return mSecondaryHomeIntent;
- }
+ public Intent getHomeIntent() {
+ return mCurrentHomeIntent;
}
/**
@@ -326,6 +301,10 @@ public final class OverviewComponentObserver {
return mIsHomeAndOverviewSame;
}
+ public boolean isHomeAndOverviewSameActivity() {
+ return isHomeAndOverviewSame() && !enableLauncherOverviewInWindow;
+ }
+
/**
* Get the current control helper for managing interactions to the overview container for
* the given displayId.
@@ -333,16 +312,10 @@ public final class OverviewComponentObserver {
* @param displayId The display id
* @return the control helper for the given display
*/
- @Nullable
public BaseContainerInterface, ?> getContainerInterface(int displayId) {
- if (enableOverviewOnConnectedDisplays() && displayId != DEFAULT_DISPLAY) {
- RecentsWindowManager recentsWindowManager = mRecentsWindowManagerRepository.get(
- displayId);
- return recentsWindowManager != null ? recentsWindowManager.getContainerInterface()
- : null;
- } else {
- return mDefaultDisplayContainerInterface;
- }
+ return (enableOverviewOnConnectedDisplays() && displayId != DEFAULT_DISPLAY)
+ ? mRecentsDisplayModel.getFallbackWindowInterface(displayId)
+ : mDefaultDisplayContainerInterface;
}
public void dump(PrintWriter pw) {
@@ -351,16 +324,15 @@ public final class OverviewComponentObserver {
pw.println(" isHomeDisabled=" + mIsHomeDisabled);
pw.println(" homeAndOverviewSame=" + mIsHomeAndOverviewSame);
pw.println(" overviewIntent=" + mOverviewIntent);
- pw.println(" homeIntent=" + mCurrentPrimaryHomeIntent);
- pw.println(" secondaryHomeIntent=" + mSecondaryHomeIntent);
+ pw.println(" homeIntent=" + mCurrentHomeIntent);
}
/**
* Starts the intent for the current home activity.
*/
public static void startHomeIntentSafely(@NonNull Context context, @Nullable Bundle options,
- @NonNull String reason, int displayId) {
- Intent intent = OverviewComponentObserver.INSTANCE.get(context).getHomeIntent(displayId);
+ @NonNull String reason) {
+ Intent intent = OverviewComponentObserver.INSTANCE.get(context).getHomeIntent();
startHomeIntentSafely(context, intent, options, reason);
}
@@ -396,9 +368,4 @@ public final class OverviewComponentObserver {
.addCategory(Intent.CATEGORY_HOME)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
- private static Intent createSecondaryHomeIntent() {
- return new Intent(Intent.ACTION_MAIN)
- .addCategory(Intent.CATEGORY_SECONDARY_HOME)
- .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- }
}
diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
index 0330d53452..e9f70242cd 100644
--- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -1 +1,268 @@
-// LC: No-op
+package com.android.quickstep;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static com.android.launcher3.taskbar.TaskbarThresholdUtils.getFromNavThreshold;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.view.WindowInsets;
+
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.taskbar.TaskbarActivityContext;
+import com.android.launcher3.testing.TestInformationHandler;
+import com.android.launcher3.testing.shared.TestProtocol;
+import com.android.launcher3.util.DisplayController;
+import com.android.quickstep.util.GroupTask;
+import com.android.quickstep.util.LayoutUtils;
+import com.android.quickstep.util.TISBindHelper;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
+import com.android.systemui.shared.recents.model.Task;
+
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+public class QuickstepTestInformationHandler extends TestInformationHandler {
+
+ protected final Context mContext;
+
+ public QuickstepTestInformationHandler(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public Bundle call(String method, String arg, @Nullable Bundle extras) {
+ final Bundle response = new Bundle();
+ switch (method) {
+ case TestProtocol.REQUEST_RECENT_TASKS_LIST: {
+ ArrayList taskBaseIntentComponents = new ArrayList<>();
+ CountDownLatch latch = new CountDownLatch(1);
+ RecentsModel.INSTANCE.get(mContext).getTasks((taskGroups) -> {
+ for (GroupTask group : taskGroups) {
+ for (Task t : group.getTasks()) {
+ taskBaseIntentComponents.add(
+ t.key.baseIntent.getComponent().flattenToString());
+ }
+ }
+ latch.countDown();
+ });
+ try {
+ latch.await(2, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ response.putStringArrayList(TestProtocol.TEST_INFO_RESPONSE_FIELD,
+ taskBaseIntentComponents);
+ return response;
+ }
+
+ case TestProtocol.REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT: {
+ final float swipeHeight =
+ LayoutUtils.getDefaultSwipeHeight(mContext, mDeviceProfile);
+ response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight);
+ return response;
+ }
+
+ case TestProtocol.REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT: {
+ final float swipeHeight = mDeviceProfile.heightPx / 2f;
+ response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, (int) swipeHeight);
+ return response;
+ }
+
+ case TestProtocol.REQUEST_GET_OVERVIEW_TASK_SIZE: {
+ return getUIProperty(Bundle::putParcelable,
+ recentsViewContainer ->
+ recentsViewContainer.>getOverviewPanel()
+ .getLastComputedTaskSize(),
+ this::getRecentsViewContainer);
+ }
+
+ case TestProtocol.REQUEST_GET_OVERVIEW_GRID_TASK_SIZE: {
+ return getUIProperty(Bundle::putParcelable,
+ recentsViewContainer ->
+ recentsViewContainer.>getOverviewPanel()
+ .getLastComputedGridTaskSize(),
+ this::getRecentsViewContainer);
+ }
+
+ case TestProtocol.REQUEST_GET_OVERVIEW_PAGE_SPACING: {
+ response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD,
+ mDeviceProfile.overviewPageSpacing);
+ return response;
+ }
+
+ case TestProtocol.REQUEST_GET_OVERVIEW_CURRENT_PAGE_INDEX: {
+ return getLauncherUIProperty(Bundle::putInt,
+ launcher -> launcher.getOverviewPanel().getCurrentPage());
+ }
+
+ case TestProtocol.REQUEST_HAS_TIS: {
+ response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD, true);
+ return response;
+ }
+
+ case TestProtocol.REQUEST_UNSTASH_TASKBAR_IF_STASHED:
+ runOnTISBinder(tisBinder -> {
+ // Allow null-pointer to catch illegal states.
+ tisBinder.getTaskbarManager().getCurrentActivityContext()
+ .unstashTaskbarIfStashed();
+ });
+ return response;
+
+ case TestProtocol.REQUEST_TASKBAR_FROM_NAV_THRESHOLD: {
+ final Resources resources = mContext.getResources();
+ response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD,
+ getFromNavThreshold(resources, mDeviceProfile));
+ return response;
+ }
+
+ case TestProtocol.REQUEST_STASHED_TASKBAR_SCALE: {
+ runOnTISBinder(tisBinder -> {
+ response.putFloat(TestProtocol.TEST_INFO_RESPONSE_FIELD,
+ tisBinder.getTaskbarManager()
+ .getCurrentActivityContext()
+ .getStashedTaskbarScale());
+ });
+ return response;
+ }
+
+ case TestProtocol.REQUEST_TASKBAR_ALL_APPS_TOP_PADDING: {
+ return getTISBinderUIProperty(Bundle::putInt, tisBinder ->
+ tisBinder.getTaskbarManager()
+ .getCurrentActivityContext()
+ .getTaskbarAllAppsTopPadding());
+ }
+
+ case TestProtocol.REQUEST_TASKBAR_APPS_LIST_SCROLL_Y: {
+ return getTISBinderUIProperty(Bundle::putInt, tisBinder ->
+ tisBinder.getTaskbarManager()
+ .getCurrentActivityContext()
+ .getTaskbarAllAppsScroll());
+ }
+
+ case TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT:
+ runOnTISBinder(tisBinder -> {
+ enableBlockingTimeout(tisBinder, true);
+ });
+ return response;
+
+ case TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT:
+ runOnTISBinder(tisBinder -> {
+ enableBlockingTimeout(tisBinder, false);
+ });
+ return response;
+
+ case TestProtocol.REQUEST_ENABLE_TRANSIENT_TASKBAR:
+ enableTransientTaskbar(true);
+ return response;
+
+ case TestProtocol.REQUEST_DISABLE_TRANSIENT_TASKBAR:
+ enableTransientTaskbar(false);
+ return response;
+
+ case TestProtocol.REQUEST_SHELL_DRAG_READY:
+ response.putBoolean(TestProtocol.TEST_INFO_RESPONSE_FIELD,
+ SystemUiProxy.INSTANCE.get(mContext).isDragAndDropReady());
+ return response;
+
+ case TestProtocol.REQUEST_REFRESH_OVERVIEW_TARGET:
+ runOnTISBinder(TouchInteractionService.TISBinder::refreshOverviewTarget);
+ return response;
+
+ case TestProtocol.REQUEST_RECREATE_TASKBAR:
+ // Allow null-pointer to catch illegal states.
+ runOnTISBinder(tisBinder -> tisBinder.getTaskbarManager().recreateTaskbars());
+ return response;
+ case TestProtocol.REQUEST_TASKBAR_IME_DOCKED:
+ return getTISBinderUIProperty(Bundle::putBoolean, tisBinder ->
+ tisBinder.getTaskbarManager()
+ .getCurrentActivityContext().isImeDocked());
+ case TestProtocol.REQUEST_UNSTASH_BUBBLE_BAR_IF_STASHED:
+ runOnTISBinder(tisBinder -> {
+ // Allow null-pointer to catch illegal states.
+ tisBinder.getTaskbarManager().getCurrentActivityContext()
+ .unstashBubbleBarIfStashed();
+ });
+ return response;
+ case TestProtocol.REQUEST_INJECT_FAKE_TRACKPAD:
+ runOnTISBinder(tisBinder -> tisBinder.injectFakeTrackpadForTesting());
+ return response;
+ case TestProtocol.REQUEST_EJECT_FAKE_TRACKPAD:
+ runOnTISBinder(tisBinder -> tisBinder.ejectFakeTrackpadForTesting());
+ return response;
+ }
+
+ return super.call(method, arg, extras);
+ }
+
+ @Override
+ protected WindowInsets getWindowInsets() {
+ RecentsViewContainer container = getRecentsViewContainer();
+ WindowInsets insets = container == null
+ ? null : container.getRootView().getRootWindowInsets();
+ return insets == null ? super.getWindowInsets() : insets;
+ }
+
+ private RecentsViewContainer getRecentsViewContainer() {
+ // TODO (b/400647896): support per-display container in e2e tests
+ return OverviewComponentObserver.INSTANCE.get(mContext)
+ .getContainerInterface(DEFAULT_DISPLAY).getCreatedContainer();
+ }
+
+ @Override
+ protected boolean isLauncherInitialized() {
+ return super.isLauncherInitialized() && SystemUiProxy.INSTANCE.get(mContext).isActive();
+ }
+
+ private void enableBlockingTimeout(
+ TouchInteractionService.TISBinder tisBinder, boolean enable) {
+ TaskbarActivityContext context = tisBinder.getTaskbarManager().getCurrentActivityContext();
+ if (context == null) {
+ return;
+ }
+ context.enableBlockingTimeoutDuringTests(enable);
+ }
+
+ private void enableTransientTaskbar(boolean enable) {
+ DisplayController.INSTANCE.get(mContext).enableTransientTaskbarForTests(enable);
+ }
+
+ /**
+ * Runs the given command on the UI thread, after ensuring we are connected to
+ * TouchInteractionService.
+ */
+ protected void runOnTISBinder(Consumer connectionCallback) {
+ try {
+ CountDownLatch countDownLatch = new CountDownLatch(1);
+ TISBindHelper helper = MAIN_EXECUTOR.submit(() ->
+ new TISBindHelper(mContext, tisBinder -> {
+ connectionCallback.accept(tisBinder);
+ countDownLatch.countDown();
+ })).get();
+ countDownLatch.await();
+ MAIN_EXECUTOR.execute(helper::onDestroy);
+ } catch (ExecutionException | InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private Bundle getTISBinderUIProperty(
+ BundleSetter bundleSetter, Function provider) {
+ Bundle response = new Bundle();
+
+ runOnTISBinder(tisBinder -> bundleSetter.set(
+ response,
+ TestProtocol.TEST_INFO_RESPONSE_FIELD,
+ provider.apply(tisBinder)));
+
+ return response;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index 50e929a221..bbe2de0de1 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -18,7 +18,9 @@ package com.android.quickstep;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static com.android.launcher3.Flags.enableSeparateExternalDisplayTasks;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.quickstep.util.SplitScreenUtils.convertShellSplitBoundsToLauncher;
import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_DESK;
import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_SPLIT;
@@ -40,6 +42,8 @@ import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.util.DaggerSingletonTracker;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.LooperExecutor;
+import com.android.launcher3.util.SplitConfigurationOptions;
+import com.android.launcher3.util.window.WindowManagerProxy;
import com.android.quickstep.util.DesktopTask;
import com.android.quickstep.util.ExternalDisplaysKt;
import com.android.quickstep.util.GroupTask;
@@ -63,7 +67,6 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -74,7 +77,10 @@ import app.lawnchair.compat.LawnchairQuickstepCompat;
/**
* Manages the recent task list from the system, caching it as necessary.
*/
-public class RecentTasksList {
+// TODO: b/401602554 - Consider letting [DesktopTasksController] notify [RecentTasksController] of
+// desk changes to trigger [IRecentTasksListener.onRecentTasksChanged()], instead of implementing
+// [DesktopVisibilityListener].
+public class RecentTasksList implements WindowManagerProxy.DesktopVisibilityListener {
private static final TaskLoadResult INVALID_RESULT = new TaskLoadResult(-1, false, 0);
@@ -82,6 +88,7 @@ public class RecentTasksList {
private final KeyguardManager mKeyguardManager;
private final LooperExecutor mMainThreadExecutor;
private final SystemUiProxy mSysUiProxy;
+ private final DesktopVisibilityController mDesktopVisibilityController;
// The list change id, increments as the task list changes in the system
private int mChangeId;
@@ -100,12 +107,14 @@ public class RecentTasksList {
public RecentTasksList(Context context, LooperExecutor mainThreadExecutor,
KeyguardManager keyguardManager, SystemUiProxy sysUiProxy,
TopTaskTracker topTaskTracker,
+ DesktopVisibilityController desktopVisibilityController,
DaggerSingletonTracker tracker) {
mContext = context;
mMainThreadExecutor = mainThreadExecutor;
mKeyguardManager = keyguardManager;
mChangeId = 1;
mSysUiProxy = sysUiProxy;
+ mDesktopVisibilityController = desktopVisibilityController;
if (LawnchairApp.isRecentsEnabled()) {
final IRecentTasksListener recentTasksListener = new IRecentTasksListener.Stub() {
@Override
@@ -158,6 +167,13 @@ public class RecentTasksList {
mSysUiProxy.registerRecentTasksListener(recentTasksListener);
tracker.addCloseable(
() -> mSysUiProxy.unregisterRecentTasksListener(recentTasksListener));
+
+ if (DesktopModeStatus.enableMultipleDesktops(mContext)) {
+ mDesktopVisibilityController.registerDesktopVisibilityListener(
+ this);
+ tracker.addCloseable(
+ () -> mDesktopVisibilityController.unregisterDesktopVisibilityListener(this));
+ }
}
// We may receive onRunningTaskAppeared events later for tasks which have already been
@@ -191,27 +207,8 @@ public class RecentTasksList {
* @param callback The callback to receive the list of recent tasks
* @return The change id of the current task list
*/
- public synchronized int getTasks(
- boolean loadKeysOnly,
- @Nullable Consumer> callback,
- Predicate filter) {
- return getTasks(
- loadKeysOnly,
- callback == null ? null : (tasks, requestId) -> callback.accept(tasks),
- filter);
- }
-
- /**
- * Asynchronously fetches the list of recent tasks, reusing cached list if available.
- *
- * @param loadKeysOnly Whether to load other associated task data, or just the key
- * @param callback The callback to receive the list of recent tasks
- * @return The change id of the current task list
- */
- public synchronized int getTasks(
- boolean loadKeysOnly,
- @Nullable BiConsumer, Integer> callback,
- Predicate filter) {
+ public synchronized int getTasks(boolean loadKeysOnly,
+ @Nullable Consumer> callback, Predicate filter) {
final int requestLoadId = mChangeId;
if (mResultsUi.isValidForRequest(requestLoadId, loadKeysOnly)) {
// The list is up to date, send the callback on the next frame,
@@ -224,7 +221,7 @@ public class RecentTasksList {
.collect(Collectors.toCollection(ArrayList::new));
mMainThreadExecutor.post(() -> {
- callback.accept(result, requestLoadId);
+ callback.accept(result);
});
}
@@ -247,7 +244,7 @@ public class RecentTasksList {
.map(GroupTask::copy)
.collect(Collectors.toCollection(ArrayList::new));
- callback.accept(result, requestLoadId);
+ callback.accept(result);
}
});
});
@@ -317,6 +314,27 @@ public class RecentTasksList {
return mRunningTasks;
}
+ @Override
+ public void onDeskAdded(int displayId, int deskId) {
+ onRecentTasksChanged();
+ }
+
+ @Override
+ public void onDeskRemoved(int displayId, int deskId) {
+ onRecentTasksChanged();
+ }
+
+ @Override
+ public void onActiveDeskChanged(int displayId, int newActiveDesk, int oldActiveDesk) {
+ // Should desk activation changes lead to the invalidation of the loaded tasks? The cases
+ // are:
+ // - Switching from one active desk to another.
+ // - Switching from out of a desk session into an active desk.
+ // - Switching from an active desk to a non-desk session.
+ // These changes don't affect the list of desks, nor their contents, so let's ignore them
+ // for now.
+ }
+
private void onRunningTaskAppeared(RunningTaskInfo taskInfo) {
// Make sure this task is not already in the list
for (RunningTaskInfo existingTask : mRunningTasks) {
@@ -406,7 +424,6 @@ public class RecentTasksList {
continue;
}
- // [getTaskInfo1] will not be null for types below beside [TYPE_DESK].
if (Flags.enableShellTopTaskTracking()) {
final TaskInfo taskInfo1 = rawTask.getBaseGroupedTask().getTaskInfo1();
final Task.TaskKey task1Key = new Task.TaskKey(taskInfo1);
@@ -418,8 +435,10 @@ public class RecentTasksList {
final Task.TaskKey task2Key = new Task.TaskKey(taskInfo2);
final Task task2 = Task.from(task2Key, taskInfo2,
tmpLockedUsers.get(task2Key.userId) /* isLocked */);
- allTasks.add(new SplitTask(task1, task2,
- rawTask.getBaseGroupedTask().getSplitBounds()));
+ final SplitConfigurationOptions.SplitBounds launcherSplitBounds =
+ convertShellSplitBoundsToLauncher(
+ rawTask.getBaseGroupedTask().getSplitBounds());
+ allTasks.add(new SplitTask(task1, task2, launcherSplitBounds));
} else {
allTasks.add(new SingleTask(task1));
}
@@ -456,7 +475,9 @@ public class RecentTasksList {
}
if (task2 != null) {
Objects.requireNonNull(rawTask.getSplitBounds());
- allTasks.add(new SplitTask(task1, task2, rawTask.getSplitBounds()));
+ final SplitConfigurationOptions.SplitBounds launcherSplitBounds =
+ convertShellSplitBoundsToLauncher(rawTask.getSplitBounds());
+ allTasks.add(new SplitTask(task1, task2, launcherSplitBounds));
} else {
allTasks.add(new SingleTask(task1));
}
@@ -481,7 +502,8 @@ public class RecentTasksList {
Set minimizedTaskIds = minimizedTaskIdArray != null
? CollectionsKt.toSet(ArraysKt.asIterable(minimizedTaskIdArray))
: Collections.emptySet();
- if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()) {
+ if (enableSeparateExternalDisplayTasks()
+ && !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()) {
// This code is not needed when the multiple desktop feature is enabled, since Shell
// will send a single `GroupedTaskInfo` for each desk with a unique `deskId` across
// all displays.
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index 269d3e8ce3..e1a5d7038e 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -104,7 +104,7 @@ import app.lawnchair.compat.LawnchairQuickstepCompat;
* See {@link com.android.quickstep.views.RecentsView}.
*/
public final class RecentsActivity extends StatefulActivity implements
- RecentsViewContainer, InvariantDeviceProfile.OnIDPChangeListener {
+ RecentsViewContainer {
private static final String TAG = "RecentsActivity";
public static final ContextTracker.ActivityTracker ACTIVITY_TRACKER =
@@ -136,7 +136,6 @@ public final class RecentsActivity extends StatefulActivity implem
* Init drag layer and overview panel views.
*/
protected void setupViews() {
- getTheme().applyStyle(getOverviewBlurStyleResId(), true);
SystemUiProxy systemUiProxy = SystemUiProxy.INSTANCE.get(this);
// SplitSelectStateController needs to be created before setContentView()
mSplitSelectStateController =
@@ -239,16 +238,6 @@ public final class RecentsActivity extends StatefulActivity implem
return mScrimView;
}
- @Override
- public FallbackActivityInterface getContainerInterface() {
- return FallbackActivityInterface.INSTANCE;
- }
-
- @Override
- public SplitSelectStateController getSplitSelectStateController() {
- return mSplitSelectStateController;
- }
-
@Override
public FallbackRecentsView getOverviewPanel() {
return mFallbackRecentsView;
@@ -390,10 +379,10 @@ public final class RecentsActivity extends StatefulActivity implem
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setWallpaperDependentTheme(this);
+
mStateManager = new StateManager<>(this, RecentsState.BG_LAUNCHER);
initDeviceProfile();
- InvariantDeviceProfile.INSTANCE.get(this).addOnChangeListener(this);
setupViews();
getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
@@ -479,7 +468,6 @@ public final class RecentsActivity extends StatefulActivity implem
mActivityLaunchAnimationRunner = null;
mSplitSelectStateController.onDestroy();
mTISBindHelper.onDestroy();
- InvariantDeviceProfile.INSTANCE.get(this).removeOnChangeListener(this);
}
@Override
@@ -503,7 +491,7 @@ public final class RecentsActivity extends StatefulActivity implem
this.getIApplicationThread(),
"StartHomeFromRecents"),
"Lawnchair");
- startHomeIntentSafely(this, options.toBundle(), TAG, getDisplayId());
+ startHomeIntentSafely(this, options.toBundle(), TAG);
}
private final RemoteAnimationFactory mAnimationToHomeFactory =
@@ -572,14 +560,4 @@ public final class RecentsActivity extends StatefulActivity implem
public boolean isRecentsViewVisible() {
return getStateManager().getState().isRecentsViewVisible();
}
-
- @Override
- public void onIdpChanged(boolean modelPropertiesChanged) {
- onHandleConfigurationChanged();
- }
-
- @Override
- public int getOverviewBlurStyleResId() {
- return R.style.OverviewBlurFallbackStyle;
- }
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
index cddfd29f5e..2cf7f15898 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
@@ -37,9 +37,8 @@ import androidx.annotation.UiThread;
import com.android.launcher3.Utilities;
import com.android.launcher3.util.Preconditions;
-import com.android.quickstep.fallback.window.RecentsWindowManager;
+import com.android.quickstep.fallback.window.RecentsWindowFlags;
import com.android.quickstep.util.ActiveGestureProtoLogProxy;
-import com.android.quickstep.views.RecentsViewContainer;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
@@ -59,15 +58,15 @@ public class RecentsAnimationCallbacks implements
com.android.systemui.shared.system.RecentsAnimationListener {
private final Set mListeners = new ArraySet<>();
- private final RecentsViewContainer mContainer;
+ private final SystemUiProxy mSystemUiProxy;
// TODO(141886704): Remove these references when they are no longer needed
private RecentsAnimationController mController;
private boolean mCancelled;
- public RecentsAnimationCallbacks(RecentsViewContainer container) {
- mContainer = container;
+ public RecentsAnimationCallbacks(SystemUiProxy systemUiProxy) {
+ mSystemUiProxy = systemUiProxy;
}
@UiThread
@@ -129,7 +128,7 @@ public class RecentsAnimationCallbacks implements
boolean isOpeningHome = Arrays.stream(appTargets).filter(app -> app.mode == MODE_OPENING
&& app.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME)
.count() > 0;
- if (appCount == 0 && (!(mContainer instanceof RecentsWindowManager)
+ if (appCount == 0 && (!RecentsWindowFlags.Companion.getEnableOverviewInWindow()
|| isOpeningHome)) {
ActiveGestureProtoLogProxy.logOnRecentsAnimationStartCancelled();
// Edge case, if there are no closing app targets, then Launcher has nothing to handle
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 17c4405151..865cc47091 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -57,6 +57,8 @@ public class RecentsAnimationController {
private boolean mFinishRequested = false;
// Only valid when mFinishRequested == true.
private boolean mFinishTargetIsLauncher;
+ // Only valid when mFinishRequested == true
+ private boolean mLauncherIsVisibleAtFinish;
private RunnableList mPendingFinishCallbacks = new RunnableList();
public RecentsAnimationController(RecentsAnimationControllerCompat controller,
@@ -130,14 +132,28 @@ public class RecentsAnimationController {
finishController(toRecents, onFinishComplete, sendUserLeaveHint);
}
+ @UiThread
+ public void finish(boolean toRecents, boolean launcherIsVisibleAtFinish,
+ Runnable onFinishComplete, boolean sendUserLeaveHint) {
+ Preconditions.assertUIThread();
+ finishController(toRecents, launcherIsVisibleAtFinish, onFinishComplete, sendUserLeaveHint,
+ false);
+ }
+
@UiThread
public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint) {
- finishController(toRecents, callback, sendUserLeaveHint, false /* forceFinish */);
+ finishController(toRecents, false, callback, sendUserLeaveHint, false /* forceFinish */);
}
@UiThread
public void finishController(boolean toRecents, Runnable callback, boolean sendUserLeaveHint,
boolean forceFinish) {
+ finishController(toRecents, toRecents, callback, sendUserLeaveHint, forceFinish);
+ }
+
+ @UiThread
+ public void finishController(boolean toRecents, boolean launcherIsVisibleAtFinish,
+ Runnable callback, boolean sendUserLeaveHint, boolean forceFinish) {
mPendingFinishCallbacks.add(callback);
if (!forceFinish && mFinishRequested) {
// If finish has already been requested, then add the callback to the pending list.
@@ -149,6 +165,7 @@ public class RecentsAnimationController {
// Finish not yet requested
mFinishRequested = true;
mFinishTargetIsLauncher = toRecents;
+ mLauncherIsVisibleAtFinish = launcherIsVisibleAtFinish;
mOnFinishedListener.accept(this);
Runnable finishCb = () -> {
mController.finish(toRecents, sendUserLeaveHint, new IResultReceiver.Stub() {
@@ -225,6 +242,14 @@ public class RecentsAnimationController {
return mFinishTargetIsLauncher;
}
+ /**
+ * RecentsAnimationListeners can check this in onRecentsAnimationFinished() to determine whether
+ * the animation was finished to launcher vs an app.
+ */
+ public boolean getLauncherIsVisibleAtFinish() {
+ return mLauncherIsVisibleAtFinish;
+ }
+
public void dump(String prefix, PrintWriter pw) {
pw.println(prefix + "RecentsAnimationController:");
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index a8ddbb4ed7..ebb6268f32 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -15,9 +15,10 @@
*/
package com.android.quickstep;
-import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static com.android.launcher3.MotionEventsUtils.isTrackpadScroll;
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
@@ -52,6 +53,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_T
import android.app.ActivityTaskManager;
import android.content.Context;
import android.graphics.Region;
+import android.inputmethodservice.InputMethodService;
import android.net.Uri;
import android.os.RemoteException;
import android.os.SystemProperties;
@@ -61,10 +63,12 @@ import android.view.ViewConfiguration;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import com.android.launcher3.Utilities;
-import com.android.app.displaylib.PerDisplayRepository;
import com.android.launcher3.dagger.ApplicationContext;
+import com.android.launcher3.dagger.LauncherAppComponent;
+import com.android.launcher3.dagger.LauncherAppSingleton;
import com.android.launcher3.util.DaggerSingletonObject;
import com.android.launcher3.util.DaggerSingletonTracker;
import com.android.launcher3.util.DisplayController;
@@ -73,7 +77,6 @@ import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.SettingsCache;
import com.android.quickstep.TopTaskTracker.CachedTaskInfo;
-import com.android.quickstep.dagger.QuickstepBaseAppComponent;
import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.ContextualSearchStateManager;
import com.android.quickstep.util.GestureExclusionManager;
@@ -86,17 +89,19 @@ import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.shared.system.TaskStackChangeListeners;
-import dagger.assisted.Assisted;
-import dagger.assisted.AssistedFactory;
-import dagger.assisted.AssistedInject;
-
import java.io.PrintWriter;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import javax.inject.Inject;
import app.lawnchair.LawnchairApp;
/**
* Manages the state of the system during a swipe up gesture.
*/
+@LauncherAppSingleton
public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, ExclusionListener {
static final String SUPPORT_ONE_HANDED_MODE = "ro.support_one_handed_mode";
@@ -105,19 +110,8 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
private static final float QUICKSTEP_TOUCH_SLOP_RATIO_TWO_BUTTON = 3f;
private static final float QUICKSTEP_TOUCH_SLOP_RATIO_GESTURAL = 1.414f;
- public static final DaggerSingletonObject>
- REPOSITORY_INSTANCE = new DaggerSingletonObject<>(
- QuickstepBaseAppComponent::getRecentsAnimationDeviceStateRepository);
-
- /** The SysUI state ignores trackpad, touch gestures, and keyboard shortcuts. */
- private static final long GESTURE_OR_KB_SHORTCUT_DISABLING_STATES =
- SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
- | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
- | SYSUI_STATE_QUICK_SETTINGS_EXPANDED
- | SYSUI_STATE_MAGNIFICATION_OVERLAP
- | SYSUI_STATE_DEVICE_DREAMING
- | SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION
- | SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING;
+ public static DaggerSingletonObject INSTANCE =
+ new DaggerSingletonObject<>(LauncherAppComponent::getRecentsAnimationDeviceState);
private final Context mContext;
private final DisplayController mDisplayController;
@@ -127,8 +121,11 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
private final RotationTouchHelper mRotationTouchHelper;
private final TaskStackChangeListener mPipListener;
+ // Cache for better performance since it doesn't change at runtime.
+ private final boolean mCanImeRenderGesturalNavButtons = isImeRenderingNavButtons();
private @SystemUiStateFlags long mSystemUiStateFlags = QuickStepContract.SYSUI_STATE_AWAKE;
+ private final Map mSysUIStateFlagsPerDisplay = new ConcurrentHashMap<>();
private NavigationMode mMode = THREE_BUTTONS;
private NavBarPosition mNavBarPosition;
@@ -145,20 +142,18 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
private int mGestureBlockingTaskId = -1;
private @NonNull Region mExclusionRegion = GestureExclusionManager.EMPTY_REGION;
private boolean mExclusionListenerRegistered;
- private final int mDisplayId;
- @AssistedInject
+ @VisibleForTesting
+ @Inject
RecentsAnimationDeviceState(
@ApplicationContext Context context,
- @Assisted int displayId,
- @Assisted RotationTouchHelper rotationTouchHelper,
GestureExclusionManager exclusionManager,
DisplayController displayController,
ContextualSearchStateManager contextualSearchStateManager,
+ RotationTouchHelper rotationTouchHelper,
SettingsCache settingsCache,
DaggerSingletonTracker lifeCycle) {
mContext = context;
- mDisplayId = displayId;
mDisplayController = displayController;
mExclusionManager = exclusionManager;
mContextualSearchStateManager = contextualSearchStateManager;
@@ -171,10 +166,10 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
// Register for exclusion updates
lifeCycle.addCloseable(this::unregisterExclusionListener);
}
-
+
// Register for display changes changes
mDisplayController.addChangeListener(this);
- onDisplayInfoChanged(context, mDisplayController.getInfoForDisplay(mDisplayId), CHANGE_ALL);
+ onDisplayInfoChanged(context, mDisplayController.getInfo(), CHANGE_ALL);
lifeCycle.addCloseable(() -> mDisplayController.removeChangeListener(this));
if (mIsOneHandedModeSupported) {
@@ -231,16 +226,16 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
}
/**
- * Adds a listener for the change flag, guaranteed to be called after the device state's
+ * Adds a listener for the nav mode change, guaranteed to be called after the device state's
* mode has changed.
*
* @return Added {@link DisplayInfoChangeListener} so that caller is
* responsible for removing the listener from {@link DisplayController} to avoid memory leak.
*/
- public DisplayController.DisplayInfoChangeListener addDisplayInfoChangeCallback(
- int changeFlag, Runnable callback) {
+ public DisplayController.DisplayInfoChangeListener addNavigationModeChangedCallback(
+ Runnable callback) {
DisplayController.DisplayInfoChangeListener listener = (context, info, flags) -> {
- if ((flags & changeFlag) != 0) {
+ if ((flags & CHANGE_NAVIGATION_MODE) != 0) {
callback.run();
}
};
@@ -251,7 +246,7 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
/**
* Remove the {DisplayController.DisplayInfoChangeListener} added from
- * {@link #addDisplayInfoChangeCallback} when {@link TouchInteractionService} is destroyed.
+ * {@link #addNavigationModeChangedCallback} when {@link TouchInteractionService} is destroyed.
*/
public void removeDisplayInfoChangeListener(
DisplayController.DisplayInfoChangeListener listener) {
@@ -370,28 +365,47 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
* Updates the system ui state flags from SystemUI for a specific display.
*
* @param stateFlags the current {@link SystemUiStateFlags} for the display.
+ * @param displayId the display's ID.
*/
- public void setSysUIStateFlags(@SystemUiStateFlags long stateFlags) {
- mSystemUiStateFlags = stateFlags;
+ public void setSysUIStateFlagsForDisplay(@SystemUiStateFlags long stateFlags,
+ int displayId) {
+ mSysUIStateFlagsPerDisplay.put(displayId, stateFlags);
}
/**
* Clears the system ui state flags for a specific display. This is called when the display is
* destroyed.
*
+ * @param displayId the display's ID.
*/
- public void clearSysUIStateFlags() {
- mSystemUiStateFlags = QuickStepContract.SYSUI_STATE_AWAKE;
+ public void clearSysUIStateFlagsForDisplay(int displayId) {
+ mSysUIStateFlagsPerDisplay.remove(displayId);
}
/**
- * @return the system ui state flags for this display.
+ * @return the system ui state flags for the default display.
*/
+ // TODO(141886704): See if we can remove this
@SystemUiStateFlags
- public long getSysuiStateFlags() {
- return mSystemUiStateFlags;
+ public long getSysuiStateFlag() {
+ return getSystemUiStateFlags(DEFAULT_DISPLAY);
}
+ /**
+ * @return the system ui state flags for a given display ID.
+ */
+ @SystemUiStateFlags
+ public long getSystemUiStateFlags(int displayId) {
+ return mSysUIStateFlagsPerDisplay.getOrDefault(displayId,
+ QuickStepContract.SYSUI_STATE_AWAKE);
+ }
+
+ /**
+ * @return the display ids that have sysui state.
+ */
+ public Set getDisplaysWithSysUIState() {
+ return mSysUIStateFlagsPerDisplay.keySet();
+ }
/**
* Sets the flag that indicates whether a predictive back-to-home animation is in progress
*/
@@ -410,8 +424,8 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
* @return whether SystemUI is in a state where we can start a system gesture.
*/
public boolean canStartSystemGesture() {
- boolean canStartWithNavHidden = (getSysuiStateFlags() & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
- || (getSysuiStateFlags() & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0
+ boolean canStartWithNavHidden = (getSysuiStateFlag() & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
+ || (getSysuiStateFlag() & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0
|| mRotationTouchHelper.isTaskListFrozen();
return canStartWithNavHidden && canStartAnyGesture();
}
@@ -423,27 +437,24 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
*/
public boolean canStartTrackpadGesture() {
boolean trackpadGesturesEnabled =
- (getSysuiStateFlags() & SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED) == 0;
+ (getSysuiStateFlag() & SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED) == 0;
return trackpadGesturesEnabled && canStartAnyGesture();
}
- /**
- * @return whether SystemUI is in a state that allows the overview command from being started.
- */
- public boolean canStartOverviewCommand() {
- final long sysUiStateFlags = getSysuiStateFlags();
- final boolean overviewEnabled = !isOverviewDisabled();
- return overviewEnabled && (sysUiStateFlags & GESTURE_OR_KB_SHORTCUT_DISABLING_STATES) == 0;
- }
-
/**
* Common logic to determine if either trackpad or finger gesture can be started
*/
private boolean canStartAnyGesture() {
- boolean homeOrOverviewEnabled = (getSysuiStateFlags() & SYSUI_STATE_HOME_DISABLED) == 0
- || (getSysuiStateFlags() & SYSUI_STATE_OVERVIEW_DISABLED) == 0;
- return (GESTURE_OR_KB_SHORTCUT_DISABLING_STATES & getSysuiStateFlags()) == 0
- && homeOrOverviewEnabled;
+ boolean homeOrOverviewEnabled = (getSysuiStateFlag() & SYSUI_STATE_HOME_DISABLED) == 0
+ || (getSysuiStateFlag() & SYSUI_STATE_OVERVIEW_DISABLED) == 0;
+ long gestureDisablingStates = SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
+ | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
+ | SYSUI_STATE_QUICK_SETTINGS_EXPANDED
+ | SYSUI_STATE_MAGNIFICATION_OVERLAP
+ | SYSUI_STATE_DEVICE_DREAMING
+ | SYSUI_STATE_DISABLE_GESTURE_SPLIT_INVOCATION
+ | SYSUI_STATE_DISABLE_GESTURE_PIP_ANIMATING;
+ return (gestureDisablingStates & getSysuiStateFlag()) == 0 && homeOrOverviewEnabled;
}
/**
@@ -451,35 +462,35 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
* (like camera or maps)
*/
public boolean isKeyguardShowingOccluded() {
- return (getSysuiStateFlags() & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0;
}
/**
* @return whether screen pinning is enabled and active
*/
public boolean isScreenPinningActive() {
- return (getSysuiStateFlags() & SYSUI_STATE_SCREEN_PINNING) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_SCREEN_PINNING) != 0;
}
/**
* @return whether assistant gesture is constraint
*/
public boolean isAssistantGestureIsConstrained() {
- return (getSysuiStateFlags() & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0;
}
/**
* @return whether the bubble stack is expanded
*/
public boolean isBubblesExpanded() {
- return (getSysuiStateFlags() & SYSUI_STATE_BUBBLES_EXPANDED) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_BUBBLES_EXPANDED) != 0;
}
/**
* @return whether the global actions dialog is showing
*/
public boolean isSystemUiDialogShowing() {
- return (getSysuiStateFlags() & SYSUI_STATE_DIALOG_SHOWING) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_DIALOG_SHOWING) != 0;
}
/**
@@ -493,35 +504,35 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
* @return whether the accessibility menu is available.
*/
public boolean isAccessibilityMenuAvailable() {
- return (getSysuiStateFlags() & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0;
}
/**
* @return whether the accessibility menu shortcut is available.
*/
public boolean isAccessibilityMenuShortcutAvailable() {
- return (getSysuiStateFlags() & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0;
}
/**
* @return whether home is disabled (either by SUW/SysUI/device policy)
*/
public boolean isHomeDisabled() {
- return (getSysuiStateFlags() & SYSUI_STATE_HOME_DISABLED) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_HOME_DISABLED) != 0;
}
/**
* @return whether overview is disabled (either by SUW/SysUI/device policy)
*/
public boolean isOverviewDisabled() {
- return (getSysuiStateFlags() & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_OVERVIEW_DISABLED) != 0;
}
/**
* @return whether one-handed mode is enabled and active
*/
public boolean isOneHandedModeActive() {
- return (getSysuiStateFlags() & SYSUI_STATE_ONE_HANDED_ACTIVE) != 0;
+ return (getSysuiStateFlag() & SYSUI_STATE_ONE_HANDED_ACTIVE) != 0;
}
/**
@@ -584,7 +595,7 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
*/
public boolean canTriggerAssistantAction(MotionEvent ev) {
return mAssistantAvailable
- && !QuickStepContract.isAssistantGestureDisabled(getSysuiStateFlags())
+ && !QuickStepContract.isAssistantGestureDisabled(getSysuiStateFlag())
&& mRotationTouchHelper.touchInAssistantRegion(ev)
&& !isTrackpadScroll(ev)
&& !isLockToAppActive();
@@ -602,7 +613,7 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
}
if (mIsOneHandedModeEnabled) {
- final Info displayInfo = mDisplayController.getInfoForDisplay(mDisplayId);
+ final Info displayInfo = mDisplayController.getInfo();
return (mRotationTouchHelper.touchInOneHandedModeRegion(ev)
&& (displayInfo.currentSize.x < displayInfo.currentSize.y));
}
@@ -623,7 +634,8 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
/** Returns whether IME is rendering nav buttons, and IME is currently showing. */
public boolean isImeRenderingNavButtons() {
- return mMode == NO_BUTTON && ((getSysuiStateFlags() & SYSUI_STATE_IME_VISIBLE) != 0);
+ return mCanImeRenderGesturalNavButtons && mMode == NO_BUTTON
+ && ((getSysuiStateFlag() & SYSUI_STATE_IME_VISIBLE) != 0);
}
/**
@@ -657,7 +669,7 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
/** Returns a string representation of the system ui state flags for the default display. */
public String getSystemUiStateString() {
- return getSystemUiStateString(getSysuiStateFlags());
+ return getSystemUiStateString(getSysuiStateFlag());
}
/** Returns a string representation of the system ui state flags. */
@@ -668,30 +680,24 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener, E
public void dump(PrintWriter pw) {
pw.println("DeviceState:");
pw.println(" canStartSystemGesture=" + canStartSystemGesture());
- pw.println(" systemUiFlagsForDefaultDisplay=" + getSysuiStateFlags());
+ pw.println(" systemUiFlagsForDefaultDisplay=" + getSysuiStateFlag());
pw.println(" systemUiFlagsDesc=" + getSystemUiStateString());
pw.println(" assistantAvailable=" + mAssistantAvailable);
pw.println(" assistantDisabled="
- + QuickStepContract.isAssistantGestureDisabled(getSysuiStateFlags()));
+ + QuickStepContract.isAssistantGestureDisabled(getSysuiStateFlag()));
pw.println(" isOneHandedModeEnabled=" + mIsOneHandedModeEnabled);
pw.println(" isSwipeToNotificationEnabled=" + mIsSwipeToNotificationEnabled);
pw.println(" deferredGestureRegion=" + mDeferredGestureRegion.getBounds());
pw.println(" exclusionRegion=" + mExclusionRegion.getBounds());
pw.println(" pipIsActive=" + mPipIsActive);
pw.println(" predictiveBackToHomeInProgress=" + mIsPredictiveBackToHomeInProgress);
+ for (int displayId : mSysUIStateFlagsPerDisplay.keySet()) {
+ pw.println(" systemUiFlagsForDisplay" + displayId + "=" + getSystemUiStateFlags(
+ displayId));
+ pw.println(" systemUiFlagsForDisplay" + displayId + "Desc=" + getSystemUiStateString(
+ getSystemUiStateFlags(displayId)));
+ }
pw.println(" RotationTouchHelper:");
mRotationTouchHelper.dump(pw);
}
-
- public int getDisplayId() {
- return mDisplayId;
- }
-
- @AssistedFactory
- public interface Factory {
- /** Creates a new instance of [RecentsAnimationDeviceState] for a given [displayId] and
- * [rotationTouchHelper]. */
- RecentsAnimationDeviceState create(int displayId, RotationTouchHelper rotationTouchHelper);
- }
-
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
index 60b5337893..0deb1ca953 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java
@@ -55,11 +55,14 @@ public class RecentsAnimationTargets extends RemoteAnimationTargets {
*
* @return {@code true} if at least one target app is a desktop task
*/
- // TODO: b/362720309 - Remove this function once multi-desks is fully launched.
public boolean hasDesktopTasks(Context context) {
if (!DesktopModeStatus.canEnterDesktopMode(context)) {
return false;
}
+ // TODO: b/400866688 - Check if we need to update this such that for an empty desk, we
+ // receive a list of apps that contain only the Launcher and the `DesktopWallpaperActivity`
+ // and both are fullscreen windowing mode. A desk can also have transparent modals and
+ // immersive apps which may not have a "freeform" windowing mode.
for (RemoteAnimationTarget target : apps) {
if (target.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
return true;
diff --git a/quickstep/src/com/android/quickstep/RecentsFilterState.java b/quickstep/src/com/android/quickstep/RecentsFilterState.java
index fa12d52032..1808a9769f 100644
--- a/quickstep/src/com/android/quickstep/RecentsFilterState.java
+++ b/quickstep/src/com/android/quickstep/RecentsFilterState.java
@@ -16,8 +16,6 @@
package com.android.quickstep;
-import static com.android.quickstep.fallback.window.RecentsWindowFlags.enableOverviewOnConnectedDisplays;
-
import androidx.annotation.Nullable;
import com.android.quickstep.util.DesksUtils;
@@ -122,17 +120,14 @@ public class RecentsFilterState {
* @param packageName package name to filter GroupTasks by
* if null, Predicate filters out desktop tasks with no non-minimized tasks,
* unless the multiple desks feature is enabled, which allows empty desks.
- * @param displayId filter out tasks not on this display
*/
- public static Predicate getFilter(@Nullable String packageName, int displayId) {
- Predicate filter = getDesktopTaskFilter();
- if (packageName != null) {
- filter = filter.and(groupTask -> groupTask.containsPackage(packageName));
+ public static Predicate getFilter(@Nullable String packageName) {
+ if (packageName == null) {
+ return getDesktopTaskFilter();
}
- if (enableOverviewOnConnectedDisplays()) {
- filter = filter.and(groupTask -> groupTask.matchesDisplayId(displayId));
- }
- return filter;
+
+ return (groupTask) -> (groupTask.containsPackage(packageName)
+ && shouldKeepGroupTask(groupTask));
}
/**
@@ -140,7 +135,7 @@ public class RecentsFilterState {
* unless the multiple desks feature is enabled, which allows empty desks.
*/
public static Predicate getDesktopTaskFilter() {
- return RecentsFilterState::shouldKeepGroupTask;
+ return (groupTask -> shouldKeepGroupTask(groupTask));
}
/**
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 96689e2866..eb032ffc7e 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -17,7 +17,7 @@ package com.android.quickstep;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
-import static com.android.launcher3.util.OverviewReleaseFlags.enableGridOnlyOverview;
+import static com.android.launcher3.Flags.enableGridOnlyOverview;
import static com.android.launcher3.Flags.enableRefactorTaskThumbnail;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
@@ -43,6 +43,7 @@ import com.android.launcher3.dagger.LauncherAppSingleton;
import com.android.launcher3.graphics.ThemeManager;
import com.android.launcher3.graphics.ThemeManager.ThemeChangeListener;
import com.android.launcher3.icons.IconProvider;
+import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.util.DaggerSingletonObject;
import com.android.launcher3.util.DaggerSingletonTracker;
import com.android.launcher3.util.DisplayController;
@@ -69,7 +70,6 @@ import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
-import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -96,17 +96,6 @@ public class RecentsModel implements RecentTasksDataSource, TaskStackChangeListe
private final ConcurrentLinkedQueue mThumbnailChangeListeners =
new ConcurrentLinkedQueue<>();
- private final ConcurrentLinkedQueue mRecentTasksChangedListeners =
- new ConcurrentLinkedQueue<>();
- private final RecentTasksChangedListener mRecentTasksListObserver =
- new RecentTasksChangedListener() {
- @Override
- public void onRecentTasksChanged() {
- mRecentTasksChangedListeners.forEach(
- RecentTasksChangedListener::onRecentTasksChanged);
- }
- };
-
private final Context mContext;
private final RecentTasksList mTaskList;
private final TaskIconCache mIconCache;
@@ -119,12 +108,14 @@ public class RecentsModel implements RecentTasksDataSource, TaskStackChangeListe
DisplayController displayController,
LockedUserState lockedUserState,
Lazy themeManagerLazy,
+ DesktopVisibilityController desktopVisibilityController,
DaggerSingletonTracker tracker
) {
// Lazily inject the ThemeManager and access themeManager once the device is
// unlocked. See b/393248495 for details.
this(context, new IconProvider(context), systemUiProxy, topTaskTracker,
- displayController, lockedUserState, themeManagerLazy, tracker);
+ displayController, lockedUserState, themeManagerLazy, desktopVisibilityController,
+ tracker);
}
@SuppressLint("VisibleForTests")
@@ -135,6 +126,7 @@ public class RecentsModel implements RecentTasksDataSource, TaskStackChangeListe
DisplayController displayController,
LockedUserState lockedUserState,
Lazy themeManagerLazy,
+ DesktopVisibilityController desktopVisibilityController,
DaggerSingletonTracker tracker) {
this(context,
new RecentTasksList(
@@ -142,7 +134,7 @@ public class RecentsModel implements RecentTasksDataSource, TaskStackChangeListe
MAIN_EXECUTOR,
context.getSystemService(KeyguardManager.class),
systemUiProxy,
- topTaskTracker, tracker),
+ topTaskTracker, desktopVisibilityController, tracker),
new TaskIconCache(context, RECENTS_MODEL_EXECUTOR, iconProvider, displayController),
new TaskThumbnailCache(context, RECENTS_MODEL_EXECUTOR),
iconProvider,
@@ -164,7 +156,6 @@ public class RecentsModel implements RecentTasksDataSource, TaskStackChangeListe
DaggerSingletonTracker tracker) {
mContext = context;
mTaskList = taskList;
- mTaskList.registerRecentTasksChangedListener(mRecentTasksListObserver);
mIconCache = iconCache;
mIconCache.registerTaskVisualsChangeListener(this);
mThumbnailCache = thumbnailCache;
@@ -192,10 +183,10 @@ public class RecentsModel implements RecentTasksDataSource, TaskStackChangeListe
Runnable unlockCallback = () -> themeManagerLazy.get().addChangeListener(this);
lockedUserState.runOnUserUnlocked(unlockCallback);
+ // Lawnchair-TODO-Merge-High: taskStackChangeListeners run when isRecentsEnabled
tracker.addCloseable(() -> {
if (LawnchairApp.isRecentsEnabled()) {
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(this);
- mTaskList.unregisterRecentTasksChangedListener();
}
iconChangeCloseable.close();
mIconCache.removeTaskVisualsChangeListener();
@@ -232,28 +223,14 @@ public class RecentsModel implements RecentTasksDataSource, TaskStackChangeListe
/**
* Fetches the list of recent tasks, based on a filter
*
- * @param filter Returns true if a GroupTask should be included into the list passed into
- * callback.
* @param callback The callback to receive the task plan once its complete or null. This is
- * always called on the UI thread.
- * @return the request id associated with this call.
- */
- public int getTasks(Predicate filter, @Nullable Consumer> callback) {
- return mTaskList.getTasks(false /* loadKeysOnly */, callback, filter);
- }
-
- /**
- * Fetches the list of recent tasks, based on a filter
- *
- * @param callback The callback to receive the task plan and request ID once its complete or
- * null. This is always called on the UI thread.
+ * always called on the UI thread.
* @param filter Returns true if a GroupTask should be included into the list passed into
* callback.
* @return the request id associated with this call.
*/
- public int getTasks(
- @Nullable BiConsumer, Integer> callback, Predicate filter) {
- return mTaskList.getTasks(/* loadKeysOnly= */ false, callback, filter);
+ public int getTasks(@Nullable Consumer> callback, Predicate filter) {
+ return mTaskList.getTasks(false /* loadKeysOnly */, callback, filter);
}
/**
@@ -413,14 +390,14 @@ public class RecentsModel implements RecentTasksDataSource, TaskStackChangeListe
* Registers a listener for recent tasks
*/
public void registerRecentTasksChangedListener(RecentTasksChangedListener listener) {
- mRecentTasksChangedListeners.add(listener);
+ mTaskList.registerRecentTasksChangedListener(listener);
}
/**
* Removes the previously registered running tasks listener
*/
- public void unregisterRecentTasksChangedListener(RecentTasksChangedListener listener) {
- mRecentTasksChangedListeners.remove(listener);
+ public void unregisterRecentTasksChangedListener() {
+ mTaskList.unregisterRecentTasksChangedListener();
}
/**
diff --git a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
index 60b1ff3e4d..0bb825f317 100644
--- a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
+++ b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java
@@ -20,12 +20,10 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import android.os.Bundle;
-import android.util.Log;
import android.view.RemoteAnimationTarget;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -33,8 +31,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/
public class RemoteAnimationTargets {
- private static final String TAG = "RemoteAnimationTargets";
-
private final CopyOnWriteArrayList mReleaseChecks = new CopyOnWriteArrayList<>();
public final RemoteAnimationTarget[] unfilteredApps;
@@ -83,8 +79,6 @@ public class RemoteAnimationTargets {
return target;
}
}
- Log.e(TAG, "taskId: " + taskId + " not found. apps contains: "
- + Arrays.stream(apps).map(target -> target.taskId).toList());
return null;
}
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
index e6e39e0a52..e38b89aec6 100644
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
@@ -16,7 +16,7 @@
package com.android.quickstep;
-import static com.android.wm.shell.shared.desktopmode.DesktopModeStatus.enableMultipleDesktops;
+import static com.android.quickstep.util.SplitScreenUtils.convertShellSplitBoundsToLauncher;
import static com.android.wm.shell.shared.split.SplitBounds.KEY_EXTRA_SPLIT_BOUNDS;
import static java.util.stream.Collectors.toList;
@@ -32,14 +32,12 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.launcher3.statehandlers.DesktopVisibilityController;
+import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.TaskViewSimulator;
import com.android.quickstep.util.TransformParams;
-import com.android.wm.shell.shared.GroupedTaskInfo;
import com.android.wm.shell.shared.split.SplitBounds;
-import kotlin.collections.CollectionsKt;
-
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -54,68 +52,56 @@ public class RemoteTargetGluer {
// This is the default number of handles to create when we don't know how many tasks are running
// (e.g. if we're in split screen). Allocate extra for potential tasks overlaid, like volume.
- private static final int DEFAULT_NUM_HANDLES = 10;
+ private static final int DEFAULT_NUM_HANDLES = 4;
+
private RemoteTargetHandle[] mRemoteTargetHandles;
- private SplitBounds mSplitBounds;
+ private SplitConfigurationOptions.SplitBounds mSplitBounds;
/**
* Use this constructor if remote targets are split-screen independent
*/
public RemoteTargetGluer(Context context, BaseContainerInterface sizingStrategy,
RemoteAnimationTargets targets, boolean forDesktop) {
- mRemoteTargetHandles = createHandles(context, sizingStrategy, forDesktop,
- targets.apps.length);
+ init(context, sizingStrategy, targets.apps.length, forDesktop);
}
/**
* Use this constructor if you want the number of handles created to match the number of active
* running tasks
*/
- public RemoteTargetGluer(Context context, BaseContainerInterface sizingStrategy,
- @Nullable GroupedTaskInfo groupedTaskInfo) {
- if (enableMultipleDesktops(context)) {
- if (groupedTaskInfo != null && groupedTaskInfo.isBaseType(GroupedTaskInfo.TYPE_DESK)) {
- // Allocate +1 to account for the DesktopWallpaperActivity added to the desk.
- int numHandles = groupedTaskInfo.getTaskInfoList().size() + 1;
- mRemoteTargetHandles = createHandles(context, sizingStrategy,
- /* forDesktop = */ true, numHandles);
- return;
- }
- } else {
- int visibleTasksCount = DesktopVisibilityController.INSTANCE.get(context)
- .getVisibleDesktopTasksCountDeprecated();
- if (visibleTasksCount > 0) {
- // Allocate +1 to account for the DesktopWallpaperActivity added to the desk.
- int numHandles = visibleTasksCount + 1;
- mRemoteTargetHandles = createHandles(context, sizingStrategy,
- /* forDesktop = */ true, numHandles);
- return;
- }
+ public RemoteTargetGluer(Context context, BaseContainerInterface sizingStrategy) {
+ // TODO: b/403344864 Make sure init with correct number of RemoteTargetHandle with
+ // multi-desks feature enabled as well.
+ int visibleTasksCount = DesktopVisibilityController.INSTANCE.get(context)
+ .getVisibleDesktopTasksCountDeprecated();
+ if (visibleTasksCount > 0) {
+ // Allocate +1 to account for a new task added to the desktop mode
+ int numHandles = visibleTasksCount + 1;
+ init(context, sizingStrategy, numHandles, true /* forDesktop */);
+ return;
}
// Assume 2 handles needed for split, scale down as needed later on when we actually
// get remote targets
- mRemoteTargetHandles = createHandles(context, sizingStrategy, /* forDesktop = */ false,
- DEFAULT_NUM_HANDLES);
+ init(context, sizingStrategy, DEFAULT_NUM_HANDLES, false /* forDesktop */);
+ }
+
+ private void init(Context context, BaseContainerInterface sizingStrategy, int numHandles,
+ boolean forDesktop) {
+ mRemoteTargetHandles = createHandles(context, sizingStrategy, numHandles, forDesktop);
}
private RemoteTargetHandle[] createHandles(Context context,
- BaseContainerInterface sizingStrategy, boolean forDesktop, int numHandles) {
+ BaseContainerInterface sizingStrategy, int numHandles, boolean forDesktop) {
RemoteTargetHandle[] handles = new RemoteTargetHandle[numHandles];
for (int i = 0; i < numHandles; i++) {
- handles[i] = createHandle(context, sizingStrategy, forDesktop, i);
+ TaskViewSimulator tvs = new TaskViewSimulator(context, sizingStrategy, forDesktop , i);
+ TransformParams transformParams = new TransformParams();
+ handles[i] = new RemoteTargetHandle(tvs, transformParams);
}
return handles;
}
- private RemoteTargetHandle createHandle(Context context,
- BaseContainerInterface sizingStrategy, boolean forDesktop, int taskIndex) {
- TaskViewSimulator tvs = new TaskViewSimulator(
- context, sizingStrategy, forDesktop , taskIndex);
- TransformParams transformParams = new TransformParams();
- return new RemoteTargetHandle(tvs, transformParams);
- }
-
/**
* Pairs together {@link TaskViewSimulator}s and {@link TransformParams} into a
* {@link RemoteTargetHandle}
@@ -140,7 +126,7 @@ public class RemoteTargetGluer {
* information specified.
*/
public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets,
- SplitBounds splitBounds) {
+ SplitConfigurationOptions.SplitBounds splitBounds) {
mSplitBounds = splitBounds;
return assignTargetsForSplitScreen(targets);
}
@@ -151,13 +137,19 @@ public class RemoteTargetGluer {
* the left/top task, index 1 right/bottom.
*/
public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets) {
+ resizeRemoteTargetHandles(targets);
+
// If we are in a true split screen case (2 apps running on screen), either:
// a) mSplitBounds was already set (from the clicked GroupedTaskView)
// b) A SplitBounds was passed up from shell (via AbsSwipeUpHandler)
// If both of these are null, we are in a 1-app or 1-app-plus-assistant case.
if (mSplitBounds == null && targets.extras != null
&& targets.extras.containsKey(KEY_EXTRA_SPLIT_BOUNDS)) {
- mSplitBounds = targets.extras.getParcelable(KEY_EXTRA_SPLIT_BOUNDS, SplitBounds.class);
+ SplitBounds shellSplitBounds = targets.extras.getParcelable(KEY_EXTRA_SPLIT_BOUNDS,
+ SplitBounds.class);
+ if (shellSplitBounds != null) {
+ mSplitBounds = convertShellSplitBoundsToLauncher(shellSplitBounds);
+ }
}
boolean containsSplitTargets = mSplitBounds != null;
@@ -165,78 +157,66 @@ public class RemoteTargetGluer {
mRemoteTargetHandles.length + " appsLength: " + targets.apps.length);
if (mRemoteTargetHandles.length == 1) {
- resizeRemoteTargetHandles(targets);
// Single fullscreen app
// If we're not in split screen, the splitIds count doesn't really matter since we
// should always hit this case.
- setRemoteTargetHandle(targets,
- targets.apps.length > 0 ? targets.apps[0] : null,
- /* targetsToExclude = */ null, /* transitionInfo = */ null,
- /* splitBounds = */ null, /* taskIndex = */ 0);
+ mRemoteTargetHandles[0].mTransformParams.setTargetSet(targets);
+ if (targets.apps.length > 0) {
+ // Unclear why/when target.apps length == 0, but it sure does happen :(
+ mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(targets.apps[0], null);
+ }
} else if (!containsSplitTargets) {
- resizeRemoteTargetHandles(targets);
// Single App + Assistant
for (int i = 0; i < mRemoteTargetHandles.length; i++) {
- setRemoteTargetHandle(targets, targets.apps[i], /* targetsToExclude = */ null,
- /* transitionInfo = */ null, /* splitBounds = */ null, /* taskIndex = */ i);
+ mRemoteTargetHandles[i].mTransformParams.setTargetSet(targets);
+ mRemoteTargetHandles[i].mTaskViewSimulator.setPreview(targets.apps[i], null);
+ }
+ } else {
+ // Split apps (+ maybe assistant)
+ RemoteAnimationTarget topLeftTarget = targets.findTask(mSplitBounds.leftTopTaskId);
+ RemoteAnimationTarget bottomRightTarget = targets.findTask(
+ mSplitBounds.rightBottomTaskId);
+ List overlayTargets = Arrays.stream(targets.apps).filter(
+ target -> target.windowConfiguration.getWindowingMode()
+ != WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW).collect(toList());
+
+ // remoteTargetHandle[0] denotes topLeft task, so we pass in the bottomRight to exclude,
+ // vice versa
+ mRemoteTargetHandles[0].mTransformParams.setTargetSet(
+ createRemoteAnimationTargetsForTarget(targets,
+ Collections.singletonList(bottomRightTarget)));
+ mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(topLeftTarget, mSplitBounds);
+
+ mRemoteTargetHandles[1].mTransformParams.setTargetSet(
+ createRemoteAnimationTargetsForTarget(targets,
+ Collections.singletonList(topLeftTarget)));
+ mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(bottomRightTarget, mSplitBounds);
+
+ // Set the remaining overlay tasks to be their own TaskViewSimulator as fullscreen tasks
+ if (!overlayTargets.isEmpty()) {
+ ArrayList targetsToExclude = new ArrayList<>();
+ targetsToExclude.add(topLeftTarget);
+ targetsToExclude.add(bottomRightTarget);
+ // Start i at 2 to account for top/left and bottom/right split handles already made
+ for (int i = 2; i < targets.apps.length; i++) {
+ if (i >= mRemoteTargetHandles.length) {
+ Log.e(TAG, String.format("Attempting to animate an untracked target"
+ + " (%d handles allocated, but %d want to animate)",
+ mRemoteTargetHandles.length, targets.apps.length));
+ break;
+ }
+ mRemoteTargetHandles[i].mTransformParams.setTargetSet(
+ createRemoteAnimationTargetsForTarget(targets, targetsToExclude));
+ mRemoteTargetHandles[i].mTaskViewSimulator.setPreview(
+ overlayTargets.get(i - 2));
+ }
+
}
- } else if (mSplitBounds != null) {
- setSplitRemoteTargetHandles(targets);
}
return mRemoteTargetHandles;
}
- private void setSplitRemoteTargetHandles(RemoteAnimationTargets targets) {
- // Split apps (+ maybe assistant)
- final List leftTopTargetIds = mSplitBounds.leftTopTaskIds;
- final List rightBottomTargetIds = mSplitBounds.rightBottomTaskIds;
- if (leftTopTargetIds.isEmpty() || rightBottomTargetIds.isEmpty()) {
- throw new IllegalStateException("The target ids is invalid: mSplitBounds = "
- + mSplitBounds);
- }
- final List