Merge changes I0d002ea4,Id0fd2491 into tm-d1-dev am: 900509b712

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19465513

Change-Id: I6900ed6863ba0fd7cf6db6d4576c6ec00b4ca84e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Wei Wang
2022-07-29 22:59:30 +00:00
committed by Automerger Merge Worker
5 changed files with 96 additions and 33 deletions

View File

@@ -400,12 +400,25 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
/** The time at which the previous process was last visible. */ /** The time at which the previous process was last visible. */
private long mPreviousProcessVisibleTime; private long mPreviousProcessVisibleTime;
/** It is set from keyguard-going-away to set-keyguard-shown. */
static final int DEMOTE_TOP_REASON_DURING_UNLOCKING = 1;
/** It is set if legacy recents animation is running. */
static final int DEMOTE_TOP_REASON_ANIMATING_RECENTS = 1 << 1;
@Retention(RetentionPolicy.SOURCE)
@IntDef({
DEMOTE_TOP_REASON_DURING_UNLOCKING,
DEMOTE_TOP_REASON_ANIMATING_RECENTS,
})
@interface DemoteTopReason {}
/** /**
* It can be true from keyguard-going-away to set-keyguard-shown. And getTopProcessState() will * If non-zero, getTopProcessState() will
* return {@link ActivityManager#PROCESS_STATE_IMPORTANT_FOREGROUND} to avoid top app from * return {@link ActivityManager#PROCESS_STATE_IMPORTANT_FOREGROUND} to avoid top app from
* preempting CPU while keyguard is animating. * preempting CPU while another process is running an important animation.
*/ */
private volatile boolean mDemoteTopAppDuringUnlocking; @DemoteTopReason
volatile int mDemoteTopAppReasons;
/** List of intents that were used to start the most recent tasks. */ /** List of intents that were used to start the most recent tasks. */
private RecentTasks mRecentTasks; private RecentTasks mRecentTasks;
@@ -2839,8 +2852,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
} }
// Always reset the state regardless of keyguard-showing change, because that means the // Always reset the state regardless of keyguard-showing change, because that means the
// unlock is either completed or canceled. // unlock is either completed or canceled.
if (mDemoteTopAppDuringUnlocking) { if ((mDemoteTopAppReasons & DEMOTE_TOP_REASON_DURING_UNLOCKING) != 0) {
mDemoteTopAppDuringUnlocking = false; mDemoteTopAppReasons &= ~DEMOTE_TOP_REASON_DURING_UNLOCKING;
// The scheduling group of top process was demoted by unlocking, so recompute // The scheduling group of top process was demoted by unlocking, so recompute
// to restore its real top priority if possible. // to restore its real top priority if possible.
if (mTopApp != null) { if (mTopApp != null) {
@@ -2881,7 +2894,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
// animation of system UI. Even if AOD is not enabled, it should be no harm. // animation of system UI. Even if AOD is not enabled, it should be no harm.
final WindowProcessController proc; final WindowProcessController proc;
synchronized (mGlobalLockWithoutBoost) { synchronized (mGlobalLockWithoutBoost) {
mDemoteTopAppDuringUnlocking = false; mDemoteTopAppReasons &= ~DEMOTE_TOP_REASON_DURING_UNLOCKING;
final WindowState notificationShade = mRootWindowContainer.getDefaultDisplay() final WindowState notificationShade = mRootWindowContainer.getDefaultDisplay()
.getDisplayPolicy().getNotificationShade(); .getDisplayPolicy().getNotificationShade();
proc = notificationShade != null proc = notificationShade != null
@@ -3423,7 +3436,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
mActivityClientController.invalidateHomeTaskSnapshot(null /* token */); mActivityClientController.invalidateHomeTaskSnapshot(null /* token */);
} else if (mKeyguardShown) { } else if (mKeyguardShown) {
// Only set if it is not unlocking to launcher which may also animate. // Only set if it is not unlocking to launcher which may also animate.
mDemoteTopAppDuringUnlocking = true; mDemoteTopAppReasons |= DEMOTE_TOP_REASON_DURING_UNLOCKING;
} }
mRootWindowContainer.forAllDisplays(displayContent -> { mRootWindowContainer.forAllDisplays(displayContent -> {
@@ -3991,6 +4004,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
mTaskOrganizerController.dump(pw, " "); mTaskOrganizerController.dump(pw, " ");
mVisibleActivityProcessTracker.dump(pw, " "); mVisibleActivityProcessTracker.dump(pw, " ");
mActiveUids.dump(pw, " "); mActiveUids.dump(pw, " ");
if (mDemoteTopAppReasons != 0) {
pw.println(" mDemoteTopAppReasons=" + mDemoteTopAppReasons);
}
} }
if (!printedAnything) { if (!printedAnything) {
@@ -5619,8 +5635,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override @Override
public int getTopProcessState() { public int getTopProcessState() {
final int topState = mTopProcessState; final int topState = mTopProcessState;
if (mDemoteTopAppDuringUnlocking && topState == ActivityManager.PROCESS_STATE_TOP) { if (mDemoteTopAppReasons != 0 && topState == ActivityManager.PROCESS_STATE_TOP) {
// The unlocking UI is more important, so defer the top state of app. // There may be a more important UI/animation than the top app.
return ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; return ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
} }
if (mRetainPowerModeAndTopProcessState) { if (mRetainPowerModeAndTopProcessState) {

View File

@@ -203,9 +203,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChan
final LaunchingState launchingState = final LaunchingState launchingState =
mTaskSupervisor.getActivityMetricsLogger().notifyActivityLaunching(mTargetIntent); mTaskSupervisor.getActivityMetricsLogger().notifyActivityLaunching(mTargetIntent);
if (mCaller != null) { setProcessAnimating(true);
mCaller.setRunningRecentsAnimation(true);
}
mService.deferWindowLayout(); mService.deferWindowLayout();
try { try {
@@ -409,15 +407,33 @@ class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChan
if (mWindowManager.mRoot.isLayoutNeeded()) { if (mWindowManager.mRoot.isLayoutNeeded()) {
mWindowManager.mRoot.performSurfacePlacement(); mWindowManager.mRoot.performSurfacePlacement();
} }
if (mCaller != null) { setProcessAnimating(false);
mCaller.setRunningRecentsAnimation(false);
}
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
} }
}); });
} }
} }
/** Gives the owner of recents animation higher priority. */
private void setProcessAnimating(boolean animating) {
if (mCaller == null) return;
// Apply the top-app scheduling group to who runs the animation.
mCaller.setRunningRecentsAnimation(animating);
int demoteReasons = mService.mDemoteTopAppReasons;
if (animating) {
demoteReasons |= ActivityTaskManagerService.DEMOTE_TOP_REASON_ANIMATING_RECENTS;
} else {
demoteReasons &= ~ActivityTaskManagerService.DEMOTE_TOP_REASON_ANIMATING_RECENTS;
}
mService.mDemoteTopAppReasons = demoteReasons;
// Make the demotion of the real top app take effect. No need to restore top app state for
// finishing recents because addToStopping -> scheduleIdle -> activityIdleInternal ->
// trimApplications will have a full update.
if (animating && mService.mTopApp != null) {
mService.mTopApp.scheduleUpdateOomAdj();
}
}
@Override @Override
public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode, public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode,
boolean sendUserLeaveHint) { boolean sendUserLeaveHint) {

View File

@@ -37,13 +37,13 @@ import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import android.app.IApplicationThread;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
@@ -91,9 +91,15 @@ public class RecentsAnimationTest extends WindowTestsBase {
TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
Task recentsStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN, Task recentsStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_RECENTS, true /* onTop */); ACTIVITY_TYPE_RECENTS, true /* onTop */);
final WindowProcessController wpc = mSystemServicesTestRule.addProcess(
mRecentsComponent.getPackageName(), mRecentsComponent.getPackageName(),
// Use real pid/uid of the test so the corresponding process can be mapped by
// Binder.getCallingPid/Uid.
android.os.Process.myPid(), android.os.Process.myUid());
ActivityRecord recentActivity = new ActivityBuilder(mAtm) ActivityRecord recentActivity = new ActivityBuilder(mAtm)
.setComponent(mRecentsComponent) .setComponent(mRecentsComponent)
.setTask(recentsStack) .setTask(recentsStack)
.setUseProcess(wpc)
.build(); .build();
ActivityRecord topActivity = new ActivityBuilder(mAtm).setCreateTask(true).build(); ActivityRecord topActivity = new ActivityBuilder(mAtm).setCreateTask(true).build();
topActivity.getRootTask().moveToFront("testRecentsActivityVisiblility"); topActivity.getRootTask().moveToFront("testRecentsActivityVisiblility");
@@ -106,11 +112,14 @@ public class RecentsAnimationTest extends WindowTestsBase {
mRecentsComponent, true /* getRecentsAnimation */); mRecentsComponent, true /* getRecentsAnimation */);
// The launch-behind state should make the recents activity visible. // The launch-behind state should make the recents activity visible.
assertTrue(recentActivity.mVisibleRequested); assertTrue(recentActivity.mVisibleRequested);
assertEquals(ActivityTaskManagerService.DEMOTE_TOP_REASON_ANIMATING_RECENTS,
mAtm.mDemoteTopAppReasons);
// Simulate the animation is cancelled without changing the stack order. // Simulate the animation is cancelled without changing the stack order.
recentsAnimation.onAnimationFinished(REORDER_KEEP_IN_PLACE, false /* sendUserLeaveHint */); recentsAnimation.onAnimationFinished(REORDER_KEEP_IN_PLACE, false /* sendUserLeaveHint */);
// The non-top recents activity should be invisible by the restored launch-behind state. // The non-top recents activity should be invisible by the restored launch-behind state.
assertFalse(recentActivity.mVisibleRequested); assertFalse(recentActivity.mVisibleRequested);
assertEquals(0, mAtm.mDemoteTopAppReasons);
} }
@Test @Test
@@ -138,11 +147,8 @@ public class RecentsAnimationTest extends WindowTestsBase {
anyInt() /* startFlags */, any() /* profilerInfo */); anyInt() /* startFlags */, any() /* profilerInfo */);
// Assume its process is alive because the caller should be the recents service. // Assume its process is alive because the caller should be the recents service.
WindowProcessController wpc = new WindowProcessController(mAtm, aInfo.applicationInfo, mSystemServicesTestRule.addProcess(aInfo.packageName, aInfo.processName, 12345 /* pid */,
aInfo.processName, aInfo.applicationInfo.uid, 0 /* userId */, aInfo.applicationInfo.uid);
mock(Object.class) /* owner */, mock(WindowProcessListener.class));
wpc.setThread(mock(IApplicationThread.class));
doReturn(wpc).when(mAtm).getProcessController(eq(wpc.mName), eq(wpc.mUid));
Intent recentsIntent = new Intent().setComponent(mRecentsComponent); Intent recentsIntent = new Intent().setComponent(mRecentsComponent);
// Null animation indicates to preload. // Null animation indicates to preload.

