Merge "Reduce invocation of surface placement of switching activities" into sc-dev am: 63a50896d8
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14661879 Change-Id: Ic71c047cf2d0e7e5fa19794ae955d6580bd538dd
This commit is contained in:
@@ -181,6 +181,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
|
||||
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_FREE_RESIZE;
|
||||
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
|
||||
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
|
||||
import static com.android.server.wm.ActivityTaskManagerService.SKIP_LAYOUT_REASON_ALLOWED;
|
||||
import static com.android.server.wm.ActivityTaskManagerService.getInputDispatchingTimeoutMillisLocked;
|
||||
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
|
||||
import static com.android.server.wm.IdentifierProto.HASH_CODE;
|
||||
@@ -5376,6 +5377,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
|
||||
mAtmService.deferWindowLayout();
|
||||
try {
|
||||
task.completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
|
||||
// If there is no possible transition to execute, then allow to skip layout
|
||||
// because it may be done by next resumed activity.
|
||||
if (!pausingActivity.mDisplayContent.areOpeningAppsReady()) {
|
||||
mAtmService.addWindowLayoutReasons(SKIP_LAYOUT_REASON_ALLOWED);
|
||||
}
|
||||
} finally {
|
||||
mAtmService.continueWindowLayout();
|
||||
}
|
||||
|
||||
@@ -1555,6 +1555,8 @@ class ActivityStarter {
|
||||
}
|
||||
try {
|
||||
mService.deferWindowLayout();
|
||||
// Allow to skip layout because it may be done by the window of the starting activity.
|
||||
mService.addWindowLayoutReasons(ActivityTaskManagerService.SKIP_LAYOUT_REASON_ALLOWED);
|
||||
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "startActivityInner");
|
||||
result = startActivityInner(r, sourceRecord, voiceSession, voiceInteractor,
|
||||
startFlags, doResume, options, inTask, restrictedBgActivity, intentGrants);
|
||||
|
||||
@@ -657,14 +657,27 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
@IntDef({
|
||||
LAYOUT_REASON_CONFIG_CHANGED,
|
||||
LAYOUT_REASON_VISIBILITY_CHANGED,
|
||||
SKIP_LAYOUT_REASON_ALLOWED,
|
||||
SKIP_LAYOUT_REASON_EXPECT_NEXT_RELAYOUT,
|
||||
})
|
||||
@interface LayoutReason {
|
||||
}
|
||||
|
||||
static final int LAYOUT_REASON_MASK = 0x0000ffff;
|
||||
static final int LAYOUT_REASON_CONFIG_CHANGED = 0x1;
|
||||
static final int LAYOUT_REASON_VISIBILITY_CHANGED = 0x2;
|
||||
static final int SKIP_LAYOUT_REASON_MASK = 0xfffe0000;
|
||||
|
||||
/** The reasons to perform surface placement. */
|
||||
/**
|
||||
* Allow to call {@link WindowSurfacePlacer#endDeferAndSkipLayout} if there is a reason
|
||||
* included in {@link #SKIP_LAYOUT_REASON_MASK} was added.
|
||||
*/
|
||||
static final int SKIP_LAYOUT_REASON_ALLOWED = 1 << 16;
|
||||
|
||||
/** Used when the client is scheduled to call relayout. */
|
||||
static final int SKIP_LAYOUT_REASON_EXPECT_NEXT_RELAYOUT = 1 << 17;
|
||||
|
||||
/** The reasons to perform or skip surface placement. */
|
||||
@LayoutReason
|
||||
private int mLayoutReasons;
|
||||
|
||||
@@ -4206,18 +4219,35 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
mWindowManager.mWindowPlacerLocked.deferLayout();
|
||||
}
|
||||
|
||||
/** @see WindowSurfacePlacer#continueLayout */
|
||||
/**
|
||||
* @see WindowSurfacePlacer#continueLayout
|
||||
* @see WindowSurfacePlacer#endDeferAndSkipLayout
|
||||
*/
|
||||
void continueWindowLayout() {
|
||||
mWindowManager.mWindowPlacerLocked.continueLayout(mLayoutReasons != 0);
|
||||
if (DEBUG_ALL && !mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
|
||||
Slog.i(TAG, "continueWindowLayout reason=" + mLayoutReasons);
|
||||
if ((mLayoutReasons & SKIP_LAYOUT_REASON_ALLOWED) != 0) {
|
||||
final int skipReasons = mLayoutReasons & SKIP_LAYOUT_REASON_MASK;
|
||||
if (skipReasons != 0) {
|
||||
if (DEBUG_ALL) {
|
||||
Slog.i(TAG, "continueWindowLayout skip-reasons="
|
||||
+ Integer.toHexString(skipReasons));
|
||||
}
|
||||
mWindowManager.mWindowPlacerLocked.endDeferAndSkipLayout();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final int reasons = mLayoutReasons & LAYOUT_REASON_MASK;
|
||||
mWindowManager.mWindowPlacerLocked.continueLayout(reasons != 0);
|
||||
if (DEBUG_ALL && reasons != 0 && !mWindowManager.mWindowPlacerLocked.isLayoutDeferred()) {
|
||||
Slog.i(TAG, "continueWindowLayout reasons=" + Integer.toHexString(reasons));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a reason is added between {@link #deferWindowLayout} and {@link #continueWindowLayout},
|
||||
* it will make sure {@link WindowSurfacePlacer#performSurfacePlacement} is called when the last
|
||||
* defer count is gone.
|
||||
* If a reason within {@link #LAYOUT_REASON_MASK} is added between {@link #deferWindowLayout}
|
||||
* and {@link #continueWindowLayout}, {@link WindowSurfacePlacer#performSurfacePlacement} will
|
||||
* be called when the last defer count is gone. Note that the {@link #SKIP_LAYOUT_REASON_MASK}
|
||||
* has higher priority to determine whether to perform layout.
|
||||
*/
|
||||
void addWindowLayoutReasons(@LayoutReason int reasons) {
|
||||
mLayoutReasons |= reasons;
|
||||
|
||||
@@ -938,6 +938,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
|
||||
if (r.app != null) {
|
||||
r.app.updateServiceConnectionActivities();
|
||||
}
|
||||
// Expect a window of the starting activity will perform relayout.
|
||||
mService.addWindowLayoutReasons(
|
||||
ActivityTaskManagerService.SKIP_LAYOUT_REASON_EXPECT_NEXT_RELAYOUT);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4035,6 +4035,22 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
|
||||
return mLayoutNeeded;
|
||||
}
|
||||
|
||||
/** Returns {@code true} if all opening apps may be ready to execute transition. */
|
||||
boolean areOpeningAppsReady() {
|
||||
final int size = mOpeningApps.size();
|
||||
for (int i = size - 1; i >= 0; i--) {
|
||||
final ActivityRecord r = mOpeningApps.valueAt(i);
|
||||
if (!r.hasVisible) {
|
||||
return false;
|
||||
}
|
||||
final WindowState w = r.findMainWindow();
|
||||
if (w != null && !w.isDrawn()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return size > 0;
|
||||
}
|
||||
|
||||
void dumpTokens(PrintWriter pw, boolean dumpAll) {
|
||||
if (mTokenMap.isEmpty()) {
|
||||
return;
|
||||
|
||||
@@ -106,6 +106,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIB
|
||||
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
|
||||
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
|
||||
import static com.android.server.wm.ActivityTaskManagerService.H.FIRST_ACTIVITY_TASK_MSG;
|
||||
import static com.android.server.wm.ActivityTaskManagerService.SKIP_LAYOUT_REASON_EXPECT_NEXT_RELAYOUT;
|
||||
import static com.android.server.wm.ActivityTaskSupervisor.DEFER_RESUME;
|
||||
import static com.android.server.wm.ActivityTaskSupervisor.ON_TOP;
|
||||
import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS;
|
||||
@@ -6289,6 +6290,8 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
if (lastResumed != null) {
|
||||
lastResumed.setWillCloseOrEnterPip(true);
|
||||
}
|
||||
// There may be a relayout from resuming next activity after the previous is paused.
|
||||
mAtmService.addWindowLayoutReasons(SKIP_LAYOUT_REASON_EXPECT_NEXT_RELAYOUT);
|
||||
return true;
|
||||
} else if (mResumedActivity == next && next.isState(RESUMED)
|
||||
&& taskDisplayArea.allResumedActivitiesComplete()) {
|
||||
@@ -6498,6 +6501,7 @@ class Task extends WindowContainer<WindowContainer> {
|
||||
ResumeActivityItem.obtain(next.app.getReportedProcState(),
|
||||
dc.isNextTransitionForward()));
|
||||
mAtmService.getLifecycleManager().scheduleTransaction(transaction);
|
||||
mAtmService.addWindowLayoutReasons(SKIP_LAYOUT_REASON_EXPECT_NEXT_RELAYOUT);
|
||||
|
||||
ProtoLog.d(WM_DEBUG_STATES, "resumeTopActivityLocked: Resumed %s", next);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -101,6 +101,16 @@ class WindowSurfacePlacer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes layout passes but skip to perform layout even if there was a request. This can only
|
||||
* be called when there will be another layout request from client side, e.g. an activity is
|
||||
* starting or resuming. And there should be no other significant changes need to apply.
|
||||
*/
|
||||
void endDeferAndSkipLayout() {
|
||||
mDeferDepth--;
|
||||
mDeferredRequests = 0;
|
||||
}
|
||||
|
||||
boolean isLayoutDeferred() {
|
||||
return mDeferDepth > 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user