summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/window/TransitionRequestInfo.java70
-rw-r--r--data/etc/services.core.protolog.json18
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java12
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java28
-rw-r--r--services/core/java/com/android/server/wm/Task.java9
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java19
-rw-r--r--services/core/java/com/android/server/wm/Transition.java17
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java18
8 files changed, 155 insertions, 36 deletions
diff --git a/core/java/android/window/TransitionRequestInfo.java b/core/java/android/window/TransitionRequestInfo.java
index edea2978c340..9b10a7ff5d12 100644
--- a/core/java/android/window/TransitionRequestInfo.java
+++ b/core/java/android/window/TransitionRequestInfo.java
@@ -36,11 +36,17 @@ public final class TransitionRequestInfo implements Parcelable {
private final @WindowManager.TransitionType int mType;
/**
- * If non-null, If non-null, the task containing the activity whose lifecycle change (start or
+ * If non-null, the task containing the activity whose lifecycle change (start or
* finish) has caused this transition to occur.
*/
private @Nullable ActivityManager.RunningTaskInfo mTriggerTask;
+ /**
+ * If non-null, the task containing the pip activity that participates in this
+ * transition.
+ */
+ private @Nullable ActivityManager.RunningTaskInfo mPipTask;
+
/** If non-null, a remote-transition associated with the source of this transition. */
private @Nullable RemoteTransition mRemoteTransition;
@@ -59,7 +65,8 @@ public final class TransitionRequestInfo implements Parcelable {
@WindowManager.TransitionType int type,
@Nullable ActivityManager.RunningTaskInfo triggerTask,
@Nullable RemoteTransition remoteTransition) {
- this(type, triggerTask, remoteTransition, null /* displayChange */, 0 /* flags */);
+ this(type, triggerTask, null /* pipTask */,
+ remoteTransition, null /* displayChange */, 0 /* flags */);
}
/** constructor override */
@@ -68,7 +75,17 @@ public final class TransitionRequestInfo implements Parcelable {
@Nullable ActivityManager.RunningTaskInfo triggerTask,
@Nullable RemoteTransition remoteTransition,
int flags) {
- this(type, triggerTask, remoteTransition, null /* displayChange */, flags);
+ this(type, triggerTask, null /* pipTask */,
+ remoteTransition, null /* displayChange */, flags);
+ }
+
+ public TransitionRequestInfo(
+ @WindowManager.TransitionType int type,
+ @Nullable ActivityManager.RunningTaskInfo triggerTask,
+ @Nullable RemoteTransition remoteTransition,
+ @Nullable TransitionRequestInfo.DisplayChange displayChange,
+ int flags) {
+ this(type, triggerTask, null /* pipTask */, remoteTransition, displayChange, flags);
}
/** Requested change to a display. */
@@ -246,7 +263,7 @@ public final class TransitionRequestInfo implements Parcelable {
};
@DataClass.Generated(
- time = 1691627678294L,
+ time = 1693425051905L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java",
inputSignatures = "private final int mDisplayId\nprivate @android.annotation.Nullable android.graphics.Rect mStartAbsBounds\nprivate @android.annotation.Nullable android.graphics.Rect mEndAbsBounds\nprivate int mStartRotation\nprivate int mEndRotation\nprivate boolean mPhysicalDisplayChanged\nclass DisplayChange extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genBuilder=false, genConstructor=false)")
@@ -283,6 +300,9 @@ public final class TransitionRequestInfo implements Parcelable {
* @param triggerTask
* If non-null, If non-null, the task containing the activity whose lifecycle change (start or
* finish) has caused this transition to occur.
+ * @param pipTask
+ * If non-null, If non-null, the task containing the activity whose lifecycle change (start or
+ * finish) has caused this transition to occur.
* @param remoteTransition
* If non-null, a remote-transition associated with the source of this transition.
* @param displayChange
@@ -296,6 +316,7 @@ public final class TransitionRequestInfo implements Parcelable {
public TransitionRequestInfo(
@WindowManager.TransitionType int type,
@Nullable ActivityManager.RunningTaskInfo triggerTask,
+ @Nullable ActivityManager.RunningTaskInfo pipTask,
@Nullable RemoteTransition remoteTransition,
@Nullable TransitionRequestInfo.DisplayChange displayChange,
int flags) {
@@ -303,6 +324,7 @@ public final class TransitionRequestInfo implements Parcelable {
com.android.internal.util.AnnotationValidations.validate(
WindowManager.TransitionType.class, null, mType);
this.mTriggerTask = triggerTask;
+ this.mPipTask = pipTask;
this.mRemoteTransition = remoteTransition;
this.mDisplayChange = displayChange;
this.mFlags = flags;
@@ -319,7 +341,7 @@ public final class TransitionRequestInfo implements Parcelable {
}
/**
- * If non-null, If non-null, the task containing the activity whose lifecycle change (start or
+ * If non-null, the task containing the activity whose lifecycle change (start or
* finish) has caused this transition to occur.
*/
@DataClass.Generated.Member
@@ -328,6 +350,15 @@ public final class TransitionRequestInfo implements Parcelable {
}
/**
+ * If non-null, the task containing the pip activity that participates in this
+ * transition.
+ */
+ @DataClass.Generated.Member
+ public @Nullable ActivityManager.RunningTaskInfo getPipTask() {
+ return mPipTask;
+ }
+
+ /**
* If non-null, a remote-transition associated with the source of this transition.
*/
@DataClass.Generated.Member
@@ -354,7 +385,7 @@ public final class TransitionRequestInfo implements Parcelable {
}
/**
- * If non-null, If non-null, the task containing the activity whose lifecycle change (start or
+ * If non-null, the task containing the activity whose lifecycle change (start or
* finish) has caused this transition to occur.
*/
@DataClass.Generated.Member
@@ -364,6 +395,16 @@ public final class TransitionRequestInfo implements Parcelable {
}
/**
+ * If non-null, the task containing the pip activity that participates in this
+ * transition.
+ */
+ @DataClass.Generated.Member
+ public @android.annotation.NonNull TransitionRequestInfo setPipTask(@android.annotation.NonNull ActivityManager.RunningTaskInfo value) {
+ mPipTask = value;
+ return this;
+ }
+
+ /**
* If non-null, a remote-transition associated with the source of this transition.
*/
@DataClass.Generated.Member
@@ -392,6 +433,7 @@ public final class TransitionRequestInfo implements Parcelable {
return "TransitionRequestInfo { " +
"type = " + mType + ", " +
"triggerTask = " + mTriggerTask + ", " +
+ "pipTask = " + mPipTask + ", " +
"remoteTransition = " + mRemoteTransition + ", " +
"displayChange = " + mDisplayChange + ", " +
"flags = " + mFlags +
@@ -406,11 +448,13 @@ public final class TransitionRequestInfo implements Parcelable {
byte flg = 0;
if (mTriggerTask != null) flg |= 0x2;
- if (mRemoteTransition != null) flg |= 0x4;
- if (mDisplayChange != null) flg |= 0x8;
+ if (mPipTask != null) flg |= 0x4;
+ if (mRemoteTransition != null) flg |= 0x8;
+ if (mDisplayChange != null) flg |= 0x10;
dest.writeByte(flg);
dest.writeInt(mType);
if (mTriggerTask != null) dest.writeTypedObject(mTriggerTask, flags);
+ if (mPipTask != null) dest.writeTypedObject(mPipTask, flags);
if (mRemoteTransition != null) dest.writeTypedObject(mRemoteTransition, flags);
if (mDisplayChange != null) dest.writeTypedObject(mDisplayChange, flags);
dest.writeInt(mFlags);
@@ -430,14 +474,16 @@ public final class TransitionRequestInfo implements Parcelable {
byte flg = in.readByte();
int type = in.readInt();
ActivityManager.RunningTaskInfo triggerTask = (flg & 0x2) == 0 ? null : (ActivityManager.RunningTaskInfo) in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
- RemoteTransition remoteTransition = (flg & 0x4) == 0 ? null : (RemoteTransition) in.readTypedObject(RemoteTransition.CREATOR);
- TransitionRequestInfo.DisplayChange displayChange = (flg & 0x8) == 0 ? null : (TransitionRequestInfo.DisplayChange) in.readTypedObject(TransitionRequestInfo.DisplayChange.CREATOR);
+ ActivityManager.RunningTaskInfo pipTask = (flg & 0x4) == 0 ? null : (ActivityManager.RunningTaskInfo) in.readTypedObject(ActivityManager.RunningTaskInfo.CREATOR);
+ RemoteTransition remoteTransition = (flg & 0x8) == 0 ? null : (RemoteTransition) in.readTypedObject(RemoteTransition.CREATOR);
+ TransitionRequestInfo.DisplayChange displayChange = (flg & 0x10) == 0 ? null : (TransitionRequestInfo.DisplayChange) in.readTypedObject(TransitionRequestInfo.DisplayChange.CREATOR);
int flags = in.readInt();
this.mType = type;
com.android.internal.util.AnnotationValidations.validate(
WindowManager.TransitionType.class, null, mType);
this.mTriggerTask = triggerTask;
+ this.mPipTask = pipTask;
this.mRemoteTransition = remoteTransition;
this.mDisplayChange = displayChange;
this.mFlags = flags;
@@ -460,10 +506,10 @@ public final class TransitionRequestInfo implements Parcelable {
};
@DataClass.Generated(
- time = 1691627678327L,
+ time = 1693425051928L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/window/TransitionRequestInfo.java",
- inputSignatures = "private final @android.view.WindowManager.TransitionType int mType\nprivate @android.annotation.Nullable android.app.ActivityManager.RunningTaskInfo mTriggerTask\nprivate @android.annotation.Nullable android.window.RemoteTransition mRemoteTransition\nprivate @android.annotation.Nullable android.window.TransitionRequestInfo.DisplayChange mDisplayChange\nprivate final int mFlags\nclass TransitionRequestInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genAidl=true)")
+ inputSignatures = "private final @android.view.WindowManager.TransitionType int mType\nprivate @android.annotation.Nullable android.app.ActivityManager.RunningTaskInfo mTriggerTask\nprivate @android.annotation.Nullable android.app.ActivityManager.RunningTaskInfo mPipTask\nprivate @android.annotation.Nullable android.window.RemoteTransition mRemoteTransition\nprivate @android.annotation.Nullable android.window.TransitionRequestInfo.DisplayChange mDisplayChange\nprivate final int mFlags\nclass TransitionRequestInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genToString=true, genSetters=true, genAidl=true)")
@Deprecated
private void __metadata() {}
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 6057852a7e4b..f72cc1d9f3d2 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -2401,6 +2401,12 @@
"group": "WM_DEBUG_TASKS",
"at": "com\/android\/server\/wm\/RootWindowContainer.java"
},
+ "61363198": {
+ "message": "Auto-PIP allowed, requesting PIP mode via requestStartTransition(): %s, willAutoPip: %b",
+ "level": "DEBUG",
+ "group": "WM_DEBUG_STATES",
+ "at": "com\/android\/server\/wm\/TaskFragment.java"
+ },
"74885950": {
"message": "Waiting for top state to be released by %s",
"level": "VERBOSE",
@@ -2413,12 +2419,6 @@
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
"at": "com\/android\/server\/wm\/RecentsAnimationController.java"
},
- "90764070": {
- "message": "Could not report token removal to the window token client.",
- "level": "WARN",
- "group": "WM_ERROR",
- "at": "com\/android\/server\/wm\/WindowContextListenerController.java"
- },
"95216706": {
"message": "hideIme target: %s ",
"level": "DEBUG",
@@ -4333,12 +4333,6 @@
"group": "WM_DEBUG_TASKS",
"at": "com\/android\/server\/wm\/RootWindowContainer.java"
},
- "1948483534": {
- "message": "Could not report config changes to the window token client.",
- "level": "WARN",
- "group": "WM_ERROR",
- "at": "com\/android\/server\/wm\/WindowContextListenerController.java"
- },
"1964565370": {
"message": "Starting remote animation",
"level": "INFO",
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 60854885d5bb..590dbda19c67 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -566,8 +566,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
boolean forceNewConfig; // force re-create with new config next time
boolean supportsEnterPipOnTaskSwitch; // This flag is set by the system to indicate that the
// activity can enter picture in picture while pausing (only when switching to another task)
+ // The PiP params used when deferring the entering of picture-in-picture.
PictureInPictureParams pictureInPictureArgs = new PictureInPictureParams.Builder().build();
- // The PiP params used when deferring the entering of picture-in-picture.
boolean shouldDockBigOverlays;
int launchCount; // count of launches since last state
long lastLaunchTime; // time of last launch of this activity
@@ -1733,6 +1733,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mAnimatingActivityRegistry = registry;
}
+ boolean canAutoEnterPip() {
+ // beforeStopping=false since the actual pip-ing will take place after startPausing()
+ final boolean activityCanPip = checkEnterPictureInPictureState(
+ "startActivityUnchecked", false /* beforeStopping */);
+
+ // check if this activity is about to auto-enter pip
+ return activityCanPip && pictureInPictureArgs != null
+ && pictureInPictureArgs.isAutoEnterEnabled();
+ }
+
/**
* Sets {@link #mLastParentBeforePip} to the current parent Task, it's caller's job to ensure
* {@link #getTask()} is set before this is called.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 42c363085017..52f8997ba76a 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -314,6 +314,8 @@ import java.util.Set;
public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
private static final String GRAMMATICAL_GENDER_PROPERTY = "persist.sys.grammatical_gender";
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_ATM;
+ private static final String ENABLE_PIP2_IMPLEMENTATION =
+ "persist.wm.debug.enable_pip2_implementation";
static final String TAG_ROOT_TASK = TAG + POSTFIX_ROOT_TASK;
static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
@@ -3608,6 +3610,28 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
}
+ /**
+ * Prepare to enter PiP mode after {@link TransitionController#requestStartTransition}.
+ *
+ * @param r activity auto entering pip
+ * @return true if the activity is about to auto-enter pip or is already in pip mode.
+ */
+ boolean prepareAutoEnterPictureAndPictureMode(ActivityRecord r) {
+ // If the activity is already in picture in picture mode, then just return early
+ if (r.inPinnedWindowingMode()) {
+ return true;
+ }
+
+ if (r.canAutoEnterPip() && getTransitionController().getCollectingTransition() != null) {
+ // This will be used later to construct TransitionRequestInfo for Shell to resolve.
+ // It will also be passed into a direct moveActivityToPinnedRootTask() call via
+ // startTransition()
+ getTransitionController().getCollectingTransition().setPipActivity(r);
+ return true;
+ }
+ return false;
+ }
+
boolean enterPictureInPictureMode(@NonNull ActivityRecord r,
@NonNull PictureInPictureParams params, boolean fromClient) {
return enterPictureInPictureMode(r, params, fromClient, false /* isAutoEnter */);
@@ -7164,4 +7188,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
ActivityTaskManagerService.this.unregisterTaskStackListener(listener);
}
}
+
+ static boolean isPip2ExperimentEnabled() {
+ return SystemProperties.getBoolean(ENABLE_PIP2_IMPLEMENTATION, false);
+ }
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 387a8767ced3..fbbba5a2edec 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -5107,7 +5107,6 @@ class Task extends TaskFragment {
void startActivityLocked(ActivityRecord r, @Nullable Task topTask, boolean newTask,
boolean isTaskSwitch, ActivityOptions options, @Nullable ActivityRecord sourceRecord) {
- final ActivityRecord pipCandidate = findEnterPipOnTaskSwitchCandidate(topTask);
Task rTask = r.getTask();
final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
final boolean isOrhasTask = rTask == this || hasChild(rTask);
@@ -5171,8 +5170,10 @@ class Task extends TaskFragment {
// supporting picture-in-picture while pausing only if the starting activity
// would not be considered an overlay on top of the current activity
// (eg. not fullscreen, or the assistant)
- enableEnterPipOnTaskSwitch(pipCandidate,
- null /* toFrontTask */, r, options);
+ if (!ActivityTaskManagerService.isPip2ExperimentEnabled()) {
+ final ActivityRecord pipCandidate = findEnterPipOnTaskSwitchCandidate(topTask);
+ enableEnterPipOnTaskSwitch(pipCandidate, null /* toFrontTask */, r, options);
+ }
}
boolean doShow = true;
if (newTask) {
@@ -5245,7 +5246,7 @@ class Task extends TaskFragment {
* enter PiP while it is pausing (if supported). Only one of {@param toFrontTask} or
* {@param toFrontActivity} should be set.
*/
- private static void enableEnterPipOnTaskSwitch(@Nullable ActivityRecord pipCandidate,
+ static void enableEnterPipOnTaskSwitch(@Nullable ActivityRecord pipCandidate,
@Nullable Task toFrontTask, @Nullable ActivityRecord toFrontActivity,
@Nullable ActivityOptions opts) {
if (pipCandidate == null) {
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 6dc896a92e52..10efb3bee8ef 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1643,7 +1643,17 @@ class TaskFragment extends WindowContainer<WindowContainer> {
// next activity.
final boolean lastResumedCanPip = prev.checkEnterPictureInPictureState(
"shouldAutoPipWhilePausing", userLeaving);
- if (userLeaving && resumingOccludesParent && lastResumedCanPip
+
+ if (ActivityTaskManagerService.isPip2ExperimentEnabled()) {
+ // If a new task is being launched, then mark the existing top activity as
+ // supporting picture-in-picture while pausing only if the starting activity
+ // would not be considered an overlay on top of the current activity
+ // (eg. not fullscreen, or the assistant)
+ Task.enableEnterPipOnTaskSwitch(prev, resuming.getTask(),
+ resuming, resuming.getOptions());
+ }
+ if (prev.supportsEnterPipOnTaskSwitch && userLeaving
+ && resumingOccludesParent && lastResumedCanPip
&& prev.pictureInPictureArgs.isAutoEnterEnabled()) {
shouldAutoPip = true;
} else if (!lastResumedCanPip) {
@@ -1656,7 +1666,12 @@ class TaskFragment extends WindowContainer<WindowContainer> {
}
if (prev.attachedToProcess()) {
- if (shouldAutoPip) {
+ if (shouldAutoPip && ActivityTaskManagerService.isPip2ExperimentEnabled()) {
+ prev.mPauseSchedulePendingForPip = true;
+ boolean willAutoPip = mAtmService.prepareAutoEnterPictureAndPictureMode(prev);
+ ProtoLog.d(WM_DEBUG_STATES, "Auto-PIP allowed, requesting PIP mode "
+ + "via requestStartTransition(): %s, willAutoPip: %b", prev, willAutoPip);
+ } else if (shouldAutoPip) {
prev.mPauseSchedulePendingForPip = true;
boolean didAutoPip = mAtmService.enterPictureInPictureMode(
prev, prev.pictureInPictureArgs, false /* fromClient */);
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 81f91c739bc3..218580b04462 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -174,6 +174,8 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
private final Token mToken;
private IApplicationThread mRemoteAnimApp;
+ private @Nullable ActivityRecord mPipActivity;
+
/** Only use for clean-up after binder death! */
private SurfaceControl.Transaction mStartTransaction = null;
private SurfaceControl.Transaction mFinishTransaction = null;
@@ -509,6 +511,21 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
}
/**
+ * Set the pip-able activity participating in this transition.
+ * @param pipActivity activity about to enter pip
+ */
+ void setPipActivity(@Nullable ActivityRecord pipActivity) {
+ mPipActivity = pipActivity;
+ }
+
+ /**
+ * @return pip-able activity participating in this transition.
+ */
+ @Nullable ActivityRecord getPipActivity() {
+ return mPipActivity;
+ }
+
+ /**
* Only set flag to the parent tasks and activity itself.
*/
private void setTransientLaunchToChanges(@NonNull WindowContainer wc) {
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index e4b9571d0028..b53f1f39b8c2 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -705,13 +705,21 @@ class TransitionController {
try {
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
"Requesting StartTransition: %s", transition);
- ActivityManager.RunningTaskInfo info = null;
+ ActivityManager.RunningTaskInfo startTaskInfo = null;
+ ActivityManager.RunningTaskInfo pipTaskInfo = null;
if (startTask != null) {
- info = new ActivityManager.RunningTaskInfo();
- startTask.fillTaskInfo(info);
+ startTaskInfo = startTask.getTaskInfo();
}
- final TransitionRequestInfo request = new TransitionRequestInfo(
- transition.mType, info, remoteTransition, displayChange, transition.getFlags());
+
+ // set the pip task in the request if provided
+ if (mCollectingTransition.getPipActivity() != null) {
+ pipTaskInfo = mCollectingTransition.getPipActivity().getTask().getTaskInfo();
+ }
+
+ final TransitionRequestInfo request = new TransitionRequestInfo(transition.mType,
+ startTaskInfo, pipTaskInfo, remoteTransition, displayChange,
+ transition.getFlags());
+
transition.mLogger.mRequestTimeNs = SystemClock.elapsedRealtimeNanos();
transition.mLogger.mRequest = request;
mTransitionPlayer.requestStartTransition(transition.getToken(), request);