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:
@@ -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) {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user