summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/wm/ActivityClientController.java13
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java46
-rw-r--r--services/core/java/com/android/server/wm/ActivityStartController.java5
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java75
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java17
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskSupervisor.java22
-rw-r--r--services/core/java/com/android/server/wm/BackNavigationController.java2
-rw-r--r--services/core/java/com/android/server/wm/RootWindowContainer.java17
-rw-r--r--services/core/java/com/android/server/wm/Task.java42
-rw-r--r--services/core/java/com/android/server/wm/TaskDisplayArea.java2
-rw-r--r--services/core/java/com/android/server/wm/TaskFragment.java5
-rw-r--r--services/core/java/com/android/server/wm/TaskOrganizerController.java2
-rw-r--r--services/core/java/com/android/server/wm/Transition.java14
-rw-r--r--services/core/java/com/android/server/wm/TransitionController.java22
-rw-r--r--services/core/java/com/android/server/wm/WindowContainer.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java31
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java6
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java4
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java4
20 files changed, 185 insertions, 152 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityClientController.java b/services/core/java/com/android/server/wm/ActivityClientController.java
index 0c10551a9b23..e27b2beb3d5a 100644
--- a/services/core/java/com/android/server/wm/ActivityClientController.java
+++ b/services/core/java/com/android/server/wm/ActivityClientController.java
@@ -1156,7 +1156,7 @@ class ActivityClientController extends IActivityClientController.Stub {
}
if (rootTask.inFreeformWindowingMode()) {
- rootTask.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ rootTask.setRootTaskWindowingMode(WINDOWING_MODE_FULLSCREEN);
rootTask.setBounds(null);
} else if (!r.supportsFreeform()) {
throw new IllegalStateException(
@@ -1165,9 +1165,9 @@ class ActivityClientController extends IActivityClientController.Stub {
// If the window is on a freeform display, set it to undefined. It will be
// resolved to freeform and it can adjust windowing mode when the display mode
// changes in runtime.
- rootTask.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+ rootTask.setRootTaskWindowingMode(WINDOWING_MODE_UNDEFINED);
} else {
- rootTask.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ rootTask.setRootTaskWindowingMode(WINDOWING_MODE_FREEFORM);
}
}
} finally {
@@ -1278,7 +1278,7 @@ class ActivityClientController extends IActivityClientController.Stub {
if (fullscreenRequest == FULLSCREEN_MODE_REQUEST_ENTER) {
final int restoreWindowingMode = requester.getRequestedOverrideWindowingMode();
targetWindowingMode = WINDOWING_MODE_FULLSCREEN;
- requester.setWindowingMode(targetWindowingMode);
+ requester.setRootTaskWindowingMode(targetWindowingMode);
// The restore windowing mode must be set after the windowing mode is set since
// Task#setWindowingMode resets the restore windowing mode to WINDOWING_MODE_INVALID.
requester.mMultiWindowRestoreWindowingMode = restoreWindowingMode;
@@ -1297,9 +1297,8 @@ class ActivityClientController extends IActivityClientController.Stub {
public void startLockTaskModeByToken(IBinder token) {
synchronized (mGlobalLock) {
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
- if (r != null) {
- mService.startLockTaskMode(r.getTask(), false /* isSystemCaller */);
- }
+ if (r == null) return;
+ mService.startLockTaskMode(r.getTask(), false /* isSystemCaller */);
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index a76f1b62fe02..d982925268b1 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2016,7 +2016,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
mIsUserAlwaysVisible = properties != null && properties.getAlwaysVisible();
mShowForAllUsers = (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0 || mIsUserAlwaysVisible;
- setOrientation(info.screenOrientation);
+ setOverrideOrientation(info.screenOrientation);
mRotationAnimationHint = info.rotationAnimation;
mShowWhenLocked = (aInfo.flags & ActivityInfo.FLAG_SHOW_WHEN_LOCKED) != 0;
@@ -3626,10 +3626,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
final WindowContainer<?> trigger = endTask ? task : this;
final Transition newTransition =
mTransitionController.requestCloseTransitionIfNeeded(trigger);
- if (newTransition != null) {
- newTransition.collectClose(trigger);
- } else if (mTransitionController.isCollecting()) {
- mTransitionController.getCollectingTransition().collectClose(trigger);
+ final Transition transition = newTransition != null
+ ? newTransition : mTransitionController.getCollectingTransition();
+ if (transition != null) {
+ transition.collectClose(trigger);
}
if (isState(RESUMED)) {
if (endTask) {
@@ -4302,9 +4302,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// closing the task.
final WindowContainer trigger = remove && task != null && task.getChildCount() == 1
? task : this;
- final Transition newTransit = mTransitionController.requestCloseTransitionIfNeeded(trigger);
- if (newTransit != null) {
- newTransit.collectClose(trigger);
+ final Transition tr = mTransitionController.requestCloseTransitionIfNeeded(trigger);
+ if (tr != null) {
+ tr.collectClose(trigger);
} else if (mTransitionController.isCollecting()) {
mTransitionController.getCollectingTransition().collectClose(trigger);
}
@@ -5320,12 +5320,14 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
task.lastDescription = description;
}
- void setDeferHidingClient(boolean deferHidingClient) {
- if (mDeferHidingClient == deferHidingClient) {
- return;
- }
- mDeferHidingClient = deferHidingClient;
- if (!mDeferHidingClient && !mVisibleRequested) {
+ void setDeferHidingClient() {
+ mDeferHidingClient = true;
+ }
+
+ void clearDeferHidingClient() {
+ if (!mDeferHidingClient) return;
+ mDeferHidingClient = false;
+ if (!mVisibleRequested) {
// Hiding the client is no longer deferred and the app isn't visible still, go ahead and
// update the visibility.
setVisibility(false);
@@ -5449,8 +5451,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
boolean isCollecting = false;
boolean inFinishingTransition = false;
if (mTransitionController.isShellTransitionsEnabled()) {
- isCollecting = mTransitionController.isCollecting();
- if (isCollecting) {
+ if (mTransitionController.isCollecting()) {
+ isCollecting = true;
mTransitionController.collect(this);
} else {
// Failsafe to make sure that we show any activities that were incorrectly hidden
@@ -6195,7 +6197,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
// stopped or stopping. This gives it a chance to enter Pip in onPause().
final boolean deferHidingClient = canEnterPictureInPicture
&& !isState(STARTED, STOPPING, STOPPED, PAUSED);
- setDeferHidingClient(deferHidingClient);
+ if (deferHidingClient) {
+ setDeferHidingClient();
+ } else {
+ clearDeferHidingClient();
+ }
setVisibility(false);
switch (getState()) {
@@ -6234,7 +6240,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
Slog.v(TAG_VISIBILITY, "Resume visible activity, " + this);
}
return getRootTask().resumeTopActivityUncheckedLocked(activeActivity /* prev */,
- null /* options */);
+ null /* options */, false /* skipPause */);
} else if (shouldPauseActivity(activeActivity)) {
if (DEBUG_VISIBILITY) {
Slog.v(TAG_VISIBILITY, "Pause visible activity, " + this);
@@ -6524,9 +6530,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
void stopIfPossible() {
if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + this);
if (finishing) {
- Slog.e(TAG, "Request to stop a finishing activity: " + this);
- destroyIfPossible("stopIfPossible-finishing");
- return;
+ throw new IllegalStateException("Request to stop a finishing activity: " + this);
}
if (isNoHistory()) {
if (!task.shouldSleepActivities()) {
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index a0ef03095010..1660ca913e59 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -612,11 +612,10 @@ public class ActivityStartController {
final Task task = r.getTask();
mService.deferWindowLayout();
try {
- final TransitionController controller = r.mTransitionController;
- final Transition transition = controller.getCollectingTransition();
+ final Transition transition = r.mTransitionController.getCollectingTransition();
if (transition != null) {
transition.setRemoteAnimationApp(r.app.getThread());
- controller.setTransientLaunch(r, TaskDisplayArea.getRootTaskAbove(rootTask));
+ transition.setTransientLaunch(r, TaskDisplayArea.getRootTaskAbove(rootTask));
}
task.moveToFront("startExistingRecents");
task.mInResumeTopActivity = true;
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 18aa9a026675..64791112a129 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1355,9 +1355,21 @@ class ActivityStarter {
mService.resumeAppSwitches();
}
+ // Only do the create here since startActivityInner can abort. If it doesn't abort,
+ // the requestStart will be sent in handleStartRequest.
+ final Transition newTransition = r.mTransitionController.isShellTransitionsEnabled()
+ ? r.mTransitionController.createAndStartCollecting(TRANSIT_OPEN) : null;
+ // Because startActivity must run immediately, it can get combined with another
+ // transition meaning it is no-longer independent. This is NOT desirable, but is the
+ // only option for the time being.
+ final boolean isIndependent = newTransition != null;
+ final Transition transition = isIndependent ? newTransition
+ : mService.getTransitionController().getCollectingTransition();
+
mLastStartActivityResult = startActivityUnchecked(r, sourceRecord, voiceSession,
request.voiceInteractor, startFlags, checkedOptions,
- inTask, inTaskFragment, balVerdict, intentGrants, realCallingUid);
+ inTask, inTaskFragment, balVerdict, intentGrants, realCallingUid, transition,
+ isIndependent);
if (request.outActivity != null) {
request.outActivity[0] = mLastStartActivityRecord;
@@ -1509,33 +1521,27 @@ class ActivityStarter {
int startFlags, ActivityOptions options, Task inTask,
TaskFragment inTaskFragment,
BalVerdict balVerdict,
- NeededUriGrants intentGrants, int realCallingUid) {
+ NeededUriGrants intentGrants, int realCallingUid, Transition transition,
+ boolean isIndependentLaunch) {
int result = START_CANCELED;
final Task startedActivityRootTask;
- // Create a transition now to record the original intent of actions taken within
- // startActivityInner. Otherwise, logic in startActivityInner could start a different
- // transition based on a sub-action.
- // Only do the create here (and defer requestStart) since startActivityInner might abort.
- final TransitionController transitionController = r.mTransitionController;
- Transition newTransition = transitionController.isShellTransitionsEnabled()
- ? transitionController.createAndStartCollecting(TRANSIT_OPEN) : null;
RemoteTransition remoteTransition = r.takeRemoteTransition();
// Create a display snapshot as soon as possible.
- if (newTransition != null && mRequest.freezeScreen) {
+ if (isIndependentLaunch && mRequest.freezeScreen) {
final TaskDisplayArea tda = mLaunchParams.hasPreferredTaskDisplayArea()
? mLaunchParams.mPreferredTaskDisplayArea
: mRootWindowContainer.getDefaultTaskDisplayArea();
final DisplayContent dc = mRootWindowContainer.getDisplayContentOrCreate(
tda.getDisplayId());
if (dc != null) {
- transitionController.collect(dc);
- transitionController.collectVisibleChange(dc);
+ transition.collect(dc);
+ transition.collectVisibleChange(dc);
}
}
try {
mService.deferWindowLayout();
- transitionController.collect(r);
+ r.mTransitionController.collect(r);
try {
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
@@ -1545,8 +1551,8 @@ class ActivityStarter {
Slog.e(TAG, "Exception on startActivityInner", ex);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
- startedActivityRootTask = handleStartResult(r, options, result, newTransition,
- remoteTransition);
+ startedActivityRootTask = handleStartResult(r, options, result, isIndependentLaunch,
+ remoteTransition, transition);
}
} finally {
mService.continueWindowLayout();
@@ -1571,8 +1577,8 @@ class ActivityStarter {
* @return the root task where the successful started activity resides.
*/
private @Nullable Task handleStartResult(@NonNull ActivityRecord started,
- ActivityOptions options, int result, Transition newTransition,
- RemoteTransition remoteTransition) {
+ ActivityOptions options, int result, boolean isIndependentLaunch,
+ RemoteTransition remoteTransition, @NonNull Transition transition) {
final boolean userLeaving = mSupervisor.mUserLeaving;
mSupervisor.mUserLeaving = false;
final Task currentRootTask = started.getRootTask();
@@ -1596,8 +1602,9 @@ class ActivityStarter {
&& !startedActivityRootTask.mCreatedByOrganizer) {
startedActivityRootTask.removeIfPossible("handleStartResult");
}
- if (newTransition != null) {
- newTransition.abort();
+ if (isIndependentLaunch
+ && mService.getTransitionController().isShellTransitionsEnabled()) {
+ transition.abort();
}
return null;
}
@@ -1649,44 +1656,46 @@ class ActivityStarter {
// The activity is started new rather than just brought forward, so record it as an
// existence change.
transitionController.collectExistenceChange(started);
- } else if (result == START_DELIVERED_TO_TOP && newTransition != null
+ } else if (result == START_DELIVERED_TO_TOP && isIndependentLaunch
// An activity has changed order/visibility or the task is occluded by a transient
// activity, so this isn't just deliver-to-top
&& mMovedToTopActivity == null
&& !transitionController.hasOrderChanges()
&& !transitionController.isTransientHide(startedActivityRootTask)
- && !newTransition.hasChanged(mLastStartActivityRecord)) {
+ && !transition.hasChanged(mLastStartActivityRecord)) {
// We just delivered to top, so there isn't an actual transition here.
if (!forceTransientTransition) {
- newTransition.abort();
- newTransition = null;
+ transition.abort();
+ transition = null;
}
}
- if (forceTransientTransition) {
- transitionController.collect(mLastStartActivityRecord);
- transitionController.collect(mPriorAboveTask);
+ if (forceTransientTransition && transition != null) {
+ transition.collect(mLastStartActivityRecord);
+ transition.collect(mPriorAboveTask);
// If keyguard is active and occluded, the transient target won't be moved to front
// to be collected, so set transient again after it is collected.
- transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask);
+ transition.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask);
final DisplayContent dc = mLastStartActivityRecord.getDisplayContent();
// update wallpaper target to TransientHide
dc.mWallpaperController.adjustWallpaperWindows();
// execute transition because there is no change
- transitionController.setReady(dc, true /* ready */);
+ transition.setReady(dc, true /* ready */);
}
- if (!userLeaving) {
+ if (!userLeaving && transition != null) {
// no-user-leaving implies not entering PiP.
- transitionController.setCanPipOnFinish(false /* canPipOnFinish */);
+ transition.setCanPipOnFinish(false /* canPipOnFinish */);
}
- if (newTransition != null) {
- transitionController.requestStartTransition(newTransition,
+ if (isIndependentLaunch && transition != null) {
+ transitionController.requestStartTransition(transition,
mTargetTask == null ? started.getTask() : mTargetTask,
remoteTransition, null /* displayChange */);
} else if (result == START_SUCCESS && mStartActivity.isState(RESUMED)) {
// Do nothing if the activity is started and is resumed directly.
} else if (isStarted) {
// Make the collecting transition wait until this request is ready.
- transitionController.setReady(started, false);
+ if (transition != null) {
+ transition.setReady(started, false);
+ }
}
return startedActivityRootTask;
}
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index f23211b98b85..5bb4a8adbd82 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -2116,12 +2116,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
Slog.w(TAG, "removeTask: No task remove with id=" + taskId);
return false;
}
-
- if (task.isLeafTask()) {
- mTaskSupervisor.removeTask(task, true, REMOVE_FROM_RECENTS, "remove-task");
- } else {
- mTaskSupervisor.removeRootTask(task);
- }
+ removeTask(task);
return true;
} finally {
Binder.restoreCallingIdentity(ident);
@@ -2129,6 +2124,14 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
}
+ void removeTask(@NonNull Task task) {
+ if (task.isLeafTask()) {
+ mTaskSupervisor.removeTask(task, true, REMOVE_FROM_RECENTS, "remove-task");
+ } else {
+ mTaskSupervisor.removeRootTask(task);
+ }
+ }
+
@Override
public void removeAllVisibleRecentTasks() {
mAmInternal.enforceCallingPermission(REMOVE_TASKS, "removeAllVisibleRecentTasks()");
@@ -2938,7 +2941,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
getTransitionController().requestStartTransition(transition, task,
null /* remoteTransition */, null /* displayChange */);
- getTransitionController().collect(task);
+ transition.collect(task);
task.resize(bounds, resizeMode, preserveWindow);
transition.setReady(task, true);
});
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index 8ef2693ec327..1446c353d9d4 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -1528,9 +1528,12 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
}
mService.deferWindowLayout();
- final Transition newTransition = task.mTransitionController.isShellTransitionsEnabled()
- ? task.mTransitionController.isCollecting() ? null
- : task.mTransitionController.createTransition(TRANSIT_TO_FRONT) : null;
+ boolean newTransition = false;
+ Transition transition = task.mTransitionController.getCollectingTransition();
+ if (transition == null && task.mTransitionController.isShellTransitionsEnabled()) {
+ transition = task.mTransitionController.createTransition(TRANSIT_TO_FRONT);
+ newTransition = true;
+ }
task.mTransitionController.collect(task);
reason = reason + " findTaskToMoveToFront";
boolean reparented = false;
@@ -1574,8 +1577,8 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// transition to avoid delaying the starting window.
r.showStartingWindow(true /* taskSwitch */);
}
- if (newTransition != null) {
- task.mTransitionController.requestStartTransition(newTransition, task,
+ if (newTransition) {
+ task.mTransitionController.requestStartTransition(transition, task,
options != null ? options.getRemoteTransition() : null,
null /* displayChange */);
}
@@ -1644,7 +1647,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
mService.deferWindowLayout();
try {
- rootTask.setWindowingMode(WINDOWING_MODE_UNDEFINED);
+ rootTask.setRootTaskWindowingMode(WINDOWING_MODE_UNDEFINED);
if (rootTask.getWindowingMode() != WINDOWING_MODE_FREEFORM) {
rootTask.setBounds(null);
}
@@ -1705,7 +1708,10 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// Prevent recursion.
return;
}
- final Transition transit = task.mTransitionController.requestCloseTransitionIfNeeded(task);
+ Transition transit = task.mTransitionController.requestCloseTransitionIfNeeded(task);
+ if (transit == null) {
+ transit = task.mTransitionController.getCollectingTransition();
+ }
if (transit != null) {
transit.collectClose(task);
if (!task.mTransitionController.useFullReadyTracking()) {
@@ -1717,8 +1723,6 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
// before anything that may need it to wait (setReady(false)).
transit.setReady(task, true);
}
- } else if (task.mTransitionController.isCollecting()) {
- task.mTransitionController.getCollectingTransition().collectClose(task);
}
// Consume the stopping activities immediately so activity manager won't skip killing
// the process because it is still foreground state, i.e. RESUMED -> PAUSING set from
diff --git a/services/core/java/com/android/server/wm/BackNavigationController.java b/services/core/java/com/android/server/wm/BackNavigationController.java
index 89e10d36caed..767effd0ef12 100644
--- a/services/core/java/com/android/server/wm/BackNavigationController.java
+++ b/services/core/java/com/android/server/wm/BackNavigationController.java
@@ -367,7 +367,7 @@ class BackNavigationController {
// client process to prevent the unexpected relayout when handling the back
// animation.
for (int i = prevActivities.size() - 1; i >= 0; --i) {
- prevActivities.get(i).setDeferHidingClient(true);
+ prevActivities.get(i).setDeferHidingClient();
}
} else {
scheduleAnimation(builder);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index bded98c6c07f..6427c3229b50 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -1633,7 +1633,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// Only resume home activity if isn't finishing.
if (r != null && !r.finishing) {
r.moveFocusableActivityToTop(myReason);
- return resumeFocusedTasksTopActivities(r.getRootTask(), prev, null);
+ return resumeFocusedTasksTopActivities(r.getRootTask(), prev);
}
int userId = mWmService.getUserAssignedToDisplay(taskDisplayArea.getDisplayId());
return startHomeOnTaskDisplayArea(userId, myReason, taskDisplayArea,
@@ -2202,7 +2202,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// During recents animations, the original task is "occluded" by launcher but
// it wasn't paused (due to transient-launch). If we reparent to the (top) task
// now, it will take focus briefly which confuses the RecentTasks tracker.
- rootTask.setWindowingMode(WINDOWING_MODE_PINNED);
+ rootTask.setRootTaskWindowingMode(WINDOWING_MODE_PINNED);
}
// Temporarily disable focus when reparenting to avoid intermediate focus change
// (because the task is on top and the activity is resumed), which could cause the
@@ -2235,7 +2235,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// TODO(remove-legacy-transit): Move this to the `singleActivity` case when removing
// legacy transit.
- rootTask.setWindowingMode(WINDOWING_MODE_PINNED);
+ rootTask.setRootTaskWindowingMode(WINDOWING_MODE_PINNED);
if (isPip2ExperimentEnabled() && bounds != null) {
// set the final pip bounds in advance if pip2 is enabled
rootTask.setBounds(bounds);
@@ -2470,12 +2470,12 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
boolean resumeFocusedTasksTopActivities() {
- return resumeFocusedTasksTopActivities(null, null, null);
+ return resumeFocusedTasksTopActivities(null, null, null, false /* deferPause */);
}
boolean resumeFocusedTasksTopActivities(
- Task targetRootTask, ActivityRecord target, ActivityOptions targetOptions) {
- return resumeFocusedTasksTopActivities(targetRootTask, target, targetOptions,
+ Task targetRootTask, ActivityRecord target) {
+ return resumeFocusedTasksTopActivities(targetRootTask, target, null /* targetOptions */,
false /* deferPause */);
}
@@ -2527,7 +2527,8 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// activity is started and resumed, and no recursion occurs.
final Task focusedRoot = display.getFocusedRootTask();
if (focusedRoot != null) {
- result |= focusedRoot.resumeTopActivityUncheckedLocked(target, targetOptions);
+ result |= focusedRoot.resumeTopActivityUncheckedLocked(
+ target, targetOptions, false /* skipPause */);
} else if (targetRootTask == null) {
result |= resumeHomeActivity(null /* prev */, "no-focusable-task",
display.getDefaultTaskDisplayArea());
@@ -2632,7 +2633,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
// process the keyguard going away, which can happen before the sleep
// token is released. As a result, it is important we resume the
// activity here.
- rootTask.resumeTopActivityUncheckedLocked(null, null);
+ rootTask.resumeTopActivityUncheckedLocked();
}
// The visibility update must not be called before resuming the top, so the
// display orientation can be updated first if needed. Otherwise there may
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 12e91adef9c5..da00d7347eff 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -4540,7 +4540,8 @@ class Task extends TaskFragment {
reparent(parent, MAX_VALUE);
}
- setWindowingMode(mMultiWindowRestoreWindowingMode);
+ // mMultiWindowRestoreWindowingMode is INVALID for non-root tasks
+ setRootTaskWindowingMode(mMultiWindowRestoreWindowingMode);
}
@Override
@@ -4553,18 +4554,30 @@ class Task extends TaskFragment {
return;
}
- setWindowingMode(windowingMode, false /* creating */);
+ setWindowingModeInner(windowingMode, false /* creating */);
}
/**
- * Specialization of {@link #setWindowingMode(int)} for this subclass.
+ * Version of {@link #setWindowingMode(int)} for root tasks.
*
* @param preferredWindowingMode the preferred windowing mode. This may not be honored depending
* on the state of things. For example, WINDOWING_MODE_UNDEFINED will resolve to the
* previous non-transient mode if this root task is currently in a transient mode.
+ */
+ public void setRootTaskWindowingMode(int preferredWindowingMode) {
+ if (!isRootTask()) {
+ Slog.wtf(TAG, "Trying to set root-task windowing-mode on a non-root-task: " + this,
+ new Throwable());
+ super.setWindowingMode(preferredWindowingMode);
+ return;
+ }
+ setWindowingModeInner(preferredWindowingMode, false /* creating */);
+ }
+
+ /**
* @param creating {@code true} if this is being run during task construction.
*/
- void setWindowingMode(int preferredWindowingMode, boolean creating) {
+ private void setWindowingModeInner(int preferredWindowingMode, boolean creating) {
final TaskDisplayArea taskDisplayArea = getDisplayArea();
if (taskDisplayArea == null) {
Slog.d(TAG, "taskDisplayArea is null, bail early");
@@ -4740,7 +4753,7 @@ class Task extends TaskFragment {
}
}
if (isAttached()) {
- setWindowingMode(WINDOWING_MODE_UNDEFINED);
+ setRootTaskWindowingMode(WINDOWING_MODE_UNDEFINED);
moveTaskToBackInner(this, null /* transition */);
}
if (top.isAttached()) {
@@ -5086,10 +5099,10 @@ class Task extends TaskFragment {
return someActivityResumed;
}
- /** @see #resumeTopActivityUncheckedLocked(ActivityRecord, ActivityOptions, boolean) */
@GuardedBy("mService")
- boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
- return resumeTopActivityUncheckedLocked(prev, options, false /* skipPause */);
+ boolean resumeTopActivityUncheckedLocked() {
+ return resumeTopActivityUncheckedLocked(null /* prev */, null /* options */,
+ false /* skipPause */);
}
@GuardedBy("mService")
@@ -5138,8 +5151,7 @@ class Task extends TaskFragment {
// Try to move focus to the next visible root task with a running activity if this
// root task is not covering the entire screen or is on a secondary display with
// no home root task.
- return mRootWindowContainer.resumeFocusedTasksTopActivities(nextFocusedTask,
- prev, null /* targetOptions */);
+ return mRootWindowContainer.resumeFocusedTasksTopActivities(nextFocusedTask, prev);
}
}
@@ -5661,8 +5673,10 @@ class Task extends TaskFragment {
if (noAnimation) {
mDisplayContent.prepareAppTransition(TRANSIT_NONE);
mTaskSupervisor.mNoAnimActivities.add(top);
- mTransitionController.collect(top);
- mTransitionController.setNoAnimation(top);
+ if (mTransitionController.isShellTransitionsEnabled()) {
+ mTransitionController.collect(top);
+ mTransitionController.setNoAnimation(top);
+ }
ActivityOptions.abort(options);
} else {
updateTransitLocked(TRANSIT_TO_FRONT, options);
@@ -6002,7 +6016,7 @@ class Task extends TaskFragment {
}
final Task task = getBottomMostTask();
- setWindowingMode(WINDOWING_MODE_UNDEFINED);
+ setRootTaskWindowingMode(WINDOWING_MODE_UNDEFINED);
// Task could have been removed from the hierarchy due to windowing mode change
// where its only child is reparented back to their original parent task.
@@ -6674,7 +6688,7 @@ class Task extends TaskFragment {
// Set windowing mode after attached to display area or it abort silently.
if (mWindowingMode != WINDOWING_MODE_UNDEFINED) {
- task.setWindowingMode(mWindowingMode, true /* creating */);
+ task.setWindowingModeInner(mWindowingMode, true /* creating */);
}
return task;
}
diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java
index dba1c364b89b..d9e88e1e460a 100644
--- a/services/core/java/com/android/server/wm/TaskDisplayArea.java
+++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java
@@ -923,7 +923,7 @@ final class TaskDisplayArea extends DisplayArea<WindowContainer> {
if (windowingMode != WINDOWING_MODE_UNDEFINED && candidateTask.isRootTask()
&& candidateTask.getWindowingMode() != windowingMode) {
candidateTask.mTransitionController.collect(candidateTask);
- candidateTask.setWindowingMode(windowingMode);
+ candidateTask.setRootTaskWindowingMode(windowingMode);
}
return candidateTask.getRootTask();
}
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 2ee157f42615..329d11bfcb95 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -1927,7 +1927,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
prev.setState(STOPPING, "completePausedLocked");
} else if (!prev.isVisibleRequested() || shouldSleepOrShutDownActivities()) {
// Clear out any deferred client hide we might currently have.
- prev.setDeferHidingClient(false);
+ prev.clearDeferHidingClient();
// If we were visible then resumeTopActivities will release resources before
// stopping.
prev.addToStopping(true /* scheduleIdle */, false /* idleDelayed */,
@@ -1948,8 +1948,7 @@ class TaskFragment extends WindowContainer<WindowContainer> {
if (resumeNext) {
final Task topRootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (topRootTask != null && !topRootTask.shouldSleepOrShutDownActivities()) {
- mRootWindowContainer.resumeFocusedTasksTopActivities(topRootTask, prev,
- null /* targetOptions */);
+ mRootWindowContainer.resumeFocusedTasksTopActivities(topRootTask, prev);
} else {
// checkReadyForSleep();
final ActivityRecord top =
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 9ee1fbe91d83..de2e4f5474c4 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -390,7 +390,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
t.mTaskAppearedSent = false;
}
if (removeFromSystem) {
- mService.removeTask(t.mTaskId);
+ mService.removeTask(t);
}
return taskAppearedSent;
}
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 836ac5f6c1fc..b768bb155563 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -420,6 +420,18 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
updateTransientFlags(mChanges.valueAt(i));
}
}
+
+ // TODO(b/188669821): Remove once legacy recents behavior is moved to shell.
+ // Also interpret HOME transient launch as recents
+ if (activity.isActivityTypeHomeOrRecents()) {
+ addFlag(TRANSIT_FLAG_IS_RECENTS);
+ // When starting recents animation, we assume the recents activity is behind the app
+ // task and should not affect system bar appearance,
+ // until WMS#setRecentsAppBehindSystemBars be called from launcher when passing
+ // the gesture threshold.
+ activity.getTask().setCanAffectSystemUiFlags(false);
+ }
+
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Transition %d: Set %s as "
+ "transient-launch", mSyncId, activity);
}
@@ -1721,6 +1733,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
transaction.addTransactionCompletedListener(Runnable::run,
(stats) -> listener.run());
}
+ mTransactionCompletedListeners = null;
}
// Fall-back to the default display if there isn't one participating.
@@ -1763,6 +1776,7 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
if (mPriorVisibilityMightBeDirty) {
updatePriorVisibility();
}
+
// Resolve the animating targets from the participants.
mTargets = calculateTargets(mParticipants, mChanges);
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 67d7b37396c0..ef25eda1d876 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -19,7 +19,6 @@ package com.android.server.wm;
import static android.view.WindowManager.KEYGUARD_VISIBILITY_TRANSIT_FLAGS;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_CLOSE;
-import static android.view.WindowManager.TRANSIT_FLAG_IS_RECENTS;
import static android.view.WindowManager.TRANSIT_NONE;
import static com.android.server.wm.ActivityTaskManagerService.POWER_MODE_REASON_CHANGE_DISPLAY;
@@ -53,8 +52,8 @@ import android.window.WindowContainerTransaction;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.protolog.ProtoLogGroup;
import com.android.internal.protolog.ProtoLog;
+import com.android.internal.protolog.ProtoLogGroup;
import com.android.server.FgThread;
import com.android.window.flags.Flags;
@@ -1311,23 +1310,6 @@ class TransitionController {
void setTransientLaunch(@NonNull ActivityRecord activity, @Nullable Task restoreBelowTask) {
if (mCollectingTransition == null) return;
mCollectingTransition.setTransientLaunch(activity, restoreBelowTask);
-
- // TODO(b/188669821): Remove once legacy recents behavior is moved to shell.
- // Also interpret HOME transient launch as recents
- if (activity.isActivityTypeHomeOrRecents()) {
- mCollectingTransition.addFlag(TRANSIT_FLAG_IS_RECENTS);
- // When starting recents animation, we assume the recents activity is behind the app
- // task and should not affect system bar appearance,
- // until WMS#setRecentsAppBehindSystemBars be called from launcher when passing
- // the gesture threshold.
- activity.getTask().setCanAffectSystemUiFlags(false);
- }
- }
-
- /** @see Transition#setCanPipOnFinish */
- void setCanPipOnFinish(boolean canPipOnFinish) {
- if (mCollectingTransition == null) return;
- mCollectingTransition.setCanPipOnFinish(canPipOnFinish);
}
void legacyDetachNavigationBarFromApp(@NonNull IBinder token) {
@@ -1459,7 +1441,7 @@ class TransitionController {
*
* WARNING: ONLY use this if the transition absolutely cannot be deferred!
*/
- @NonNull
+ @Nullable
Transition createAndStartCollecting(int type) {
if (mTransitionPlayers.isEmpty()) {
return null;
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 64f9c012ea28..15d67eb61a43 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1611,8 +1611,8 @@ class WindowContainer<E extends WindowContainer> extends ConfigurationContainer<
*
* @param orientation the specified orientation.
*/
- void setOrientation(@ScreenOrientation int orientation) {
- setOrientation(orientation, null /* requestingContainer */);
+ protected void setOrientation(@ScreenOrientation int orientation) {
+ setOrientation(orientation, null /* requesting */);
}
/**
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index c6d0b729cd5a..9d40b16c37ae 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -322,11 +322,11 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
// This is a direct call from shell, so the entire transition lifecycle is
// contained in the provided transaction if provided. Thus, we can setReady
// immediately after apply.
- final Transition.ReadyCondition wctApplied =
- new Transition.ReadyCondition("start WCT applied");
final boolean needsSetReady = t != null;
final Transition nextTransition = new Transition(type, 0 /* flags */,
mTransitionController, mService.mWindowManager.mSyncEngine);
+ final Transition.ReadyCondition wctApplied =
+ new Transition.ReadyCondition("start WCT applied");
nextTransition.mReadyTracker.add(wctApplied);
nextTransition.calcParallelCollectType(wct);
mTransitionController.startCollectOrQueue(nextTransition,
@@ -342,15 +342,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
});
return nextTransition.getToken();
}
- // Currently, application of wct can span multiple looper loops (ie.
- // waitAsyncStart), so add a condition to ensure that it finishes applying.
- final Transition.ReadyCondition wctApplied;
- if (t != null) {
- wctApplied = new Transition.ReadyCondition("start WCT applied");
- transition.mReadyTracker.add(wctApplied);
- } else {
- wctApplied = null;
- }
// The transition already started collecting before sending a request to shell,
// so just start here.
if (!transition.isCollecting() && !transition.isForcePlaying()) {
@@ -358,11 +349,17 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
+ " means Shell took too long to respond to a request. WM State may be"
+ " incorrect now, please file a bug");
applyTransaction(wct, -1 /*syncId*/, null /*transition*/, caller);
- if (wctApplied != null) {
- wctApplied.meet();
- }
return transition.getToken();
}
+ // Currently, application of wct can span multiple looper loops (ie.
+ // waitAsyncStart), so add a condition to ensure that it finishes applying.
+ final Transition.ReadyCondition wctApplied;
+ if (t != null) {
+ wctApplied = new Transition.ReadyCondition("start WCT applied");
+ transition.mReadyTracker.add(wctApplied);
+ } else {
+ wctApplied = null;
+ }
transition.mLogger.mStartWCT = wct;
if (transition.shouldApplyOnDisplayThread()) {
mService.mH.post(() -> {
@@ -851,7 +848,11 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
}
final int prevMode = container.getRequestedOverrideWindowingMode();
- container.setWindowingMode(windowingMode);
+ if (container.asTask() != null && container.asTask().isRootTask()) {
+ container.asTask().setRootTaskWindowingMode(windowingMode);
+ } else {
+ container.setWindowingMode(windowingMode);
+ }
if (prevMode != container.getWindowingMode()) {
// The activity in the container may become focusable or non-focusable due to
// windowing modes changes (such as entering or leaving pinned windowing mode),
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index ab0c8d4ed60a..ec5e51e7b842 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -2656,6 +2656,7 @@ public class DisplayContentTests extends WindowTestsBase {
* display.
*/
@Test
+ @SuppressWarnings("GuardedBy")
public void testNotResumeHomeRootTaskOnRemovingDisplay() {
// Create a display which supports system decoration and allows reparenting root tasks to
// another display when the display is removed.
@@ -2678,7 +2679,8 @@ public class DisplayContentTests extends WindowTestsBase {
// The removed display should have no focused root task and its home root task should never
// resume.
assertNull(display.getFocusedRootTask());
- verify(homeRootTask, never()).resumeTopActivityUncheckedLocked(any(), any());
+ verify(homeRootTask, never()).resumeTopActivityUncheckedLocked(
+ any(), any(), anyBoolean());
}
/**
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
index d29505f02fe8..84c2c32054d8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -54,6 +54,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.refEq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.mock;
@@ -598,7 +599,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
mRootWindowContainer.applySleepTokens(true);
verify(task, times(expectWakeFromSleep ? 1 : 0)).awakeFromSleeping();
verify(task, times(expectResumeTopActivity ? 1 : 0)).resumeTopActivityUncheckedLocked(
- null /* target */, null /* targetOptions */);
+ isNull() /* target */, isNull() /* targetOptions */, eq(false) /* deferPause */);
}
@Test
@@ -790,8 +791,7 @@ public class RootWindowContainerTests extends WindowTestsBase {
doReturn(rootTask).when(mRootWindowContainer).getTopDisplayFocusedRootTask();
// Use the task as target to resume.
- mRootWindowContainer.resumeFocusedTasksTopActivities(rootTask, activity,
- null /* targetOptions */);
+ mRootWindowContainer.resumeFocusedTasksTopActivities(rootTask, activity);
// Verify the target task should resume its activity.
verify(rootTask, times(1)).resumeTopActivityUncheckedLocked(
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 36696a16fa39..65e3baad87d1 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -3017,6 +3017,7 @@ public class SizeCompatTests extends WindowTestsBase {
}
@Test
+ @SuppressWarnings("GuardedBy")
public void testDisplayIgnoreOrientationRequest_pausedAppNotLostSizeCompat() {
// Set up a display in landscape and ignoring orientation request.
setUpDisplaySizeWithApp(2800, 1400);
@@ -3043,7 +3044,8 @@ public class SizeCompatTests extends WindowTestsBase {
assertActivityMaxBoundsSandboxed();
final Rect activityBounds = new Rect(mActivity.getBounds());
- mTask.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */);
+ mTask.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */,
+ false /* deferPause */);
// App still in size compat, and the bounds don't change.
verify(mActivity, never()).clearSizeCompatMode();
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
index 18255b8d82f8..f56825faab73 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowOrganizerTests.java
@@ -265,7 +265,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
rootTask.setTaskOrganizer(null);
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
- verify(mWm.mAtmService).removeTask(eq(rootTask.mTaskId));
+ verify(mWm.mAtmService).removeTask(eq(rootTask));
}
@Test
@@ -283,7 +283,7 @@ public class WindowOrganizerTests extends WindowTestsBase {
rootTask.setTaskOrganizer(null);
mWm.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
- verify(mWm.mAtmService, never()).removeTask(eq(rootTask.mTaskId));
+ verify(mWm.mAtmService, never()).removeTask(eq(rootTask));
}
@Test