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

Commit 99493dbc authored by Karthik Ravi Shankar's avatar Karthik Ravi Shankar
Browse files

Launch 2D activities in VR mode



When in VR mode, launch all activities into the virtual display ID as
provided by the Compatibility display. This includes two cases -

- New activity launches
- Existing activity in the background.

Testing Done: Tested with PlanarVirtualDisplay app and Settings,
Calculator and GestureApp with different intent flags.

Bug: 36071574
Bug: 36071445
Test: android.server.cts.ActivityManagerDisplayTests
Test: #testVrActivityLaunch
Test: #testVrActivityReLaunch

Change-Id: Ic590a7cbd6f9b339dc83b22a8ffb1252219ef22e
Signed-off-by: default avatarKarthik Ravi Shankar <karthikrs@google.com>
parent 79a973f6
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -241,4 +241,11 @@ public abstract class ActivityManagerInternal {
     * {@param procStateSeq}.
     */
    public abstract void notifyNetworkPolicyRulesUpdated(int uid, long procStateSeq);

    /**
     * Called after virtual display Id is updated by
     * {@link com.android.server.vr.CompatibilityDisplay} with a specific
     * {@param compatibilityDisplayId}.
     */
    public abstract void setVrCompatibilityDisplayId(int vrCompatibilityDisplayId);
}
+20 −0
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
import static android.provider.Settings.System.FONT_SCALE;
import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICATION;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
import static com.android.internal.util.XmlUtils.readLongAttribute;
@@ -689,6 +690,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
    };
    // VR Compatibility Display Id.
    int mVrCompatibilityDisplayId = INVALID_DISPLAY;
    // Whether we should use SCHED_FIFO for UI and RenderThreads.
    private boolean mUseFifoUiScheduling = false;
