Merge "Fix task-organizer + shell transit interractions during tests" into sc-v2-dev

This commit is contained in:
Evan Rosky
2021-06-19 00:44:51 +00:00
committed by Android (Google) Code Review
2 changed files with 74 additions and 6 deletions

View File

@@ -388,6 +388,15 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
mOrganizer.mTaskOrganizer, t); mOrganizer.mTaskOrganizer, t);
} }
} }
if (mService.getTransitionController().isShellTransitionsEnabled()) {
// dispose is only called outside of transitions (eg during unregister). Since
// we "migrate" surfaces when replacing organizers, visibility gets delegated
// to transitions; however, since there is no transition at this point, we have
// to manually show the surface here.
if (t.mTaskOrganizer != null && t.getSurfaceControl() != null) {
t.getSyncTransaction().show(t.getSurfaceControl());
}
}
} }
// Remove organizer state after removing tasks so we get a chance to send // Remove organizer state after removing tasks so we get a chance to send
@@ -480,7 +489,8 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
final int uid = Binder.getCallingUid(); final int uid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity();
try { try {
synchronized (mGlobalLock) { final ArrayList<TaskAppearedInfo> taskInfos = new ArrayList<>();
final Runnable withGlobalLock = () -> {
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);
if (!mTaskOrganizerStates.containsKey(organizer.asBinder())) { if (!mTaskOrganizerStates.containsKey(organizer.asBinder())) {
@@ -489,10 +499,10 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
new TaskOrganizerState(organizer, uid)); new TaskOrganizerState(organizer, uid));
} }
final ArrayList<TaskAppearedInfo> taskInfos = new ArrayList<>();
final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder()); final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
mService.mRootWindowContainer.forAllTasks((task) -> { mService.mRootWindowContainer.forAllTasks((task) -> {
if (ArrayUtils.contains(UNSUPPORTED_WINDOWING_MODES, task.getWindowingMode())) { if (ArrayUtils.contains(UNSUPPORTED_WINDOWING_MODES,
task.getWindowingMode())) {
return; return;
} }
@@ -502,11 +512,19 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
if (returnTask) { if (returnTask) {
SurfaceControl outSurfaceControl = state.addTaskWithoutCallback(task, SurfaceControl outSurfaceControl = state.addTaskWithoutCallback(task,
"TaskOrganizerController.registerTaskOrganizer"); "TaskOrganizerController.registerTaskOrganizer");
taskInfos.add(new TaskAppearedInfo(task.getTaskInfo(), outSurfaceControl)); taskInfos.add(
new TaskAppearedInfo(task.getTaskInfo(), outSurfaceControl));
} }
}); });
return new ParceledListSlice<>(taskInfos); };
if (mService.getTransitionController().isShellTransitionsEnabled()) {
mService.getTransitionController().mRunningLock.runWhenIdle(1000, withGlobalLock);
} else {
synchronized (mGlobalLock) {
withGlobalLock.run();
}
} }
return new ParceledListSlice<>(taskInfos);
} finally { } finally {
Binder.restoreCallingIdentity(origId); Binder.restoreCallingIdentity(origId);
} }
@@ -518,7 +536,7 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
final int uid = Binder.getCallingUid(); final int uid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity(); final long origId = Binder.clearCallingIdentity();
try { try {
synchronized (mGlobalLock) { final Runnable withGlobalLock = () -> {
final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder()); final TaskOrganizerState state = mTaskOrganizerStates.get(organizer.asBinder());
if (state == null) { if (state == null) {
return; return;
@@ -527,6 +545,13 @@ class TaskOrganizerController extends ITaskOrganizerController.Stub {
organizer.asBinder(), uid); organizer.asBinder(), uid);
state.unlinkDeath(); state.unlinkDeath();
state.dispose(); state.dispose();
};
if (mService.getTransitionController().isShellTransitionsEnabled()) {
mService.getTransitionController().mRunningLock.runWhenIdle(1000, withGlobalLock);
} else {
synchronized (mGlobalLock) {
withGlobalLock.run();
}
} }
} finally { } finally {
Binder.restoreCallingIdentity(origId); Binder.restoreCallingIdentity(origId);

View File

@@ -63,6 +63,8 @@ class TransitionController {
*/ */
private final ArrayList<Transition> mPlayingTransitions = new ArrayList<>(); private final ArrayList<Transition> mPlayingTransitions = new ArrayList<>();
final Lock mRunningLock = new Lock();
private final IBinder.DeathRecipient mTransitionPlayerDeath = () -> { private final IBinder.DeathRecipient mTransitionPlayerDeath = () -> {
// clean-up/finish any playing transitions. // clean-up/finish any playing transitions.
for (int i = 0; i < mPlayingTransitions.size(); ++i) { for (int i = 0; i < mPlayingTransitions.size(); ++i) {
@@ -70,6 +72,7 @@ class TransitionController {
} }
mPlayingTransitions.clear(); mPlayingTransitions.clear();
mTransitionPlayer = null; mTransitionPlayer = null;
mRunningLock.doNotifyLocked();
}; };
/** The transition currently being constructed (collecting participants). */ /** The transition currently being constructed (collecting participants). */
@@ -285,6 +288,7 @@ class TransitionController {
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Finish Transition: %s", record); ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Finish Transition: %s", record);
mPlayingTransitions.remove(record); mPlayingTransitions.remove(record);
record.finishTransition(); record.finishTransition();
mRunningLock.doNotifyLocked();
} }
void moveToPlaying(Transition transition) { void moveToPlaying(Transition transition) {
@@ -357,4 +361,43 @@ class TransitionController {
false /* keyguardGoingAway */); false /* keyguardGoingAway */);
} }
} }
class Lock {
private int mTransitionWaiters = 0;
void runWhenIdle(long timeout, Runnable r) {
synchronized (mAtm.mGlobalLock) {
if (!inTransition()) {
r.run();
return;
}
mTransitionWaiters += 1;
}
final long startTime = SystemClock.uptimeMillis();
final long endTime = startTime + timeout;
while (true) {
synchronized (mAtm.mGlobalLock) {
if (!inTransition() || SystemClock.uptimeMillis() > endTime) {
mTransitionWaiters -= 1;
r.run();
return;
}
}
synchronized (this) {
try {
this.wait(timeout);
} catch (InterruptedException e) {
return;
}
}
}
}
void doNotifyLocked() {
synchronized (this) {
if (mTransitionWaiters > 0) {
this.notifyAll();
}
}
}
}
} }