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

Commit 39ba54bc authored by Louis Chang's avatar Louis Chang
Browse files

Allow activities to be launched on VR 2D display

We were unable to start home activity on VR 2D display since
it doesn't support system decorations. Other standard type
2D activities were also unable to land on VR 2D display due
the launch parameters calculation wasn't take VR into
consideration.

Move all preferred display id calculation to launch parameters
and allow VR 2D display to support system decorations.

Bug: 117614904
Test: atest ActivityManagerMultiDisplayTests
Test: Manual
Change-Id: I4a5cc4d10502815e104c491e927cf60e8446e4cc
parent e80963da
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -37,16 +37,16 @@ import static com.android.server.am.ActivityDisplayProto.FOCUSED_STACK_ID;
import static com.android.server.am.ActivityDisplayProto.ID;
import static com.android.server.am.ActivityDisplayProto.RESUMED_ACTIVITY;
import static com.android.server.am.ActivityDisplayProto.STACKS;
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
import static com.android.server.am.ActivityStackSupervisor.TAG_STATES;
import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS;
import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STACK;
import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_STATES;
import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_TASKS;
import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_STACK;
import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
import static com.android.server.am.ActivityStackSupervisor.TAG_STATES;
import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS;

import android.annotation.Nullable;
import android.app.ActivityOptions;
@@ -998,7 +998,10 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
     * @see Display#FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
     */
    boolean supportsSystemDecorations() {
        return mDisplay.supportsSystemDecorations();
        return mDisplay.supportsSystemDecorations()
                // TODO (b/111363427): Remove this and set the new FLAG_SHOULD_SHOW_LAUNCHER flag
                // (b/114338689) whenever vr 2d display id is set.
                || mDisplayId == mSupervisor.mService.mVr2dDisplayId;
    }

    private boolean shouldDestroyContentOnRemove() {
+19 −18
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED;
import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY;
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
import static android.app.WaitResult.INVALID_DELAY;
@@ -54,6 +55,21 @@ import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.TYPE_VIRTUAL;
import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;

import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
import static com.android.server.am.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER;
import static com.android.server.am.ActivityStackSupervisorProto.DISPLAYS;
import static com.android.server.am.ActivityStackSupervisorProto.FOCUSED_STACK_ID;
import static com.android.server.am.ActivityStackSupervisorProto.IS_HOME_RECENTS_COMPONENT;
import static com.android.server.am.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER;
import static com.android.server.am.ActivityStackSupervisorProto.PENDING_ACTIVITIES;
import static com.android.server.am.ActivityStackSupervisorProto.RESUMED_ACTIVITY;
import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ALL;
import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_IDLE;
import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
@@ -76,22 +92,6 @@ import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLAS
import static com.android.server.am.ActivityTaskManagerService.ANIMATE;
import static com.android.server.am.ActivityTaskManagerService.H.FIRST_SUPERVISOR_STACK_MSG;
import static com.android.server.am.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
import static com.android.server.am.ActivityStack.ActivityState.PAUSED;
import static com.android.server.am.ActivityStack.ActivityState.PAUSING;
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
import static com.android.server.am.ActivityStack.ActivityState.STOPPED;
import static com.android.server.am.ActivityStack.ActivityState.STOPPING;
import static com.android.server.am.ActivityStack.REMOVE_TASK_MODE_MOVING;
import static com.android.server.am.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER;
import static com.android.server.am.ActivityStackSupervisorProto.DISPLAYS;
import static com.android.server.am.ActivityStackSupervisorProto.FOCUSED_STACK_ID;
import static com.android.server.am.ActivityStackSupervisorProto.IS_HOME_RECENTS_COMPONENT;
import static com.android.server.am.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER;
import static com.android.server.am.ActivityStackSupervisorProto.PENDING_ACTIVITIES;
import static com.android.server.am.ActivityStackSupervisorProto.RESUMED_ACTIVITY;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_WHITELISTED;
@@ -789,8 +789,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
    }

    boolean canStartHomeOnDisplay(ActivityInfo homeActivity, int displayId) {
        if (displayId == DEFAULT_DISPLAY) {
            // No restrictions to default display.
        if (displayId == DEFAULT_DISPLAY || (displayId != INVALID_DISPLAY
                && displayId == mService.mVr2dDisplayId)) {
            // No restrictions to default display or vr 2d display.
            return true;
        }

+8 −45
Original line number Diff line number Diff line
@@ -53,6 +53,11 @@ import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;

import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS;
import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
@@ -67,11 +72,6 @@ import static com.android.server.am.ActivityTaskManagerDebugConfig.POSTFIX_USER_
import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.am.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.ActivityTaskManagerService.ANIMATE;
import static com.android.server.am.ActivityStack.ActivityState.RESUMED;
import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.am.ActivityStackSupervisor.TAG_TASKS;
import static com.android.server.am.EventLogTags.AM_NEW_INTENT;
import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
import static com.android.server.am.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
@@ -1277,6 +1277,7 @@ class ActivityStarter {

        setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,
                voiceInteractor);
        final int preferredWindowingMode = mLaunchParams.mWindowingMode;

        // Do not start home activity if it cannot be launched on preferred display. We are not
        // doing this in ActivityStackSupervisor#canPlaceEntityOnDisplay because it might
@@ -1295,25 +1296,6 @@ class ActivityStarter {

        ActivityRecord reusedActivity = getReusableIntentActivity();

        int preferredWindowingMode = WINDOWING_MODE_UNDEFINED;
        int preferredLaunchDisplayId = DEFAULT_DISPLAY;
        if (mOptions != null) {
            preferredWindowingMode = mOptions.getLaunchWindowingMode();
            preferredLaunchDisplayId = mOptions.getLaunchDisplayId();
        }

        // windowing mode and preferred launch display values from {@link LaunchParams} take
        // priority over those specified in {@link ActivityOptions}.
        if (!mLaunchParams.isEmpty()) {
            if (mLaunchParams.hasPreferredDisplay()) {
                preferredLaunchDisplayId = mLaunchParams.mPreferredDisplayId;
            }

            if (mLaunchParams.hasWindowingMode()) {
                preferredWindowingMode = mLaunchParams.mWindowingMode;
            }
        }

        if (reusedActivity != null) {
            // When the flags NEW_TASK and CLEAR_TASK are set, then the task gets reused but
            // still needs to be a lock task mode violation since the task gets cleared out and
@@ -1460,7 +1442,7 @@ class ActivityStarter {
            // Don't use mStartActivity.task to show the toast. We're not starting a new activity
            // but reusing 'top'. Fields in mStartActivity may not be fully initialized.
            mSupervisor.handleNonResizableTaskIfNeeded(top.getTask(), preferredWindowingMode,
                    preferredLaunchDisplayId, topStack);
                    mPreferredDisplayId, topStack);

            return START_DELIVERED_TO_TOP;
        }
@@ -1540,7 +1522,7 @@ class ActivityStarter {
        mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);

        mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredWindowingMode,
                preferredLaunchDisplayId, mTargetStack);
                mPreferredDisplayId, mTargetStack);

        return START_SUCCESS;
    }
