Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 436c3510 authored by Wei Wang's avatar Wei Wang Committed by Automerger Merge Worker
Browse files

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

parents 922942c0 900509b7
Loading
Loading
Loading
Loading
+25 −9
Original line number Diff line number Diff line
@@ -400,12 +400,25 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    /** The time at which the previous process was last visible. */
    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
     * 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. */
    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
            // unlock is either completed or canceled.
            if (mDemoteTopAppDuringUnlocking) {
                mDemoteTopAppDuringUnlocking = false;
            if ((mDemoteTopAppReasons & DEMOTE_TOP_REASON_DURING_UNLOCKING) != 0) {
                mDemoteTopAppReasons &= ~DEMOTE_TOP_REASON_DURING_UNLOCKING;
                // The scheduling group of top process was demoted by unlocking, so recompute
                // to restore its real top priority if possible.
                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.
        final WindowProcessController proc;
        synchronized (mGlobalLockWithoutBoost) {
            mDemoteTopAppDuringUnlocking = false;
            mDemoteTopAppReasons &= ~DEMOTE_TOP_REASON_DURING_UNLOCKING;
            final WindowState notificationShade = mRootWindowContainer.getDefaultDisplay()
                    .getDisplayPolicy().getNotificationShade();
            proc = notificationShade != null
@@ -3423,7 +3436,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                    mActivityClientController.invalidateHomeTaskSnapshot(null /* token */);
                } else if (mKeyguardShown) {
                    // Only set if it is not unlocking to launcher which may also animate.
                    mDemoteTopAppDuringUnlocking = true;
                    mDemoteTopAppReasons |= DEMOTE_TOP_REASON_DURING_UNLOCKING;
                }

                mRootWindowContainer.forAllDisplays(displayContent -> {
@@ -3991,6 +4004,9 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            mTaskOrganizerController.dump(pw, "  ");
            mVisibleActivityProcessTracker.dump(pw, "  ");
            mActiveUids.dump(pw, "  ");
            if (mDemoteTopAppReasons != 0) {
                pw.println("  mDemoteTopAppReasons=" + mDemoteTopAppReasons);
            }
        }

        if (!printedAnything) {
@@ -5619,8 +5635,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        @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.
            if (mDemoteTopAppReasons != 0 && topState == ActivityManager.PROCESS_STATE_TOP) {
                // There may be a more important UI/animation than the top app.
                return ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
            }
            if (mRetainPowerModeAndTopProcessState) {
+22 −6
Original line number Diff line number Diff line
@@ -203,9 +203,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChan
        final LaunchingState launchingState =
                mTaskSupervisor.getActivityMetricsLogger().notifyActivityLaunching(mTargetIntent);

        if (mCaller != null) {
            mCaller.setRunningRecentsAnimation(true);
        }
        setProcessAnimating(true);

        mService.deferWindowLayout();
        try {
@@ -409,15 +407,33 @@ class RecentsAnimation implements RecentsAnimationCallbacks, OnRootTaskOrderChan
                    if (mWindowManager.mRoot.isLayoutNeeded()) {
                        mWindowManager.mRoot.performSurfacePlacement();
                    }
                    if (mCaller != null) {
                        mCaller.setRunningRecentsAnimation(false);
                    }
                    setProcessAnimating(false);
                    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
    public void onAnimationFinished(@RecentsAnimationController.ReorderMode int reorderMode,
            boolean sendUserLeaveHint) {
+12 −6
Original line number Diff line number Diff line
@@ -37,13 +37,13 @@ import static com.android.server.wm.WindowContainer.POSITION_TOP;

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.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;

import android.app.IApplicationThread;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -91,9 +91,15 @@ public class RecentsAnimationTest extends WindowTestsBase {
        TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
        Task recentsStack = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
                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)
                .setComponent(mRecentsComponent)
                .setTask(recentsStack)
                .setUseProcess(wpc)
                .build();
        ActivityRecord topActivity = new ActivityBuilder(mAtm).setCreateTask(true).build();
        topActivity.getRootTask().moveToFront("testRecentsActivityVisiblility");
@@ -106,11 +112,14 @@ public class RecentsAnimationTest extends WindowTestsBase {
                mRecentsComponent, true /* getRecentsAnimation */);
        // The launch-behind state should make the recents activity visible.
        assertTrue(recentActivity.mVisibleRequested);
        assertEquals(ActivityTaskManagerService.DEMOTE_TOP_REASON_ANIMATING_RECENTS,
                mAtm.mDemoteTopAppReasons);

        // Simulate the animation is cancelled without changing the stack order.
        recentsAnimation.onAnimationFinished(REORDER_KEEP_IN_PLACE, false /* sendUserLeaveHint */);
        // The non-top recents activity should be invisible by the restored launch-behind state.
        assertFalse(recentActivity.mVisibleRequested);
        assertEquals(0, mAtm.mDemoteTopAppReasons);
    }

    @Test
@@ -138,11 +147,8 @@ public class RecentsAnimationTest extends WindowTestsBase {
                anyInt() /* startFlags */, any() /* profilerInfo */);

        // Assume its process is alive because the caller should be the recents service.
        WindowProcessController wpc = new WindowProcessController(mAtm, aInfo.applicationInfo,
                aInfo.processName, aInfo.applicationInfo.uid, 0 /* userId */,
                mock(Object.class) /* owner */, mock(WindowProcessListener.class));
        wpc.setThread(mock(IApplicationThread.class));
        doReturn(wpc).when(mAtm).getProcessController(eq(wpc.mName), eq(wpc.mUid));
        mSystemServicesTestRule.addProcess(aInfo.packageName, aInfo.processName, 12345 /* pid */,
                aInfo.applicationInfo.uid);

        Intent recentsIntent = new Intent().setComponent(mRecentsComponent);
        // Null animation indicates to preload.
+28 −2
Original line number Diff line number Diff line
@@ -43,12 +43,14 @@ import static org.mockito.Mockito.withSettings;

import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.IApplicationThread;
import android.app.usage.UsageStatsManagerInternal;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManagerInternal;
import android.database.ContentObserver;
@@ -454,8 +456,32 @@ public class SystemServicesTestRule implements TestRule {
                .spiedInstance(sWakeLock).stubOnly());
    }

    void setSurfaceFactory(Supplier<Surface> factory) {
        mSurfaceFactory = factory;
    WindowProcessController addProcess(String pkgName, String procName, int pid, int uid) {
        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() {
+9 −10
Original line number Diff line number Diff line
@@ -64,7 +64,6 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityOptions;
import android.app.IApplicationThread;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -915,13 +914,15 @@ class WindowTestsBase extends SystemServiceTestsBase {
     */
    protected static class ActivityBuilder {
        static final int DEFAULT_FAKE_UID = 12345;
        static final String DEFAULT_PROCESS_NAME = "procName";
        static int sProcNameSeq;

        private final ActivityTaskManagerService mService;

        private ComponentName mComponent;
        private String mTargetActivity;
        private Task mTask;
        private String mProcessName = "name";
        private String mProcessName = DEFAULT_PROCESS_NAME;
        private String mAffinity;
        private int mUid = DEFAULT_FAKE_UID;
        private boolean mCreateTask = false;
@@ -1109,6 +1110,9 @@ class WindowTestsBase extends SystemServiceTestsBase {
            aInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
            aInfo.applicationInfo.packageName = mComponent.getPackageName();
            aInfo.applicationInfo.uid = mUid;
            if (DEFAULT_PROCESS_NAME.equals(mProcessName)) {
                mProcessName += ++sProcNameSeq;
            }
            aInfo.processName = mProcessName;
            aInfo.packageName = mComponent.getPackageName();
            aInfo.name = mComponent.getClassName();
@@ -1173,16 +1177,11 @@ class WindowTestsBase extends SystemServiceTestsBase {
            if (mWpc != null) {
                wpc = mWpc;
            } else {
                wpc = new WindowProcessController(mService,
                        aInfo.applicationInfo, mProcessName, mUid,
                        UserHandle.getUserId(mUid), mock(Object.class),
                        mock(WindowProcessListener.class));
                wpc.setThread(mock(IApplicationThread.class));
                final WindowProcessController p = mService.getProcessController(mProcessName, mUid);
                wpc = p != null ? p : SystemServicesTestRule.addProcess(
                        mService, aInfo.applicationInfo, mProcessName, 0 /* pid */);
            }
            wpc.setThread(mock(IApplicationThread.class));
            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.
            mService.mRootWindowContainer.resumeFocusedTasksTopActivities();