diff options
| author | 2018-04-25 15:41:44 -0700 | |
|---|---|---|
| committer | 2018-06-06 18:26:21 -0700 | |
| commit | 65ebd955e1b19a0d3c995e66d1d749bae5dc8575 (patch) | |
| tree | 8c6b2b82d06e0290816a8de36fc08db8e42b5c83 | |
| parent | 3193b1537c9b31b8345cfb98ea7fc1d7d3ee0ac2 (diff) | |
Split interfaces and service for activities from current AM interfaces (1/n)
First step in unifying the window hierarchy that is currently split
within AM and WM packages. We separate the interfaces and service dealing
with activities and their containers (tasks, stack, display) from the
rest of AM interfaces and services. This will allow us to move the new
interfaces and services to WM when the internal states are cleaned-up.
Test: Existing tests pass
Test: go/wm-smoke-auto
Bug: 80414790
Change-Id: Ide9b3f89123b768cdbd3e3878113c7a8021187f3
47 files changed, 906 insertions, 562 deletions
diff --git a/Android.bp b/Android.bp index b50593dfcd22..8e9ffa8ef77b 100644 --- a/Android.bp +++ b/Android.bp @@ -58,6 +58,7 @@ java_library { "core/java/android/app/IActivityController.aidl", "core/java/android/app/IActivityManager.aidl", "core/java/android/app/IActivityPendingResult.aidl", + "core/java/android/app/IActivityTaskManager.aidl", "core/java/android/app/IAlarmCompleteListener.aidl", "core/java/android/app/IAlarmListener.aidl", "core/java/android/app/IAlarmManager.aidl", diff --git a/api/test-current.txt b/api/test-current.txt index 9be252f92831..e589f1eab051 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -30,25 +30,12 @@ package android.app { method public long getTotalRam(); method public int getUidImportance(int); 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 void setTaskWindowingMode(int, int, boolean) throws java.lang.SecurityException; - method public void setTaskWindowingModeSplitScreenPrimary(int, int, boolean, boolean, android.graphics.Rect, boolean) throws java.lang.SecurityException; - method public static boolean supportsMultiWindow(android.content.Context); - method public static boolean supportsSplitScreenMultiWindow(android.content.Context); - field public static final int SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT = 1; // 0x1 - field public static final int SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT = 0; // 0x0 } public static abstract interface ActivityManager.OnUidImportanceListener { method public abstract void onUidImportance(int, int); } - public static class ActivityManager.StackId { - field public static final int INVALID_STACK_ID = -1; // 0xffffffff - } - public static class ActivityManager.TaskDescription implements android.os.Parcelable { method public java.lang.String getIconFilename(); method public int getIconResource(); @@ -61,6 +48,19 @@ package android.app { method public void setTaskOverlay(boolean, boolean); } + public class ActivityTaskManager { + 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 void setTaskWindowingMode(int, int, boolean) throws java.lang.SecurityException; + method public void setTaskWindowingModeSplitScreenPrimary(int, int, boolean, boolean, android.graphics.Rect, boolean) throws java.lang.SecurityException; + method public static boolean supportsMultiWindow(android.content.Context); + method public static boolean supportsSplitScreenMultiWindow(android.content.Context); + field public static final int INVALID_STACK_ID = -1; // 0xffffffff + field public static final int SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT = 1; // 0x1 + field public static final int SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT = 0; // 0x0 + } + public class AppOpsManager { method public static int getNumOps(); method public static java.lang.String[] getOpStrs(); diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 929e119dc2d2..842012530511 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -123,8 +123,6 @@ import java.util.List; public class ActivityManager { private static String TAG = "ActivityManager"; - private static int gMaxRecentTasks = -1; - private final Context mContext; private static volatile boolean sSystemReady = false; @@ -746,83 +744,6 @@ public class ActivityManager { SystemProperties.getBoolean("debug.force_low_ram", false); /** @hide */ - @TestApi - public static class StackId { - - private StackId() { - } - - /** Invalid stack ID. */ - public static final int INVALID_STACK_ID = -1; - - } - - /** - * Parameter to {@link android.app.IActivityManager#setTaskWindowingModeSplitScreenPrimary} - * which specifies the position of the created docked stack at the top half of the screen if - * in portrait mode or at the left half of the screen if in landscape mode. - * @hide - */ - @TestApi - public static final int SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT = 0; - - /** - * Parameter to {@link android.app.IActivityManager#setTaskWindowingModeSplitScreenPrimary} - * which - * specifies the position of the created docked stack at the bottom half of the screen if - * in portrait mode or at the right half of the screen if in landscape mode. - * @hide - */ - @TestApi - public static final int SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT = 1; - - /** - * Input parameter to {@link android.app.IActivityManager#resizeTask} which indicates - * that the resize doesn't need to preserve the window, and can be skipped if bounds - * is unchanged. This mode is used by window manager in most cases. - * @hide - */ - public static final int RESIZE_MODE_SYSTEM = 0; - - /** - * Input parameter to {@link android.app.IActivityManager#resizeTask} which indicates - * that the resize should preserve the window if possible. - * @hide - */ - public static final int RESIZE_MODE_PRESERVE_WINDOW = (0x1 << 0); - - /** - * Input parameter to {@link android.app.IActivityManager#resizeTask} which indicates - * that the resize should be performed even if the bounds appears unchanged. - * @hide - */ - public static final int RESIZE_MODE_FORCED = (0x1 << 1); - - /** - * Input parameter to {@link android.app.IActivityManager#resizeTask} used by window - * manager during a screen rotation. - * @hide - */ - public static final int RESIZE_MODE_SYSTEM_SCREEN_ROTATION = RESIZE_MODE_PRESERVE_WINDOW; - - /** - * Input parameter to {@link android.app.IActivityManager#resizeTask} used when the - * resize is due to a drag action. - * @hide - */ - public static final int RESIZE_MODE_USER = RESIZE_MODE_PRESERVE_WINDOW; - - /** - * Input parameter to {@link android.app.IActivityManager#resizeTask} which indicates - * that the resize should preserve the window if possible, and should not be skipped - * even if the bounds is unchanged. Usually used to force a resizing when a drag action - * is ending. - * @hide - */ - public static final int RESIZE_MODE_USER_FORCED = - RESIZE_MODE_PRESERVE_WINDOW | RESIZE_MODE_FORCED; - - /** @hide */ public int getFrontActivityScreenCompatMode() { try { return getService().getFrontActivityScreenCompatMode(); @@ -977,57 +898,13 @@ public class ActivityManager { } /** - * Return the maximum number of recents entries that we will maintain and show. + * TODO(b/80414790): Remove once no longer on hiddenapi-light-greylist.txt * @hide + * @deprecated Use {@link ActivityTaskManager#getMaxRecentTasksStatic()} */ + @Deprecated static public int getMaxRecentTasksStatic() { - if (gMaxRecentTasks < 0) { - return gMaxRecentTasks = isLowRamDeviceStatic() ? 36 : 48; - } - return gMaxRecentTasks; - } - - /** - * Return the default limit on the number of recents that an app can make. - * @hide - */ - static public int getDefaultAppRecentsLimitStatic() { - return getMaxRecentTasksStatic() / 6; - } - - /** - * Return the maximum limit on the number of recents that an app can make. - * @hide - */ - static public int getMaxAppRecentsLimitStatic() { - return getMaxRecentTasksStatic() / 2; - } - - /** - * Returns true if the system supports at least one form of multi-window. - * E.g. freeform, split-screen, picture-in-picture. - * @hide - */ - @TestApi - static public boolean supportsMultiWindow(Context context) { - // On watches, multi-window is used to present essential system UI, and thus it must be - // supported regardless of device memory characteristics. - boolean isWatch = context.getPackageManager().hasSystemFeature( - PackageManager.FEATURE_WATCH); - return (!isLowRamDeviceStatic() || isWatch) - && Resources.getSystem().getBoolean( - com.android.internal.R.bool.config_supportsMultiWindow); - } - - /** - * Returns true if the system supports split screen multi-window. - * @hide - */ - @TestApi - static public boolean supportsSplitScreenMultiWindow(Context context) { - return supportsMultiWindow(context) - && Resources.getSystem().getBoolean( - com.android.internal.R.bool.config_supportsSplitScreenMultiWindow); + return ActivityTaskManager.getMaxRecentTasksStatic(); } /** @removed */ @@ -1998,102 +1875,6 @@ 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(); - } - } - - /** - * Moves the input task to the primary-split-screen stack. - * @param taskId Id of task to move. - * @param createMode The mode the primary split screen stack should be created in if it doesn't - * exist already. See - * {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT} - * and - * {@link android.app.ActivityManager - * #SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT} - * @param toTop If the task and stack should be moved to the top. - * @param animate Whether we should play an animation for the moving the task - * @param initialBounds If the primary stack gets created, it will use these bounds for the - * docked stack. Pass {@code null} to use default bounds. - * @param showRecents If the recents activity should be shown on the other side of the task - * going into split-screen mode. - * @hide - */ - @TestApi - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) - public void setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, - boolean animate, Rect initialBounds, boolean showRecents) throws SecurityException { - try { - getService().setTaskWindowingModeSplitScreenPrimary(taskId, createMode, toTop, animate, - initialBounds, showRecents); - } 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); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Removes stack of the activity types from the system. - * - * @hide - */ - @TestApi - @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) - public void removeStacksWithActivityTypes(int[] activityTypes) throws SecurityException { - try { - getService().removeStacksWithActivityTypes(activityTypes); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** * Represents a task snapshot. * @hide */ diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java index ecd99a7b5402..89408cc340d9 100644 --- a/core/java/android/app/ActivityOptions.java +++ b/core/java/android/app/ActivityOptions.java @@ -17,7 +17,7 @@ package android.app; import static android.Manifest.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.Display.INVALID_DISPLAY; diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java new file mode 100644 index 000000000000..398644afd17a --- /dev/null +++ b/core/java/android/app/ActivityTaskManager.java @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app; + +import android.annotation.RequiresPermission; +import android.annotation.SystemService; +import android.annotation.TestApi; +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.graphics.Rect; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.util.Singleton; + +/** + * This class gives information about, and interacts with activities and their containers like task, + * stacks, and displays. + * + * @hide + */ +@TestApi +@SystemService(Context.ACTIVITY_TASK_SERVICE) +public class ActivityTaskManager { + + /** Invalid stack ID. */ + public static final int INVALID_STACK_ID = -1; + + /** + * Parameter to {@link IActivityTaskManager#setTaskWindowingModeSplitScreenPrimary} which + * specifies the position of the created docked stack at the top half of the screen if + * in portrait mode or at the left half of the screen if in landscape mode. + */ + public static final int SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT = 0; + + /** + * Parameter to {@link IActivityTaskManager#setTaskWindowingModeSplitScreenPrimary} which + * specifies the position of the created docked stack at the bottom half of the screen if + * in portrait mode or at the right half of the screen if in landscape mode. + */ + public static final int SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT = 1; + + /** + * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates + * that the resize doesn't need to preserve the window, and can be skipped if bounds + * is unchanged. This mode is used by window manager in most cases. + * @hide + */ + public static final int RESIZE_MODE_SYSTEM = 0; + + /** + * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates + * that the resize should preserve the window if possible. + * @hide + */ + public static final int RESIZE_MODE_PRESERVE_WINDOW = (0x1 << 0); + + /** + * Input parameter to {@link IActivityTaskManager#resizeTask} used when the + * resize is due to a drag action. + * @hide + */ + public static final int RESIZE_MODE_USER = RESIZE_MODE_PRESERVE_WINDOW; + + /** + * Input parameter to {@link IActivityTaskManager#resizeTask} used by window + * manager during a screen rotation. + * @hide + */ + public static final int RESIZE_MODE_SYSTEM_SCREEN_ROTATION = RESIZE_MODE_PRESERVE_WINDOW; + + /** + * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates + * that the resize should be performed even if the bounds appears unchanged. + * @hide + */ + public static final int RESIZE_MODE_FORCED = (0x1 << 1); + + /** + * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates + * that the resize should preserve the window if possible, and should not be skipped + * even if the bounds is unchanged. Usually used to force a resizing when a drag action + * is ending. + * @hide + */ + public static final int RESIZE_MODE_USER_FORCED = + RESIZE_MODE_PRESERVE_WINDOW | RESIZE_MODE_FORCED; + + private static int sMaxRecentTasks = -1; + + ActivityTaskManager(Context context, Handler handler) { + } + + /** @hide */ + public static IActivityTaskManager getService() { + return IActivityTaskManagerSingleton.get(); + } + + private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton = + new Singleton<IActivityTaskManager>() { + @Override + protected IActivityTaskManager create() { + final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE); + return IActivityTaskManager.Stub.asInterface(b); + } + }; + + /** + * 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. + */ + @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(); + } + } + + /** + * Moves the input task to the primary-split-screen stack. + * @param taskId Id of task to move. + * @param createMode The mode the primary split screen stack should be created in if it doesn't + * exist already. See + * {@link ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT} + * and + * {@link android.app.ActivityManager + * #SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT} + * @param toTop If the task and stack should be moved to the top. + * @param animate Whether we should play an animation for the moving the task + * @param initialBounds If the primary stack gets created, it will use these bounds for the + * docked stack. Pass {@code null} to use default bounds. + * @param showRecents If the recents activity should be shown on the other side of the task + * going into split-screen mode. + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + public void setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, + boolean animate, Rect initialBounds, boolean showRecents) throws SecurityException { + try { + getService().setTaskWindowingModeSplitScreenPrimary(taskId, createMode, toTop, animate, + initialBounds, showRecents); + } 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. + */ + @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 + */ + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + public void removeStacksInWindowingModes(int[] windowingModes) throws SecurityException { + try { + getService().removeStacksInWindowingModes(windowingModes); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** Removes stack of the activity types from the system. */ + @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) + public void removeStacksWithActivityTypes(int[] activityTypes) throws SecurityException { + try { + getService().removeStacksWithActivityTypes(activityTypes); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Return the maximum number of recents entries that we will maintain and show. + * @hide + */ + public static int getMaxRecentTasksStatic() { + if (sMaxRecentTasks < 0) { + return sMaxRecentTasks = ActivityManager.isLowRamDeviceStatic() ? 36 : 48; + } + return sMaxRecentTasks; + } + + /** + * Return the default limit on the number of recents that an app can make. + * @hide + */ + public static int getDefaultAppRecentsLimitStatic() { + return getMaxRecentTasksStatic() / 6; + } + + /** + * Return the maximum limit on the number of recents that an app can make. + * @hide + */ + public static int getMaxAppRecentsLimitStatic() { + return getMaxRecentTasksStatic() / 2; + } + + /** + * Returns true if the system supports at least one form of multi-window. + * E.g. freeform, split-screen, picture-in-picture. + */ + public static boolean supportsMultiWindow(Context context) { + // On watches, multi-window is used to present essential system UI, and thus it must be + // supported regardless of device memory characteristics. + boolean isWatch = context.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_WATCH); + return (!ActivityManager.isLowRamDeviceStatic() || isWatch) + && Resources.getSystem().getBoolean( + com.android.internal.R.bool.config_supportsMultiWindow); + } + + /** Returns true if the system supports split screen multi-window. */ + public static boolean supportsSplitScreenMultiWindow(Context context) { + return supportsMultiWindow(context) + && Resources.getSystem().getBoolean( + com.android.internal.R.bool.config_supportsSplitScreenMultiWindow); + } +} diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl index 569c2bd37b6a..1dfd0a61cf74 100644 --- a/core/java/android/app/IActivityManager.aidl +++ b/core/java/android/app/IActivityManager.aidl @@ -391,14 +391,6 @@ interface IActivityManager { 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. @@ -525,8 +517,6 @@ interface IActivityManager { void exitFreeformMode(in IBinder token); void reportSizeConfigurations(in IBinder token, in int[] horizontalSizeConfiguration, in int[] verticalSizeConfigurations, in int[] smallestWidthConfigurations); - boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, - boolean animate, in Rect initialBounds, boolean showRecents); /** * Dismisses split-screen multi-window mode. * {@param toTop} If true the current primary split-screen stack will be placed or left on top. @@ -594,13 +584,6 @@ interface IActivityManager { void notifyPinnedStackAnimationStarted(); void notifyPinnedStackAnimationEnded(); void removeStack(int stackId); - /** - * Removes stacks in the input windowing modes from the system if they are of activity type - * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED - */ - void removeStacksInWindowingModes(in int[] windowingModes); - /** Removes stack of the activity types from the system. */ - void removeStacksWithActivityTypes(in int[] activityTypes); void makePackageIdle(String packageName, int userId); int getMemoryTrimLevel(); /** diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl new file mode 100644 index 000000000000..8dfd6ab75b10 --- /dev/null +++ b/core/java/android/app/IActivityTaskManager.aidl @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.app; + +import android.app.ActivityManager; +import android.app.ApplicationErrorReport; +import android.app.ContentProviderHolder; +import android.app.GrantedUriPermission; +import android.app.IApplicationThread; +import android.app.IActivityController; +import android.app.IAppTask; +import android.app.IAssistDataReceiver; +import android.app.IInstrumentationWatcher; +import android.app.IProcessObserver; +import android.app.IServiceConnection; +import android.app.IStopUserCallback; +import android.app.ITaskStackListener; +import android.app.IUiAutomationConnection; +import android.app.IUidObserver; +import android.app.IUserSwitchObserver; +import android.app.Notification; +import android.app.PendingIntent; +import android.app.PictureInPictureParams; +import android.app.ProfilerInfo; +import android.app.WaitResult; +import android.app.assist.AssistContent; +import android.app.assist.AssistStructure; +import android.content.ComponentName; +import android.content.IIntentReceiver; +import android.content.IIntentSender; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.IntentSender; +import android.content.pm.ApplicationInfo; +import android.content.pm.ConfigurationInfo; +import android.content.pm.IPackageDataObserver; +import android.content.pm.ParceledListSlice; +import android.content.pm.ProviderInfo; +import android.content.pm.UserInfo; +import android.content.res.Configuration; +import android.graphics.Bitmap; +import android.graphics.GraphicBuffer; +import android.graphics.Point; +import android.graphics.Rect; +import android.net.Uri; +import android.os.Bundle; +import android.os.Debug; +import android.os.IBinder; +import android.os.IProgressListener; +import android.os.ParcelFileDescriptor; +import android.os.PersistableBundle; +import android.os.StrictMode; +import android.os.WorkSource; +import android.service.voice.IVoiceInteractionSession; +import android.view.IRecentsAnimationRunner; +import android.view.RemoteAnimationDefinition; +import android.view.RemoteAnimationAdapter; +import com.android.internal.app.IVoiceInteractor; +import com.android.internal.os.IResultReceiver; +import com.android.internal.policy.IKeyguardDismissCallback; + +import java.util.List; + +/** + * System private API for talking with the activity task manager that handles how activities are + * managed on screen. + * + * {@hide} + */ +interface IActivityTaskManager { + List<ActivityManager.RunningTaskInfo> getTasks(int maxNum); + List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum, int ignoreActivityType, + int ignoreWindowingMode); + /** + * 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. + * + * @param stackId Id of the stack to resize. + * @param bounds Bounds to resize the stack to or {@code null} for fullscreen. + * @param allowResizeInDockedMode True if the resize should be allowed when the docked stack is + * active. + * @param preserveWindows True if the windows of activities contained in the stack should be + * preserved. + * @param animate True if the stack resize should be animated. + * @param animationDuration The duration of the resize animation in milliseconds or -1 if the + * default animation duration should be used. + * @throws RemoteException + */ + void resizeStack(int stackId, in Rect bounds, boolean allowResizeInDockedMode, + boolean preserveWindows, boolean animate, int animationDuration); + boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, + boolean animate, in Rect initialBounds, boolean showRecents); + + + /** + * Removes stacks in the input windowing modes from the system if they are of activity type + * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED + */ + void removeStacksInWindowingModes(in int[] windowingModes); + /** Removes stack of the activity types from the system. */ + void removeStacksWithActivityTypes(in int[] activityTypes); +} diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index e8ca4ff9e91c..2ad00e0a7fd8 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -215,6 +215,14 @@ final class SystemServiceRegistry { return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler()); }}); + registerService(Context.ACTIVITY_TASK_SERVICE, ActivityTaskManager.class, + new CachedServiceFetcher<ActivityTaskManager>() { + @Override + public ActivityTaskManager createService(ContextImpl ctx) { + return new ActivityTaskManager( + ctx.getOuterContext(), ctx.mMainThread.getHandler()); + }}); + registerService(Context.ALARM_SERVICE, AlarmManager.class, new CachedServiceFetcher<AlarmManager>() { @Override diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 1da77a24621e..c0cfb90e6676 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3328,6 +3328,16 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve a + * {@link android.app.ActivityTaskManager} for interacting with the global system state. + * + * @see #getSystemService(String) + * @see android.app.ActivityTaskManager + * @hide + */ + public static final String ACTIVITY_TASK_SERVICE = "activity_task"; + + /** + * Use with {@link #getSystemService(String)} to retrieve a * {@link android.app.AlarmManager} for receiving intents at a * time of your choosing. * diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index b8eb074d1636..7df5a8ac0666 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -45,7 +45,7 @@ import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.TestApi; -import android.app.ActivityManager; +import android.app.ActivityTaskManager; import android.content.ComponentName; import android.content.Intent; import android.content.IntentFilter; @@ -4233,7 +4233,7 @@ public class PackageParser { ActivityInfo.DOCUMENT_LAUNCH_NONE); a.info.maxRecents = sa.getInt( R.styleable.AndroidManifestActivity_maxRecents, - ActivityManager.getDefaultAppRecentsLimitStatic()); + ActivityTaskManager.getDefaultAppRecentsLimitStatic()); a.info.configChanges = getActivityConfigChanges( sa.getInt(R.styleable.AndroidManifestActivity_configChanges, 0), sa.getInt(R.styleable.AndroidManifestActivity_recreateOnConfigChanges, 0)); diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java index a04a6a3fe0c5..f69e91145dfc 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoadPlan.java @@ -19,6 +19,7 @@ package com.android.systemui.shared.recents.model; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import android.app.ActivityManager; +import android.app.ActivityTaskManager; import android.app.KeyguardManager; import android.content.ComponentName; import android.content.Context; @@ -92,7 +93,7 @@ public class RecentsTaskLoadPlan { ArrayList<Task> allTasks = new ArrayList<>(); if (mRawTasks == null) { mRawTasks = ActivityManagerWrapper.getInstance().getRecentTasks( - ActivityManager.getMaxRecentTasksStatic(), currentUserId); + ActivityTaskManager.getMaxRecentTasksStatic(), currentUserId); // Since the raw tasks are given in most-recent to least-recent order, we need to reverse it Collections.reverse(mRawTasks); diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java index 1309a6065c8a..ab2e277ecfd6 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/RecentsTaskLoader.java @@ -17,6 +17,7 @@ package com.android.systemui.shared.recents.model; import android.app.ActivityManager; +import android.app.ActivityTaskManager; import android.content.ComponentCallbacks2; import android.content.ComponentName; import android.content.Context; @@ -98,7 +99,7 @@ public class RecentsTaskLoader { mSvelteLevel = svelteLevel; // Initialize the proxy, cache and loaders - int numRecentTasks = ActivityManager.getMaxRecentTasksStatic(); + int numRecentTasks = ActivityTaskManager.getMaxRecentTasksStatic(); mHighResThumbnailLoader = new HighResThumbnailLoader(ActivityManagerWrapper.getInstance(), Looper.getMainLooper(), ActivityManager.isLowRamDeviceStatic()); mLoadQueue = new TaskResourceLoadQueue(); @@ -221,14 +222,14 @@ public class RecentsTaskLoader { // We are leaving recents, so trim the data a bit mIconCache.trimToSize(Math.max(1, mMaxIconCacheSize / 2)); mActivityInfoCache.trimToSize(Math.max(1, - ActivityManager.getMaxRecentTasksStatic() / 2)); + ActivityTaskManager.getMaxRecentTasksStatic() / 2)); break; case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW: case ComponentCallbacks2.TRIM_MEMORY_MODERATE: // We are going to be low on memory mIconCache.trimToSize(Math.max(1, mMaxIconCacheSize / 4)); mActivityInfoCache.trimToSize(Math.max(1, - ActivityManager.getMaxRecentTasksStatic() / 4)); + ActivityTaskManager.getMaxRecentTasksStatic() / 4)); break; case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL: case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java index 712cca67c5d6..36fb3a7b4307 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityOptionsCompat.java @@ -16,8 +16,8 @@ package com.android.systemui.shared.system; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import android.app.ActivityOptions; 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 2af7ae27873c..ee15655d87b2 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java @@ -20,7 +20,9 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.INPUT_CONSUMER_PIP; import android.app.ActivityManager; +import android.app.ActivityTaskManager; import android.app.IActivityManager; +import android.app.IActivityTaskManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.ParceledListSlice; @@ -55,6 +57,7 @@ public class PipManager implements BasePipManager { private Context mContext; private IActivityManager mActivityManager; + private IActivityTaskManager mActivityTaskManager; private IWindowManager mWindowManager; private Handler mHandler = new Handler(); @@ -172,6 +175,7 @@ public class PipManager implements BasePipManager { public void initialize(Context context) { mContext = context; mActivityManager = ActivityManager.getService(); + mActivityTaskManager = ActivityTaskManager.getService(); mWindowManager = WindowManagerGlobal.getWindowManagerService(); try { @@ -186,8 +190,8 @@ public class PipManager implements BasePipManager { mMediaController = new PipMediaController(context, mActivityManager); mMenuController = new PipMenuActivityController(context, mActivityManager, mMediaController, mInputConsumerController); - mTouchHandler = new PipTouchHandler(context, mActivityManager, mMenuController, - mInputConsumerController); + mTouchHandler = new PipTouchHandler(context, mActivityManager, mActivityTaskManager, + mMenuController, mInputConsumerController); mAppOpsListener = new PipAppOpsListener(context, mActivityManager, mTouchHandler.getMotionHelper()); EventBus.getDefault().register(this); 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 ad841308cb0d..2ec566247d52 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMotionHelper.java @@ -31,6 +31,7 @@ import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.app.ActivityManager.StackInfo; import android.app.IActivityManager; +import android.app.IActivityTaskManager; import android.content.Context; import android.graphics.Point; import android.graphics.PointF; @@ -81,6 +82,7 @@ public class PipMotionHelper implements Handler.Callback { private Context mContext; private IActivityManager mActivityManager; + private IActivityTaskManager mActivityTaskManager; private Handler mHandler; private PipMenuActivityController mMenuController; @@ -94,11 +96,12 @@ public class PipMotionHelper implements Handler.Callback { private ValueAnimator mBoundsAnimator = null; public PipMotionHelper(Context context, IActivityManager activityManager, - PipMenuActivityController menuController, PipSnapAlgorithm snapAlgorithm, - FlingAnimationUtils flingAnimationUtils) { + IActivityTaskManager activityTaskManager, PipMenuActivityController menuController, + PipSnapAlgorithm snapAlgorithm, FlingAnimationUtils flingAnimationUtils) { mContext = context; mHandler = new Handler(ForegroundThread.get().getLooper(), this); mActivityManager = activityManager; + mActivityTaskManager = activityTaskManager; mMenuController = menuController; mSnapAlgorithm = snapAlgorithm; mFlingAnimationUtils = flingAnimationUtils; @@ -177,7 +180,8 @@ public class PipMotionHelper implements Handler.Callback { mMenuController.hideMenuWithoutResize(); mHandler.post(() -> { try { - mActivityManager.removeStacksInWindowingModes(new int[]{ WINDOWING_MODE_PINNED }); + mActivityTaskManager.removeStacksInWindowingModes( + new int[]{ WINDOWING_MODE_PINNED }); } catch (RemoteException e) { Log.e(TAG, "Failed to remove PiP", e); } @@ -533,7 +537,7 @@ public class PipMotionHelper implements Handler.Callback { return true; } - mActivityManager.resizeStack(stackInfo.stackId, toBounds, + mActivityTaskManager.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/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index 02345c9ffdb8..3742194738b0 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -25,6 +25,7 @@ import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; import android.app.IActivityManager; +import android.app.IActivityTaskManager; import android.content.ComponentName; import android.content.Context; import android.content.res.Resources; @@ -69,6 +70,7 @@ public class PipTouchHandler { private final boolean mEnableDimissDragToEdge; private final Context mContext; private final IActivityManager mActivityManager; + private final IActivityTaskManager mActivityTaskManager; private final ViewConfiguration mViewConfig; private final PipMenuListener mMenuListener = new PipMenuListener(); private IPinnedStackController mPinnedStackController; @@ -172,12 +174,13 @@ public class PipTouchHandler { } public PipTouchHandler(Context context, IActivityManager activityManager, - PipMenuActivityController menuController, + IActivityTaskManager activityTaskManager, PipMenuActivityController menuController, InputConsumerController inputConsumerController) { // Initialize the Pip input consumer mContext = context; mActivityManager = activityManager; + mActivityTaskManager = activityTaskManager; mAccessibilityManager = context.getSystemService(AccessibilityManager.class); mViewConfig = ViewConfiguration.get(context); mMenuController = menuController; @@ -188,8 +191,8 @@ public class PipTouchHandler { mGestures = new PipTouchGesture[] { mDefaultMovementGesture }; - mMotionHelper = new PipMotionHelper(mContext, mActivityManager, mMenuController, - mSnapAlgorithm, mFlingAnimationUtils); + mMotionHelper = new PipMotionHelper(mContext, mActivityManager, mActivityTaskManager, + mMenuController, mSnapAlgorithm, mFlingAnimationUtils); mTouchState = new PipTouchState(mViewConfig, mHandler, () -> mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(), mMovementBounds, true /* allowMenuTimeout */, willResizeMenu())); 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 d6f67604a050..1dcdc5fe8275 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java @@ -19,7 +19,9 @@ package com.android.systemui.pip.tv; import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.StackInfo; +import android.app.ActivityTaskManager; import android.app.IActivityManager; +import android.app.IActivityTaskManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -53,7 +55,7 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; -import static android.app.ActivityManager.StackId.INVALID_STACK_ID; +import static android.app.ActivityTaskManager.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; @@ -108,6 +110,7 @@ public class PipManager implements BasePipManager { private Context mContext; private IActivityManager mActivityManager; + private IActivityTaskManager mActivityTaskManager; private IWindowManager mWindowManager; private MediaSessionManager mMediaSessionManager; private int mState = STATE_NO_PIP; @@ -238,6 +241,7 @@ public class PipManager implements BasePipManager { mContext = context; mActivityManager = ActivityManager.getService(); + mActivityTaskManager = ActivityTaskManager.getService(); mWindowManager = WindowManagerGlobal.getWindowManagerService(); ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener); IntentFilter intentFilter = new IntentFilter(); @@ -433,7 +437,7 @@ public class PipManager implements BasePipManager { } try { int animationDurationMs = -1; - mActivityManager.resizeStack(mPinnedStackId, mCurrentPipBounds, + mActivityTaskManager.resizeStack(mPinnedStackId, mCurrentPipBounds, true, true, true, animationDurationMs); } catch (RemoteException e) { Log.e(TAG, "resizeStack failed", e); 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 544d95c7b62f..7321507cefc9 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -28,8 +28,10 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import android.app.ActivityManager; import android.app.ActivityManager.StackInfo; import android.app.ActivityOptions; +import android.app.ActivityTaskManager; import android.app.AppGlobals; import android.app.IActivityManager; +import android.app.IActivityTaskManager; import android.app.WindowConfiguration; import android.content.ComponentName; import android.content.ContentResolver; @@ -94,6 +96,7 @@ public class SystemServicesProxy { AccessibilityManager mAccm; ActivityManager mAm; IActivityManager mIam; + IActivityTaskManager mIatm; PackageManager mPm; IPackageManager mIpm; private final IDreamManager mDreamManager; @@ -133,6 +136,7 @@ public class SystemServicesProxy { mAccm = AccessibilityManager.getInstance(context); mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); mIam = ActivityManager.getService(); + mIatm = ActivityTaskManager.getService(); mPm = context.getPackageManager(); mIpm = AppGlobals.getPackageManager(); mAssistUtils = new AssistUtils(context); @@ -261,13 +265,13 @@ public class SystemServicesProxy { /** Moves an already resumed task to the side of the screen to initiate split screen. */ public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, Rect initialBounds) { - if (mIam == null) { + if (mIatm == null) { return false; } try { - return mIam.setTaskWindowingModeSplitScreenPrimary(taskId, createMode, true /* onTop */, - false /* animate */, initialBounds, true /* showRecents */); + return mIatm.setTaskWindowingModeSplitScreenPrimary(taskId, createMode, + true /* onTop */, false /* animate */, initialBounds, true /* showRecents */); } catch (RemoteException e) { e.printStackTrace(); } @@ -324,10 +328,10 @@ public class SystemServicesProxy { /** Set the task's windowing mode. */ public void setTaskWindowingMode(int taskId, int windowingMode) { - if (mIam == null) return; + if (mIatm == null) return; try { - mIam.setTaskWindowingMode(taskId, windowingMode, false /* onTop */); + mIatm.setTaskWindowingMode(taskId, windowingMode, false /* onTop */); } catch (RemoteException | IllegalArgumentException e) { e.printStackTrace(); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/DockState.java b/packages/SystemUI/src/com/android/systemui/recents/views/DockState.java index 65b96fbb52f9..a246141c74f8 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/DockState.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/DockState.java @@ -16,8 +16,8 @@ package com.android.systemui.recents.views; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.view.WindowManager.DOCKED_BOTTOM; import static android.view.WindowManager.DOCKED_INVALID; import static android.view.WindowManager.DOCKED_LEFT; diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index 0f64ea33176e..5c925fda640e 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -16,7 +16,7 @@ package com.android.systemui.recents.views; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_RECENT_APPS; diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java index 5c69ae3915b3..53a91e536c8a 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java @@ -17,6 +17,7 @@ package com.android.systemui.recents.views; import android.app.ActivityManager; +import android.app.ActivityTaskManager; import android.graphics.Point; import android.graphics.Rect; import android.view.InputDevice; @@ -137,7 +138,7 @@ public class RecentsViewTouchHandler { } mVisibleDockStates.clear(); - if (ActivityManager.supportsMultiWindow(mRv.getContext()) && !ssp.hasDockedTask() + if (ActivityTaskManager.supportsMultiWindow(mRv.getContext()) && !ssp.hasDockedTask() && mDividerSnapAlgorithm.isSplitScreenFeasible()) { Recents.logDockAttempt(mRv.getContext(), event.task.getTopComponent(), event.task.resizeMode); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java index 0fc507b92bf3..f217596bd4a9 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewAccessibilityDelegate.java @@ -17,6 +17,7 @@ package com.android.systemui.recents.views; import android.app.ActivityManager; +import android.app.ActivityTaskManager; import android.content.Context; import android.graphics.Point; import android.os.Bundle; @@ -58,7 +59,7 @@ public class TaskViewAccessibilityDelegate extends View.AccessibilityDelegate { @Override public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(host, info); - if (ActivityManager.supportsSplitScreenMultiWindow(mTaskView.getContext()) + if (ActivityTaskManager.supportsSplitScreenMultiWindow(mTaskView.getContext()) && !Recents.getSystemServices().hasDockedTask()) { DockState[] dockStates = Recents.getConfiguration() .getDockStatesForCurrentOrientation(); diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java index da798848f7e8..750002cbc5ca 100644 --- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java @@ -16,8 +16,8 @@ package com.android.systemui.shortcut; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.os.UserHandle.USER_CURRENT; import static com.android.systemui.statusbar.phone.NavigationBarGestureHelper.DRAG_MODE_NONE; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java index f9a540c7b0ca..faf9d525385d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java @@ -35,6 +35,7 @@ import android.annotation.IdRes; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerNative; +import android.app.ActivityTaskManager; import android.app.Fragment; import android.app.IActivityManager; import android.app.StatusBarManager; @@ -933,7 +934,7 @@ public class NavigationBarFragment extends Fragment implements Callbacks { } private boolean onLongPressRecents() { - if (mRecents == null || !ActivityManager.supportsMultiWindow(getContext()) + if (mRecents == null || !ActivityTaskManager.supportsMultiWindow(getContext()) || !mDivider.getView().getSnapAlgorithm().isSplitScreenFeasible() || Recents.getConfiguration().isLowRamDevice // If we are connected to the overview service, then disable the recents button diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java index 18e8775de21f..dce7537be61e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarGestureHelper.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.phone; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.view.WindowManager.DOCKED_INVALID; import static android.view.WindowManager.DOCKED_LEFT; import static android.view.WindowManager.DOCKED_TOP; @@ -216,7 +218,7 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture && mDivider.getView().getWindowManagerProxy().getDockSide() == DOCKED_INVALID) { Rect initialBounds = null; int dragMode = calculateDragMode(); - int createMode = ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; + int createMode = SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; if (dragMode == DRAG_MODE_DIVIDER) { initialBounds = new Rect(); mDivider.getView().calculateBoundsForPosition(mIsVertical @@ -228,7 +230,7 @@ public class NavigationBarGestureHelper implements TunerService.Tunable, Gesture initialBounds); } else if (dragMode == DRAG_MODE_RECENTS && mTouchDownX < mContext.getResources().getDisplayMetrics().widthPixels / 2) { - createMode = ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT; + createMode = SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT; } boolean docked = mRecentsComponent.splitPrimaryTask(dragMode, createMode, initialBounds, MetricsEvent.ACTION_WINDOW_DOCK_SWIPE); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index c70f03405db3..3a96aa22c7ff 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.phone; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN; import static android.app.StatusBarManager.WINDOW_STATE_SHOWING; import static android.app.StatusBarManager.windowStateToString; @@ -1352,8 +1354,8 @@ public class StatusBar extends SystemUI implements DemoMode, return false; } int createMode = navbarPos == NAV_BAR_POS_LEFT - ? ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT - : ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; + ? SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT + : SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; return mRecents.splitPrimaryTask(NavigationBarGestureHelper.DRAG_MODE_NONE, createMode, null, metricsDockAction); } else { diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/RecentsTest.java b/packages/SystemUI/tests/src/com/android/systemui/recents/RecentsTest.java index bdbd24418d3f..2160f9a2ac0f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/recents/RecentsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/recents/RecentsTest.java @@ -23,9 +23,9 @@ import static com.android.systemui.recents.RecentsImpl.RECENTS_PACKAGE; import static org.junit.Assert.fail; -import android.app.ActivityManager; import android.app.ActivityManager.RunningTaskInfo; -import android.app.IActivityManager; +import android.app.ActivityTaskManager; +import android.app.IActivityTaskManager; import android.os.SystemClock; import android.support.test.filters.MediumTest; import android.support.test.runner.AndroidJUnit4; @@ -44,8 +44,8 @@ public class RecentsTest extends SysuiTestCase { @Test public void testRecentsActivityType() throws Exception { // Clear the state - final IActivityManager am = ActivityManager.getService(); - am.removeStacksWithActivityTypes(new int[] { ACTIVITY_TYPE_RECENTS }); + final IActivityTaskManager atm = ActivityTaskManager.getService(); + atm.removeStacksWithActivityTypes(new int[] { ACTIVITY_TYPE_RECENTS }); // Toggle recents, use a shell command because it is not exported runShellCommand("am start -n " + RECENTS_PACKAGE + "/" + RECENTS_ACTIVITY); @@ -53,7 +53,7 @@ public class RecentsTest extends SysuiTestCase { // Verify that an activity was launched with the right activity type int retryCount = 0; while (retryCount < 10) { - List<RunningTaskInfo> tasks = am.getTasks(Integer.MAX_VALUE); + List<RunningTaskInfo> tasks = atm.getTasks(Integer.MAX_VALUE); for (RunningTaskInfo info : tasks) { if (info.configuration.windowConfiguration.getActivityType() == ACTIVITY_TYPE_RECENTS) { @@ -66,4 +66,4 @@ public class RecentsTest extends SysuiTestCase { } fail("Expected Recents activity with ACTIVITY_TYPE_RECENTS"); } -}
\ No newline at end of file +} diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 10639736847f..0fe16f807a8c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -29,9 +29,8 @@ import static android.Manifest.permission.REMOVE_TASKS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.Manifest.permission.STOP_APP_SWITCHES; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; -import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; -import static android.app.ActivityManager.StackId.INVALID_STACK_ID; +import static android.app.ActivityTaskManager.RESIZE_MODE_PRESERVE_WINDOW; +import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.ActivityManagerInternal.ASSIST_KEY_CONTENT; import static android.app.ActivityManagerInternal.ASSIST_KEY_DATA; import static android.app.ActivityManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS; @@ -44,7 +43,6 @@ 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.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; @@ -227,6 +225,7 @@ import android.app.ActivityManagerInternal.ScreenObserver; import android.app.ActivityManagerInternal.SleepToken; import android.app.ActivityManagerProto; import android.app.ActivityOptions; +import android.app.ActivityTaskManager; import android.app.ActivityThread; import android.app.AlertDialog; import android.app.AppGlobals; @@ -1859,6 +1858,7 @@ public class ActivityManagerService extends IActivityManager.Stub int mBootPhase; WindowManagerService mWindowManager; + ActivityTaskManagerService mActivityTaskManager; final ActivityThread mSystemThread; private final class AppDeathRecipient implements IBinder.DeathRecipient { @@ -2776,6 +2776,14 @@ public class ActivityManagerService extends IActivityManager.Stub } } + public void setActivityTaskManager(ActivityTaskManagerService atm) { + synchronized (this) { + mActivityTaskManager = atm; + mStackSupervisor.setActivityTaskManager(atm); + mActivityTaskManager.setActivityManagerService(this); + } + } + public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { mUsageStatsService = usageStatsManager; } @@ -3679,7 +3687,8 @@ public class ActivityManagerService extends IActivityManager.Stub + " to main stack for VR"); final ActivityStack stack = mStackSupervisor.getDefaultDisplay().getOrCreateStack( WINDOWING_MODE_FULLSCREEN, r.getActivityType(), true /* toTop */); - moveTaskToStack(r.getTask().taskId, stack.mStackId, true /* toTop */); + mActivityTaskManager.moveTaskToStack(r.getTask().taskId, stack.mStackId, + true /* toTop */); } mHandler.sendMessage( mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r)); @@ -10531,28 +10540,17 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public List<RunningTaskInfo> getTasks(int maxNum) { - return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED); + return mActivityTaskManager.getTasks(maxNum); } @Override public List<RunningTaskInfo> getFilteredTasks(int maxNum, @ActivityType int ignoreActivityType, @WindowingMode int ignoreWindowingMode) { - final int callingUid = Binder.getCallingUid(); - ArrayList<RunningTaskInfo> list = new ArrayList<>(); - - synchronized(this) { - if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum); - - final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(), - callingUid); - mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType, - ignoreWindowingMode, callingUid, allowed); - } - - return list; + return mActivityTaskManager.getFilteredTasks( + maxNum, ignoreActivityType, ignoreWindowingMode); } - private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { + boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) { if (mRecentTasks.isCallerRecents(callingUid)) { // Always allow the recents component to get tasks return true; @@ -10892,38 +10890,6 @@ public class ActivityManagerService extends IActivityManager.Stub } } - /** - * Removes stacks in the input windowing modes from the system if they are of activity type - * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED - */ - @Override - public void removeStacksInWindowingModes(int[] windowingModes) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, - "removeStacksInWindowingModes()"); - synchronized (this) { - final long ident = Binder.clearCallingIdentity(); - try { - mStackSupervisor.removeStacksInWindowingModes(windowingModes); - } finally { - Binder.restoreCallingIdentity(ident); - } - } - } - - @Override - public void removeStacksWithActivityTypes(int[] activityTypes) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, - "removeStacksWithActivityTypes()"); - synchronized (this) { - final long ident = Binder.clearCallingIdentity(); - try { - mStackSupervisor.removeStacksWithActivityTypes(activityTypes); - } finally { - Binder.restoreCallingIdentity(ident); - } - } - } - @Override public void moveStackToDisplay(int stackId, int displayId) { enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()"); @@ -11117,128 +11083,8 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override - public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) { - if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { - setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, - toTop, ANIMATE, null /* initialBounds */, true /* showRecents */); - return; - } - enforceCallerIsRecentsOrHasPermission(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 (!task.isActivityTypeStandardOrUndefined()) { - throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move" - + " non-standard task " + taskId + " to windowing mode=" - + windowingMode); - } - - final ActivityStack stack = task.getStack(); - if (toTop) { - stack.moveToFront("setTaskWindowingMode", task); - } - stack.setWindowingMode(windowingMode); - } finally { - Binder.restoreCallingIdentity(ident); - } - } - } - - /** - * Moves the specified task to the primary-split-screen stack. - * - * @param taskId Id of task to move. - * @param createMode The mode the primary split screen stack should be created in if it doesn't - * exist already. See - * {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT} - * and - * {@link android.app.ActivityManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT} - * @param toTop If the task and stack should be moved to the top. - * @param animate Whether we should play an animation for the moving the task. - * @param initialBounds If the primary stack gets created, it will use these bounds for the - * stack. Pass {@code null} to use default bounds. - * @param showRecents If the recents activity should be shown on the other side of the task - * going into split-screen mode. - */ - @Override - public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, - boolean animate, Rect initialBounds, boolean showRecents) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, - "setTaskWindowingModeSplitScreenPrimary()"); - synchronized (this) { - long ident = Binder.clearCallingIdentity(); - try { - final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); - if (task == null) { - Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId); - return false; - } - if (DEBUG_STACK) Slog.d(TAG_STACK, - "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId - + " to createMode=" + createMode + " toTop=" + toTop); - if (!task.isActivityTypeStandardOrUndefined()) { - throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move" - + " non-standard task " + taskId + " to split-screen windowing mode"); - } - - mWindowManager.setDockedStackCreateState(createMode, initialBounds); - final int windowingMode = task.getWindowingMode(); - final ActivityStack stack = task.getStack(); - if (toTop) { - stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task); - } - stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents, - false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */); - return windowingMode != task.getWindowingMode(); - } finally { - Binder.restoreCallingIdentity(ident); - } - } - } - - @Override public void moveTaskToStack(int taskId, int stackId, boolean toTop) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()"); - synchronized (this) { - long ident = Binder.clearCallingIdentity(); - try { - final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); - if (task == null) { - Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId); - return; - } - - if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId - + " to stackId=" + stackId + " toTop=" + toTop); - - final ActivityStack stack = mStackSupervisor.getStack(stackId); - if (stack == null) { - throw new IllegalStateException( - "moveTaskToStack: No stack for stackId=" + stackId); - } - if (!stack.isActivityTypeStandardOrUndefined()) { - throw new IllegalArgumentException("moveTaskToStack: Attempt to move task " - + taskId + " to stack " + stackId); - } - if (stack.inSplitScreenPrimaryWindowingMode()) { - mWindowManager.setDockedStackCreateState( - SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */); - } - task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, - "moveTaskToStack"); - } finally { - Binder.restoreCallingIdentity(ident); - } - } + mActivityTaskManager.moveTaskToStack(taskId, stackId, toTop); } /** @@ -11345,36 +11191,8 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode, boolean preserveWindows, boolean animate, int animationDuration) { - enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()"); - long ident = Binder.clearCallingIdentity(); - try { - synchronized (this) { - if (animate) { - final PinnedActivityStack stack = mStackSupervisor.getStack(stackId); - if (stack == null) { - Slog.w(TAG, "resizeStack: stackId " + stackId + " not found."); - return; - } - if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) { - throw new IllegalArgumentException("Stack: " + stackId - + " doesn't support animated resize."); - } - stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds, - animationDuration, false /* fromFullscreen */); - } else { - final ActivityStack stack = mStackSupervisor.getStack(stackId); - if (stack == null) { - Slog.w(TAG, "resizeStack: stackId " + stackId + " not found."); - return; - } - mStackSupervisor.resizeStackLocked(stack, destBounds, null /* tempTaskBounds */, - null /* tempTaskInsetBounds */, preserveWindows, - allowResizeInDockedMode, !DEFER_RESUME); - } - } - } finally { - Binder.restoreCallingIdentity(ident); - } + mActivityTaskManager.resizeStack(stackId, destBounds, allowResizeInDockedMode, + preserveWindows, animate, animationDuration); } @Override @@ -14922,11 +14740,11 @@ public class ActivityManagerService extends IActivityManager.Stub || Settings.Global.getInt( resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0; - final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow(mContext); + final boolean supportsMultiWindow = ActivityTaskManager.supportsMultiWindow(mContext); final boolean supportsPictureInPicture = supportsMultiWindow && mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE); final boolean supportsSplitScreenMultiWindow = - ActivityManager.supportsSplitScreenMultiWindow(mContext); + ActivityTaskManager.supportsSplitScreenMultiWindow(mContext); final boolean supportsMultiDisplay = mContext.getPackageManager() .hasSystemFeature(FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS); final String debugApp = Settings.Global.getString(resolver, DEBUG_APP); diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index dc9a5adb5a0c..b3e4d602628f 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -18,9 +18,11 @@ package com.android.server.am; import android.app.ActivityManager; import android.app.ActivityOptions; +import android.app.ActivityTaskManager; import android.app.AppGlobals; import android.app.IActivityController; import android.app.IActivityManager; +import android.app.IActivityTaskManager; import android.app.IStopUserCallback; import android.app.IUidObserver; import android.app.KeyguardManager; @@ -96,9 +98,9 @@ import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.egl.EGLSurface; -import static android.app.ActivityManager.RESIZE_MODE_SYSTEM; -import static android.app.ActivityManager.RESIZE_MODE_USER; -import static android.app.ActivityManager.StackId.INVALID_STACK_ID; +import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM; +import static android.app.ActivityTaskManager.RESIZE_MODE_USER; +import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.Display.INVALID_DISPLAY; @@ -111,6 +113,7 @@ final class ActivityManagerShellCommand extends ShellCommand { // IPC interface to activity manager -- don't need to do additional security checks. final IActivityManager mInterface; + final IActivityTaskManager mTaskInterface; // Internal service impl -- must perform security checks before touching. final ActivityManagerService mInternal; @@ -143,6 +146,7 @@ final class ActivityManagerShellCommand extends ShellCommand { ActivityManagerShellCommand(ActivityManagerService service, boolean dumping) { mInterface = service; + mTaskInterface = service.mActivityTaskManager; mInternal = service; mPm = AppGlobals.getPackageManager(); mDumping = dumping; @@ -2465,7 +2469,7 @@ final class ActivityManagerShellCommand extends ShellCommand { return -1; } - mInterface.moveTaskToStack(taskId, stackId, toTop); + mTaskInterface.moveTaskToStack(taskId, stackId, toTop); return 0; } @@ -2499,7 +2503,7 @@ final class ActivityManagerShellCommand extends ShellCommand { int resizeStackUnchecked(int stackId, Rect bounds, int delayMs, boolean animate) throws RemoteException { try { - mInterface.resizeStack(stackId, bounds, false, false, animate, -1); + mTaskInterface.resizeStack(stackId, bounds, false, false, animate, -1); Thread.sleep(delayMs); } catch (InterruptedException e) { } @@ -2752,7 +2756,7 @@ final class ActivityManagerShellCommand extends ShellCommand { if (res == null) { return -1; } - pw.println(ActivityManager.supportsMultiWindow(mInternal.mContext)); + pw.println(ActivityTaskManager.supportsMultiWindow(mInternal.mContext)); return 0; } @@ -2761,7 +2765,7 @@ final class ActivityManagerShellCommand extends ShellCommand { if (res == null) { return -1; } - pw.println(ActivityManager.supportsSplitScreenMultiWindow(mInternal.mContext)); + pw.println(ActivityTaskManager.supportsSplitScreenMultiWindow(mInternal.mContext)); return 0; } diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 75f27231c976..696a184bbaab 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -17,7 +17,7 @@ package com.android.server.am; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; -import static android.app.ActivityManager.StackId.INVALID_STACK_ID; +import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.ActivityManager.TaskDescription.ATTR_TASKDESCRIPTION_PREFIX; import static android.app.ActivityOptions.ANIM_CLIP_REVEAL; import static android.app.ActivityOptions.ANIM_CUSTOM; diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index cc7a2308834e..2596b7a37fa6 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -4758,8 +4758,9 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai // TODO: Figure-out a way to consolidate with resize() method below. @Override public void requestResize(Rect bounds) { - mService.resizeStack(mStackId, bounds, true /* allowResizeInDockedMode */, - false /* preserveWindows */, false /* animate */, -1 /* animationDuration */); + mService.mActivityTaskManager.resizeStack(mStackId, bounds, + true /* allowResizeInDockedMode */, false /* preserveWindows */, + false /* animate */, -1 /* animationDuration */); } // TODO: Can only be called from special methods in ActivityStackSupervisor. diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index e034b824dc50..7a6f5707019a 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -24,7 +24,7 @@ import static android.Manifest.permission.START_TASKS_FROM_RECENTS; import static android.app.ActivityManager.LOCK_TASK_MODE_LOCKED; import static android.app.ActivityManager.START_DELIVERED_TO_TOP; import static android.app.ActivityManager.START_TASK_TO_FRONT; -import static android.app.ActivityManager.StackId.INVALID_STACK_ID; +import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SECONDARY_DISPLAY; import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN; import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; @@ -305,7 +305,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D /** The number of distinct task ids that can be assigned to the tasks of a single user */ private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE; - final ActivityManagerService mService; + ActivityManagerService mService; /** The historial list of recent tasks including inactive tasks */ RecentTasks mRecentTasks; @@ -319,6 +319,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D /** Short cut */ WindowManagerService mWindowManager; DisplayManager mDisplayManager; + ActivityTaskManagerService mAtm; private LaunchParamsController mLaunchParamsController; @@ -610,6 +611,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D mHandler = new ActivityStackSupervisorHandler(looper); } + @VisibleForTesting + void setService(ActivityManagerService service) { + mService = service; + } + public void initialize() { if (mInitialized) { return; @@ -660,27 +666,29 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D mLaunchingActivity.setReferenceCounted(false); } - void setWindowManager(WindowManagerService wm) { - synchronized (mService) { - mWindowManager = wm; - getKeyguardController().setWindowManager(wm); + void setActivityTaskManager(ActivityTaskManagerService atm) { + mAtm = atm; + } - mDisplayManager = - (DisplayManager)mService.mContext.getSystemService(Context.DISPLAY_SERVICE); - mDisplayManager.registerDisplayListener(this, null); - mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); + void setWindowManager(WindowManagerService wm) { + mWindowManager = wm; + getKeyguardController().setWindowManager(wm); - Display[] displays = mDisplayManager.getDisplays(); - for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) { - final Display display = displays[displayNdx]; - ActivityDisplay activityDisplay = new ActivityDisplay(this, display); - mActivityDisplays.put(display.getDisplayId(), activityDisplay); - calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); - } + mDisplayManager = + (DisplayManager) mService.mContext.getSystemService(Context.DISPLAY_SERVICE); + mDisplayManager.registerDisplayListener(this, null); + mDisplayManagerInternal = LocalServices.getService(DisplayManagerInternal.class); - mHomeStack = mFocusedStack = mLastFocusedStack = getDefaultDisplay().getOrCreateStack( - WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP); + Display[] displays = mDisplayManager.getDisplays(); + for (int displayNdx = displays.length - 1; displayNdx >= 0; --displayNdx) { + final Display display = displays[displayNdx]; + ActivityDisplay activityDisplay = new ActivityDisplay(this, display); + mActivityDisplays.put(display.getDisplayId(), activityDisplay); + calculateDefaultMinimalSizeOfResizeableTasks(activityDisplay); } + + mHomeStack = mFocusedStack = mLastFocusedStack = getDefaultDisplay().getOrCreateStack( + WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, ON_TOP); } ActivityStack getFocusedStack() { @@ -4496,7 +4504,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D } // The task might have landed on a display different from requested. // TODO(multi-display): Find proper stack for the task on the default display. - mService.setTaskWindowingMode(task.taskId, + mAtm.setTaskWindowingMode(task.taskId, WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY, true /* toTop */); if (preferredDisplayId != actualDisplayId) { // Display a warning toast that we tried to put a non-resizeable task on a secondary diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 73e3d33073fc..3297560612ec 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -2251,7 +2251,8 @@ class ActivityStarter { final ActivityStack stack = task.getStack(); if (stack != null && stack.resizeStackWithLaunchBounds()) { - mService.resizeStack(stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1); + mService.mActivityTaskManager.resizeStack( + stack.mStackId, bounds, true, !PRESERVE_WINDOWS, ANIMATE, -1); } else { task.updateOverrideConfiguration(bounds); } diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java new file mode 100644 index 000000000000..d7caa1a7b795 --- /dev/null +++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.server.am; + +import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; +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_UNDEFINED; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; +import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK; +import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK; +import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; +import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; +import static com.android.server.am.ActivityManagerService.ANIMATE; +import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME; +import static com.android.server.am.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT; + +import android.app.ActivityManager; +import android.app.IActivityTaskManager; +import android.app.WindowConfiguration; +import android.content.Context; +import android.graphics.Rect; +import android.os.Binder; +import android.util.Slog; + +import com.android.server.SystemService; + +import java.util.ArrayList; +import java.util.List; + +/** + * System service for managing activities and their containers (task, stacks, displays,... ). + * + * {@hide} + */ +public class ActivityTaskManagerService extends IActivityTaskManager.Stub { + private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityTaskManagerService" : TAG_AM; + private static final String TAG_STACK = TAG + POSTFIX_STACK; + + private Context mContext; + private ActivityManagerService mAm; + /* Global service lock used by the package the owns this service. */ + Object mGlobalLock; + private ActivityStackSupervisor mStackSupervisor; + + ActivityTaskManagerService(Context context) { + mContext = context; + } + + // TODO: Will be converted to WM lock once transition is complete. + void setActivityManagerService(ActivityManagerService am) { + mAm = am; + mGlobalLock = mAm; + mStackSupervisor = mAm.mStackSupervisor; + } + + public static final class Lifecycle extends SystemService { + private final ActivityTaskManagerService mService; + + public Lifecycle(Context context) { + super(context); + mService = new ActivityTaskManagerService(context); + } + + @Override + public void onStart() { + publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService); + } + + public ActivityTaskManagerService getService() { + return mService; + } + } + + @Override + public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) { + if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) { + setTaskWindowingModeSplitScreenPrimary(taskId, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, + toTop, ANIMATE, null /* initialBounds */, true /* showRecents */); + return; + } + mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "setTaskWindowingMode()"); + synchronized (mGlobalLock) { + 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 (!task.isActivityTypeStandardOrUndefined()) { + throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move" + + " non-standard task " + taskId + " to windowing mode=" + + windowingMode); + } + + final ActivityStack stack = task.getStack(); + if (toTop) { + stack.moveToFront("setTaskWindowingMode", task); + } + stack.setWindowingMode(windowingMode); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + } + + @Override + public List<ActivityManager.RunningTaskInfo> getTasks(int maxNum) { + return getFilteredTasks(maxNum, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED); + } + + @Override + public List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum, + @WindowConfiguration.ActivityType int ignoreActivityType, + @WindowConfiguration.WindowingMode int ignoreWindowingMode) { + final int callingUid = Binder.getCallingUid(); + ArrayList<ActivityManager.RunningTaskInfo> list = new ArrayList<>(); + + synchronized (mGlobalLock) { + if (DEBUG_ALL) Slog.v(TAG, "getTasks: max=" + maxNum); + + final boolean allowed = mAm.isGetTasksAllowed("getTasks", Binder.getCallingPid(), + callingUid); + mStackSupervisor.getRunningTasks(maxNum, list, ignoreActivityType, + ignoreWindowingMode, callingUid, allowed); + } + + return list; + } + + @Override + public void moveTaskToStack(int taskId, int stackId, boolean toTop) { + mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()"); + synchronized (mGlobalLock) { + final long ident = Binder.clearCallingIdentity(); + try { + final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); + if (task == null) { + Slog.w(TAG, "moveTaskToStack: No task for id=" + taskId); + return; + } + + if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId + + " to stackId=" + stackId + " toTop=" + toTop); + + final ActivityStack stack = mStackSupervisor.getStack(stackId); + if (stack == null) { + throw new IllegalStateException( + "moveTaskToStack: No stack for stackId=" + stackId); + } + if (!stack.isActivityTypeStandardOrUndefined()) { + throw new IllegalArgumentException("moveTaskToStack: Attempt to move task " + + taskId + " to stack " + stackId); + } + if (stack.inSplitScreenPrimaryWindowingMode()) { + mAm.mWindowManager.setDockedStackCreateState( + SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, null /* initialBounds */); + } + task.reparent(stack, toTop, REPARENT_KEEP_STACK_AT_FRONT, ANIMATE, !DEFER_RESUME, + "moveTaskToStack"); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + } + + @Override + public void resizeStack(int stackId, Rect destBounds, boolean allowResizeInDockedMode, + boolean preserveWindows, boolean animate, int animationDuration) { + mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()"); + + final long ident = Binder.clearCallingIdentity(); + try { + synchronized (mGlobalLock) { + if (animate) { + final PinnedActivityStack stack = mStackSupervisor.getStack(stackId); + if (stack == null) { + Slog.w(TAG, "resizeStack: stackId " + stackId + " not found."); + return; + } + if (stack.getWindowingMode() != WINDOWING_MODE_PINNED) { + throw new IllegalArgumentException("Stack: " + stackId + + " doesn't support animated resize."); + } + stack.animateResizePinnedStack(null /* sourceHintBounds */, destBounds, + animationDuration, false /* fromFullscreen */); + } else { + final ActivityStack stack = mStackSupervisor.getStack(stackId); + if (stack == null) { + Slog.w(TAG, "resizeStack: stackId " + stackId + " not found."); + return; + } + mStackSupervisor.resizeStackLocked(stack, destBounds, + null /* tempTaskBounds */, null /* tempTaskInsetBounds */, + preserveWindows, allowResizeInDockedMode, !DEFER_RESUME); + } + } + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + /** + * Moves the specified task to the primary-split-screen stack. + * + * @param taskId Id of task to move. + * @param createMode The mode the primary split screen stack should be created in if it doesn't + * exist already. See + * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT} + * and + * {@link android.app.ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT} + * @param toTop If the task and stack should be moved to the top. + * @param animate Whether we should play an animation for the moving the task. + * @param initialBounds If the primary stack gets created, it will use these bounds for the + * stack. Pass {@code null} to use default bounds. + * @param showRecents If the recents activity should be shown on the other side of the task + * going into split-screen mode. + */ + @Override + public boolean setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, + boolean toTop, boolean animate, Rect initialBounds, boolean showRecents) { + mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + "setTaskWindowingModeSplitScreenPrimary()"); + synchronized (mGlobalLock) { + final long ident = Binder.clearCallingIdentity(); + try { + final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); + if (task == null) { + Slog.w(TAG, "setTaskWindowingModeSplitScreenPrimary: No task for id=" + taskId); + return false; + } + if (DEBUG_STACK) Slog.d(TAG_STACK, + "setTaskWindowingModeSplitScreenPrimary: moving task=" + taskId + + " to createMode=" + createMode + " toTop=" + toTop); + if (!task.isActivityTypeStandardOrUndefined()) { + throw new IllegalArgumentException("setTaskWindowingMode: Attempt to move" + + " non-standard task " + taskId + " to split-screen windowing mode"); + } + + mAm.mWindowManager.setDockedStackCreateState(createMode, initialBounds); + final int windowingMode = task.getWindowingMode(); + final ActivityStack stack = task.getStack(); + if (toTop) { + stack.moveToFront("setTaskWindowingModeSplitScreenPrimary", task); + } + stack.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, animate, showRecents, + false /* enteringSplitScreenMode */, false /* deferEnsuringVisibility */); + return windowingMode != task.getWindowingMode(); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + } + + /** + * Removes stacks in the input windowing modes from the system if they are of activity type + * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED + */ + @Override + public void removeStacksInWindowingModes(int[] windowingModes) { + mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + "removeStacksInWindowingModes()"); + + synchronized (mGlobalLock) { + final long ident = Binder.clearCallingIdentity(); + try { + mStackSupervisor.removeStacksInWindowingModes(windowingModes); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + } + + @Override + public void removeStacksWithActivityTypes(int[] activityTypes) { + mAm.enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, + "removeStacksWithActivityTypes()"); + + synchronized (mGlobalLock) { + final long ident = Binder.clearCallingIdentity(); + try { + mStackSupervisor.removeStacksWithActivityTypes(activityTypes); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + } +} diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java index 06a30780e9ea..810b9fd38f39 100644 --- a/services/core/java/com/android/server/am/RecentTasks.java +++ b/services/core/java/com/android/server/am/RecentTasks.java @@ -41,6 +41,7 @@ import static com.android.server.am.ActivityStackSupervisor.REMOVE_FROM_RECENTS; import static com.android.server.am.TaskRecord.INVALID_TASK_ID; import android.app.ActivityManager; +import android.app.ActivityTaskManager; import android.app.AppGlobals; import android.content.ComponentName; import android.content.Intent; @@ -184,7 +185,7 @@ class RecentTasks { mService = service; mUserController = userController; mTaskPersister = taskPersister; - mGlobalMaxNumTasks = ActivityManager.getMaxRecentTasksStatic(); + mGlobalMaxNumTasks = ActivityTaskManager.getMaxRecentTasksStatic(); mHasVisibleRecentTasks = true; } @@ -194,7 +195,7 @@ class RecentTasks { mService = service; mUserController = service.mUserController; mTaskPersister = new TaskPersister(systemDir, stackSupervisor, service, this); - mGlobalMaxNumTasks = ActivityManager.getMaxRecentTasksStatic(); + mGlobalMaxNumTasks = ActivityTaskManager.getMaxRecentTasksStatic(); mHasVisibleRecentTasks = res.getBoolean(com.android.internal.R.bool.config_hasRecents); loadParametersFromResources(res); } diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index d3ac7cb15824..c8410815f141 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -16,9 +16,9 @@ package com.android.server.am; -import static android.app.ActivityManager.RESIZE_MODE_FORCED; -import static android.app.ActivityManager.RESIZE_MODE_SYSTEM; -import static android.app.ActivityManager.StackId.INVALID_STACK_ID; +import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED; +import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM; +import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; @@ -85,6 +85,7 @@ import android.app.ActivityManager; import android.app.ActivityManager.TaskDescription; import android.app.ActivityManager.TaskSnapshot; import android.app.ActivityOptions; +import android.app.ActivityTaskManager; import android.app.AppGlobals; import android.app.IActivityManager; import android.content.ComponentName; @@ -364,7 +365,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi isPersistable = true; // Clamp to [1, max]. maxRecents = Math.min(Math.max(info.maxRecents, 1), - ActivityManager.getMaxAppRecentsLimitStatic()); + ActivityTaskManager.getMaxAppRecentsLimitStatic()); lastTaskDescription = _taskDescription; touchActiveTime(); @@ -1233,7 +1234,7 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi mCallingPackage = r.launchedFromPackage; // Clamp to [1, max]. maxRecents = Math.min(Math.max(r.info.maxRecents, 1), - ActivityManager.getMaxAppRecentsLimitStatic()); + ActivityTaskManager.getMaxAppRecentsLimitStatic()); } else { // Otherwise make all added activities match this one. r.setActivityType(getActivityType()); diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index b0e6208fdff3..599cdcfb2754 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -16,7 +16,7 @@ package com.android.server.wm; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index f87538a2a890..16277d50897e 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -16,7 +16,7 @@ package com.android.server.wm; -import static android.app.ActivityManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION; +import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION; import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY; import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY; import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION; diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java index c85e1f9ca90f..223c666e56ad 100644 --- a/services/core/java/com/android/server/wm/TaskPositioner.java +++ b/services/core/java/com/android/server/wm/TaskPositioner.java @@ -16,8 +16,8 @@ package com.android.server.wm; -import static android.app.ActivityManager.RESIZE_MODE_USER; -import static android.app.ActivityManager.RESIZE_MODE_USER_FORCED; +import static android.app.ActivityTaskManager.RESIZE_MODE_USER; +import static android.app.ActivityTaskManager.RESIZE_MODE_USER_FORCED; import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING; diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 76c9c262cd76..731a06e299b3 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -16,8 +16,8 @@ package com.android.server.wm; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 947c937f52ec..df3b16c17eee 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -21,7 +21,7 @@ import static android.Manifest.permission.MANAGE_APP_TOKENS; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS; import static android.Manifest.permission.RESTRICTED_VR_ACCESS; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW; import static android.app.StatusBarManager.DISABLE_MASK; import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 0154e0aad8d4..1eb56178def9 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -16,7 +16,7 @@ package com.android.server.wm; -import static android.app.ActivityManager.StackId.INVALID_STACK_ID; +import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_DEFAULT; import static android.app.AppOpsManager.OP_NONE; diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index c864190bb34b..6108504797b5 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -63,6 +63,7 @@ import com.android.internal.util.EmergencyAffordanceManager; import com.android.internal.widget.ILockSettings; import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.am.ActivityManagerService; +import com.android.server.am.ActivityTaskManagerService; import com.android.server.audio.AudioService; import com.android.server.broadcastradio.BroadcastRadioService; import com.android.server.camera.CameraServiceProxy; @@ -560,6 +561,10 @@ public final class SystemServer { ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); + // TODO: Might need to move after migration to WM. + ActivityTaskManagerService atm = mSystemServiceManager.startService( + ActivityTaskManagerService.Lifecycle.class).getService(); + mActivityManagerService.setActivityTaskManager(atm); traceEnd(); // Power manager needs to be started early because other services need it. diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java index 1520859d4aac..74e5816d4a1b 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java @@ -134,7 +134,7 @@ public class ActivityStarterTests extends ActivityTestsBase { assertTrue(task2.getStack() instanceof PinnedActivityStack); mStarter.updateBounds(task2, bounds); - verify(mService, times(1)).resizeStack(eq(task2.getStack().mStackId), + verify(mService.mActivityTaskManager, times(1)).resizeStack(eq(task2.getStack().mStackId), eq(bounds), anyBoolean(), anyBoolean(), anyBoolean(), anyInt()); // In the case of no animation, the stack and task bounds should be set immediately. diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java index 1cd111fce0ec..0154d36bf3bb 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java @@ -110,6 +110,12 @@ public class ActivityTestsBase { protected ActivityManagerService setupActivityManagerService(ActivityManagerService service) { service = spy(service); + // Makes sure the supervisor is using with the spy object. + service.mStackSupervisor.setService(service); + // Makes sure activity task is created with the spy object. + TestActivityTaskManagerService atm = + spy(new TestActivityTaskManagerService(service.mContext)); + service.setActivityTaskManager(atm); doReturn(mock(IPackageManager.class)).when(service).getPackageManager(); doNothing().when(service).grantEphemeralAccessLocked(anyInt(), any(), anyInt(), anyInt()); service.mWindowManager = prepareMockWindowManager(); @@ -333,6 +339,12 @@ public class ActivityTestsBase { } } + protected static class TestActivityTaskManagerService extends ActivityTaskManagerService { + TestActivityTaskManagerService(Context context) { + super(context); + } + } + /** * An {@link ActivityManagerService} subclass which provides a test * {@link ActivityStackSupervisor}. @@ -367,10 +379,6 @@ public class ActivityTestsBase { return mLockTaskController; } - void setLifecycleManager(ClientLifecycleManager manager) { - mLifecycleManager = manager; - } - @Override final protected ActivityStackSupervisor createStackSupervisor() { final ActivityStackSupervisor supervisor = spy(createTestSupervisor()); diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java index b73ac8934cb0..57c3bcbb04c3 100644 --- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java +++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java @@ -16,7 +16,7 @@ package com.android.server.am; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; +import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; @@ -40,11 +40,9 @@ import static org.mockito.Mockito.spy; import static java.lang.Integer.MAX_VALUE; -import android.annotation.TestApi; -import android.app.ActivityManager; import android.app.ActivityManager.RecentTaskInfo; import android.app.ActivityManager.RunningTaskInfo; -import android.app.WindowConfiguration; +import android.app.ActivityTaskManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.PackageManager; @@ -700,16 +698,19 @@ public class RecentTasksTest extends ActivityTestsBase { private void testRecentTasksApis(boolean expectCallable) { assertSecurityException(expectCallable, () -> mService.removeStack(INVALID_STACK_ID)); assertSecurityException(expectCallable, - () -> mService.removeStacksInWindowingModes(new int[] {WINDOWING_MODE_UNDEFINED})); + () -> mService.mActivityTaskManager.removeStacksInWindowingModes( + new int[] {WINDOWING_MODE_UNDEFINED})); assertSecurityException(expectCallable, - () -> mService.removeStacksWithActivityTypes(new int[] {ACTIVITY_TYPE_UNDEFINED})); + () -> mService.mActivityTaskManager.removeStacksWithActivityTypes( + new int[] {ACTIVITY_TYPE_UNDEFINED})); assertSecurityException(expectCallable, () -> mService.removeTask(0)); assertSecurityException(expectCallable, - () -> mService.setTaskWindowingMode(0, WINDOWING_MODE_UNDEFINED, true)); + () -> mService.mActivityTaskManager.setTaskWindowingMode( + 0, WINDOWING_MODE_UNDEFINED, true)); assertSecurityException(expectCallable, () -> mService.moveTaskToStack(0, INVALID_STACK_ID, true)); assertSecurityException(expectCallable, - () -> mService.setTaskWindowingModeSplitScreenPrimary(0, + () -> mService.mActivityTaskManager.setTaskWindowingModeSplitScreenPrimary(0, SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT, true, true, new Rect(), true)); assertSecurityException(expectCallable, () -> mService.dismissSplitScreenMode(true)); assertSecurityException(expectCallable, () -> mService.dismissPip(true, 0)); @@ -794,7 +795,7 @@ public class RecentTasksTest extends ActivityTestsBase { .setFlags(FLAG_ACTIVITY_NEW_DOCUMENT | flags) .build(); task.affinity = null; - task.maxRecents = ActivityManager.getMaxAppRecentsLimitStatic(); + task.maxRecents = ActivityTaskManager.getMaxAppRecentsLimitStatic(); return task; } diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java index 7541b92dbe2c..b26efd545828 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java @@ -23,7 +23,6 @@ import static android.app.ActivityManager.START_VOICE_NOT_ACTIVE_SESSION; import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; import android.app.ActivityManager; -import android.app.ActivityManager.StackId; import android.app.ActivityManagerInternal; import android.app.ActivityOptions; import android.app.IActivityManager; |