@@ -23526,6 +23530,22 @@ public class ActivityManagerService extends IActivityManager.Stub
                }
            }
        }
        /**
         * Called after virtual display Id is updated by
         * {@link com.android.server.vr.CompatibilityDisplay} with a specific
         * {@param vrCompatibilityDisplayId}.
         */
        @Override
        public void setVrCompatibilityDisplayId(int vrCompatibilityDisplayId) {
            if (DEBUG_STACK) {
                Slog.d(TAG, "setVrCompatibilityDisplayId called for: " +
                        vrCompatibilityDisplayId);
            }
            synchronized (ActivityManagerService.this) {
                mVrCompatibilityDisplayId = vrCompatibilityDisplayId;
            }
        }
    }
    /**
+50 −6
Original line number Diff line number Diff line
@@ -125,8 +125,10 @@ import android.view.Display;

import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.app.IVoiceInteractor;
import com.android.server.LocalServices;
import com.android.server.am.ActivityStackSupervisor.PendingActivityLaunch;
import com.android.server.pm.InstantAppResolver;
import com.android.server.vr.VrManagerInternal;
import com.android.server.wm.WindowManagerService;

import java.util.ArrayList;
@@ -192,6 +194,8 @@ class ActivityStarter {
    private IVoiceInteractionSession mVoiceSession;
    private IVoiceInteractor mVoiceInteractor;

    private boolean mUsingVrCompatibilityDisplay;

    private void reset() {
        mStartActivity = null;
        mIntent = null;
@@ -229,12 +233,15 @@ class ActivityStarter {

        mVoiceSession = null;
        mVoiceInteractor = null;

        mUsingVrCompatibilityDisplay = false;
    }

    ActivityStarter(ActivityManagerService service, ActivityStackSupervisor supervisor) {
        mService = service;
        mSupervisor = supervisor;
        mInterceptor = new ActivityStartInterceptor(mService, mSupervisor);
        mUsingVrCompatibilityDisplay = false;
    }

    final int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
@@ -1208,10 +1215,7 @@ class ActivityStarter {
        mVoiceSession = voiceSession;
        mVoiceInteractor = voiceInteractor;

        mSourceDisplayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
        if (mSourceDisplayId == INVALID_DISPLAY) {
            mSourceDisplayId = DEFAULT_DISPLAY;
        }
        mSourceDisplayId = getSourceDisplayId(mSourceRecord, mStartActivity);

        mLaunchBounds = getOverrideBounds(r, options, inTask);

@@ -1465,6 +1469,36 @@ class ActivityStarter {
        return intentActivity;
    }

    /**
     * Returns the ID of the display to use for a new activity. If the source activity has
     * a explicit display ID set, use that to launch the activity. If not and the device is in VR
     * mode, then return the Vr mode's virtual display ID.
     */
    private int getSourceDisplayId(ActivityRecord sourceRecord, ActivityRecord startingActivity) {
        int displayId = sourceRecord != null ? sourceRecord.getDisplayId() : INVALID_DISPLAY;
        // If the activity has a displayId set explicitly, launch it on the same displayId.
        if (displayId != INVALID_DISPLAY) {
            return displayId;
        }

        // Check if the Activity is a VR activity. If so, the activity should be launched in
        // main display.
        if (startingActivity != null && startingActivity.requestedVrComponent != null) {
            return DEFAULT_DISPLAY;
        }

        // Get the virtual display id from ActivityManagerService.
        displayId = mService.mVrCompatibilityDisplayId;
        if (displayId != INVALID_DISPLAY) {
            if (DEBUG_STACK) {
                Slog.d(TAG, "getSourceDisplayId :" + displayId);
            }
            mUsingVrCompatibilityDisplay = true;
            return displayId;
        }
        return DEFAULT_DISPLAY;
    }

    /**
     * Figure out which task and activity to bring to front when we have found an existing matching
     * activity record in history. May also clear the task if needed.
@@ -2073,7 +2107,17 @@ class ActivityStarter {
            return mSupervisor.getValidLaunchStackOnDisplay(launchDisplayId, r);
        }

        if ((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0
        // If we are using Vr compatibility display, find the virtual display stack.
        if (mUsingVrCompatibilityDisplay) {
            ActivityStack as = mSupervisor.getValidLaunchStackOnDisplay(mSourceDisplayId, r);
            if (DEBUG_STACK) {
                Slog.v(TAG, "Launch stack for app: " + r.toString() +
                    ", on virtual display stack:" + as.toString());
            }
            return as;
        }

        if (((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) == 0)
                 || mSourceDisplayId != DEFAULT_DISPLAY) {
            return null;
        }
+15 −1
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ package com.android.server.vr;

import static android.view.Display.INVALID_DISPLAY;

import android.app.ActivityManagerInternal;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -48,6 +49,7 @@ class CompatibilityDisplay {
    private final static String DEBUG_EXTRA_SURFACE =
            "com.android.server.vr.CompatibilityDisplay.EXTRA_SURFACE";

    private final ActivityManagerInternal mActivityManagerInternal;
    private final DisplayManager mDisplayManager;
    private final IVrManager mVrManager;
    private final Object mVdLock = new Object();
@@ -74,8 +76,10 @@ class CompatibilityDisplay {
    private boolean mIsVrModeOverrideEnabled;
    private boolean mIsVrModeEnabled;

    public CompatibilityDisplay(DisplayManager displayManager, IVrManager vrManager) {
    public CompatibilityDisplay(DisplayManager displayManager,
           ActivityManagerInternal activityManagerInternal, IVrManager vrManager) {
        mDisplayManager = displayManager;
        mActivityManagerInternal = activityManagerInternal;
        mVrManager = vrManager;
    }

@@ -200,6 +204,15 @@ class CompatibilityDisplay {

            mVirtualDisplay = mDisplayManager.createVirtualDisplay("VR 2D Display", WIDTH, HEIGHT,
                    DPI, null /* Surface */, 0 /* flags */);

            if (mVirtualDisplay != null) {
                mActivityManagerInternal.setVrCompatibilityDisplayId(
                    mVirtualDisplay.getDisplay().getDisplayId());
            } else {
                Log.w(TAG, "Virtual display id is null after createVirtualDisplay");
                mActivityManagerInternal.setVrCompatibilityDisplayId(INVALID_DISPLAY);
                return;
            }
        }

        if (DEBUG) {
@@ -222,6 +235,7 @@ class CompatibilityDisplay {
                    } else {
                        Log.i(TAG, "Stopping Virtual Display");
                        synchronized (mVdLock) {
                            mActivityManagerInternal.setVrCompatibilityDisplayId(INVALID_DISPLAY);
                            setSurfaceLocked(null); // clean up and release the surface first.
                            if (mVirtualDisplay != null) {
                                mVirtualDisplay.release();
+4 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.vr;
import static android.view.Display.INVALID_DISPLAY;

import android.Manifest;
import android.app.ActivityManagerInternal;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.NotificationManager;
@@ -54,6 +55,7 @@ import android.util.Slog;
import android.util.SparseArray;

import com.android.internal.R;
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.SystemService;
import com.android.server.utils.ManagedApplicationService.PendingEvent;
@@ -594,7 +596,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC

            DisplayManager dm =
                    (DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE);
            mCompatibilityDisplay = new CompatibilityDisplay(dm, mVrManager);
            ActivityManagerInternal ami = LocalServices.getService(ActivityManagerInternal.class);
            mCompatibilityDisplay = new CompatibilityDisplay(dm, ami, mVrManager);
            mCompatibilityDisplay.init(getContext());
        } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
            synchronized (mLock) {