1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.app; 18 19 import android.annotation.RequiresPermission; 20 import android.annotation.SystemService; 21 import android.annotation.TestApi; 22 import android.annotation.UnsupportedAppUsage; 23 import android.content.Context; 24 import android.content.pm.PackageManager; 25 import android.content.res.Resources; 26 import android.graphics.Rect; 27 import android.os.Handler; 28 import android.os.IBinder; 29 import android.os.RemoteException; 30 import android.os.ServiceManager; 31 import android.util.Singleton; 32 33 import java.util.List; 34 35 /** 36 * This class gives information about, and interacts with activities and their containers like task, 37 * stacks, and displays. 38 * 39 * @hide 40 */ 41 @TestApi 42 @SystemService(Context.ACTIVITY_TASK_SERVICE) 43 public class ActivityTaskManager { 44 45 /** Invalid stack ID. */ 46 public static final int INVALID_STACK_ID = -1; 47 48 /** 49 * Invalid task ID. 50 * @hide 51 */ 52 public static final int INVALID_TASK_ID = -1; 53 54 /** 55 * Parameter to {@link IActivityTaskManager#setTaskWindowingModeSplitScreenPrimary} which 56 * specifies the position of the created docked stack at the top half of the screen if 57 * in portrait mode or at the left half of the screen if in landscape mode. 58 */ 59 public static final int SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT = 0; 60 61 /** 62 * Parameter to {@link IActivityTaskManager#setTaskWindowingModeSplitScreenPrimary} which 63 * specifies the position of the created docked stack at the bottom half of the screen if 64 * in portrait mode or at the right half of the screen if in landscape mode. 65 */ 66 public static final int SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT = 1; 67 68 /** 69 * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates 70 * that the resize doesn't need to preserve the window, and can be skipped if bounds 71 * is unchanged. This mode is used by window manager in most cases. 72 * @hide 73 */ 74 public static final int RESIZE_MODE_SYSTEM = 0; 75 76 /** 77 * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates 78 * that the resize should preserve the window if possible. 79 * @hide 80 */ 81 public static final int RESIZE_MODE_PRESERVE_WINDOW = (0x1 << 0); 82 83 /** 84 * Input parameter to {@link IActivityTaskManager#resizeTask} used when the 85 * resize is due to a drag action. 86 * @hide 87 */ 88 public static final int RESIZE_MODE_USER = RESIZE_MODE_PRESERVE_WINDOW; 89 90 /** 91 * Input parameter to {@link IActivityTaskManager#resizeTask} used by window 92 * manager during a screen rotation. 93 * @hide 94 */ 95 public static final int RESIZE_MODE_SYSTEM_SCREEN_ROTATION = RESIZE_MODE_PRESERVE_WINDOW; 96 97 /** 98 * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates 99 * that the resize should be performed even if the bounds appears unchanged. 100 * @hide 101 */ 102 public static final int RESIZE_MODE_FORCED = (0x1 << 1); 103 104 /** 105 * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates 106 * that the resize should preserve the window if possible, and should not be skipped 107 * even if the bounds is unchanged. Usually used to force a resizing when a drag action 108 * is ending. 109 * @hide 110 */ 111 public static final int RESIZE_MODE_USER_FORCED = 112 RESIZE_MODE_PRESERVE_WINDOW | RESIZE_MODE_FORCED; 113 114 /** 115 * Extra included on intents that are delegating the call to 116 * ActivityManager#startActivityAsCaller to another app. This token is necessary for that call 117 * to succeed. Type is IBinder. 118 * @hide 119 */ 120 public static final String EXTRA_PERMISSION_TOKEN = "android.app.extra.PERMISSION_TOKEN"; 121 122 /** 123 * Extra included on intents that contain an EXTRA_INTENT, with options that the contained 124 * intent may want to be started with. Type is Bundle. 125 * TODO: remove once the ChooserActivity moves to systemui 126 * @hide 127 */ 128 public static final String EXTRA_OPTIONS = "android.app.extra.OPTIONS"; 129 130 /** 131 * Extra included on intents that contain an EXTRA_INTENT, use this boolean value for the 132 * parameter of the same name when starting the contained intent. 133 * TODO: remove once the ChooserActivity moves to systemui 134 * @hide 135 */ 136 public static final String EXTRA_IGNORE_TARGET_SECURITY = 137 "android.app.extra.EXTRA_IGNORE_TARGET_SECURITY"; 138 139 140 private static int sMaxRecentTasks = -1; 141 ActivityTaskManager(Context context, Handler handler)142 ActivityTaskManager(Context context, Handler handler) { 143 } 144 145 /** @hide */ getService()146 public static IActivityTaskManager getService() { 147 return IActivityTaskManagerSingleton.get(); 148 } 149 150 @UnsupportedAppUsage(trackingBug = 129726065) 151 private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton = 152 new Singleton<IActivityTaskManager>() { 153 @Override 154 protected IActivityTaskManager create() { 155 final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE); 156 return IActivityTaskManager.Stub.asInterface(b); 157 } 158 }; 159 160 /** 161 * Sets the windowing mode for a specific task. Only works on tasks of type 162 * {@link WindowConfiguration#ACTIVITY_TYPE_STANDARD} 163 * @param taskId The id of the task to set the windowing mode for. 164 * @param windowingMode The windowing mode to set for the task. 165 * @param toTop If the task should be moved to the top once the windowing mode changes. 166 */ 167 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) setTaskWindowingMode(int taskId, int windowingMode, boolean toTop)168 public void setTaskWindowingMode(int taskId, int windowingMode, boolean toTop) 169 throws SecurityException { 170 try { 171 getService().setTaskWindowingMode(taskId, windowingMode, toTop); 172 } catch (RemoteException e) { 173 throw e.rethrowFromSystemServer(); 174 } 175 } 176 177 /** 178 * Moves the input task to the primary-split-screen stack. 179 * @param taskId Id of task to move. 180 * @param createMode The mode the primary split screen stack should be created in if it doesn't 181 * exist already. See 182 * {@link ActivityTaskManager#SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT} 183 * and 184 * {@link android.app.ActivityManager 185 * #SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT} 186 * @param toTop If the task and stack should be moved to the top. 187 * @param animate Whether we should play an animation for the moving the task 188 * @param initialBounds If the primary stack gets created, it will use these bounds for the 189 * docked stack. Pass {@code null} to use default bounds. 190 * @param showRecents If the recents activity should be shown on the other side of the task 191 * going into split-screen mode. 192 */ 193 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, boolean animate, Rect initialBounds, boolean showRecents)194 public void setTaskWindowingModeSplitScreenPrimary(int taskId, int createMode, boolean toTop, 195 boolean animate, Rect initialBounds, boolean showRecents) throws SecurityException { 196 try { 197 getService().setTaskWindowingModeSplitScreenPrimary(taskId, createMode, toTop, animate, 198 initialBounds, showRecents); 199 } catch (RemoteException e) { 200 throw e.rethrowFromSystemServer(); 201 } 202 } 203 204 /** 205 * Resizes the input stack id to the given bounds. 206 * @param stackId Id of the stack to resize. 207 * @param bounds Bounds to resize the stack to or {@code null} for fullscreen. 208 */ 209 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) resizeStack(int stackId, Rect bounds)210 public void resizeStack(int stackId, Rect bounds) throws SecurityException { 211 try { 212 getService().resizeStack(stackId, bounds, false /* allowResizeInDockedMode */, 213 false /* preserveWindows */, false /* animate */, -1 /* animationDuration */); 214 } catch (RemoteException e) { 215 throw e.rethrowFromSystemServer(); 216 } 217 } 218 219 /** 220 * Removes stacks in the windowing modes from the system if they are of activity type 221 * ACTIVITY_TYPE_STANDARD or ACTIVITY_TYPE_UNDEFINED 222 */ 223 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) removeStacksInWindowingModes(int[] windowingModes)224 public void removeStacksInWindowingModes(int[] windowingModes) throws SecurityException { 225 try { 226 getService().removeStacksInWindowingModes(windowingModes); 227 } catch (RemoteException e) { 228 throw e.rethrowFromSystemServer(); 229 } 230 } 231 232 /** Removes stack of the activity types from the system. */ 233 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) removeStacksWithActivityTypes(int[] activityTypes)234 public void removeStacksWithActivityTypes(int[] activityTypes) throws SecurityException { 235 try { 236 getService().removeStacksWithActivityTypes(activityTypes); 237 } catch (RemoteException e) { 238 throw e.rethrowFromSystemServer(); 239 } 240 } 241 242 /** 243 * Removes all visible recent tasks from the system. 244 * @hide 245 */ 246 @RequiresPermission(android.Manifest.permission.REMOVE_TASKS) removeAllVisibleRecentTasks()247 public void removeAllVisibleRecentTasks() { 248 try { 249 getService().removeAllVisibleRecentTasks(); 250 } catch (RemoteException e) { 251 throw e.rethrowFromSystemServer(); 252 } 253 } 254 255 /** 256 * Return the maximum number of recents entries that we will maintain and show. 257 * @hide 258 */ getMaxRecentTasksStatic()259 public static int getMaxRecentTasksStatic() { 260 if (sMaxRecentTasks < 0) { 261 return sMaxRecentTasks = ActivityManager.isLowRamDeviceStatic() ? 36 : 48; 262 } 263 return sMaxRecentTasks; 264 } 265 266 /** 267 * Return the default limit on the number of recents that an app can make. 268 * @hide 269 */ getDefaultAppRecentsLimitStatic()270 public static int getDefaultAppRecentsLimitStatic() { 271 return getMaxRecentTasksStatic() / 6; 272 } 273 274 /** 275 * Return the maximum limit on the number of recents that an app can make. 276 * @hide 277 */ getMaxAppRecentsLimitStatic()278 public static int getMaxAppRecentsLimitStatic() { 279 return getMaxRecentTasksStatic() / 2; 280 } 281 282 /** 283 * Returns true if the system supports at least one form of multi-window. 284 * E.g. freeform, split-screen, picture-in-picture. 285 */ supportsMultiWindow(Context context)286 public static boolean supportsMultiWindow(Context context) { 287 // On watches, multi-window is used to present essential system UI, and thus it must be 288 // supported regardless of device memory characteristics. 289 boolean isWatch = context.getPackageManager().hasSystemFeature( 290 PackageManager.FEATURE_WATCH); 291 return (!ActivityManager.isLowRamDeviceStatic() || isWatch) 292 && Resources.getSystem().getBoolean( 293 com.android.internal.R.bool.config_supportsMultiWindow); 294 } 295 296 /** Returns true if the system supports split screen multi-window. */ supportsSplitScreenMultiWindow(Context context)297 public static boolean supportsSplitScreenMultiWindow(Context context) { 298 return supportsMultiWindow(context) 299 && Resources.getSystem().getBoolean( 300 com.android.internal.R.bool.config_supportsSplitScreenMultiWindow); 301 } 302 303 /** 304 * Moves the top activity in the input stackId to the pinned stack. 305 * @param stackId Id of stack to move the top activity to pinned stack. 306 * @param bounds Bounds to use for pinned stack. 307 * @return True if the top activity of stack was successfully moved to the pinned stack. 308 */ 309 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) moveTopActivityToPinnedStack(int stackId, Rect bounds)310 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) { 311 try { 312 return getService().moveTopActivityToPinnedStack(stackId, bounds); 313 } catch (RemoteException e) { 314 throw e.rethrowFromSystemServer(); 315 } 316 } 317 318 /** 319 * Start to enter lock task mode for given task by system(UI). 320 * @param taskId Id of task to lock. 321 */ 322 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) startSystemLockTaskMode(int taskId)323 public void startSystemLockTaskMode(int taskId) { 324 try { 325 getService().startSystemLockTaskMode(taskId); 326 } catch (RemoteException e) { 327 throw e.rethrowFromSystemServer(); 328 } 329 } 330 331 /** 332 * Stop lock task mode by system(UI). 333 */ 334 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) stopSystemLockTaskMode()335 public void stopSystemLockTaskMode() { 336 try { 337 getService().stopSystemLockTaskMode(); 338 } catch (RemoteException e) { 339 throw e.rethrowFromSystemServer(); 340 } 341 } 342 343 /** 344 * Move task to stack with given id. 345 * @param taskId Id of the task to move. 346 * @param stackId Id of the stack for task moving. 347 * @param toTop Whether the given task should shown to top of stack. 348 */ 349 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) moveTaskToStack(int taskId, int stackId, boolean toTop)350 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 351 try { 352 getService().moveTaskToStack(taskId, stackId, toTop); 353 } catch (RemoteException e) { 354 throw e.rethrowFromSystemServer(); 355 } 356 } 357 358 /** 359 * Resize the input stack id to the given bounds with animate setting. 360 * @param stackId Id of the stack to resize. 361 * @param bounds Bounds to resize the stack to or {@code null} for fullscreen. 362 * @param animate Whether we should play an animation for resizing stack. 363 */ 364 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) resizeStack(int stackId, Rect bounds, boolean animate)365 public void resizeStack(int stackId, Rect bounds, boolean animate) { 366 try { 367 getService().resizeStack(stackId, bounds, false, false, animate /* animate */, 368 -1 /* animationDuration */); 369 } catch (RemoteException e) { 370 throw e.rethrowFromSystemServer(); 371 } 372 } 373 374 /** 375 * Resize task to given bounds. 376 * @param taskId Id of task to resize. 377 * @param bounds Bounds to resize task. 378 */ 379 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) resizeTask(int taskId, Rect bounds)380 public void resizeTask(int taskId, Rect bounds) { 381 try { 382 getService().resizeTask(taskId, bounds, RESIZE_MODE_SYSTEM); 383 } catch (RemoteException e) { 384 throw e.rethrowFromSystemServer(); 385 } 386 } 387 388 /** 389 * Resize docked stack & its task to given stack & task bounds. 390 * @param stackBounds Bounds to resize stack. 391 * @param taskBounds Bounds to resize task. 392 */ 393 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) resizeDockedStack(Rect stackBounds, Rect taskBounds)394 public void resizeDockedStack(Rect stackBounds, Rect taskBounds) { 395 try { 396 getService().resizeDockedStack(stackBounds, taskBounds, null, null, null); 397 } catch (RemoteException e) { 398 throw e.rethrowFromSystemServer(); 399 } 400 } 401 402 /** 403 * List all activity stacks information. 404 */ 405 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) listAllStacks()406 public String listAllStacks() { 407 final List<ActivityManager.StackInfo> stacks; 408 try { 409 stacks = getService().getAllStackInfos(); 410 } catch (RemoteException e) { 411 throw e.rethrowFromSystemServer(); 412 } 413 414 final StringBuilder sb = new StringBuilder(); 415 if (stacks != null) { 416 for (ActivityManager.StackInfo info : stacks) { 417 sb.append(info).append("\n"); 418 } 419 } 420 return sb.toString(); 421 } 422 423 /** 424 * Clears launch params for the given package. 425 * @param packageNames the names of the packages of which the launch params are to be cleared 426 */ 427 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) clearLaunchParamsForPackages(List<String> packageNames)428 public void clearLaunchParamsForPackages(List<String> packageNames) { 429 try { 430 getService().clearLaunchParamsForPackages(packageNames); 431 } catch (RemoteException e) { 432 e.rethrowFromSystemServer(); 433 } 434 } 435 436 /** 437 * Makes the display with the given id a single task instance display. I.e the display can only 438 * contain one task. 439 */ 440 @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS) setDisplayToSingleTaskInstance(int displayId)441 public void setDisplayToSingleTaskInstance(int displayId) { 442 try { 443 getService().setDisplayToSingleTaskInstance(displayId); 444 } catch (RemoteException e) { 445 throw e.rethrowFromSystemServer(); 446 } 447 } 448 } 449