diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index 284679838213c..051295e450fa7 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -159,6 +159,12 @@ public class ActivityOptions { */ private static final String KEY_LAUNCH_TASK_ID = "android.activity.launchTaskId"; + /** + * See {@link #setAvoidMoveToFront}. + * @hide + */ + private static final String KEY_DONT_MOVE_TO_FRONT = "android.activity.dontMoveToFront"; + /** * Where the docked stack should be positioned. * @hide @@ -232,6 +238,7 @@ public class ActivityOptions { private int mLaunchStackId = INVALID_STACK_ID; private int mLaunchTaskId = -1; private int mDockCreateMode = DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; + private boolean mAvoidMoveToFront; private AppTransitionAnimationSpec mAnimSpecs[]; /** @@ -774,6 +781,7 @@ public class ActivityOptions { } mLaunchStackId = opts.getInt(KEY_LAUNCH_STACK_ID, INVALID_STACK_ID); mLaunchTaskId = opts.getInt(KEY_LAUNCH_TASK_ID, -1); + mAvoidMoveToFront = opts.getBoolean(KEY_DONT_MOVE_TO_FRONT, false); mDockCreateMode = opts.getInt(KEY_DOCK_CREATE_MODE, DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT); if (opts.containsKey(KEY_ANIM_SPECS)) { Parcelable[] specs = opts.getParcelableArray(KEY_ANIM_SPECS); @@ -950,6 +958,23 @@ public class ActivityOptions { return mLaunchTaskId; } + /** + * Set's whether the task should be moved to the front. This is different from + * {@link #getLaunchTaskBehind()} as we don't want to have an animation at all when launching + * an activity that shouldn't be moved to the front. + * @hide + */ + public void setAvoidMoveToFront(boolean avoidMoveToFront) { + mAvoidMoveToFront = avoidMoveToFront; + } + + /** + * @hide + */ + public boolean getAvoidMoveToFront() { + return mAvoidMoveToFront; + } + /** @hide */ public int getDockCreateMode() { return mDockCreateMode; @@ -1103,6 +1128,7 @@ public class ActivityOptions { } b.putInt(KEY_LAUNCH_STACK_ID, mLaunchStackId); b.putInt(KEY_LAUNCH_TASK_ID, mLaunchTaskId); + b.putBoolean(KEY_DONT_MOVE_TO_FRONT, mAvoidMoveToFront); b.putInt(KEY_DOCK_CREATE_MODE, mDockCreateMode); if (mAnimSpecs != null) { b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs); diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java index 9294ecdfb86a5..34a37ba51bf14 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/ForcedResizableInfoActivityController.java @@ -111,6 +111,7 @@ public class ForcedResizableInfoActivityController { Intent intent = new Intent(mContext, ForcedResizableInfoActivity.class); ActivityOptions options = ActivityOptions.makeBasic(); options.setLaunchTaskId(mPendingTaskIds.valueAt(i)); + options.setAvoidMoveToFront(true); mContext.startActivity(intent, options.toBundle()); } mPendingTaskIds.clear(); diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index a41a8ef0cb131..2386a361d94b8 100755 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -21,6 +21,7 @@ import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS; import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; +import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_AND_PIPABLE; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH; @@ -822,6 +823,11 @@ final class ActivityRecord { return !isHomeActivity() && (isResizeable() || service.mForceResizableActivities); } + boolean isNonResizableOrForced() { + return !isHomeActivity() && info.resizeMode != RESIZE_MODE_RESIZEABLE + && info.resizeMode != RESIZE_MODE_RESIZEABLE_AND_PIPABLE; + } + boolean supportsPictureInPicture() { return !isHomeActivity() && info.resizeMode == RESIZE_MODE_RESIZEABLE_AND_PIPABLE; } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index f192a9ddb3b24..20ef0e8652540 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -3508,6 +3508,7 @@ public final class ActivityStackSupervisor implements DisplayListener { return; } + final ActivityRecord topActivity = task.getTopActivity(); if (!task.canGoInDockedStack() || forceNonResizable) { // Display a warning toast that we tried to put a non-dockable task in the docked stack. mService.mHandler.sendEmptyMessage(NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG); @@ -3515,9 +3516,9 @@ public final class ActivityStackSupervisor implements DisplayListener { // Dismiss docked stack. If task appeared to be in docked stack but is not resizable - // we need to move it to top of fullscreen stack, otherwise it will be covered. moveTasksToFullscreenStackLocked(DOCKED_STACK_ID, actualStackId == DOCKED_STACK_ID); - } else if (task.mResizeMode == RESIZE_MODE_FORCE_RESIZEABLE) { - String packageName = task.getTopActivity() != null - ? task.getTopActivity().appInfo.packageName : null; + } else if (topActivity != null && topActivity.isNonResizableOrForced() + && !topActivity.noDisplay) { + String packageName = topActivity.appInfo.packageName; mService.mHandler.obtainMessage(NOTIFY_FORCED_RESIZABLE_MSG, task.taskId, 0, packageName).sendToTarget(); } diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 6622b34c11066..94e442fe3a7e2 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -171,6 +171,7 @@ class ActivityStarter { private boolean mMovedToFront; private boolean mNoAnimation; private boolean mKeepCurTransition; + private boolean mAvoidMoveToFront; private IVoiceInteractionSession mVoiceSession; private IVoiceInteractor mVoiceInteractor; @@ -207,6 +208,7 @@ class ActivityStarter { mMovedToFront = false; mNoAnimation = false; mKeepCurTransition = false; + mAvoidMoveToFront = false; mVoiceSession = null; mVoiceInteractor = null; @@ -1223,6 +1225,18 @@ class ActivityStarter { mDoResume = false; } + if (mOptions != null && mOptions.getLaunchTaskId() != -1 && mOptions.getAvoidMoveToFront()) { + final TaskRecord task = mSupervisor.anyTaskForIdLocked(mOptions.getLaunchTaskId()); + final ActivityRecord top = task != null ? task.getTopActivity() : null; + if (top != null && !top.visible) { + + // The caller specifies that we'd like to be avoided to be moved to the front, so be + // it! + mDoResume = false; + mAvoidMoveToFront = true; + } + } + mNotTop = (mLaunchFlags & FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null; mInTask = inTask; @@ -1419,8 +1433,9 @@ class ActivityStarter { ActivityRecord curTop = (focusStack == null) ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop); - if (curTop != null && (curTop.task != intentActivity.task || - curTop.task != focusStack.topTask())) { + if (curTop != null + && (curTop.task != intentActivity.task || curTop.task != focusStack.topTask()) + && !mAvoidMoveToFront) { mStartActivity.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); if (mSourceRecord == null || (mSourceStack.topActivity() != null && mSourceStack.topActivity().task == mSourceRecord.task)) { @@ -1631,7 +1646,7 @@ class ActivityStarter { mTargetStack.moveToFront("sourceStackToFront"); } final TaskRecord topTask = mTargetStack.topTask(); - if (topTask != sourceTask) { + if (topTask != sourceTask && !mAvoidMoveToFront) { mTargetStack.moveTaskToFrontLocked(sourceTask, mNoAnimation, mOptions, mStartActivity.appTimeTracker, "sourceTaskToFront"); }