From f80e196f4d4ceb9b0cdf85d16453e3639186f1e4 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Mon, 7 Jun 2021 21:06:16 +0800 Subject: [PATCH] Execute app transition if starting window is drawn For non-cold launch, the transition is executed after scheduling to start/resume next activity. But for cold launch, the activity will be started until its process is attached. Because transition should be able to run if the starting window is drawn, it can be executed earlier to have better response time. That may reduce transition delay up to 40ms. Bug: 161781889 Bug: 182836977 Test: Cold launch app with starting window. Check the trace that AppTransitionReady happens before attachApplication. Test: atest CloseImeAutoOpenWindowToAppTest Change-Id: I66b9a6ef4e14289ddbecb4971620981a9eca4afa --- .../com/android/server/wm/ActivityRecord.java | 22 +++++++++++++++++-- .../server/wm/ActivityTaskSupervisor.java | 6 ++--- .../com/android/server/wm/StartingData.java | 6 +++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 45da45aafabaf..047dcdbfeba60 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -5739,10 +5739,24 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } void onStartingWindowDrawn() { + boolean wasTaskVisible = false; if (task != null) { mSplashScreenStyleEmpty = true; + wasTaskVisible = task.getHasBeenVisible(); task.setHasBeenVisible(true); } + + // The transition may not be executed if the starting process hasn't attached. But if the + // starting window is drawn, the transition can start earlier. Exclude finishing and bubble + // because it may be a trampoline. + if (!wasTaskVisible && mStartingData != null && !finishing && !mLaunchedFromBubble + && !mDisplayContent.mAppTransition.isReady() + && !mDisplayContent.mAppTransition.isRunning()) { + // The pending transition state will be cleared after the transition is started, so + // save the state for launching the client later (used by LaunchActivityItem). + mStartingData.mIsTransitionForward = mDisplayContent.isNextTransitionForward(); + mDisplayContent.executeAppTransition(); + } } /** Called when the windows associated app window container are drawn. */ @@ -6455,6 +6469,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A || dc.mChangingContainers.contains(this)); } + boolean isTransitionForward() { + return (mStartingData != null && mStartingData.mIsTransitionForward) + || mDisplayContent.isNextTransitionForward(); + } + private int getAnimationLayer() { // The leash is parented to the animation layer. We need to preserve the z-order by using // the prefix order index, but we boost if necessary. @@ -8060,8 +8079,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A preserveWindow); final ActivityLifecycleItem lifecycleItem; if (andResume) { - lifecycleItem = ResumeActivityItem.obtain( - mDisplayContent.isNextTransitionForward()); + lifecycleItem = ResumeActivityItem.obtain(isTransitionForward()); } else { lifecycleItem = PauseActivityItem.obtain(); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index 7fe0f5be287c6..d3d1c1ca6a2bc 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -836,7 +836,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { final ClientTransaction clientTransaction = ClientTransaction.obtain( proc.getThread(), r.appToken); - final DisplayContent dc = r.mDisplayContent; + final boolean isTransitionForward = r.isTransitionForward(); clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent), System.identityHashCode(r), r.info, // TODO: Have this take the merged configuration instead of separate global @@ -845,7 +845,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { mergedConfiguration.getOverrideConfiguration(), r.compat, r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(), results, newIntents, - r.takeOptions(), dc.isNextTransitionForward(), + r.takeOptions(), isTransitionForward, proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController, r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken, r.getLaunchedFromBubble())); @@ -853,7 +853,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // Set desired final state. final ActivityLifecycleItem lifecycleItem; if (andResume) { - lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward()); + lifecycleItem = ResumeActivityItem.obtain(isTransitionForward); } else { lifecycleItem = PauseActivityItem.obtain(); } diff --git a/services/core/java/com/android/server/wm/StartingData.java b/services/core/java/com/android/server/wm/StartingData.java index 59de43ac95a38..3f9c93bbcfbea 100644 --- a/services/core/java/com/android/server/wm/StartingData.java +++ b/services/core/java/com/android/server/wm/StartingData.java @@ -26,6 +26,12 @@ public abstract class StartingData { protected final WindowManagerService mService; protected final int mTypeParams; + /** + * Tell whether the launching activity should use + * {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_IS_FORWARD_NAVIGATION}. + */ + boolean mIsTransitionForward; + protected StartingData(WindowManagerService service, int typeParams) { mService = service; mTypeParams = typeParams;