summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/test-current.txt6
-rw-r--r--core/java/android/app/ActivityManager.java64
-rw-r--r--core/java/android/app/IActivityManager.aidl21
-rw-r--r--core/java/android/app/ITaskStackListener.aidl2
-rw-r--r--core/java/android/app/TaskStackListener.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/HighResThumbnailLoader.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/Task.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyCache.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java26
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java3
-rw-r--r--packages/VpnDialogs/res/values-cs/strings.xml2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java101
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java4
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java66
-rw-r--r--services/core/java/com/android/server/am/TaskChangeNotificationController.java8
28 files changed, 346 insertions, 153 deletions
diff --git a/api/test-current.txt b/api/test-current.txt
index 38b15b418a4a..f10e3d679e08 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3866,7 +3866,9 @@ package android.app {
method public void removeOnUidImportanceListener(android.app.ActivityManager.OnUidImportanceListener);
method public void removeStacksInWindowingModes(int[]) throws java.lang.SecurityException;
method public void removeStacksWithActivityTypes(int[]) throws java.lang.SecurityException;
+ method public void resizeStack(int, android.graphics.Rect) throws java.lang.SecurityException;
method public deprecated void restartPackage(java.lang.String);
+ method public void setTaskWindowingMode(int, int, boolean) throws java.lang.SecurityException;
method public static void setVrThread(int);
method public void setWatchHeapLimit(long);
method public static boolean supportsMultiWindow(android.content.Context);
@@ -4019,11 +4021,7 @@ package android.app {
}
public static class ActivityManager.StackId {
- field public static final int DOCKED_STACK_ID = 3; // 0x3
- field public static final int FREEFORM_WORKSPACE_STACK_ID = 2; // 0x2
- field public static final int FULLSCREEN_WORKSPACE_STACK_ID = 1; // 0x1
field public static final int INVALID_STACK_ID = -1; // 0xffffffff
- field public static final int PINNED_STACK_ID = 4; // 0x4
}
public static class ActivityManager.TaskDescription implements android.os.Parcelable {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 26f96fbeede1..5e61727fc1c3 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -16,10 +16,10 @@
package android.app;
-import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -674,16 +674,20 @@ public class ActivityManager {
* @hide */
private static final int FIRST_STATIC_STACK_ID = 0;
- /** ID of stack where fullscreen activities are normally launched into. */
+ /** ID of stack where fullscreen activities are normally launched into.
+ * @hide */
public static final int FULLSCREEN_WORKSPACE_STACK_ID = 1;
- /** ID of stack where freeform/resized activities are normally launched into. */
+ /** ID of stack where freeform/resized activities are normally launched into.
+ * @hide */
public static final int FREEFORM_WORKSPACE_STACK_ID = FULLSCREEN_WORKSPACE_STACK_ID + 1;
- /** ID of stack that occupies a dedicated region of the screen. */
+ /** ID of stack that occupies a dedicated region of the screen.
+ * @hide */
public static final int DOCKED_STACK_ID = FREEFORM_WORKSPACE_STACK_ID + 1;
- /** ID of stack that always on top (always visible) when it exist. */
+ /** ID of stack that always on top (always visible) when it exist.
+ * @hide */
public static final int PINNED_STACK_ID = DOCKED_STACK_ID + 1;
/** Last static stack stack ID.
@@ -1531,6 +1535,12 @@ public class ActivityManager {
*/
public int resizeMode;
+ /**
+ * The current configuration this task is in.
+ * @hide
+ */
+ final public Configuration configuration = new Configuration();
+
public RecentTaskInfo() {
}
@@ -1576,6 +1586,7 @@ public class ActivityManager {
}
dest.writeInt(supportsSplitScreenMultiWindow ? 1 : 0);
dest.writeInt(resizeMode);
+ configuration.writeToParcel(dest, flags);
}
public void readFromParcel(Parcel source) {
@@ -1600,6 +1611,7 @@ public class ActivityManager {
Rect.CREATOR.createFromParcel(source) : null;
supportsSplitScreenMultiWindow = source.readInt() == 1;
resizeMode = source.readInt();
+ configuration.readFromParcel(source);
}
public static final Creator<RecentTaskInfo> CREATOR
@@ -1798,7 +1810,7 @@ public class ActivityManager {
* The full configuration the task is currently running in.
* @hide
*/
- public Configuration configuration = new Configuration();
+ final public Configuration configuration = new Configuration();
public RunningTaskInfo() {
}
@@ -2025,12 +2037,49 @@ public class ActivityManager {
}
/**
+ * Sets the windowing mode for a specific task. Only works on tasks of type
+ * {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}
+ * @param taskId The id of the task to set the windowing mode for.
+ * @param windowingMode The windowing mode to set for the task.
+ * @param toTop If the task should be moved to the top once the windowing mode changes.
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+ public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop)
+ throws SecurityException {
+ try {
+ getService().setTaskWindowingMode(taskId, windowingMode, toTop);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Resizes the input stack id to the given bounds.
+ * @param stackId Id of the stack to resize.
+ * @param bounds Bounds to resize the stack to or {@code null} for fullscreen.
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
+ public void resizeStack(int stackId, Rect bounds) throws SecurityException {
+ try {
+ getService().resizeStack(stackId, bounds, false /* allowResizeInDockedMode */,
+ false /* preserveWindows */, false /* animate */, -1 /* animationDuration */);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Removes stacks in the windowing modes from the system if they are of activity type
* ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED
*
* @hide
*/
@TestApi
+ @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public void removeStacksInWindowingModes(int[] windowingModes) throws SecurityException {
try {
getService().removeStacksInWindowingModes(windowingModes);
@@ -2045,6 +2094,7 @@ public class ActivityManager {
* @hide
*/
@TestApi
+ @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS)
public void removeStacksWithActivityTypes(int[] activityTypes) throws SecurityException {
try {
getService().removeStacksWithActivityTypes(activityTypes);
@@ -2535,7 +2585,7 @@ public class ActivityManager {
* The full configuration the stack is currently running in.
* @hide
*/
- public Configuration configuration = new Configuration();
+ final public Configuration configuration = new Configuration();
@Override
public int describeContents() {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 955b46300ea0..f03951607678 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -361,6 +361,15 @@ interface IActivityManager {
void killUid(int appId, int userId, in String reason);
void setUserIsMonkey(boolean monkey);
void hang(in IBinder who, boolean allowRestart);
+
+ /**
+ * Sets the windowing mode for a specific task. Only works on tasks of type
+ * {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD}
+ * @param taskId The id of the task to set the windowing mode for.
+ * @param windowingMode The windowing mode to set for the task.
+ * @param toTop If the task should be moved to the top once the windowing mode changes.
+ */
+ void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop);
void moveTaskToStack(int taskId, int stackId, boolean toTop);
/**
* Resizes the input stack id to the given bounds.
@@ -490,6 +499,18 @@ interface IActivityManager {
in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations);
boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
in Rect initialBounds);
+ /**
+ * Dismisses split-screen multi-window mode.
+ * {@param toTop} If true the current primary split-screen stack will be placed or left on top.
+ */
+ void dismissSplitScreenMode(boolean toTop);
+ /**
+ * Dismisses PiP
+ * @param animate True if the dismissal should be animated.
+ * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
+ * default animation duration should be used.
+ */
+ void dismissPip(boolean animate, int animationDuration);
void suppressResizeConfigChanges(boolean suppress);
void moveTasksToFullscreenStack(int fromStackId, boolean onTop);
boolean moveTopActivityToPinnedStack(int stackId, in Rect bounds);
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index a56965bdbd4d..2e1e9889eadc 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -30,7 +30,7 @@ oneway interface ITaskStackListener {
void onTaskStackChanged();
/** Called whenever an Activity is moved to the pinned stack from another stack. */
- void onActivityPinned(String packageName, int userId, int taskId);
+ void onActivityPinned(String packageName, int userId, int taskId, int stackId);
/** Called whenever an Activity is moved from the pinned stack to another stack. */
void onActivityUnpinned();
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 4674c9cd2389..402e2095a749 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -31,7 +31,7 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub {
}
@Override
- public void onActivityPinned(String packageName, int userId, int taskId)
+ public void onActivityPinned(String packageName, int userId, int taskId, int stackId)
throws RemoteException {
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 58243b487d64..f8996aae9a20 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -16,7 +16,6 @@
package com.android.systemui.pip.phone;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -73,7 +72,7 @@ public class PipManager implements BasePipManager {
*/
TaskStackListener mTaskStackListener = new TaskStackListener() {
@Override
- public void onActivityPinned(String packageName, int userId, int taskId) {
+ public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
mTouchHandler.onActivityPinned();
mMediaController.onActivityPinned();
mMenuController.onActivityPinned();
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index d71d4def576c..9fb201b82d8c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -16,7 +16,6 @@
package com.android.systemui.pip.phone;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
index eef0e7d46943..21a836c030cb 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java
@@ -16,7 +16,7 @@
package com.android.systemui.pip.phone;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
@@ -161,13 +161,7 @@ public class PipMotionHelper implements Handler.Callback {
mMenuController.hideMenuWithoutResize();
mHandler.post(() -> {
try {
- if (skipAnimation) {
- mActivityManager.moveTasksToFullscreenStack(PINNED_STACK_ID, true /* onTop */);
- } else {
- mActivityManager.resizeStack(PINNED_STACK_ID, null /* bounds */,
- true /* allowResizeInDockedMode */, true /* preserveWindows */,
- true /* animate */, EXPAND_STACK_TO_FULLSCREEN_DURATION);
- }
+ mActivityManager.dismissPip(!skipAnimation, EXPAND_STACK_TO_FULLSCREEN_DURATION);
} catch (RemoteException e) {
Log.e(TAG, "Error expanding PiP activity", e);
}
@@ -185,7 +179,7 @@ public class PipMotionHelper implements Handler.Callback {
mMenuController.hideMenuWithoutResize();
mHandler.post(() -> {
try {
- mActivityManager.removeStack(PINNED_STACK_ID);
+ mActivityManager.removeStacksInWindowingModes(new int[]{ WINDOWING_MODE_PINNED });
} catch (RemoteException e) {
Log.e(TAG, "Failed to remove PiP", e);
}
@@ -540,7 +534,7 @@ public class PipMotionHelper implements Handler.Callback {
return true;
}
- mActivityManager.resizeStack(PINNED_STACK_ID, toBounds,
+ mActivityManager.resizeStack(stackInfo.stackId, toBounds,
false /* allowResizeInDockedMode */, true /* preserveWindows */,
true /* animate */, duration);
mBounds.set(toBounds);
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java
index 84410f2fdb1d..2f53de96db2d 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipUtils.java
@@ -16,7 +16,6 @@
package com.android.systemui.pip.phone;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 6e8554901f45..e0445c16b50c 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -53,7 +53,7 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -123,6 +123,7 @@ public class PipManager implements BasePipManager {
private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
private boolean mInitialized;
private int mPipTaskId = TASK_ID_NO_PIP;
+ private int mPinnedStackId = INVALID_STACK_ID;
private ComponentName mPipComponentName;
private MediaController mPipMediaController;
private String[] mLastPackagesResourceGranted;
@@ -338,9 +339,11 @@ public class PipManager implements BasePipManager {
mMediaSessionManager.removeOnActiveSessionsChangedListener(mActiveMediaSessionListener);
if (removePipStack) {
try {
- mActivityManager.removeStack(PINNED_STACK_ID);
+ mActivityManager.removeStack(mPinnedStackId);
} catch (RemoteException e) {
Log.e(TAG, "removeStack failed", e);
+ } finally {
+ mPinnedStackId = INVALID_STACK_ID;
}
}
for (int i = mListeners.size() - 1; i >= 0; --i) {
@@ -426,7 +429,7 @@ public class PipManager implements BasePipManager {
}
try {
int animationDurationMs = -1;
- mActivityManager.resizeStack(PINNED_STACK_ID, mCurrentPipBounds,
+ mActivityManager.resizeStack(mPinnedStackId, mCurrentPipBounds,
true, true, true, animationDurationMs);
} catch (RemoteException e) {
Log.e(TAG, "resizeStack failed", e);
@@ -657,7 +660,7 @@ public class PipManager implements BasePipManager {
}
@Override
- public void onActivityPinned(String packageName, int userId, int taskId) {
+ public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
if (DEBUG) Log.d(TAG, "onActivityPinned()");
if (!checkCurrentUserId(mContext, DEBUG)) {
return;
@@ -668,6 +671,7 @@ public class PipManager implements BasePipManager {
return;
}
if (DEBUG) Log.d(TAG, "PINNED_STACK:" + stackInfo);
+ mPinnedStackId = stackInfo.stackId;
mPipTaskId = stackInfo.taskIds[stackInfo.taskIds.length - 1];
mPipComponentName = ComponentName.unflattenFromString(
stackInfo.taskNames[stackInfo.taskNames.length - 1]);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index dc83333da2e8..3e2a5f3f2043 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -16,9 +16,9 @@
package com.android.systemui.recents;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.view.View.MeasureSpec;
import android.app.ActivityManager;
@@ -173,7 +173,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
}
@Override
- public void onActivityPinned(String packageName, int userId, int taskId) {
+ public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
// Check this is for the right user
if (!checkCurrentUserId(mContext, false /* debug */)) {
return;
@@ -873,7 +873,9 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
getThumbnailTransitionActivityOptions(ActivityManager.RunningTaskInfo runningTask,
Rect windowOverrideRect) {
final boolean isLowRamDevice = Recents.getConfiguration().isLowRamDevice;
- if (runningTask != null && runningTask.stackId == FREEFORM_WORKSPACE_STACK_ID) {
+ if (runningTask != null
+ && runningTask.configuration.windowConfiguration.getWindowingMode()
+ == WINDOWING_MODE_FREEFORM) {
ArrayList<AppTransitionAnimationSpec> specs = new ArrayList<>();
ArrayList<Task> tasks = mDummyStackView.getStack().getStackTasks();
TaskStackLayoutAlgorithm stackLayout = mDummyStackView.getStackAlgorithm();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 4580b1f5c1a3..bddf9a5983db 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -16,8 +16,6 @@
package com.android.systemui.recents.misc;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
@@ -177,7 +175,7 @@ public class SystemServicesProxy {
public void onTaskStackChangedBackground() { }
public void onTaskStackChanged() { }
public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { }
- public void onActivityPinned(String packageName, int userId, int taskId) { }
+ public void onActivityPinned(String packageName, int userId, int taskId, int stackId) { }
public void onActivityUnpinned() { }
public void onPinnedActivityRestartAttempt(boolean clearedTask) { }
public void onPinnedStackAnimationStarted() { }
@@ -232,10 +230,11 @@ public class SystemServicesProxy {
}
@Override
- public void onActivityPinned(String packageName, int userId, int taskId)
+ public void onActivityPinned(String packageName, int userId, int taskId, int stackId)
throws RemoteException {
mHandler.removeMessages(H.ON_ACTIVITY_PINNED);
- mHandler.obtainMessage(H.ON_ACTIVITY_PINNED, userId, taskId, packageName).sendToTarget();
+ mHandler.obtainMessage(H.ON_ACTIVITY_PINNED,
+ new PinnedActivityInfo(packageName, userId, taskId, stackId)).sendToTarget();
}
@Override
@@ -618,13 +617,6 @@ public class SystemServicesProxy {
}
/**
- * Returns whether the given stack id is the freeform workspace stack id.
- */
- public static boolean isFreeformStack(int stackId) {
- return stackId == FREEFORM_WORKSPACE_STACK_ID;
- }
-
- /**
* @return whether there are any docked tasks for the current user.
*/
public boolean hasDockedTask() {
@@ -734,14 +726,12 @@ public class SystemServicesProxy {
}
}
- /**
- * Moves a task into another stack.
- */
- public void moveTaskToStack(int taskId, int stackId) {
+ /** Set the task's windowing mode. */
+ public void setTaskWindowingMode(int taskId, int windowingMode) {
if (mIam == null) return;
try {
- mIam.positionTaskInStack(taskId, stackId, 0);
+ mIam.setTaskWindowingMode(taskId, windowingMode, false /* onTop */);
} catch (RemoteException | IllegalArgumentException e) {
e.printStackTrace();
}
@@ -1132,7 +1122,7 @@ public class SystemServicesProxy {
if (mIam == null) {
return;
}
- if (taskKey.stackId == DOCKED_STACK_ID) {
+ if (taskKey.windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
// We show non-visible docked tasks in Recents, but we always want to launch
// them in the fullscreen stack.
if (options == null) {
@@ -1314,6 +1304,20 @@ public class SystemServicesProxy {
void onStartActivityResult(boolean succeeded);
}
+ private class PinnedActivityInfo {
+ final String mPackageName;
+ final int mUserId;
+ final int mTaskId;
+ final int mStackId;
+
+ PinnedActivityInfo(String packageName, int userId, int taskId, int stackId) {
+ mPackageName = packageName;
+ mUserId = userId;
+ mTaskId = taskId;
+ mStackId = stackId;
+ }
+ }
+
private final class H extends Handler {
private static final int ON_TASK_STACK_CHANGED = 1;
private static final int ON_TASK_SNAPSHOT_CHANGED = 2;
@@ -1349,9 +1353,10 @@ public class SystemServicesProxy {
break;
}
case ON_ACTIVITY_PINNED: {
+ final PinnedActivityInfo info = (PinnedActivityInfo) msg.obj;
for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
- mTaskStackListeners.get(i).onActivityPinned((String) msg.obj, msg.arg1,
- msg.arg2);
+ mTaskStackListeners.get(i).onActivityPinned(
+ info.mPackageName, info.mUserId, info.mTaskId, info.mStackId);
}
break;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/HighResThumbnailLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/HighResThumbnailLoader.java
index 48fa6c3c053b..6414ea1e9783 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/HighResThumbnailLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/HighResThumbnailLoader.java
@@ -187,7 +187,7 @@ public class HighResThumbnailLoader implements TaskCallbacks {
}
@Override
- public void onTaskStackIdChanged() {
+ public void onTaskWindowingModeChanged() {
}
private final Runnable mLoader = new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 8d31730d8602..d5e031355810 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -16,6 +16,8 @@
package com.android.systemui.recents.model;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
@@ -155,12 +157,13 @@ public class RecentsTaskLoadPlan {
ActivityManager.RecentTaskInfo t = mRawTasks.get(i);
// Compose the task key
- Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, t.stackId, t.baseIntent,
+ final int windowingMode = t.configuration.windowConfiguration.getWindowingMode();
+ Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, windowingMode, t.baseIntent,
t.userId, t.firstActiveTime, t.lastActiveTime);
// This task is only shown in the stack if it satisfies the historical time or min
// number of tasks constraints. Freeform tasks are also always shown.
- boolean isFreeformTask = SystemServicesProxy.isFreeformStack(t.stackId);
+ boolean isFreeformTask = windowingMode == WINDOWING_MODE_FREEFORM;
boolean isStackTask;
if (Recents.getConfiguration().isGridEnabled) {
// When grid layout is enabled, we only show the first
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index 9e6bf85445a0..abdb5cb8c2e3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -16,6 +16,8 @@
package com.android.systemui.recents.model;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Intent;
@@ -46,8 +48,8 @@ public class Task {
public void onTaskDataLoaded(Task task, ThumbnailData thumbnailData);
/* Notifies when a task has been unbound */
public void onTaskDataUnloaded();
- /* Notifies when a task's stack id has changed. */
- public void onTaskStackIdChanged();
+ /* Notifies when a task's windowing mode has changed. */
+ public void onTaskWindowingModeChanged();
}
/* The Task Key represents the unique primary key for the task */
@@ -55,7 +57,7 @@ public class Task {
@ViewDebug.ExportedProperty(category="recents")
public final int id;
@ViewDebug.ExportedProperty(category="recents")
- public int stackId;
+ public int windowingMode;
@ViewDebug.ExportedProperty(category="recents")
public final Intent baseIntent;
@ViewDebug.ExportedProperty(category="recents")
@@ -67,10 +69,10 @@ public class Task {
private int mHashCode;
- public TaskKey(int id, int stackId, Intent intent, int userId, long firstActiveTime,
+ public TaskKey(int id, int windowingMode, Intent intent, int userId, long firstActiveTime,
long lastActiveTime) {
this.id = id;
- this.stackId = stackId;
+ this.windowingMode = windowingMode;
this.baseIntent = intent;
this.userId = userId;
this.firstActiveTime = firstActiveTime;
@@ -78,8 +80,8 @@ public class Task {
updateHashCode();
}
- public void setStackId(int stackId) {
- this.stackId = stackId;
+ public void setWindowingMode(int windowingMode) {
+ this.windowingMode = windowingMode;
updateHashCode();
}
@@ -93,7 +95,9 @@ public class Task {
return false;
}
TaskKey otherKey = (TaskKey) o;
- return id == otherKey.id && stackId == otherKey.stackId && userId == otherKey.userId;
+ return id == otherKey.id
+ && windowingMode == otherKey.windowingMode
+ && userId == otherKey.userId;
}
@Override
@@ -103,12 +107,12 @@ public class Task {
@Override
public String toString() {
- return "id=" + id + " stackId=" + stackId + " user=" + userId + " lastActiveTime=" +
- lastActiveTime;
+ return "id=" + id + " windowingMode=" + windowingMode + " user=" + userId
+ + " lastActiveTime=" + lastActiveTime;
}
private void updateHashCode() {
- mHashCode = Objects.hash(id, stackId, userId);
+ mHashCode = Objects.hash(id, windowingMode, userId);
}
}
@@ -277,14 +281,12 @@ public class Task {
this.group = group;
}
- /**
- * Updates the stack id of this task.
- */
- public void setStackId(int stackId) {
- key.setStackId(stackId);
+ /** Updates the task's windowing mode. */
+ public void setWindowingMode(int windowingMode) {
+ key.setWindowingMode(windowingMode);
int callbackCount = mCallbacks.size();
for (int i = 0; i < callbackCount; i++) {
- mCallbacks.get(i).onTaskStackIdChanged();
+ mCallbacks.get(i).onTaskWindowingModeChanged();
}
}
@@ -293,7 +295,7 @@ public class Task {
*/
public boolean isFreeformTask() {
SystemServicesProxy ssp = Recents.getSystemServices();
- return ssp.hasFreeformWorkspaceSupport() && ssp.isFreeformStack(key.stackId);
+ return ssp.hasFreeformWorkspaceSupport() && key.windowingMode == WINDOWING_MODE_FREEFORM;
}
/** Notifies the callback listeners that this task has been loaded */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyCache.java
index be99f93028dc..247a654207c8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyCache.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskKeyCache.java
@@ -45,7 +45,7 @@ public abstract class TaskKeyCache<V> {
final V getAndInvalidateIfModified(Task.TaskKey key) {
Task.TaskKey lastKey = mKeys.get(key.id);
if (lastKey != null) {
- if ((lastKey.stackId != key.stackId) ||
+ if ((lastKey.windowingMode != key.windowingMode) ||
(lastKey.lastActiveTime != key.lastActiveTime)) {
// The task has updated (been made active since the last time it was put into the
// LRU cache) or the stack id for the task has changed, invalidate that cache item
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index 6e3be09b2ae9..fdae917cf1ab 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -18,8 +18,8 @@ package com.android.systemui.recents.model;
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT;
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.DOCKED_BOTTOM;
import static android.view.WindowManager.DOCKED_INVALID;
import static android.view.WindowManager.DOCKED_LEFT;
@@ -115,7 +115,7 @@ class FilteredTaskList {
/**
* Moves the given task.
*/
- public void moveTaskToStack(Task task, int insertIndex, int newStackId) {
+ public void setTaskWindowingMode(Task task, int insertIndex, int windowingMode) {
int taskIndex = indexOf(task);
if (taskIndex != insertIndex) {
mTasks.remove(taskIndex);
@@ -127,7 +127,7 @@ class FilteredTaskList {
// Update the stack id now, after we've moved the task, and before we update the
// filtered tasks
- task.setStackId(newStackId);
+ task.setWindowingMode(windowingMode);
updateFilteredTasks();
}
@@ -590,17 +590,15 @@ public class TaskStack {
mCb = cb;
}
- /**
- * Moves the given task to either the front of the freeform workspace or the stack.
- */
- public void moveTaskToStack(Task task, int newStackId) {
+ /** Sets the windowing mode for a given task. */
+ public void setTaskWindowingMode(Task task, int windowingMode) {
// Find the index to insert into
ArrayList<Task> taskList = mStackTaskList.getTasks();
int taskCount = taskList.size();
- if (!task.isFreeformTask() && (newStackId == FREEFORM_WORKSPACE_STACK_ID)) {
+ if (!task.isFreeformTask() && (windowingMode == WINDOWING_MODE_FREEFORM)) {
// Insert freeform tasks at the front
- mStackTaskList.moveTaskToStack(task, taskCount, newStackId);
- } else if (task.isFreeformTask() && (newStackId == FULLSCREEN_WORKSPACE_STACK_ID)) {
+ mStackTaskList.setTaskWindowingMode(task, taskCount, windowingMode);
+ } else if (task.isFreeformTask() && (windowingMode == WINDOWING_MODE_FULLSCREEN)) {
// Insert after the first stacked task
int insertIndex = 0;
for (int i = taskCount - 1; i >= 0; i--) {
@@ -609,7 +607,7 @@ public class TaskStack {
break;
}
}
- mStackTaskList.moveTaskToStack(task, insertIndex, newStackId);
+ mStackTaskList.setTaskWindowingMode(task, insertIndex, windowingMode);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 7ede0c5d08c8..3160ee0ee8df 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -16,9 +16,8 @@
package com.android.systemui.recents.views;
-import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
-import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -2094,18 +2093,18 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
boolean isFreeformTask = event.task.isFreeformTask();
- boolean hasChangedStacks =
+ boolean hasChangedWindowingMode =
(!isFreeformTask && event.dropTarget == mFreeformWorkspaceDropTarget) ||
(isFreeformTask && event.dropTarget == mStackDropTarget);
- if (hasChangedStacks) {
+ if (hasChangedWindowingMode) {
// Move the task to the right position in the stack (ie. the front of the stack if
// freeform or the front of the stack if fullscreen). Note, we MUST move the tasks
// before we update their stack ids, otherwise, the keys will have changed.
if (event.dropTarget == mFreeformWorkspaceDropTarget) {
- mStack.moveTaskToStack(event.task, FREEFORM_WORKSPACE_STACK_ID);
+ mStack.setTaskWindowingMode(event.task, WINDOWING_MODE_FREEFORM);
} else if (event.dropTarget == mStackDropTarget) {
- mStack.moveTaskToStack(event.task, FULLSCREEN_WORKSPACE_STACK_ID);
+ mStack.setTaskWindowingMode(event.task, WINDOWING_MODE_FULLSCREEN);
}
updateLayoutAlgorithm(true /* boundScroll */);
@@ -2114,7 +2113,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
@Override
public void run() {
SystemServicesProxy ssp = Recents.getSystemServices();
- ssp.moveTaskToStack(event.task.key.id, event.task.key.stackId);
+ ssp.setTaskWindowingMode(event.task.key.id, event.task.key.windowingMode);
}
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index c64f6dfcea4a..9d639647acdb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -647,7 +647,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
}
@Override
- public void onTaskStackIdChanged() {
+ public void onTaskWindowingModeChanged() {
// Force rebind the header, the thumbnail does not change due to stack changes
mHeaderView.bindToTask(mTask, mTouchExplorationEnabled, mIsDisabledInSafeMode);
mHeaderView.onTaskDataLoaded();
diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
index f7c04116c767..85a60624c275 100644
--- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java
@@ -16,7 +16,6 @@
package com.android.systemui.stackdivider;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
import static android.view.WindowManager.DOCKED_INVALID;
import android.app.ActivityManager;
@@ -88,8 +87,7 @@ public class WindowManagerProxy {
@Override
public void run() {
try {
- ActivityManager.getService().moveTasksToFullscreenStack(
- DOCKED_STACK_ID, false /* onTop */);
+ ActivityManager.getService().dismissSplitScreenMode(false /* onTop */);
} catch (RemoteException e) {
Log.w(TAG, "Failed to remove stack: " + e);
}
@@ -100,8 +98,7 @@ public class WindowManagerProxy {
@Override
public void run() {
try {
- ActivityManager.getService().resizeStack(
- DOCKED_STACK_ID, null, true, true, false, -1);
+ ActivityManager.getService().dismissSplitScreenMode(true /* onTop */);
} catch (RemoteException e) {
Log.w(TAG, "Failed to resize stack: " + e);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 561fbb2b4aba..6cfd42fa00eb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -43,6 +43,7 @@ import android.util.FloatProperty;
import android.util.Log;
import android.util.Property;
import android.util.TypedValue;
+import android.view.View;
import android.view.ViewDebug;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.Interpolator;
@@ -142,6 +143,7 @@ public class StatusBarIconView extends AnimatedImageView {
private float[] mMatrix;
private ColorMatrixColorFilter mMatrixColorFilter;
private boolean mIsInShelf;
+ private Runnable mLayoutRunnable;
public StatusBarIconView(Context context, String slot, StatusBarNotification sbn) {
this(context, slot, sbn, false);
@@ -822,6 +824,19 @@ public class StatusBarIconView extends AnimatedImageView {
return mIsInShelf;
}
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ if (mLayoutRunnable != null) {
+ mLayoutRunnable.run();
+ mLayoutRunnable = null;
+ }
+ }
+
+ public void executeOnLayout(Runnable runnable) {
+ mLayoutRunnable = runnable;
+ }
+
public interface OnVisibilityChangedListener {
void onVisibilityChanged(int newVisibility);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 41a69b4ba557..40fe50fb9325 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -4,10 +4,8 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
-import android.graphics.drawable.Icon;
import android.support.annotation.NonNull;
import android.support.v4.util.ArrayMap;
-import android.support.v4.util.ArraySet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
@@ -269,18 +267,26 @@ public class NotificationIconAreaController implements DarkReceiver {
*/
private void applyNotificationIconsTint() {
for (int i = 0; i < mNotificationIcons.getChildCount(); i++) {
- StatusBarIconView v = (StatusBarIconView) mNotificationIcons.getChildAt(i);
- boolean isPreL = Boolean.TRUE.equals(v.getTag(R.id.icon_is_pre_L));
- int color = StatusBarIconView.NO_COLOR;
- boolean colorize = !isPreL || NotificationUtils.isGrayscale(v, mNotificationColorUtil);
- if (colorize) {
- color = DarkIconDispatcher.getTint(mTintArea, v, mIconTint);
+ final StatusBarIconView iv = (StatusBarIconView) mNotificationIcons.getChildAt(i);
+ if (iv.getWidth() != 0) {
+ updateTintForIcon(iv);
+ } else {
+ iv.executeOnLayout(() -> updateTintForIcon(iv));
}
- v.setStaticDrawableColor(color);
- v.setDecorColor(mIconTint);
}
}
+ private void updateTintForIcon(StatusBarIconView v) {
+ boolean isPreL = Boolean.TRUE.equals(v.getTag(R.id.icon_is_pre_L));
+ int color = StatusBarIconView.NO_COLOR;
+ boolean colorize = !isPreL || NotificationUtils.isGrayscale(v, mNotificationColorUtil);
+ if (colorize) {
+ color = DarkIconDispatcher.getTint(mTintArea, v, mIconTint);
+ }
+ v.setStaticDrawableColor(color);
+ v.setDecorColor(mIconTint);
+ }
+
public void setDark(boolean dark) {
mNotificationIcons.setDark(dark, false, 0);
mShelfIcons.setDark(dark, false, 0);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java b/packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java
index 5a8c6dd97908..767e1246e45b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/model/HighResThumbnailLoaderTest.java
@@ -16,6 +16,7 @@
package com.android.systemui.recents.model;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.anyBoolean;
@@ -59,7 +60,7 @@ public class HighResThumbnailLoaderTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
mLoader = new HighResThumbnailLoader(mMockSystemServicesProxy, Looper.getMainLooper(),
false);
- mTask.key = new TaskKey(0, 0, null, 0, 0, 0);
+ mTask.key = new TaskKey(0, WINDOWING_MODE_UNDEFINED, null, 0, 0, 0);
when(mMockSystemServicesProxy.getTaskThumbnail(anyInt(), anyBoolean()))
.thenReturn(mThumbnailData);
mLoader.setVisible(true);
diff --git a/packages/VpnDialogs/res/values-cs/strings.xml b/packages/VpnDialogs/res/values-cs/strings.xml
index 7a3d515877fa..47d950ff8cdb 100644
--- a/packages/VpnDialogs/res/values-cs/strings.xml
+++ b/packages/VpnDialogs/res/values-cs/strings.xml
@@ -31,6 +31,6 @@
<string name="always_on_disconnected_message_settings_link" msgid="6172280302829992412">"Změnit nastavení VPN"</string>
<string name="configure" msgid="4905518375574791375">"Konfigurovat"</string>
<string name="disconnect" msgid="971412338304200056">"Odpojit"</string>
- <string name="open_app" msgid="3717639178595958667">"Spustit aplikaci"</string>
+ <string name="open_app" msgid="3717639178595958667">"Do aplikace"</string>
<string name="dismiss" msgid="6192859333764711227">"Zavřít"</string>
</resources>
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5160474f091a..e6fe620485da 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -38,6 +38,7 @@ import static android.app.ActivityManager.StackId.isStaticStack;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
@@ -3243,7 +3244,8 @@ public class ActivityManagerService extends IActivityManager.Stub
if (r.requestedVrComponent != null && r.getStackId() >= FIRST_DYNAMIC_STACK_ID) {
Slog.i(TAG, "Moving " + r.shortComponentName + " from stack " + r.getStackId()
+ " to main stack for VR");
- moveTaskToStack(r.getTask().taskId, FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */);
+ setTaskWindowingMode(r.getTask().taskId,
+ WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, true /* toTop */);
}
mHandler.sendMessage(
mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
@@ -9877,6 +9879,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
rti.supportsSplitScreenMultiWindow = tr.supportsSplitScreenWindowingMode();
rti.resizeMode = tr.mResizeMode;
+ rti.configuration.setTo(tr.getConfiguration());
ActivityRecord base = null;
ActivityRecord top = null;
@@ -10625,6 +10628,42 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
+ public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) {
+ enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()");
+ synchronized (this) {
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
+ if (task == null) {
+ Slog.w(TAG, "setTaskWindowingMode: No task for id=" + taskId);
+ return;
+ }
+
+ if (DEBUG_STACK) Slog.d(TAG_STACK, "setTaskWindowingMode: moving task=" + taskId
+ + " to windowingMode=" + windowingMode + " toTop=" + toTop);
+ if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
+ mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
+ null /* initialBounds */);
+ }
+
+ if (!task.isActivityTypeStandardOrUndefined()) {
+ throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move task "
+ + taskId + " to non-standard windowin mode=" + windowingMode);
+ }
+ final ActivityDisplay display = task.getStack().getDisplay();
+ final ActivityStack stack = display.getOrCreateStack(windowingMode,
+ task.getStack().getActivityType(), toTop);
+ // TODO: We should just change the windowing mode for the task vs. creating and
+ // moving it to a stack.
+ task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME,
+ "moveTaskToStack");
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+ }
+
+ @Override
public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
synchronized (this) {
@@ -10718,6 +10757,66 @@ public class ActivityManagerService extends IActivityManager.Stub
}
/**
+ * Dismisses split-screen multi-window mode.
+ * @param toTop If true the current primary split-screen stack will be placed or left on top.
+ */
+ @Override
+ public void dismissSplitScreenMode(boolean toTop) {
+ enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "dismissSplitScreenMode()");
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (this) {
+ final ActivityStack stack =
+ mStackSupervisor.getDefaultDisplay().getSplitScreenStack();
+ if (toTop) {
+ mStackSupervisor.resizeStackLocked(stack.mStackId, null /* destBounds */,
+ null /* tempTaskBounds */, null /* tempTaskInsetBounds */,
+ true /* preserveWindows */, true /* allowResizeInDockedMode */,
+ !DEFER_RESUME);
+ } else {
+ mStackSupervisor.moveTasksToFullscreenStackLocked(stack, false /* onTop */);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ /**
+ * Dismisses Pip
+ * @param animate True if the dismissal should be animated.
+ * @param animationDuration The duration of the resize animation in milliseconds or -1 if the
+ * default animation duration should be used.
+ */
+ @Override
+ public void dismissPip(boolean animate, int animationDuration) {
+ enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "dismissPip()");
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (this) {
+ final PinnedActivityStack stack =
+ mStackSupervisor.getDefaultDisplay().getPinnedStack();
+
+ if (stack == null) {
+ return;
+ }
+ if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) {
+ throw new IllegalArgumentException("Stack: " + stack
+ + " doesn't support animated resize.");
+ }
+ if (animate) {
+ stack.animateResizePinnedStack(null /* sourceHintBounds */,
+ null /* destBounds */, animationDuration, false /* fromFullscreen */);
+ } else {
+ mStackSupervisor.moveTasksToFullscreenStackLocked(stack, true /* onTop */);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ /**
* Moves the top activity in the input stackId to the pinned stack.
*
* @param stackId Id of stack to move the top activity to pinned stack.
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 34eaab234381..1940ca2b4c31 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -4900,7 +4900,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
ci.numRunning = numRunning;
ci.supportsSplitScreenMultiWindow = task.supportsSplitScreenWindowingMode();
ci.resizeMode = task.mResizeMode;
- ci.configuration = task.getConfiguration();
+ ci.configuration.setTo(task.getConfiguration());
list.add(ci);
}
}
@@ -5089,7 +5089,7 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
if (isAttached()) {
getDisplay().positionChildAtBottom(this);
}
- if (!isHomeOrRecentsStack()) {
+ if (!isActivityTypeHome()) {
remove();
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 42f3550da8b9..da2827a6aedc 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2625,38 +2625,41 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
// the picture-in-picture mode.
final boolean schedulePictureInPictureModeChange = inPinnedWindowingMode;
final ArrayList<TaskRecord> tasks = fromStack.getAllTasks();
- final int size = tasks.size();
- final ActivityStack fullscreenStack = toDisplay.getOrCreateStack(
- WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, onTop);
- if (onTop) {
- final int returnToType =
- toDisplay.getTopVisibleStackActivityType(WINDOWING_MODE_PINNED);
- for (int i = 0; i < size; i++) {
- final TaskRecord task = tasks.get(i);
- final boolean isTopTask = i == (size - 1);
- if (inPinnedWindowingMode) {
- // Update the return-to to reflect where the pinned stack task was moved
- // from so that we retain the stack that was previously visible if the
- // pinned stack is recreated. See moveActivityToPinnedStackLocked().
- task.setTaskToReturnTo(returnToType);
+ if (!tasks.isEmpty()) {
+ final int size = tasks.size();
+ final ActivityStack fullscreenStack = toDisplay.getOrCreateStack(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, onTop);
+
+ if (onTop) {
+ final int returnToType =
+ toDisplay.getTopVisibleStackActivityType(WINDOWING_MODE_PINNED);
+ for (int i = 0; i < size; i++) {
+ final TaskRecord task = tasks.get(i);
+ final boolean isTopTask = i == (size - 1);
+ if (inPinnedWindowingMode) {
+ // Update the return-to to reflect where the pinned stack task was moved
+ // from so that we retain the stack that was previously visible if the
+ // pinned stack is recreated. See moveActivityToPinnedStackLocked().
+ task.setTaskToReturnTo(returnToType);
+ }
+ // Defer resume until all the tasks have been moved to the fullscreen stack
+ task.reparent(fullscreenStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT,
+ isTopTask /* animate */, DEFER_RESUME,
+ schedulePictureInPictureModeChange,
+ "moveTasksToFullscreenStack - onTop");
+ }
+ } else {
+ for (int i = 0; i < size; i++) {
+ final TaskRecord task = tasks.get(i);
+ // Position the tasks in the fullscreen stack in order at the bottom of the
+ // stack. Also defer resume until all the tasks have been moved to the
+ // fullscreen stack.
+ task.reparent(fullscreenStack, i /* position */,
+ REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE, DEFER_RESUME,
+ schedulePictureInPictureModeChange,
+ "moveTasksToFullscreenStack - NOT_onTop");
}
- // Defer resume until all the tasks have been moved to the fullscreen stack
- task.reparent(fullscreenStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT,
- isTopTask /* animate */, DEFER_RESUME,
- schedulePictureInPictureModeChange,
- "moveTasksToFullscreenStack - onTop");
- }
- } else {
- for (int i = 0; i < size; i++) {
- final TaskRecord task = tasks.get(i);
- // Position the tasks in the fullscreen stack in order at the bottom of the
- // stack. Also defer resume until all the tasks have been moved to the
- // fullscreen stack.
- task.reparent(fullscreenStack, i /* position */,
- REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE, DEFER_RESUME,
- schedulePictureInPictureModeChange,
- "moveTasksToFullscreenStack - NOT_onTop");
}
}
@@ -3216,8 +3219,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
resumeFocusedStackTopActivityLocked();
- mService.mTaskChangeNotificationController.notifyActivityPinned(r.packageName, r.userId,
- r.getTask().taskId);
+ mService.mTaskChangeNotificationController.notifyActivityPinned(r);
}
/** Move activity with its stack to front and make the stack focused. */
diff --git a/services/core/java/com/android/server/am/TaskChangeNotificationController.java b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
index 6a986bb8a684..5a7e7ced930c 100644
--- a/services/core/java/com/android/server/am/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
@@ -95,7 +95,8 @@ class TaskChangeNotificationController {
};
private final TaskStackConsumer mNotifyActivityPinned = (l, m) -> {
- l.onActivityPinned((String) m.obj, m.arg1, m.arg2);
+ final ActivityRecord r = (ActivityRecord) m.obj;
+ l.onActivityPinned(r.packageName, r.userId, r.getTask().taskId, r.getStackId());
};
private final TaskStackConsumer mNotifyActivityUnpinned = (l, m) -> {
@@ -278,10 +279,9 @@ class TaskChangeNotificationController {
}
/** Notifies all listeners when an Activity is pinned. */
- void notifyActivityPinned(String packageName, int userId, int taskId) {
+ void notifyActivityPinned(ActivityRecord r) {
mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
- final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG,
- userId, taskId, packageName);
+ final Message msg = mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG, r);
forAllLocalListeners(mNotifyActivityPinned, msg);
msg.sendToTarget();
}