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

Commit 16802aab authored by Andrii Kulian's avatar Andrii Kulian
Browse files

Add API to launch activities on secondary displays

displayId can be specified as a part of ActivityOptions.
We will look for a valid stack on the specified display, starting
from the topmost one. If no valid stack is found, new dynamic stack
can be created on external display.
Launch stack and display id can't be set at the same time, otherwise
exception will be thrown.

Test: ActivityManagerDisplayTests
Test: #testLaunchActivityOnSecondaryDisplay
Test: #testConsequentLaunchActivity
Test: #testConsequentLaunchActivityFromSecondaryDisplay
Test: #testLaunchActivityFromAppToSecondaryDisplay
Change-Id: I8a202bc076319e23948d81b99a2c68d7b733b5e4
parent 14fee436
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3892,6 +3892,7 @@ package android.app {
  public class ActivityOptions {
    method public android.graphics.Rect getLaunchBounds();
    method public int getLaunchDisplayId();
    method public static android.app.ActivityOptions makeBasic();
    method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
    method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
@@ -3902,6 +3903,7 @@ package android.app {
    method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
    method public void requestUsageTimeReport(android.app.PendingIntent);
    method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
    method public android.app.ActivityOptions setLaunchDisplayId(int);
    method public android.os.Bundle toBundle();
    method public void update(android.app.ActivityOptions);
    field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
+2 −0
Original line number Diff line number Diff line
@@ -4024,6 +4024,7 @@ package android.app {
  public class ActivityOptions {
    method public android.graphics.Rect getLaunchBounds();
    method public int getLaunchDisplayId();
    method public static android.app.ActivityOptions makeBasic();
    method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
    method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
@@ -4034,6 +4035,7 @@ package android.app {
    method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
    method public void requestUsageTimeReport(android.app.PendingIntent);
    method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
    method public android.app.ActivityOptions setLaunchDisplayId(int);
    method public android.os.Bundle toBundle();
    method public void update(android.app.ActivityOptions);
    field public static final java.lang.String EXTRA_USAGE_TIME_REPORT = "android.activity.usage_time";
+2 −0
Original line number Diff line number Diff line
@@ -3901,6 +3901,7 @@ package android.app {
  public class ActivityOptions {
    method public android.graphics.Rect getLaunchBounds();
    method public int getLaunchDisplayId();
    method public static android.app.ActivityOptions makeBasic();
    method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
    method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
@@ -3911,6 +3912,7 @@ package android.app {
    method public static android.app.ActivityOptions makeThumbnailScaleUpAnimation(android.view.View, android.graphics.Bitmap, int, int);
    method public void requestUsageTimeReport(android.app.PendingIntent);
    method public android.app.ActivityOptions setLaunchBounds(android.graphics.Rect);
    method public android.app.ActivityOptions setLaunchDisplayId(int);
    method public void setLaunchStackId(int);
    method public android.os.Bundle toBundle();
    method public void update(android.app.ActivityOptions);
+29 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.app;

import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.view.Display.INVALID_DISPLAY;

import android.annotation.Nullable;
import android.annotation.TestApi;
@@ -151,6 +152,12 @@ public class ActivityOptions {
     */
    private static final String KEY_ANIM_SPECS = "android:activity.animSpecs";

    /**
     * The display id the activity should be launched into.
     * @hide
     */
    private static final String KEY_LAUNCH_DISPLAY_ID = "android.activity.launchDisplayId";

    /**
     * The stack id the activity should be launched into.
     * @hide
@@ -240,6 +247,7 @@ public class ActivityOptions {
    private int mResultCode;
    private int mExitCoordinatorIndex;
    private PendingIntent mUsageTimeReport;
    private int mLaunchDisplayId = INVALID_DISPLAY;
    private int mLaunchStackId = INVALID_STACK_ID;
    private int mLaunchTaskId = -1;
    private int mDockCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
@@ -850,6 +858,7 @@ public class ActivityOptions {
                mExitCoordinatorIndex = opts.getInt(KEY_EXIT_COORDINATOR_INDEX);
                break;
        }
        mLaunchDisplayId = opts.getInt(KEY_LAUNCH_DISPLAY_ID, INVALID_DISPLAY);
        mLaunchStackId = opts.getInt(KEY_LAUNCH_STACK_ID, INVALID_STACK_ID);
        mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1);
        mTaskOverlay = opts.getBoolean(KEY_TASK_OVERLAY, false);
@@ -1015,6 +1024,25 @@ public class ActivityOptions {
        }
    }

    /**
     * Gets the id of the display where activity should be launched.
     * @return The id of the display where activity should be launched,
     *         {@link android.view.Display#INVALID_DISPLAY} if not set.
     */
    public int getLaunchDisplayId() {
        return mLaunchDisplayId;
    }

    /**
     * Sets the id of the display where activity should be launched.
     * @param launchDisplayId The id of the display where the activity should be launched.
     * @return {@code this} {@link ActivityOptions} instance.
     */
    public ActivityOptions setLaunchDisplayId(int launchDisplayId) {
        mLaunchDisplayId = launchDisplayId;
        return this;
    }

    /** @hide */
    public int getLaunchStackId() {
        return mLaunchStackId;
@@ -1209,6 +1237,7 @@ public class ActivityOptions {
                b.putInt(KEY_EXIT_COORDINATOR_INDEX, mExitCoordinatorIndex);
                break;
        }
        b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId);
        b.putInt(KEY_LAUNCH_STACK_ID, mLaunchStackId);
        b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId);
        b.putBoolean(KEY_TASK_OVERLAY, mTaskOverlay);
+9 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ import static android.app.ActivityManager.RESIZE_MODE_SYSTEM;
import static android.app.ActivityManager.RESIZE_MODE_USER;
import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.view.Display.INVALID_DISPLAY;

final class ActivityManagerShellCommand extends ShellCommand {
    public static final String NO_CLASS_ERROR_CODE = "Error type 3";
@@ -114,6 +115,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
    private String mProfileFile;
    private int mSamplingInterval;
    private boolean mAutoStop;
    private int mDisplayId;
    private int mStackId;

    final boolean mDumping;
@@ -249,6 +251,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
        mSamplingInterval = 0;
        mAutoStop = false;
        mUserId = defUser;
        mDisplayId = INVALID_DISPLAY;
        mStackId = INVALID_STACK_ID;

        return Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() {
@@ -278,6 +281,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    mUserId = UserHandle.parseUserArg(getNextArgRequired());
                } else if (opt.equals("--receiver-permission")) {
                    mReceiverPermission = getNextArgRequired();
                } else if (opt.equals("--display")) {
                    mDisplayId = Integer.parseInt(getNextArgRequired());
                } else if (opt.equals("--stack")) {
                    mStackId = Integer.parseInt(getNextArgRequired());
                } else {
@@ -354,6 +359,10 @@ final class ActivityManagerShellCommand extends ShellCommand {
            int res;
            final long startTime = SystemClock.uptimeMillis();
            ActivityOptions options = null;
            if (mDisplayId != INVALID_DISPLAY) {
                options = ActivityOptions.makeBasic();
                options.setLaunchDisplayId(mDisplayId);
            }
            if (mStackId != INVALID_STACK_ID) {
                options = ActivityOptions.makeBasic();
                options.setLaunchStackId(mStackId);
Loading