Merge "Consider process priority of unknown visibility launching app" into sc-v2-dev

This commit is contained in:
TreeHugger Robot
2021-09-13 04:59:24 +00:00
committed by Android (Google) Code Review
3 changed files with 86 additions and 16 deletions

View File

@@ -653,16 +653,25 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
*/
volatile int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
/** Whether to keep higher priority to launch app while device is sleeping. */
private volatile boolean mRetainPowerModeAndTopProcessState;
/** The timeout to restore power mode if {@link #mRetainPowerModeAndTopProcessState} is set. */
private static final long POWER_MODE_UNKNOWN_VISIBILITY_TIMEOUT_MS = 1000;
@Retention(RetentionPolicy.SOURCE)
@IntDef({
POWER_MODE_REASON_START_ACTIVITY,
POWER_MODE_REASON_FREEZE_DISPLAY,
POWER_MODE_REASON_UNKNOWN_VISIBILITY,
POWER_MODE_REASON_ALL,
})
@interface PowerModeReason {}
static final int POWER_MODE_REASON_START_ACTIVITY = 1 << 0;
static final int POWER_MODE_REASON_FREEZE_DISPLAY = 1 << 1;
/** @see UnknownAppVisibilityController */
static final int POWER_MODE_REASON_UNKNOWN_VISIBILITY = 1 << 2;
/** This can only be used by {@link #endLaunchPowerMode(int)}.*/
static final int POWER_MODE_REASON_ALL = (1 << 2) - 1;
@@ -4248,15 +4257,39 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
void startLaunchPowerMode(@PowerModeReason int reason) {
if (mPowerManagerInternal == null) return;
mPowerManagerInternal.setPowerMode(Mode.LAUNCH, true);
if (mPowerManagerInternal != null) {
mPowerManagerInternal.setPowerMode(Mode.LAUNCH, true);
}
mLaunchPowerModeReasons |= reason;
if ((reason & POWER_MODE_REASON_UNKNOWN_VISIBILITY) != 0) {
if (mRetainPowerModeAndTopProcessState) {
mH.removeMessages(H.END_POWER_MODE_UNKNOWN_VISIBILITY_MSG);
}
mRetainPowerModeAndTopProcessState = true;
mH.sendEmptyMessageDelayed(H.END_POWER_MODE_UNKNOWN_VISIBILITY_MSG,
POWER_MODE_UNKNOWN_VISIBILITY_TIMEOUT_MS);
Slog.d(TAG, "Temporarily retain top process state for launching app");
}
}
void endLaunchPowerMode(@PowerModeReason int reason) {
if (mPowerManagerInternal == null || mLaunchPowerModeReasons == 0) return;
if (mLaunchPowerModeReasons == 0) return;
mLaunchPowerModeReasons &= ~reason;
if (mLaunchPowerModeReasons == 0) {
if ((mLaunchPowerModeReasons & POWER_MODE_REASON_UNKNOWN_VISIBILITY) != 0) {
boolean allResolved = true;
for (int i = mRootWindowContainer.getChildCount() - 1; i >= 0; i--) {
allResolved &= mRootWindowContainer.getChildAt(i).mUnknownAppVisibilityController
.allResolved();
}
if (allResolved) {
mLaunchPowerModeReasons &= ~POWER_MODE_REASON_UNKNOWN_VISIBILITY;
mRetainPowerModeAndTopProcessState = false;
mH.removeMessages(H.END_POWER_MODE_UNKNOWN_VISIBILITY_MSG);
}
}
if (mLaunchPowerModeReasons == 0 && mPowerManagerInternal != null) {
mPowerManagerInternal.setPowerMode(Mode.LAUNCH, false);
}
}
@@ -5123,6 +5156,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final class H extends Handler {
static final int REPORT_TIME_TRACKER_MSG = 1;
static final int UPDATE_PROCESS_ANIMATING_STATE = 2;
static final int END_POWER_MODE_UNKNOWN_VISIBILITY_MSG = 3;
static final int FIRST_ACTIVITY_TASK_MSG = 100;
static final int FIRST_SUPERVISOR_TASK_MSG = 200;
@@ -5146,6 +5180,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
}
break;
case END_POWER_MODE_UNKNOWN_VISIBILITY_MSG: {
synchronized (mGlobalLock) {
mRetainPowerModeAndTopProcessState = false;
endLaunchPowerMode(POWER_MODE_REASON_UNKNOWN_VISIBILITY);
if (mTopApp != null
&& mTopProcessState == ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
// Restore the scheduling group for sleeping.
mTopApp.updateProcessInfo(false /* updateServiceConnection */,
false /* activityChange */, true /* updateOomAdj */,
false /* addPendingTopUid */);
}
}
}
break;
}
}
}
@@ -5464,6 +5512,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@HotPath(caller = HotPath.OOM_ADJUSTMENT)
@Override
public int getTopProcessState() {
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;
}

