Attempt to fix race of task surface visibility
1. Remove TaskOrganizerController#mTransaction because the standalone transaction may not be synced with pending transaction of window container and WMShell. That may cause potential race such as reverting the task surface visibility. The transaction was added in commit14a657cfor the case of entering PiP. Since commit6567742, the task will be moved to back when setForceHidden, so it is already invisible. So the removal of14a657cdoesn't affect the PiP case. 2. Make task surface default invisible if the task can be organized, so the extra hide operation can be eliminated. That simplifies the control of task surface visibility. Bug: 185400889 Test: atest FlickerTests WMShellFlickerTests Change-Id: I29d80acce2019a7d01a09e98112bc07763c9054b
This commit is contained in:
@@ -4971,12 +4971,13 @@ class Task extends WindowContainer<WindowContainer> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean showSurfaceOnCreation() {
|
boolean showSurfaceOnCreation() {
|
||||||
|
if (mCreatedByOrganizer) {
|
||||||
|
// Tasks created by the organizer are default visible because they can synchronously
|
||||||
|
// update the leash before new children are added to the task.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
// Organized tasks handle their own surface visibility
|
// Organized tasks handle their own surface visibility
|
||||||
final boolean willBeOrganized =
|
return !canBeOrganized();
|
||||||
mAtmService.mTaskOrganizerController.isSupportedWindowingMode(getWindowingMode())
|
|
||||||
&& isRootTask();
|
|
||||||
return !mAtmService.getTransitionController().isShellTransitionsEnabled()
|
|
||||||
|| !willBeOrganized;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -4992,22 +4993,8 @@ class Task extends WindowContainer<WindowContainer> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setHasBeenVisible(boolean hasBeenVisible) {
|
void setHasBeenVisible(boolean hasBeenVisible) {
|
||||||
final boolean prevHasBeenVisible = mHasBeenVisible;
|
|
||||||
mHasBeenVisible = hasBeenVisible;
|
mHasBeenVisible = hasBeenVisible;
|
||||||
if (hasBeenVisible) {
|
if (hasBeenVisible) {
|
||||||
// If the task is not yet visible when it is added to the task organizer, then we should
|
|
||||||
// hide it to allow the task organizer to show it when it is properly reparented. We
|
|
||||||
// skip this for tasks created by the organizer because they can synchronously update
|
|
||||||
// the leash before new children are added to the task. Also skip this if the task
|
|
||||||
// has already been sent to the organizer which can happen before the first draw if
|
|
||||||
// an existing task is reported to the organizer when it first registers.
|
|
||||||
if (!mAtmService.getTransitionController().isShellTransitionsEnabled()
|
|
||||||
&& !mCreatedByOrganizer && !mTaskAppearedSent
|
|
||||||
&& mTaskOrganizer != null && !prevHasBeenVisible) {
|
|
||||||
getSyncTransaction().hide(getSurfaceControl());
|
|
||||||
commitPendingTransaction();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mDeferTaskAppear) sendTaskAppeared();
|
if (!mDeferTaskAppear) sendTaskAppeared();
|
||||||
if (!isRootTask()) {
|
if (!isRootTask()) {
|
||||||
getRootTask().setHasBeenVisible(true);
|
getRootTask().setHasBeenVisible(true);
|
||||||
|
|||||||
@@ -215,23 +215,15 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceControl prepareLeash(Task task, boolean visible, String reason) {
|
SurfaceControl prepareLeash(Task task, String reason) {
|
||||||
SurfaceControl outSurfaceControl = new SurfaceControl(task.getSurfaceControl(), reason);
|
return new SurfaceControl(task.getSurfaceControl(), reason);
|
||||||
if (!task.mCreatedByOrganizer && !visible) {
|
|
||||||
// To prevent flashes, we hide the task prior to sending the leash to the
|
|
||||||
// task org if the task has previously hidden (ie. when entering PIP)
|
|
||||||
mTransaction.hide(outSurfaceControl);
|
|
||||||
mTransaction.apply();
|
|
||||||
}
|
|
||||||
return outSurfaceControl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void onTaskAppeared(Task task) {
|
void onTaskAppeared(Task task) {
|
||||||
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Task appeared taskId=%d", task.mTaskId);
|
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Task appeared taskId=%d", task.mTaskId);
|
||||||
final boolean visible = task.isVisible();
|
|
||||||
final RunningTaskInfo taskInfo = task.getTaskInfo();
|
final RunningTaskInfo taskInfo = task.getTaskInfo();
|
||||||
try {
|
try {
|
||||||
mTaskOrganizer.onTaskAppeared(taskInfo, prepareLeash(task, visible,
|
mTaskOrganizer.onTaskAppeared(taskInfo, prepareLeash(task,
|
||||||
"TaskOrganizerController.onTaskAppeared"));
|
"TaskOrganizerController.onTaskAppeared"));
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Slog.e(TAG, "Exception sending onTaskAppeared callback", e);
|
Slog.e(TAG, "Exception sending onTaskAppeared callback", e);
|
||||||
@@ -331,7 +323,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
|||||||
if (!mOrganizedTasks.contains(t)) {
|
if (!mOrganizedTasks.contains(t)) {
|
||||||
mOrganizedTasks.add(t);
|
mOrganizedTasks.add(t);
|
||||||
}
|
}
|
||||||
return mOrganizer.prepareLeash(t, t.isVisible(), reason);
|
return mOrganizer.prepareLeash(t, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean addTask(Task t) {
|
private boolean addTask(Task t) {
|
||||||
@@ -434,7 +426,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
|||||||
// Set of organized tasks (by taskId) that dispatch back pressed to their organizers
|
// Set of organized tasks (by taskId) that dispatch back pressed to their organizers
|
||||||
private final HashSet<Integer> mInterceptBackPressedOnRootTasks = new HashSet();
|
private final HashSet<Integer> mInterceptBackPressedOnRootTasks = new HashSet();
|
||||||
|
|
||||||
private SurfaceControl.Transaction mTransaction;
|
|
||||||
private RunningTaskInfo mTmpTaskInfo;
|
private RunningTaskInfo mTmpTaskInfo;
|
||||||
private Consumer<Runnable> mDeferTaskOrgCallbacksConsumer;
|
private Consumer<Runnable> mDeferTaskOrgCallbacksConsumer;
|
||||||
|
|
||||||
@@ -479,13 +470,6 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
|
|||||||
synchronized (mGlobalLock) {
|
synchronized (mGlobalLock) {
|
||||||
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Register task organizer=%s uid=%d",
|
ProtoLog.v(WM_DEBUG_WINDOW_ORGANIZER, "Register task organizer=%s uid=%d",
|
||||||
organizer.asBinder(), uid);
|
organizer.asBinder(), uid);
|
||||||
|
|
||||||
// Defer initializing the transaction since the transaction factory can be set up
|
|
||||||
// by the tests after construction of the controller
|
|
||||||
if (mTransaction == null) {
|
|
||||||
mTransaction = mService.mWindowManager.mTransactionFactory.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mTaskOrganizerStates.containsKey(organizer.asBinder())) {
|
if (!mTaskOrganizerStates.containsKey(organizer.asBinder())) {
|
||||||
mTaskOrganizers.add(organizer);
|
mTaskOrganizers.add(organizer);
|
||||||
mTaskOrganizerStates.put(organizer.asBinder(),
|
mTaskOrganizerStates.put(organizer.asBinder(),
|
||||||
|
|||||||
Reference in New Issue
Block a user