View File

@@ -43,12 +43,14 @@ import static org.mockito.Mockito.withSettings;
import android.app.ActivityManagerInternal; import android.app.ActivityManagerInternal;
import android.app.AppOpsManager; import android.app.AppOpsManager;
import android.app.IApplicationThread;
import android.app.usage.UsageStatsManagerInternal; import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager; import android.content.pm.IPackageManager;
import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManagerInternal;
import android.database.ContentObserver; import android.database.ContentObserver;
@@ -454,8 +456,32 @@ public class SystemServicesTestRule implements TestRule {
.spiedInstance(sWakeLock).stubOnly()); .spiedInstance(sWakeLock).stubOnly());
} }
void setSurfaceFactory(Supplier<Surface> factory) { WindowProcessController addProcess(String pkgName, String procName, int pid, int uid) {
mSurfaceFactory = factory; return addProcess(mAtmService, pkgName, procName, pid, uid);
}
static WindowProcessController addProcess(ActivityTaskManagerService atmService, String pkgName,
String procName, int pid, int uid) {
final ApplicationInfo info = new ApplicationInfo();
info.uid = uid;
info.packageName = pkgName;
return addProcess(atmService, info, procName, pid);
}
static WindowProcessController addProcess(ActivityTaskManagerService atmService,
ApplicationInfo info, String procName, int pid) {
final WindowProcessListener mockListener = mock(WindowProcessListener.class,
withSettings().stubOnly());
final int uid = info.uid;
final WindowProcessController proc = new WindowProcessController(atmService,
info, procName, uid, UserHandle.getUserId(uid), mockListener, mockListener);
proc.setThread(mock(IApplicationThread.class, withSettings().stubOnly()));
atmService.mProcessNames.put(procName, uid, proc);
if (pid > 0) {
proc.setPid(pid);
atmService.mProcessMap.put(pid, proc);
}
return proc;
} }
void cleanupWindowManagerHandlers() { void cleanupWindowManagerHandlers() {

View File

@@ -64,7 +64,6 @@ import android.annotation.IntDef;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.ActivityOptions; import android.app.ActivityOptions;
import android.app.IApplicationThread;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@@ -915,13 +914,15 @@ class WindowTestsBase extends SystemServiceTestsBase {
*/ */
protected static class ActivityBuilder { protected static class ActivityBuilder {
static final int DEFAULT_FAKE_UID = 12345; static final int DEFAULT_FAKE_UID = 12345;
static final String DEFAULT_PROCESS_NAME = "procName";
static int sProcNameSeq;
private final ActivityTaskManagerService mService; private final ActivityTaskManagerService mService;
private ComponentName mComponent; private ComponentName mComponent;
private String mTargetActivity; private String mTargetActivity;
private Task mTask; private Task mTask;
private String mProcessName = "name"; private String mProcessName = DEFAULT_PROCESS_NAME;
private String mAffinity; private String mAffinity;
private int mUid = DEFAULT_FAKE_UID; private int mUid = DEFAULT_FAKE_UID;
private boolean mCreateTask = false; private boolean mCreateTask = false;
@@ -1109,6 +1110,9 @@ class WindowTestsBase extends SystemServiceTestsBase {
aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT; aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
aInfo.applicationInfo.packageName = mComponent.getPackageName(); aInfo.applicationInfo.packageName = mComponent.getPackageName();
aInfo.applicationInfo.uid = mUid; aInfo.applicationInfo.uid = mUid;
if (DEFAULT_PROCESS_NAME.equals(mProcessName)) {
mProcessName += ++sProcNameSeq;
}
aInfo.processName = mProcessName; aInfo.processName = mProcessName;
aInfo.packageName = mComponent.getPackageName(); aInfo.packageName = mComponent.getPackageName();
aInfo.name = mComponent.getClassName(); aInfo.name = mComponent.getClassName();
@@ -1173,16 +1177,11 @@ class WindowTestsBase extends SystemServiceTestsBase {
if (mWpc != null) { if (mWpc != null) {
wpc = mWpc; wpc = mWpc;
} else { } else {
wpc = new WindowProcessController(mService, final WindowProcessController p = mService.getProcessController(mProcessName, mUid);
aInfo.applicationInfo, mProcessName, mUid, wpc = p != null ? p : SystemServicesTestRule.addProcess(
UserHandle.getUserId(mUid), mock(Object.class), mService, aInfo.applicationInfo, mProcessName, 0 /* pid */);
mock(WindowProcessListener.class));
wpc.setThread(mock(IApplicationThread.class));
} }
wpc.setThread(mock(IApplicationThread.class));
activity.setProcess(wpc); activity.setProcess(wpc);
doReturn(wpc).when(mService).getProcessController(
activity.processName, activity.info.applicationInfo.uid);
// Resume top activities to make sure all other signals in the system are connected. // Resume top activities to make sure all other signals in the system are connected.
mService.mRootWindowContainer.resumeFocusedTasksTopActivities(); mService.mRootWindowContainer.resumeFocusedTasksTopActivities();