Defer dispatching task appeared until transition ready

So fillTaskInfo and onTaskAppeared will be called only once at
the surface placement after transition ready. It can also avoid
sending multiple task appeared event by the intermediate state.
Then the time to reach ITransitionPlayer#onTransitionReady may
be shorter.

Bug: 260059642
Test: TransitionTests#testRunningRemoteTransition
Test: OpenAppMicrobenchmark with shell transition.
Change-Id: I866189c327778f8c1e41de17326257bd1502b9b0
This commit is contained in:
Riddle Hsu
2023-01-18 11:21:18 +00:00
parent 2d0bf6b84b
commit 676b24cf86
4 changed files with 45 additions and 12 deletions

View File

@@ -6578,12 +6578,29 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
updateReportedVisibilityLocked();
}
/**
* Sets whether something has been visible in the task and returns {@code true} if the state
* is changed from invisible to visible.
*/
private boolean setTaskHasBeenVisible() {
final boolean wasTaskVisible = task.getHasBeenVisible();
if (wasTaskVisible) {
return false;
}
if (inTransition()) {
// The deferring will be canceled until transition is ready so it won't dispatch
// intermediate states to organizer.
task.setDeferTaskAppear(true);
}
task.setHasBeenVisible(true);
return true;
}
void onStartingWindowDrawn() {
boolean wasTaskVisible = false;
if (task != null) {
mSplashScreenStyleSolidColor = true;
wasTaskVisible = task.getHasBeenVisible();
task.setHasBeenVisible(true);
wasTaskVisible = !setTaskHasBeenVisible();
}
// The transition may not be executed if the starting process hasn't attached. But if the
@@ -6621,7 +6638,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
}
finishLaunchTickingLocked();
if (task != null) {
task.setHasBeenVisible(true);
setTaskHasBeenVisible();
}
// Clear indicated launch root task because there's no trampoline activity to expect after
// the windows are drawn.

View File

@@ -4148,21 +4148,28 @@ class Task extends TaskFragment {
void setHasBeenVisible(boolean hasBeenVisible) {
mHasBeenVisible = hasBeenVisible;
if (hasBeenVisible) {
if (!mDeferTaskAppear) sendTaskAppeared();
if (!isRootTask()) {
getRootTask().setHasBeenVisible(true);
if (!hasBeenVisible || mDeferTaskAppear) {
return;
}
sendTaskAppeared();
for (WindowContainer<?> parent = getParent(); parent != null; parent = parent.getParent()) {
final Task parentTask = parent.asTask();
if (parentTask == null) {
break;
}
parentTask.setHasBeenVisible(true);
}
}
boolean getHasBeenVisible() {
return mHasBeenVisible;
}
void setDeferTaskAppear(boolean deferTaskAppear) {
final boolean wasDeferred = mDeferTaskAppear;
mDeferTaskAppear = deferTaskAppear;
if (!mDeferTaskAppear) {
if (wasDeferred && !deferTaskAppear) {
sendTaskAppeared();
}
}

View File

@@ -1142,12 +1142,15 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
private void commitVisibleActivities(SurfaceControl.Transaction transaction) {
for (int i = mParticipants.size() - 1; i >= 0; --i) {
final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
if (ar == null || !ar.isVisibleRequested()) {
if (ar == null || ar.getTask() == null) {
continue;
}
ar.commitVisibility(true /* visible */, false /* performLayout */,
true /* fromTransition */);
ar.commitFinishDrawing(transaction);
if (ar.isVisibleRequested()) {
ar.commitVisibility(true /* visible */, false /* performLayout */,
true /* fromTransition */);
ar.commitFinishDrawing(transaction);
}
ar.getTask().setDeferTaskAppear(false);
}
}

View File

@@ -566,6 +566,8 @@ public class TransitionTests extends WindowTestsBase {
doReturn(mock(IBinder.class)).when(delegateProc.getThread()).asBinder();
final ActivityRecord app = new ActivityBuilder(mAtm).setCreateTask(true)
.setVisible(false).build();
final Task task = app.getTask();
task.setTaskOrganizer(mock(ITaskOrganizer.class), true /* skipTaskAppeared */);
app.setVisibleRequested(true);
final TransitionController controller = app.mTransitionController;
final Transition transition = controller.createTransition(TRANSIT_OPEN);
@@ -576,7 +578,11 @@ public class TransitionTests extends WindowTestsBase {
controller.requestStartTransition(transition, null /* startTask */, remoteTransition,
null /* displayChange */);
testPlayer.startTransition();
app.onStartingWindowDrawn();
// The task appeared event should be deferred until transition ready.
assertFalse(task.taskAppearedReady());
testPlayer.onTransactionReady(app.getSyncTransaction());
assertTrue(task.taskAppearedReady());
assertTrue(playerProc.isRunningRemoteTransition());
assertTrue(delegateProc.isRunningRemoteTransition());
assertTrue(controller.mRemotePlayer.reportRunning(delegateProc.getThread()));