Merge "Don't use mock TaskViewTransitions in BubblesTest" into udc-qpr-dev
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 40ea276..6d14440 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -63,6 +63,7 @@
import com.android.wm.shell.transition.Transitions
import com.android.wm.shell.util.KtProtoLog
import com.android.wm.shell.windowdecor.DesktopModeWindowDecoration
+import com.android.wm.shell.windowdecor.MoveToDesktopAnimator
import java.io.PrintWriter
import java.util.concurrent.Executor
import java.util.function.Consumer
@@ -204,7 +205,11 @@
* Moves a single task to freeform and sets the taskBounds to the passed in bounds,
* startBounds
*/
- fun moveToFreeform(taskInfo: RunningTaskInfo, startBounds: Rect) {
+ fun moveToFreeform(
+ taskInfo: RunningTaskInfo,
+ startBounds: Rect,
+ dragToDesktopValueAnimator: MoveToDesktopAnimator
+ ) {
KtProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: moveToFreeform with bounds taskId=%d",
@@ -216,8 +221,8 @@
wct.setBounds(taskInfo.token, startBounds)
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- enterDesktopTaskTransitionHandler.startTransition(
- Transitions.TRANSIT_ENTER_FREEFORM, wct, mOnAnimationFinishedCallback)
+ enterDesktopTaskTransitionHandler.startMoveToFreeformAnimation(wct,
+ dragToDesktopValueAnimator, mOnAnimationFinishedCallback)
} else {
shellTaskOrganizer.applyTransaction(wct)
}
@@ -270,7 +275,7 @@
* Move a task to fullscreen after being dragged from fullscreen and released back into
* status bar area
*/
- fun cancelMoveToFreeform(task: RunningTaskInfo, position: Point) {
+ fun cancelMoveToFreeform(task: RunningTaskInfo, moveToDesktopAnimator: MoveToDesktopAnimator) {
KtProtoLog.v(
WM_SHELL_DESKTOP_MODE,
"DesktopTasksController: cancelMoveToFreeform taskId=%d",
@@ -280,8 +285,8 @@
wct.setBounds(task.token, null)
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
- enterDesktopTaskTransitionHandler.startCancelMoveToDesktopMode(
- wct, position) { t ->
+ enterDesktopTaskTransitionHandler.startCancelMoveToDesktopMode(wct,
+ moveToDesktopAnimator) { t ->
val callbackWCT = WindowContainerTransaction()
visualIndicator?.releaseVisualIndicator(t)
visualIndicator = null
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
index 3e175f3..650cac5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandler.java
@@ -22,9 +22,10 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.app.ActivityManager;
-import android.graphics.Point;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.os.IBinder;
+import android.util.Slog;
import android.view.SurfaceControl;
import android.view.WindowManager;
import android.window.TransitionInfo;
@@ -35,6 +36,7 @@
import androidx.annotation.Nullable;
import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.windowdecor.MoveToDesktopAnimator;
import java.util.ArrayList;
import java.util.List;
@@ -47,18 +49,17 @@
*/
public class EnterDesktopTaskTransitionHandler implements Transitions.TransitionHandler {
+ private static final String TAG = "EnterDesktopTaskTransitionHandler";
private final Transitions mTransitions;
private final Supplier<SurfaceControl.Transaction> mTransactionSupplier;
- // The size of the screen during drag relative to the fullscreen size
- public static final float DRAG_FREEFORM_SCALE = 0.4f;
// The size of the screen after drag relative to the fullscreen size
public static final float FINAL_FREEFORM_SCALE = 0.6f;
public static final int FREEFORM_ANIMATION_DURATION = 336;
private final List<IBinder> mPendingTransitionTokens = new ArrayList<>();
- private Point mPosition;
private Consumer<SurfaceControl.Transaction> mOnAnimationFinishedCallback;
+ private MoveToDesktopAnimator mMoveToDesktopAnimator;
public EnterDesktopTaskTransitionHandler(
Transitions transitions) {
@@ -87,15 +88,30 @@
}
/**
+ * Starts Transition of type TRANSIT_ENTER_FREEFORM
+ * @param wct WindowContainerTransaction for transition
+ * @param moveToDesktopAnimator Animator that shrinks and positions task during two part move
+ * to desktop animation
+ * @param onAnimationEndCallback to be called after animation
+ */
+ public void startMoveToFreeformAnimation(@NonNull WindowContainerTransaction wct,
+ @NonNull MoveToDesktopAnimator moveToDesktopAnimator,
+ Consumer<SurfaceControl.Transaction> onAnimationEndCallback) {
+ mMoveToDesktopAnimator = moveToDesktopAnimator;
+ startTransition(Transitions.TRANSIT_ENTER_FREEFORM, wct, onAnimationEndCallback);
+ }
+
+ /**
* Starts Transition of type TRANSIT_CANCEL_ENTERING_DESKTOP_MODE
* @param wct WindowContainerTransaction for transition
- * @param position Position of task when transition is triggered
+ * @param moveToDesktopAnimator Animator that shrinks and positions task during two part move
+ * to desktop animation
* @param onAnimationEndCallback to be called after animation
*/
public void startCancelMoveToDesktopMode(@NonNull WindowContainerTransaction wct,
- Point position,
+ MoveToDesktopAnimator moveToDesktopAnimator,
Consumer<SurfaceControl.Transaction> onAnimationEndCallback) {
- mPosition = position;
+ mMoveToDesktopAnimator = moveToDesktopAnimator;
startTransition(Transitions.TRANSIT_CANCEL_ENTERING_DESKTOP_MODE, wct,
onAnimationEndCallback);
}
@@ -145,9 +161,23 @@
// to null and we don't require an animation
final SurfaceControl sc = change.getLeash();
startT.setWindowCrop(sc, null);
+
+ if (mMoveToDesktopAnimator == null
+ || mMoveToDesktopAnimator.getTaskId() != change.getTaskInfo().taskId) {
+ Slog.e(TAG, "No animator available for this transition");
+ return false;
+ }
+
+ // Calculate and set position of the task
+ final PointF position = mMoveToDesktopAnimator.getPosition();
+ startT.setPosition(sc, position.x, position.y);
+ finishT.setPosition(sc, position.x, position.y);
+
startT.apply();
+
mTransitions.getMainExecutor().execute(
() -> finishCallback.onTransitionFinished(null, null));
+
return true;
}
@@ -162,12 +192,18 @@
endBounds.height());
startT.apply();
+ // End the animation that shrinks the window when task is first dragged from fullscreen
+ if (mMoveToDesktopAnimator != null) {
+ mMoveToDesktopAnimator.endAnimator();
+ }
+
// We want to find the scale of the current bounds relative to the end bounds. The
// task is currently scaled to DRAG_FREEFORM_SCALE and the final bounds will be
// scaled to FINAL_FREEFORM_SCALE. So, it is scaled to
// DRAG_FREEFORM_SCALE / FINAL_FREEFORM_SCALE relative to the freeform bounds
final ValueAnimator animator =
- ValueAnimator.ofFloat(DRAG_FREEFORM_SCALE / FINAL_FREEFORM_SCALE, 1f);
+ ValueAnimator.ofFloat(
+ MoveToDesktopAnimator.DRAG_FREEFORM_SCALE / FINAL_FREEFORM_SCALE, 1f);
animator.setDuration(FREEFORM_ANIMATION_DURATION);
final SurfaceControl.Transaction t = mTransactionSupplier.get();
animator.addUpdateListener(animation -> {
@@ -199,8 +235,7 @@
}
if (type == Transitions.TRANSIT_CANCEL_ENTERING_DESKTOP_MODE
- && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM
- && mPosition != null) {
+ && taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) {
// This Transition animates a task to fullscreen after being dragged from the status
// bar and then released back into the status bar area
final SurfaceControl sc = change.getLeash();
@@ -210,13 +245,27 @@
.setWindowCrop(sc, endBounds.width(), endBounds.height())
.apply();
+ if (mMoveToDesktopAnimator == null
+ || mMoveToDesktopAnimator.getTaskId() != change.getTaskInfo().taskId) {
+ Slog.e(TAG, "No animator available for this transition");
+ return false;
+ }
+
+ // End the animation that shrinks the window when task is first dragged from fullscreen
+ mMoveToDesktopAnimator.endAnimator();
+
final ValueAnimator animator = new ValueAnimator();
- animator.setFloatValues(DRAG_FREEFORM_SCALE, 1f);
+ animator.setFloatValues(MoveToDesktopAnimator.DRAG_FREEFORM_SCALE, 1f);
animator.setDuration(FREEFORM_ANIMATION_DURATION);
final SurfaceControl.Transaction t = mTransactionSupplier.get();
+
+ // Get position of the task
+ final float x = mMoveToDesktopAnimator.getPosition().x;
+ final float y = mMoveToDesktopAnimator.getPosition().y;
+
animator.addUpdateListener(animation -> {
final float scale = (float) animation.getAnimatedValue();
- t.setPosition(sc, mPosition.x * (1 - scale), mPosition.y * (1 - scale))
+ t.setPosition(sc, x * (1 - scale), y * (1 - scale))
.setScale(sc, scale, scale)
.show(sc)
.apply();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
index 837f118..39b6675 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -573,10 +573,12 @@
}
final boolean isRootTask = taskInfo != null
&& TransitionInfo.isIndependent(change, info);
+ final boolean isRecentsTask = mRecentsTask != null
+ && mRecentsTask.equals(change.getContainer());
hasTaskChange = hasTaskChange || isRootTask;
final boolean isLeafTask = leafTaskFilter.test(change);
if (TransitionUtil.isOpeningType(change.getMode())) {
- if (mRecentsTask != null && mRecentsTask.equals(change.getContainer())) {
+ if (isRecentsTask) {
recentsOpening = change;
} else if (isRootTask || isLeafTask) {
if (isLeafTask && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
@@ -591,7 +593,7 @@
openingTaskIsLeafs.add(isLeafTask ? 1 : 0);
}
} else if (TransitionUtil.isClosingType(change.getMode())) {
- if (mRecentsTask != null && mRecentsTask.equals(change.getContainer())) {
+ if (isRecentsTask) {
foundRecentsClosing = true;
} else if (isRootTask || isLeafTask) {
if (closingTasks == null) {
@@ -612,7 +614,7 @@
if (!TransitionUtil.isOrderOnly(change) && isLeafTask) {
hasChangingApp = true;
} else if (isLeafTask && taskInfo.topActivityType == ACTIVITY_TYPE_HOME
- && !mRecentsTask.equals(change.getContainer())) {
+ && !isRecentsTask ) {
// Unless it is a 3p launcher. This means that the 3p launcher was already
// visible (eg. the "pausing" task is translucent over the 3p launcher).
// Treat it as if we are "re-opening" the 3p launcher.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index 7245bc9..14f2f9b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -24,9 +24,9 @@
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT;
import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
-import static com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.DRAG_FREEFORM_SCALE;
import static com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FINAL_FREEFORM_SCALE;
import static com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FREEFORM_ANIMATION_DURATION;
+import static com.android.wm.shell.windowdecor.MoveToDesktopAnimator.DRAG_FREEFORM_SCALE;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -112,9 +112,8 @@
private SplitScreenController mSplitScreenController;
- private ValueAnimator mDragToDesktopValueAnimator;
+ private MoveToDesktopAnimator mMoveToDesktopAnimator;
private final Rect mDragToDesktopAnimationStartBounds = new Rect();
- private boolean mDragToDesktopAnimationStarted;
public DesktopModeWindowDecorViewModel(
Context context,
@@ -233,7 +232,6 @@
removeTaskFromEventReceiver(oldTaskInfo.displayId);
incrementEventReceiverTasks(taskInfo.displayId);
}
-
decoration.relayout(taskInfo);
}
@@ -599,7 +597,7 @@
}
case MotionEvent.ACTION_UP: {
if (relevantDecor == null) {
- mDragToDesktopAnimationStarted = false;
+ mMoveToDesktopAnimator = null;
mTransitionDragActive = false;
return;
}
@@ -613,14 +611,14 @@
} else if (DesktopModeStatus.isProto1Enabled()) {
mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
}
- mDragToDesktopAnimationStarted = false;
+ mMoveToDesktopAnimator = null;
return;
- } else if (mDragToDesktopAnimationStarted) {
- Point position = new Point((int) ev.getX(), (int) ev.getY());
+ } else if (mMoveToDesktopAnimator != null) {
relevantDecor.incrementRelayoutBlock();
mDesktopTasksController.ifPresent(
- c -> c.cancelMoveToFreeform(relevantDecor.mTaskInfo, position));
- mDragToDesktopAnimationStarted = false;
+ c -> c.cancelMoveToFreeform(relevantDecor.mTaskInfo,
+ mMoveToDesktopAnimator));
+ mMoveToDesktopAnimator = null;
return;
}
}
@@ -640,21 +638,19 @@
final int statusBarHeight = getStatusBarHeight(
relevantDecor.mTaskInfo.displayId);
if (ev.getY() > statusBarHeight) {
- if (!mDragToDesktopAnimationStarted) {
- mDragToDesktopAnimationStarted = true;
+ if (mMoveToDesktopAnimator == null) {
+ mMoveToDesktopAnimator = new MoveToDesktopAnimator(
+ mDragToDesktopAnimationStartBounds, relevantDecor.mTaskInfo,
+ relevantDecor.mTaskSurface);
mDesktopTasksController.ifPresent(
c -> c.moveToFreeform(relevantDecor.mTaskInfo,
- mDragToDesktopAnimationStartBounds));
- startAnimation(relevantDecor);
+ mDragToDesktopAnimationStartBounds,
+ mMoveToDesktopAnimator));
+ mMoveToDesktopAnimator.startAnimation();
}
}
- if (mDragToDesktopAnimationStarted) {
- Transaction t = mTransactionFactory.get();
- float width = (float) mDragToDesktopValueAnimator.getAnimatedValue()
- * mDragToDesktopAnimationStartBounds.width();
- float x = ev.getX() - (width / 2);
- t.setPosition(relevantDecor.mTaskSurface, x, ev.getY());
- t.apply();
+ if (mMoveToDesktopAnimator != null) {
+ mMoveToDesktopAnimator.updatePosition(ev);
}
}
break;
@@ -662,7 +658,7 @@
case MotionEvent.ACTION_CANCEL: {
mTransitionDragActive = false;
- mDragToDesktopAnimationStarted = false;
+ mMoveToDesktopAnimator = null;
}
}
}
@@ -729,20 +725,6 @@
animator.start();
}
- private void startAnimation(@NonNull DesktopModeWindowDecoration focusedDecor) {
- mDragToDesktopValueAnimator = ValueAnimator.ofFloat(1f, DRAG_FREEFORM_SCALE);
- mDragToDesktopValueAnimator.setDuration(FREEFORM_ANIMATION_DURATION);
- final Transaction t = mTransactionFactory.get();
- mDragToDesktopValueAnimator.addUpdateListener(animation -> {
- final float animatorValue = (float) animation.getAnimatedValue();
- SurfaceControl sc = focusedDecor.mTaskSurface;
- t.setScale(sc, animatorValue, animatorValue);
- t.apply();
- });
-
- mDragToDesktopValueAnimator.start();
- }
-
@Nullable
private DesktopModeWindowDecoration getRelevantWindowDecor(MotionEvent ev) {
if (mSplitScreenController != null && mSplitScreenController.isSplitScreenVisible()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
new file mode 100644
index 0000000..b2267dd
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MoveToDesktopAnimator.kt
@@ -0,0 +1,72 @@
+package com.android.wm.shell.windowdecor
+
+import android.animation.ValueAnimator
+import android.app.ActivityManager.RunningTaskInfo
+import android.graphics.PointF
+import android.graphics.Rect
+import android.view.MotionEvent
+import android.view.SurfaceControl
+
+/**
+ * Creates an animator to shrink and position task after a user drags a fullscreen task from
+ * the top of the screen to transition it into freeform and before the user releases the task. The
+ * MoveToDesktopAnimator object also holds information about the state of the task that are
+ * accessed by the EnterDesktopTaskTransitionHandler.
+ */
+class MoveToDesktopAnimator @JvmOverloads constructor(
+ private val startBounds: Rect,
+ private val taskInfo: RunningTaskInfo,
+ private val taskSurface: SurfaceControl,
+ private val transactionFactory: () -> SurfaceControl.Transaction =
+ SurfaceControl::Transaction
+) {
+ companion object {
+ // The size of the screen during drag relative to the fullscreen size
+ const val DRAG_FREEFORM_SCALE: Float = 0.4f
+ const val ANIMATION_DURATION = 336
+ }
+
+ private val animatedTaskWidth
+ get() = dragToDesktopAnimator.animatedValue as Float * startBounds.width()
+ private val dragToDesktopAnimator: ValueAnimator = ValueAnimator.ofFloat(1f,
+ DRAG_FREEFORM_SCALE)
+ .setDuration(ANIMATION_DURATION.toLong())
+ .apply {
+ val t = SurfaceControl.Transaction()
+ addUpdateListener { animation ->
+ val animatorValue = animation.animatedValue as Float
+ t.setScale(taskSurface, animatorValue, animatorValue)
+ .apply()
+ }
+ }
+
+ val taskId get() = taskInfo.taskId
+ val position: PointF = PointF(0.0f, 0.0f)
+
+ /**
+ * Starts the animation that scales the task down.
+ */
+ fun startAnimation() {
+ dragToDesktopAnimator.start()
+ }
+
+ /**
+ * Uses the position of the motion event and the current scale of the task as defined by the
+ * ValueAnimator to update the local position variable and set the task surface's position
+ */
+ fun updatePosition(ev: MotionEvent) {
+ position.x = ev.x - animatedTaskWidth / 2
+ position.y = ev.y
+
+ val t = transactionFactory()
+ t.setPosition(taskSurface, position.x, position.y)
+ t.apply()
+ }
+
+ /**
+ * Ends the animation, setting the scale and position to the final animation value
+ */
+ fun endAnimator() {
+ dragToDesktopAnimator.end()
+ }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandlerTest.java
index 8592dea..c6642f3 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/EnterDesktopTaskTransitionHandlerTest.java
@@ -28,6 +28,7 @@
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.WindowConfiguration;
+import android.graphics.PointF;
import android.graphics.Rect;
import android.os.IBinder;
import android.view.SurfaceControl;
@@ -41,6 +42,7 @@
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.windowdecor.MoveToDesktopAnimator;
import junit.framework.AssertionFailedError;
@@ -73,6 +75,10 @@
ShellExecutor mExecutor;
@Mock
SurfaceControl mSurfaceControl;
+ @Mock
+ MoveToDesktopAnimator mMoveToDesktopAnimator;
+ @Mock
+ PointF mPosition;
private EnterDesktopTaskTransitionHandler mEnterDesktopTaskTransitionHandler;
@@ -82,6 +88,7 @@
doReturn(mExecutor).when(mTransitions).getMainExecutor();
doReturn(mAnimationT).when(mTransactionFactory).get();
+ doReturn(mPosition).when(mMoveToDesktopAnimator).getPosition();
mEnterDesktopTaskTransitionHandler = new EnterDesktopTaskTransitionHandler(mTransitions,
mTransactionFactory);
@@ -89,12 +96,15 @@
@Test
public void testEnterFreeformAnimation() {
- final int transitionType = Transitions.TRANSIT_ENTER_FREEFORM;
final int taskId = 1;
WindowContainerTransaction wct = new WindowContainerTransaction();
doReturn(mToken).when(mTransitions)
- .startTransition(transitionType, wct, mEnterDesktopTaskTransitionHandler);
- mEnterDesktopTaskTransitionHandler.startTransition(transitionType, wct, null);
+ .startTransition(Transitions.TRANSIT_ENTER_FREEFORM, wct,
+ mEnterDesktopTaskTransitionHandler);
+ doReturn(taskId).when(mMoveToDesktopAnimator).getTaskId();
+
+ mEnterDesktopTaskTransitionHandler.startMoveToFreeformAnimation(wct,
+ mMoveToDesktopAnimator, null);
TransitionInfo.Change change =
createChange(WindowManager.TRANSIT_CHANGE, taskId, WINDOWING_MODE_FREEFORM);
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index 6abe951..cf26b1c 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -89,7 +89,7 @@
// TODO(b/277338665): Tracking Bug
@JvmField
val NOTIFICATION_SHELF_REFACTOR =
- unreleasedFlag(271161129, "notification_shelf_refactor")
+ unreleasedFlag(271161129, "notification_shelf_refactor", teamfood = true)
// TODO(b/288326013): Tracking Bug
@JvmField
@@ -146,6 +146,14 @@
val LOCKSCREEN_WITHOUT_SECURE_LOCK_WHEN_DREAMING = releasedFlag(208,
"lockscreen_without_secure_lock_when_dreaming")
+ // TODO(b/286092087): Tracking Bug
+ @JvmField
+ val ENABLE_SYSTEM_UI_DREAM_CONTROLLER = unreleasedFlag(301, "enable_system_ui_dream_controller")
+
+ // TODO(b/288287730): Tracking Bug
+ @JvmField
+ val ENABLE_SYSTEM_UI_DREAM_HOSTING = unreleasedFlag(302, "enable_system_ui_dream_hosting")
+
/**
* Whether the clock on a wide lock screen should use the new "stepping" animation for moving
* the digits when the clock moves.
@@ -559,6 +567,12 @@
val WALLPAPER_MULTI_CROP =
sysPropBooleanFlag(1118, "persist.wm.debug.wallpaper_multi_crop", default = false)
+ // TODO(b/290220798): Tracking Bug
+ @Keep
+ @JvmField
+ val ENABLE_PIP2_IMPLEMENTATION =
+ sysPropBooleanFlag(1119, "persist.wm.debug.enable_pip2_implementation", default = false)
+
// 1200 - predictive back
@Keep
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
index 6b993ce..a2bb950 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/pipeline/MediaDataManager.kt
@@ -1253,6 +1253,9 @@
return try {
val options = BroadcastOptions.makeBasic()
options.setInteractive(true)
+ options.setPendingIntentBackgroundActivityStartMode(
+ BroadcastOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED
+ )
intent.send(options.toBundle())
true
} catch (e: PendingIntent.CanceledException) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index 35082fd..a978b92 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -23,6 +23,7 @@
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
+import android.app.ActivityOptions;
import android.app.BroadcastOptions;
import android.app.PendingIntent;
import android.app.WallpaperColors;
@@ -535,7 +536,10 @@
mLockscreenUserManager.getCurrentUserId());
if (showOverLockscreen) {
try {
- clickIntent.send();
+ ActivityOptions opts = ActivityOptions.makeBasic();
+ opts.setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ clickIntent.send(opts.toBundle());
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, "Pending intent for " + key + " was cancelled");
}
@@ -684,6 +688,8 @@
try {
BroadcastOptions options = BroadcastOptions.makeBasic();
options.setInteractive(true);
+ options.setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
deviceIntent.send(options.toBundle());
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, "Device pending intent was canceled");
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
index 3aefcb3..7e234ae 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ActionProxyReceiver.java
@@ -71,6 +71,8 @@
ActivityOptions opts = ActivityOptions.makeBasic();
opts.setDisallowEnterPictureInPictureWhileLaunching(
intent.getBooleanExtra(EXTRA_DISALLOW_ENTER_PIP, false));
+ opts.setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
try {
actionIntent.send(context, 0, null, null, null, null, opts.toBundle());
if (intent.getBooleanExtra(ScreenshotController.EXTRA_OVERRIDE_TRANSITION, false)) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java b/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java
index 13678b0..9e8ea3a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/OverlayActionChip.java
@@ -99,6 +99,8 @@
try {
BroadcastOptions options = BroadcastOptions.makeBasic();
options.setInteractive(true);
+ options.setPendingIntentBackgroundActivityStartMode(
+ BroadcastOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
intent.send(options.toBundle());
finisher.run();
} catch (PendingIntent.CanceledException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsReceiver.java
index 9761f59..ef58b9d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsReceiver.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/SmartActionsReceiver.java
@@ -55,7 +55,8 @@
Log.d(TAG, "Executing smart action [" + actionType + "]:" + pendingIntent.getIntent());
}
ActivityOptions opts = ActivityOptions.makeBasic();
-
+ opts.setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
try {
pendingIntent.send(context, 0, fillIn, null, null, null, opts.toBundle());
} catch (PendingIntent.CanceledException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index e6e3e7e..ea5ca27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -19,6 +19,7 @@
import static com.android.systemui.DejankUtils.whitelistIpcs;
+import android.app.ActivityOptions;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.admin.DevicePolicyManager;
@@ -158,7 +159,11 @@
final String notificationKey = intent.getStringExtra(Intent.EXTRA_INDEX);
if (intentSender != null) {
try {
- mContext.startIntentSender(intentSender, null, 0, 0, 0);
+ ActivityOptions options = ActivityOptions.makeBasic();
+ options.setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ mContext.startIntentSender(intentSender, null, 0, 0, 0,
+ options.toBundle());
} catch (IntentSender.SendIntentException e) {
/* ignore */
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index 0d3dfae..8902a18 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -42,6 +42,7 @@
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
import android.app.IWallpaperManager;
import android.app.KeyguardManager;
import android.app.Notification;
@@ -1773,7 +1774,10 @@
EventLog.writeEvent(EventLogTags.SYSUI_HEADS_UP_ESCALATION,
sbn.getKey());
wakeUpForFullScreenIntent();
- notification.fullScreenIntent.send();
+ ActivityOptions opts = ActivityOptions.makeBasic();
+ opts.setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ notification.fullScreenIntent.send(opts.toBundle());
entry.notifyFullScreenIntentLaunched();
} catch (PendingIntent.CanceledException e) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
index 22b4c9d..736b145 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.policy
+import android.app.ActivityOptions
import android.app.Notification
import android.app.PendingIntent
import android.app.RemoteInput
@@ -275,7 +276,10 @@
entry.sbn.instanceId)
try {
- pendingIntent.send(view.context, 0, intent)
+ val options = ActivityOptions.makeBasic()
+ options.setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+ pendingIntent.send(view.context, 0, intent, null, null, null, options.toBundle())
} catch (e: PendingIntent.CanceledException) {
Log.i(TAG, "Unable to send remote input result", e)
uiEventLogger.logWithInstanceId(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
index cac5e32..1776e5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.policy
+import android.app.ActivityOptions
import android.app.Notification
import android.app.Notification.Action.SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY
import android.app.PendingIntent
@@ -491,7 +492,11 @@
entry.setHasSentReply()
try {
val intent = createRemoteInputIntent(smartReplies, choice)
- smartReplies.pendingIntent.send(context, 0, intent)
+ val opts = ActivityOptions.makeBasic()
+ opts.setPendingIntentBackgroundActivityStartMode(
+ ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
+ smartReplies.pendingIntent.send(context, 0, intent, /* onFinished */null,
+ /* handler */ null, /* requiredPermission */ null, opts.toBundle())
} catch (e: PendingIntent.CanceledException) {
Log.w(TAG, "Unable to send smart reply", e)
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java
index 3362097..fd7c30f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/notifications/TvNotificationAdapter.java
@@ -103,6 +103,8 @@
if (mPendingIntent != null) {
BroadcastOptions options = BroadcastOptions.makeBasic();
options.setInteractive(true);
+ options.setPendingIntentBackgroundActivityStartMode(
+ BroadcastOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
mPendingIntent.send(options.toBundle());
}
} catch (PendingIntent.CanceledException e) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index f902be3..dc771d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -1793,7 +1793,7 @@
// THEN it sends the PendingIntent without dismissing keyguard first,
// and does not use the Intent directly (see b/271845008)
captor.value.onClick(viewHolder.player)
- verify(pendingIntent).send()
+ verify(pendingIntent).send(any(Bundle::class.java))
verify(pendingIntent, never()).getIntent()
verify(activityStarter, never()).postStartActivityDismissingKeyguard(eq(clickIntent), any())
}