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

Commit 891146c6 authored by Garfield Tan's avatar Garfield Tan
Browse files

Implement launch bounds logic in Android (3/3)

This CL introduces persistence to launch bounds logic. It also wires up
the following state changes and persister:
1) freeform resizing;
2) windowing mode change;
3) display change;
4) task closing.

We may still need to persist immersive mode, but that needs further
discussion.

Changed launch bounds modifier a bit so that it won't launch tasks that
are completely out of the new display or conflict to existing tasks.

Bug: 113252871
Test: Manual tests on that freeform launch bounds are persisted across
reboots.
atest WmTests:LaunchParamsPersisterTests
atest WmTests:LaunchParamsControllerTests
atest WmTests:PersisterQueueTests
Change-Id: I20f3056735253c668c7f09c6eb5204e6a5990b1c
parent 25d07aad
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -450,6 +450,19 @@ public final class Display {
        return mDisplayId;
    }

    /**
     * Gets the display unique id.
     * <p>
     * Unique id is different from display id because physical displays have stable unique id across
     * reboots.
     *
     * @see com.android.service.display.DisplayDevice#hasStableUniqueId().
     * @hide
     */
    public String getUniqueId() {
        return mDisplayInfo.uniqueId;
    }

    /**
     * Returns true if this display is still valid, false if the display has been removed.
     *
+5 −0
Original line number Diff line number Diff line
@@ -5184,12 +5184,14 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai

    /**
     * Removes the input task from this stack.
     *
     * @param task to remove.
     * @param reason for removal.
     * @param mode task removal mode. Either {@link #REMOVE_TASK_MODE_DESTROYING},
     *             {@link #REMOVE_TASK_MODE_MOVING}, {@link #REMOVE_TASK_MODE_MOVING_TO_TOP}.
     */
    void removeTask(TaskRecord task, String reason, int mode) {
        // TODO(b/119259346): Move some logic below to TaskRecord. See bug for more context.
        for (ActivityRecord record : task.mActivities) {
            onActivityRemovedFromStack(record);
        }
@@ -5204,6 +5206,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
        updateTaskMovement(task, true);

        if (mode == REMOVE_TASK_MODE_DESTROYING && task.mActivities.isEmpty()) {
            // This task is going away, so save the last state if necessary.
            task.saveLaunchingStateIfNeeded();

            // TODO: VI what about activity?
            final boolean isVoiceSession = task.voiceSession != null;
            if (isVoiceSession) {
+30 −1
Original line number Diff line number Diff line
@@ -174,6 +174,7 @@ import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.view.Display;
import android.view.DisplayInfo;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -327,6 +328,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
    WindowManagerService mWindowManager;
    DisplayManager mDisplayManager;

     /** Common synchronization logic used to save things to disks. */
    PersisterQueue mPersisterQueue;
    LaunchParamsPersister mLaunchParamsPersister;
    private LaunchParamsController mLaunchParamsController;

    /**
@@ -631,10 +635,16 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext, mHandler.getLooper());
        mKeyguardController = new KeyguardController(mService, this);

        mLaunchParamsController = new LaunchParamsController(mService);
        mPersisterQueue = new PersisterQueue();
        mLaunchParamsPersister = new LaunchParamsPersister(mPersisterQueue, this);
        mLaunchParamsController = new LaunchParamsController(mService, mLaunchParamsPersister);
        mLaunchParamsController.registerDefaultModifiers(this);
    }

    void onSystemReady() {
        mPersisterQueue.startPersisting();
        mLaunchParamsPersister.onSystemReady();
    }

    public ActivityMetricsLogger getActivityMetricsLogger() {
        return mActivityMetricsLogger;
@@ -4233,6 +4243,25 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
        return activityDisplay;
    }

    /**
     * Get an existing instance of {@link ActivityDisplay} that has the given uniqueId. Unique ID is
     * defined in {@link DisplayInfo#uniqueId}.
     *
     * @param uniqueId the unique ID of the display
     * @return the {@link ActivityDisplay} or {@code null} if nothing is found.
     */
    ActivityDisplay getActivityDisplay(String uniqueId) {
        for (int i = mActivityDisplays.size() - 1; i >= 0; --i) {
            final ActivityDisplay display = mActivityDisplays.get(i);
            final boolean isValid = display.mDisplay.isValid();
            if (isValid && display.mDisplay.getUniqueId().equals(uniqueId)) {
                return display;
            }
        }

        return null;
    }

    boolean startHomeOnAllDisplays(int userId, String reason) {
        boolean homeStarted = false;
        for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {
+15 −0
Original line number Diff line number Diff line
@@ -628,6 +628,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            mAssistUtils = new AssistUtils(mContext);
            mVrController.onSystemReady();
            mRecentTasks.onSystemReadyLocked();
            mStackSupervisor.onSystemReady();
        }
    }

@@ -887,6 +888,20 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
            mService.start();
        }

        @Override
        public void onUnlockUser(int userId) {
            synchronized (mService.getGlobalLock()) {
                mService.mStackSupervisor.mLaunchParamsPersister.onUnlockUser(userId);
            }
        }

        @Override
        public void onCleanupUser(int userId) {
            synchronized (mService.getGlobalLock()) {
                mService.mStackSupervisor.mLaunchParamsPersister.onCleanupUser(userId);
            }
        }

        public ActivityTaskManagerService getService() {
            return mService;
        }
+19 −5
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import java.util.List;
 */
class LaunchParamsController {
    private final ActivityTaskManagerService mService;
    private final LaunchParamsPersister mPersister;
    private final List<LaunchParamsModifier> mModifiers = new ArrayList<>();

    // Temporary {@link LaunchParams} for internal calculations. This is kept separate from
@@ -49,8 +50,9 @@ class LaunchParamsController {
    private final LaunchParams mTmpCurrent = new LaunchParams();
    private final LaunchParams mTmpResult = new LaunchParams();

    LaunchParamsController(ActivityTaskManagerService service) {
    LaunchParamsController(ActivityTaskManagerService service, LaunchParamsPersister persister) {
        mService = service;
        mPersister = persister;
    }

    /**
@@ -75,6 +77,10 @@ class LaunchParamsController {
                   ActivityRecord source, ActivityOptions options, LaunchParams result) {
        result.reset();

        if (task != null || activity != null) {
            mPersister.getLaunchParams(task, activity, result);
        }

        // We start at the last registered {@link LaunchParamsModifier} as this represents
        // The modifier closest to the product level. Moving back through the list moves closer to
        // the platform logic.
@@ -139,12 +145,20 @@ class LaunchParamsController {
                task.getStack().setWindowingMode(mTmpParams.mWindowingMode);
            }

            if (!mTmpParams.mBounds.isEmpty()) {
            if (mTmpParams.mBounds.isEmpty()) {
                return false;
            }

            if (task.getStack().inFreeformWindowingMode()) {
                // Only set bounds if it's in freeform mode.
                task.updateOverrideConfiguration(mTmpParams.mBounds);
                return true;
            } else {
                return false;
            }

            // Setting last non-fullscreen bounds to the bounds so next time the task enters
            // freeform windowing mode it can be in this bounds.
            task.setLastNonFullscreenBounds(mTmpParams.mBounds);
            return false;
        } finally {
            mService.mWindowManager.continueSurfaceLayout();
        }
Loading