@@ -1614,7 +1596,6 @@ class ActivityStarter {
        } else {
            mPreferredDisplayId = DEFAULT_DISPLAY;
        }
        ensureValidPreferredDisplayId(r);

        mLaunchMode = r.launchMode;

@@ -1707,24 +1688,6 @@ class ActivityStarter {
        mNoAnimation = (mLaunchFlags & FLAG_ACTIVITY_NO_ANIMATION) != 0;
    }

    /**
     * Ensure preferred display ID matches the starting activity.
     */
    private void ensureValidPreferredDisplayId(ActivityRecord startingActivity) {
        // Check if the Activity is a VR activity. If so, the activity should be launched in
        // main display.
        if (startingActivity != null && startingActivity.requestedVrComponent != null) {
            mPreferredDisplayId = DEFAULT_DISPLAY;
        }

        // Get the virtual display ID from ActivityStackManagerService. If that's set we should
        // always use that.
        final int displayId = mService.mVr2dDisplayId;
        if (displayId != INVALID_DISPLAY) {
            mPreferredDisplayId = displayId;
        }
    }

    private void sendNewTaskResultRequestIfNeeded() {
        final ActivityStack sourceStack = mStartActivity.resultTo != null
                ? mStartActivity.resultTo.getStack() : null;
+10 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.server.am;

import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;

import static com.android.server.am.LaunchParamsController.LaunchParamsModifier.RESULT_CONTINUE;
@@ -97,6 +98,15 @@ class LaunchParamsController {
                    break;
            }
        }

        if (activity != null && activity.requestedVrComponent != null) {
            // Check if the Activity is a VR activity. If so, it should be launched in main display.
            result.mPreferredDisplayId = DEFAULT_DISPLAY;
        } else if (mService.mVr2dDisplayId != INVALID_DISPLAY) {
            // Get the virtual display ID from ActivityTaskManagerService. If that's set we
            // should always use that.
            result.mPreferredDisplayId = mService.mVr2dDisplayId;
        }
    }

    /**