View File

@@ -3545,14 +3545,7 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
}
void startPowerModeLaunchIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
final boolean sendPowerModeLaunch;
if (forceSend) {
sendPowerModeLaunch = true;
} else if (targetActivity == null || targetActivity.app == null) {
// Set power mode if we don't know what we're launching yet.
sendPowerModeLaunch = true;
} else {
if (!forceSend && targetActivity != null && targetActivity.app != null) {
// Set power mode when the activity's process is different than the current top resumed
// activity on all display areas, or if there are no resumed activities in the system.
boolean[] noResumedActivities = {true};
@@ -3568,13 +3561,28 @@ class RootWindowContainer extends WindowContainer<DisplayContent>
!resumedActivityProcess.equals(targetActivity.app);
}
});
sendPowerModeLaunch = noResumedActivities[0] || allFocusedProcessesDiffer[0];
if (!noResumedActivities[0] && !allFocusedProcessesDiffer[0]) {
// All focused activities are resumed and the process of the target activity is
// the same as them, e.g. delivering new intent to the current top.
return;
}
}
if (sendPowerModeLaunch) {
mService.startLaunchPowerMode(
ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY);
int reason = ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY;
// If the activity is launching while keyguard is locked (including occluded), the activity
// may be visible until its first relayout is done (e.g. apply show-when-lock flag). To
// avoid power mode from being cleared before that, add a special reason to consider whether
// the unknown visibility is resolved. The case from SystemUI is excluded because it should
// rely on keyguard-going-away.
if (mService.mKeyguardController.isKeyguardLocked() && targetActivity != null
&& !targetActivity.isLaunchSourceType(ActivityRecord.LAUNCH_SOURCE_TYPE_SYSTEMUI)) {
final ActivityOptions opts = targetActivity.getOptions();
if (opts == null || opts.getSourceInfo() == null
|| opts.getSourceInfo().type != ActivityOptions.SourceInfo.TYPE_LOCKSCREEN) {
reason |= ActivityTaskManagerService.POWER_MODE_REASON_UNKNOWN_VISIBILITY;
}
}
mService.startLaunchPowerMode(reason);
}
// TODO(b/191434136): handle this properly when we add multi-window support on secondary

View File

@@ -301,6 +301,15 @@ public class ActivityTaskManagerServiceTests extends WindowTestsBase {
// The top app should not change while sleeping.
assertEquals(topActivity.app, mAtm.mInternal.getTopApp());
mAtm.startLaunchPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY
| ActivityTaskManagerService.POWER_MODE_REASON_UNKNOWN_VISIBILITY);
assertEquals(ActivityManager.PROCESS_STATE_TOP, mAtm.mInternal.getTopProcessState());
// Because there is no unknown visibility record, the state will be restored if other
// reasons are all done.
mAtm.endLaunchPowerMode(ActivityTaskManagerService.POWER_MODE_REASON_START_ACTIVITY);
assertEquals(ActivityManager.PROCESS_STATE_TOP_SLEEPING,
mAtm.mInternal.getTopProcessState());
// If all activities are stopped, the sleep wake lock must be released.
final Task topRootTask = topActivity.getRootTask();
doReturn(true).when(rootHomeTask).goToSleepIfPossible(anyBoolean());