Demote top app scheduling group when unlocking
SystemUI may be running the unlock animation. If both SystemUI
and the resuming top app have top-app scheduling group, there
may be CPU contention which causes animation jank.
An exceptional case is unlocking to home which may also animate,
then keep original behavior: both system ui and home will have
top-app scheduling group.
Bug: 240356132
Bug: 226367352
Test: Launch calculator.
Keep executing command "adb shell dumpsys activity o | grep calc"
Lock and unlock device.
The dump will have the changes:
b/A/TPSL ---- t: 0 20687:calc/u0a158 (top-sleeping)
F/A/TOP LCMN t: 0 20687:calc/u0a158 (intermediate-top-activity)
T/A/TOP LCMN t: 0 20687:calc/u0a158 (top-activity)
(b=BG, F=FG, T=TOP)
Change-Id: Id0fd2491a11bac7b81bc654e646b3d01643ca8b4
Merged-In: Id0fd2491a11bac7b81bc654e646b3d01643ca8b4
(cherry picked from commit f3139a9e51)
This commit is contained in:
@@ -1556,14 +1556,22 @@ public class OomAdjuster {
|
||||
|
||||
boolean foregroundActivities = false;
|
||||
boolean hasVisibleActivities = false;
|
||||
if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == topApp) {
|
||||
if (app == topApp && (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP
|
||||
|| PROCESS_STATE_CUR_TOP == PROCESS_STATE_IMPORTANT_FOREGROUND)) {
|
||||
// The last app on the list is the foreground app.
|
||||
adj = ProcessList.FOREGROUND_APP_ADJ;
|
||||
schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
|
||||
state.setAdjType("top-activity");
|
||||
if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP) {
|
||||
schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
|
||||
state.setAdjType("top-activity");
|
||||
} else {
|
||||
// Demote the scheduling group to avoid CPU contention if there is another more
|
||||
// important process which also uses top-app, such as if SystemUI is animating.
|
||||
schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
|
||||
state.setAdjType("intermediate-top-activity");
|
||||
}
|
||||
foregroundActivities = true;
|
||||
hasVisibleActivities = true;
|
||||
procState = PROCESS_STATE_CUR_TOP;
|
||||
procState = PROCESS_STATE_TOP;
|
||||
if (DEBUG_OOM_ADJ_REASON || logUid == appUid) {
|
||||
reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app);
|
||||
}
|
||||
|
||||
@@ -64,8 +64,8 @@ import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
|
||||
import static android.provider.Settings.System.FONT_SCALE;
|
||||
import static android.view.Display.DEFAULT_DISPLAY;
|
||||
import static android.view.Display.INVALID_DISPLAY;
|
||||
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT;
|
||||
import static android.view.WindowManager.TRANSIT_WAKE;
|
||||
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT;
|
||||
|
||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION;
|
||||
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_FOCUS;
|
||||
@@ -400,6 +400,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
/** The time at which the previous process was last visible. */
|
||||
private long mPreviousProcessVisibleTime;
|
||||
|
||||
/**
|
||||
* It can be true from keyguard-going-away to set-keyguard-shown. And getTopProcessState() will
|
||||
* return {@link ActivityManager#PROCESS_STATE_IMPORTANT_FOREGROUND} to avoid top app from
|
||||
* preempting CPU while keyguard is animating.
|
||||
*/
|
||||
private volatile boolean mDemoteTopAppDuringUnlocking;
|
||||
|
||||
/** List of intents that were used to start the most recent tasks. */
|
||||
private RecentTasks mRecentTasks;
|
||||
/** State of external calls telling us if the device is awake or asleep. */
|
||||
@@ -2830,12 +2837,24 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
keyguardShowing);
|
||||
mH.sendMessage(msg);
|
||||
}
|
||||
// Always reset the state regardless of keyguard-showing change, because that means the
|
||||
// unlock is either completed or canceled.
|
||||
if (mDemoteTopAppDuringUnlocking) {
|
||||
mDemoteTopAppDuringUnlocking = false;
|
||||
// The scheduling group of top process was demoted by unlocking, so recompute
|
||||
// to restore its real top priority if possible.
|
||||
if (mTopApp != null) {
|
||||
mTopApp.scheduleUpdateOomAdj();
|
||||
}
|
||||
}
|
||||
try {
|
||||
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "setLockScreenShown");
|
||||
mRootWindowContainer.forAllDisplays(displayContent -> {
|
||||
mKeyguardController.setKeyguardShown(displayContent.getDisplayId(),
|
||||
keyguardShowing, aodShowing);
|
||||
});
|
||||
} finally {
|
||||
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
}
|
||||
@@ -2862,6 +2881,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
// animation of system UI. Even if AOD is not enabled, it should be no harm.
|
||||
final WindowProcessController proc;
|
||||
synchronized (mGlobalLockWithoutBoost) {
|
||||
mDemoteTopAppDuringUnlocking = false;
|
||||
final WindowState notificationShade = mRootWindowContainer.getDefaultDisplay()
|
||||
.getDisplayPolicy().getNotificationShade();
|
||||
proc = notificationShade != null
|
||||
@@ -3399,8 +3419,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
try {
|
||||
synchronized (mGlobalLock) {
|
||||
// Keyguard asked us to clear the home task snapshot before going away, so do that.
|
||||
if ((flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_LAUNCHER_CLEAR_SNAPSHOT) != 0) {
|
||||
if ((flags & KEYGUARD_GOING_AWAY_FLAG_TO_LAUNCHER_CLEAR_SNAPSHOT) != 0) {
|
||||
mActivityClientController.invalidateHomeTaskSnapshot(null /* token */);
|
||||
} else if (mKeyguardShown) {
|
||||
// Only set if it is not unlocking to launcher which may also animate.
|
||||
mDemoteTopAppDuringUnlocking = true;
|
||||
}
|
||||
|
||||
mRootWindowContainer.forAllDisplays(displayContent -> {
|
||||
@@ -5595,12 +5618,17 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
|
||||
@HotPath(caller = HotPath.OOM_ADJUSTMENT)
|
||||
@Override
|
||||
public int getTopProcessState() {
|
||||
final int topState = mTopProcessState;
|
||||
if (mDemoteTopAppDuringUnlocking && topState == ActivityManager.PROCESS_STATE_TOP) {
|
||||
// The unlocking UI is more important, so defer the top state of app.
|
||||
return ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
|
||||
}
|
||||
if (mRetainPowerModeAndTopProcessState) {
|
||||
// There is a launching app while device may be sleeping, force the top state so
|
||||
// the launching process can have top-app scheduling group.
|
||||
return ActivityManager.PROCESS_STATE_TOP;
|
||||
}
|
||||
return mTopProcessState;
|
||||
return topState;
|
||||
}
|
||||
|
||||
@HotPath(caller = HotPath.PROCESS_CHANGE)
|
||||
|
||||
@@ -1126,6 +1126,13 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
|
||||
mAtm.mH.sendMessage(m);
|
||||
}
|
||||
|
||||
/** Refreshes oom adjustment and process state of this process. */
|
||||
void scheduleUpdateOomAdj() {
|
||||
mAtm.mH.sendMessage(PooledLambda.obtainMessage(WindowProcessListener::updateProcessInfo,
|
||||
mListener, false /* updateServiceConnectionActivities */,
|
||||
false /* activityChange */, true /* updateOomAdj */));
|
||||
}
|
||||
|
||||
/** Makes the process have top state before oom-adj is computed from a posted message. */
|
||||
void addToPendingTop() {
|
||||
mAtm.mAmInternal.addPendingTopUid(mUid, mPid, mThread);
|
||||
|
||||
Reference in New Issue
Block a user