Merge "Fix pip bundling" into tm-qpr-dev am: 97b292f627
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18382174
Change-Id: I8051427e16798e7adb225c504e42a3a250060441
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index 3e6fa56..494ae97 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -769,6 +769,12 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
+ "-1383884640": {
+ "message": " allReady query: used=%b override=%b defer=%d states=[%s]",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_WINDOW_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/Transition.java"
+ },
"-1376035390": {
"message": "No task found",
"level": "DEBUG",
@@ -2551,12 +2557,6 @@
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/ActivityRecord.java"
},
- "352982444": {
- "message": " allReady query: used=%b override=%b states=[%s]",
- "level": "VERBOSE",
- "group": "WM_DEBUG_WINDOW_TRANSITIONS",
- "at": "com\/android\/server\/wm\/Transition.java"
- },
"355720268": {
"message": "stopFreezingDisplayLocked: Unfreezing now",
"level": "DEBUG",
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 6113af4..47aa587 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -737,7 +737,7 @@
synchronized (mGlobalLock) {
final ActivityRecord r = ensureValidPictureInPictureActivityParams(
"enterPictureInPictureMode", token, params);
- return mService.enterPictureInPictureMode(r, params);
+ return mService.enterPictureInPictureMode(r, params, true /* fromClient */);
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -868,7 +868,8 @@
}
if (r.pictureInPictureArgs.isAutoEnterEnabled()) {
- return mService.enterPictureInPictureMode(r, r.pictureInPictureArgs);
+ return mService.enterPictureInPictureMode(r, r.pictureInPictureArgs,
+ false /* fromClient */);
}
try {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 7524825..06242b3 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -95,6 +95,7 @@
import static com.android.server.am.EventLogTags.writeConfigurationChanged;
import static com.android.server.wm.ActivityInterceptorCallback.FIRST_ORDERED_ID;
import static com.android.server.wm.ActivityInterceptorCallback.LAST_ORDERED_ID;
+import static com.android.server.wm.ActivityRecord.State.PAUSING;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_ROOT_TASK;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITCH;
@@ -3449,10 +3450,12 @@
/**
* Puts the given activity in picture in picture mode if possible.
*
+ * @param fromClient true if this comes from a client call (eg. Activity.enterPip).
* @return true if the activity is now in picture-in-picture mode, or false if it could not
* enter picture-in-picture mode.
*/
- boolean enterPictureInPictureMode(@NonNull ActivityRecord r, PictureInPictureParams params) {
+ boolean enterPictureInPictureMode(@NonNull ActivityRecord r,
+ @NonNull PictureInPictureParams params, boolean fromClient) {
// If the activity is already in picture in picture mode, then just return early
if (r.inPinnedWindowingMode()) {
return true;
@@ -3465,9 +3468,17 @@
return false;
}
- // Create a transition for this pip entry. We guarantee that this gets its own transition
- // by queueing this transition on SyncEngine. This is shared by all the entry paths.
- final Transition transition = getTransitionController().isShellTransitionsEnabled()
+ // If the app is using legacy-entry (not auto-enter), then we will get a client-request
+ // that was actually a server-request (via pause(userLeaving=true)). This happens when
+ // the app is PAUSING, so detect that case here.
+ boolean originallyFromClient = fromClient
+ && (!r.isState(PAUSING) || params.isAutoEnterEnabled());
+
+ // Create a transition only for this pip entry if it is coming from the app without the
+ // system requesting that the app enter-pip. If the system requested it, that means it
+ // should be part of that transition if possible.
+ final Transition transition =
+ (getTransitionController().isShellTransitionsEnabled() && originallyFromClient)
? new Transition(TRANSIT_PIP, 0 /* flags */,
getTransitionController(), mWindowManager.mSyncEngine)
: null;
@@ -3498,7 +3509,7 @@
mActivityClientController.dismissKeyguard(r.token, new KeyguardDismissCallback() {
@Override
public void onDismissSucceeded() {
- if (mWindowManager.mSyncEngine.hasActiveSync()) {
+ if (transition != null && mWindowManager.mSyncEngine.hasActiveSync()) {
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
"Creating Pending Pip-Enter: %s", transition);
mWindowManager.mSyncEngine.queueSyncSet(
@@ -3516,7 +3527,7 @@
}, null /* message */);
} else {
// Enter picture in picture immediately otherwise
- if (mWindowManager.mSyncEngine.hasActiveSync()) {
+ if (transition != null && mWindowManager.mSyncEngine.hasActiveSync()) {
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
"Creating Pending Pip-Enter: %s", transition);
mWindowManager.mSyncEngine.queueSyncSet(
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index c62e859..0395f82 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1533,7 +1533,7 @@
if (prev.attachedToProcess()) {
if (shouldAutoPip) {
boolean didAutoPip = mAtmService.enterPictureInPictureMode(
- prev, prev.pictureInPictureArgs);
+ prev, prev.pictureInPictureArgs, false /* fromClient */);
ProtoLog.d(WM_DEBUG_STATES, "Auto-PIP allowed, entering PIP mode "
+ "directly: %s, didAutoPip: %b", prev, didAutoPip);
} else {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index d5acf4f..3fcaa5c 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -54,6 +54,7 @@
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
+import static com.android.server.wm.ActivityRecord.State.RESUMED;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
@@ -477,6 +478,58 @@
mCanPipOnFinish = canPipOnFinish;
}
+ private boolean didCommitTransientLaunch() {
+ if (mTransientLaunches == null) return false;
+ for (int j = 0; j < mTransientLaunches.size(); ++j) {
+ if (mTransientLaunches.keyAt(j).isVisibleRequested()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Check if pip-entry is possible after finishing and enter-pip if it is.
+ *
+ * @return true if we are *guaranteed* to enter-pip. This means we return false if there's
+ * a chance we won't thus legacy-entry (via pause+userLeaving) will return false.
+ */
+ private boolean checkEnterPipOnFinish(@NonNull ActivityRecord ar) {
+ if (!mCanPipOnFinish || !ar.isVisible() || ar.getTask() == null) return false;
+
+ if (ar.pictureInPictureArgs != null && ar.pictureInPictureArgs.isAutoEnterEnabled()) {
+ if (didCommitTransientLaunch()) {
+ // force enable pip-on-task-switch now that we've committed to actually launching
+ // to the transient activity.
+ ar.supportsEnterPipOnTaskSwitch = true;
+ }
+ return mController.mAtm.enterPictureInPictureMode(ar, ar.pictureInPictureArgs,
+ false /* fromClient */);
+ }
+
+ // Legacy pip-entry (not via isAutoEnterEnabled).
+ boolean canPip = ar.getDeferHidingClient();
+ if (!canPip && didCommitTransientLaunch()) {
+ // force enable pip-on-task-switch now that we've committed to actually launching to the
+ // transient activity, and then recalculate whether we can attempt pip.
+ ar.supportsEnterPipOnTaskSwitch = true;
+ canPip = ar.checkEnterPictureInPictureState(
+ "finishTransition", true /* beforeStopping */)
+ && ar.isState(RESUMED);
+ }
+ if (!canPip) return false;
+ try {
+ // Legacy PIP-enter requires pause event with user-leaving.
+ mController.mAtm.mTaskSupervisor.mUserLeaving = true;
+ ar.getTaskFragment().startPausing(false /* uiSleeping */,
+ null /* resuming */, "finishTransition");
+ } finally {
+ mController.mAtm.mTaskSupervisor.mUserLeaving = false;
+ }
+ // Return false anyway because there's no guarantee that the app will enter pip.
+ return false;
+ }
+
/**
* The transition has finished animating and is ready to finalize WM state. This should not
* be called directly; use {@link TransitionController#finishTransition} instead.
@@ -503,32 +556,9 @@
// then doing commitVisibility here would actually be out-of-order and leave the
// activity in a bad state.
if (!visibleAtTransitionEnd && !ar.isVisibleRequested()) {
- boolean commitVisibility = true;
- if (mCanPipOnFinish && ar.isVisible() && ar.getTask() != null) {
- if (ar.pictureInPictureArgs != null
- && ar.pictureInPictureArgs.isAutoEnterEnabled()) {
- if (mTransientLaunches != null) {
- for (int j = 0; j < mTransientLaunches.size(); ++j) {
- if (mTransientLaunches.keyAt(j).isVisibleRequested()) {
- // force enable pip-on-task-switch now that we've committed
- // to actually launching to the transient activity.
- ar.supportsEnterPipOnTaskSwitch = true;
- break;
- }
- }
- }
- mController.mAtm.enterPictureInPictureMode(ar, ar.pictureInPictureArgs);
- // Avoid commit visibility to false here, or else we will get a sudden
- // "flash" / surface going invisible for a split second.
- commitVisibility = false;
- } else if (ar.getDeferHidingClient()) {
- // Legacy PIP-enter requires pause event with user-leaving.
- mController.mAtm.mTaskSupervisor.mUserLeaving = true;
- ar.getTaskFragment().startPausing(false /* uiSleeping */,
- null /* resuming */, "finishTransition");
- mController.mAtm.mTaskSupervisor.mUserLeaving = false;
- }
- }
+ final boolean commitVisibility = !checkEnterPipOnFinish(ar);
+ // Avoid commit visibility if entering pip or else we will get a sudden
+ // "flash" / surface going invisible for a split second.
if (commitVisibility) {
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
" Commit activity becoming invisible: %s", ar);
@@ -1720,7 +1750,8 @@
/** @return true if all tracked subtrees are ready. */
boolean allReady() {
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, " allReady query: used=%b "
- + "override=%b states=[%s]", mUsed, mReadyOverride, groupsToString());
+ + "override=%b defer=%d states=[%s]", mUsed, mReadyOverride, mDeferReadyDepth,
+ groupsToString());
// If the readiness has never been touched, mUsed will be false. We never want to
// consider a transition ready if nothing has been reported on it.
if (!mUsed) return false;