diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 926044bffdd0e..b8d9575f4b0f8 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -176,6 +176,13 @@ public class ActivityOptions { */ private static final String KEY_LAUNCH_DISPLAY_ID = "android.activity.launchDisplayId"; + /** + * The id of the display where the caller was on. + * @see #setCallerDisplayId(int) + * @hide + */ + private static final String KEY_CALLER_DISPLAY_ID = "android.activity.callerDisplayId"; + /** * The windowing mode the activity should be launched into. * @hide @@ -268,6 +275,8 @@ public class ActivityOptions { private static final String KEY_REMOTE_ANIMATION_ADAPTER = "android:activity.remoteAnimationAdapter"; + /** @hide */ + public static final int ANIM_UNDEFINED = -1; /** @hide */ public static final int ANIM_NONE = 0; /** @hide */ @@ -299,7 +308,7 @@ public class ActivityOptions { private String mPackageName; private Rect mLaunchBounds; - private int mAnimationType = ANIM_NONE; + private int mAnimationType = ANIM_UNDEFINED; private int mCustomEnterResId; private int mCustomExitResId; private int mCustomInPlaceResId; @@ -318,6 +327,7 @@ public class ActivityOptions { private int mExitCoordinatorIndex; private PendingIntent mUsageTimeReport; private int mLaunchDisplayId = INVALID_DISPLAY; + private int mCallerDisplayId = INVALID_DISPLAY; @WindowConfiguration.WindowingMode private int mLaunchWindowingMode = WINDOWING_MODE_UNDEFINED; @WindowConfiguration.ActivityType @@ -896,7 +906,7 @@ public class ActivityOptions { Slog.w(TAG, e); } mLaunchBounds = opts.getParcelable(KEY_LAUNCH_BOUNDS); - mAnimationType = opts.getInt(KEY_ANIM_TYPE); + mAnimationType = opts.getInt(KEY_ANIM_TYPE, ANIM_UNDEFINED); switch (mAnimationType) { case ANIM_CUSTOM: mCustomEnterResId = opts.getInt(KEY_ANIM_ENTER_RES_ID, 0); @@ -945,6 +955,7 @@ public class ActivityOptions { } mLockTaskMode = opts.getBoolean(KEY_LOCK_TASK_MODE, false); mLaunchDisplayId = opts.getInt(KEY_LAUNCH_DISPLAY_ID, INVALID_DISPLAY); + mCallerDisplayId = opts.getInt(KEY_CALLER_DISPLAY_ID, INVALID_DISPLAY); mLaunchWindowingMode = opts.getInt(KEY_LAUNCH_WINDOWING_MODE, WINDOWING_MODE_UNDEFINED); mLaunchActivityType = opts.getInt(KEY_LAUNCH_ACTIVITY_TYPE, ACTIVITY_TYPE_UNDEFINED); mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1); @@ -1203,6 +1214,17 @@ public class ActivityOptions { return this; } + /** @hide */ + public int getCallerDisplayId() { + return mCallerDisplayId; + } + + /** @hide */ + public ActivityOptions setCallerDisplayId(int callerDisplayId) { + mCallerDisplayId = callerDisplayId; + return this; + } + /** @hide */ public int getLaunchWindowingMode() { return mLaunchWindowingMode; @@ -1447,7 +1469,9 @@ public class ActivityOptions { if (mLaunchBounds != null) { b.putParcelable(KEY_LAUNCH_BOUNDS, mLaunchBounds); } - b.putInt(KEY_ANIM_TYPE, mAnimationType); + if (mAnimationType != ANIM_UNDEFINED) { + b.putInt(KEY_ANIM_TYPE, mAnimationType); + } if (mUsageTimeReport != null) { b.putParcelable(KEY_USAGE_TIME_REPORT, mUsageTimeReport); } @@ -1506,6 +1530,9 @@ public class ActivityOptions { if (mLaunchDisplayId != INVALID_DISPLAY) { b.putInt(KEY_LAUNCH_DISPLAY_ID, mLaunchDisplayId); } + if (mCallerDisplayId != INVALID_DISPLAY) { + b.putInt(KEY_CALLER_DISPLAY_ID, mCallerDisplayId); + } if (mLaunchWindowingMode != WINDOWING_MODE_UNDEFINED) { b.putInt(KEY_LAUNCH_WINDOWING_MODE, mLaunchWindowingMode); } diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java index 6f7a0607cbdb9..4b4a071ecf72b 100644 --- a/core/java/android/app/PendingIntent.java +++ b/core/java/android/app/PendingIntent.java @@ -893,6 +893,17 @@ public final class PendingIntent implements Parcelable { String resolvedType = intent != null ? intent.resolveTypeIfNeeded(context.getContentResolver()) : null; + + if (context != null && isActivity()) { + // Set the context display id as preferred for this activity launches, so that it + // can land on caller's display. Or just brought the task to front at the display + // where it was on since it has higher preference. + ActivityOptions activityOptions = options != null ? new ActivityOptions(options) + : ActivityOptions.makeBasic(); + activityOptions.setCallerDisplayId(context.getDisplayId()); + options = activityOptions.toBundle(); + } + return ActivityManager.getService().sendIntentSender( mTarget, mWhitelistToken, code, intent, resolvedType, onFinished != null diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 015464e94ffca..31e8bbdab71cf 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -30,6 +30,7 @@ import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_DOWN; import static android.app.ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_UP; import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_DOWN; import static android.app.ActivityOptions.ANIM_THUMBNAIL_SCALE_UP; +import static android.app.ActivityOptions.ANIM_UNDEFINED; import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.AppOpsManager.MODE_ALLOWED; @@ -2096,6 +2097,7 @@ final class ActivityRecord extends ConfigurationContainer { pendingOptions.getRemoteAnimationAdapter()); break; case ANIM_NONE: + case ANIM_UNDEFINED: break; default: Slog.e(TAG_WM, "applyOptionsLocked: Unknown animationType=" + animationType); diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java index 0d18b30c1b0b1..47c53e91578a4 100644 --- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java +++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java @@ -321,6 +321,12 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { displayId = sourceDisplayId; } + if (displayId == INVALID_DISPLAY && options != null) { + final int callerDisplayId = options.getCallerDisplayId(); + if (DEBUG) appendLog("display-from-caller=" + callerDisplayId); + displayId = callerDisplayId; + } + if (displayId != INVALID_DISPLAY && mSupervisor.mRootActivityContainer.getActivityDisplay(displayId) == null) { displayId = currentParams.mPreferredDisplayId;