1 /* 2 * Copyright (C) 2007 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.Manifest; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.RequiresPermission; 24 import android.annotation.SystemApi; 25 import android.annotation.SystemService; 26 import android.annotation.TestApi; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.UriPermission; 31 import android.content.pm.ActivityInfo; 32 import android.content.pm.ApplicationInfo; 33 import android.content.pm.ConfigurationInfo; 34 import android.content.pm.IPackageDataObserver; 35 import android.content.pm.PackageManager; 36 import android.content.pm.ParceledListSlice; 37 import android.content.pm.UserInfo; 38 import android.content.res.Configuration; 39 import android.content.res.Resources; 40 import android.graphics.Bitmap; 41 import android.graphics.Canvas; 42 import android.graphics.Color; 43 import android.graphics.GraphicBuffer; 44 import android.graphics.Matrix; 45 import android.graphics.Point; 46 import android.graphics.Rect; 47 import android.os.BatteryStats; 48 import android.os.Build; 49 import android.os.Build.VERSION_CODES; 50 import android.os.Bundle; 51 import android.os.Debug; 52 import android.os.Handler; 53 import android.os.IBinder; 54 import android.os.Parcel; 55 import android.os.ParcelFileDescriptor; 56 import android.os.Parcelable; 57 import android.os.Process; 58 import android.os.RemoteException; 59 import android.os.ServiceManager; 60 import android.os.SystemProperties; 61 import android.os.UserHandle; 62 import android.text.TextUtils; 63 import android.util.ArrayMap; 64 import android.util.DisplayMetrics; 65 import android.util.Singleton; 66 import android.util.Size; 67 68 import com.android.internal.app.procstats.ProcessStats; 69 import com.android.internal.os.RoSystemProperties; 70 import com.android.internal.os.TransferPipe; 71 import com.android.internal.util.FastPrintWriter; 72 import com.android.server.LocalServices; 73 74 import org.xmlpull.v1.XmlSerializer; 75 76 import java.io.FileDescriptor; 77 import java.io.FileOutputStream; 78 import java.io.IOException; 79 import java.io.PrintWriter; 80 import java.lang.annotation.Retention; 81 import java.lang.annotation.RetentionPolicy; 82 import java.util.ArrayList; 83 import java.util.List; 84 85 /** 86 * <p> 87 * This class gives information about, and interacts 88 * with, activities, services, and the containing 89 * process. 90 * </p> 91 * 92 * <p> 93 * A number of the methods in this class are for 94 * debugging or informational purposes and they should 95 * not be used to affect any runtime behavior of 96 * your app. These methods are called out as such in 97 * the method level documentation. 98 * </p> 99 * 100 *<p> 101 * Most application developers should not have the need to 102 * use this class, most of whose methods are for specialized 103 * use cases. However, a few methods are more broadly applicable. 104 * For instance, {@link android.app.ActivityManager#isLowRamDevice() isLowRamDevice()} 105 * enables your app to detect whether it is running on a low-memory device, 106 * and behave accordingly. 107 * {@link android.app.ActivityManager#clearApplicationUserData() clearApplicationUserData()} 108 * is for apps with reset-data functionality. 109 * </p> 110 * 111 * <p> 112 * In some special use cases, where an app interacts with 113 * its Task stack, the app may use the 114 * {@link android.app.ActivityManager.AppTask} and 115 * {@link android.app.ActivityManager.RecentTaskInfo} inner 116 * classes. However, in general, the methods in this class should 117 * be used for testing and debugging purposes only. 118 * </p> 119 */ 120 @SystemService(Context.ACTIVITY_SERVICE) 121 public class ActivityManager { 122 private static String TAG = "ActivityManager"; 123 124 private static int gMaxRecentTasks = -1; 125 126 private final Context mContext; 127 128 private static volatile boolean sSystemReady = false; 129 130 131 private static final int FIRST_START_FATAL_ERROR_CODE = -100; 132 private static final int LAST_START_FATAL_ERROR_CODE = -1; 133 private static final int FIRST_START_SUCCESS_CODE = 0; 134 private static final int LAST_START_SUCCESS_CODE = 99; 135 private static final int FIRST_START_NON_FATAL_ERROR_CODE = 100; 136 private static final int LAST_START_NON_FATAL_ERROR_CODE = 199; 137 138 /** 139 * System property to enable task snapshots. 140 * @hide 141 */ 142 public final static boolean ENABLE_TASK_SNAPSHOTS; 143 144 static { 145 ENABLE_TASK_SNAPSHOTS = SystemProperties.getBoolean("persist.enable_task_snapshots", true); 146 } 147 148 static final class UidObserver extends IUidObserver.Stub { 149 final OnUidImportanceListener mListener; 150 final Context mContext; 151 UidObserver(OnUidImportanceListener listener, Context clientContext)152 UidObserver(OnUidImportanceListener listener, Context clientContext) { 153 mListener = listener; 154 mContext = clientContext; 155 } 156 157 @Override onUidStateChanged(int uid, int procState, long procStateSeq)158 public void onUidStateChanged(int uid, int procState, long procStateSeq) { 159 mListener.onUidImportance(uid, RunningAppProcessInfo.procStateToImportanceForClient( 160 procState, mContext)); 161 } 162 163 @Override onUidGone(int uid, boolean disabled)164 public void onUidGone(int uid, boolean disabled) { 165 mListener.onUidImportance(uid, RunningAppProcessInfo.IMPORTANCE_GONE); 166 } 167 168 @Override onUidActive(int uid)169 public void onUidActive(int uid) { 170 } 171 172 @Override onUidIdle(int uid, boolean disabled)173 public void onUidIdle(int uid, boolean disabled) { 174 } 175 onUidCachedChanged(int uid, boolean cached)176 @Override public void onUidCachedChanged(int uid, boolean cached) { 177 } 178 } 179 180 final ArrayMap<OnUidImportanceListener, UidObserver> mImportanceListeners = new ArrayMap<>(); 181 182 /** 183 * Defines acceptable types of bugreports. 184 * @hide 185 */ 186 @Retention(RetentionPolicy.SOURCE) 187 @IntDef({ 188 BUGREPORT_OPTION_FULL, 189 BUGREPORT_OPTION_INTERACTIVE, 190 BUGREPORT_OPTION_REMOTE, 191 BUGREPORT_OPTION_WEAR, 192 BUGREPORT_OPTION_TELEPHONY 193 }) 194 public @interface BugreportMode {} 195 /** 196 * Takes a bugreport without user interference (and hence causing less 197 * interference to the system), but includes all sections. 198 * @hide 199 */ 200 public static final int BUGREPORT_OPTION_FULL = 0; 201 /** 202 * Allows user to monitor progress and enter additional data; might not include all 203 * sections. 204 * @hide 205 */ 206 public static final int BUGREPORT_OPTION_INTERACTIVE = 1; 207 /** 208 * Takes a bugreport requested remotely by administrator of the Device Owner app, 209 * not the device's user. 210 * @hide 211 */ 212 public static final int BUGREPORT_OPTION_REMOTE = 2; 213 /** 214 * Takes a bugreport on a wearable device. 215 * @hide 216 */ 217 public static final int BUGREPORT_OPTION_WEAR = 3; 218 219 /** 220 * Takes a lightweight version of bugreport that only includes a few, urgent sections 221 * used to report telephony bugs. 222 * @hide 223 */ 224 public static final int BUGREPORT_OPTION_TELEPHONY = 4; 225 226 /** 227 * <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code 228 * <meta-data>}</a> name for a 'home' Activity that declares a package that is to be 229 * uninstalled in lieu of the declaring one. The package named here must be 230 * signed with the same certificate as the one declaring the {@code <meta-data>}. 231 */ 232 public static final String META_HOME_ALTERNATE = "android.app.home.alternate"; 233 234 // NOTE: Before adding a new start result, please reference the defined ranges to ensure the 235 // result is properly categorized. 236 237 /** 238 * Result for IActivityManager.startVoiceActivity: active session is currently hidden. 239 * @hide 240 */ 241 public static final int START_VOICE_HIDDEN_SESSION = FIRST_START_FATAL_ERROR_CODE; 242 243 /** 244 * Result for IActivityManager.startVoiceActivity: active session does not match 245 * the requesting token. 246 * @hide 247 */ 248 public static final int START_VOICE_NOT_ACTIVE_SESSION = FIRST_START_FATAL_ERROR_CODE + 1; 249 250 /** 251 * Result for IActivityManager.startActivity: trying to start a background user 252 * activity that shouldn't be displayed for all users. 253 * @hide 254 */ 255 public static final int START_NOT_CURRENT_USER_ACTIVITY = FIRST_START_FATAL_ERROR_CODE + 2; 256 257 /** 258 * Result for IActivityManager.startActivity: trying to start an activity under voice 259 * control when that activity does not support the VOICE category. 260 * @hide 261 */ 262 public static final int START_NOT_VOICE_COMPATIBLE = FIRST_START_FATAL_ERROR_CODE + 3; 263 264 /** 265 * Result for IActivityManager.startActivity: an error where the 266 * start had to be canceled. 267 * @hide 268 */ 269 public static final int START_CANCELED = FIRST_START_FATAL_ERROR_CODE + 4; 270 271 /** 272 * Result for IActivityManager.startActivity: an error where the 273 * thing being started is not an activity. 274 * @hide 275 */ 276 public static final int START_NOT_ACTIVITY = FIRST_START_FATAL_ERROR_CODE + 5; 277 278 /** 279 * Result for IActivityManager.startActivity: an error where the 280 * caller does not have permission to start the activity. 281 * @hide 282 */ 283 public static final int START_PERMISSION_DENIED = FIRST_START_FATAL_ERROR_CODE + 6; 284 285 /** 286 * Result for IActivityManager.startActivity: an error where the 287 * caller has requested both to forward a result and to receive 288 * a result. 289 * @hide 290 */ 291 public static final int START_FORWARD_AND_REQUEST_CONFLICT = FIRST_START_FATAL_ERROR_CODE + 7; 292 293 /** 294 * Result for IActivityManager.startActivity: an error where the 295 * requested class is not found. 296 * @hide 297 */ 298 public static final int START_CLASS_NOT_FOUND = FIRST_START_FATAL_ERROR_CODE + 8; 299 300 /** 301 * Result for IActivityManager.startActivity: an error where the 302 * given Intent could not be resolved to an activity. 303 * @hide 304 */ 305 public static final int START_INTENT_NOT_RESOLVED = FIRST_START_FATAL_ERROR_CODE + 9; 306 307 /** 308 * Result for IActivityManager.startAssistantActivity: active session is currently hidden. 309 * @hide 310 */ 311 public static final int START_ASSISTANT_HIDDEN_SESSION = FIRST_START_FATAL_ERROR_CODE + 10; 312 313 /** 314 * Result for IActivityManager.startAssistantActivity: active session does not match 315 * the requesting token. 316 * @hide 317 */ 318 public static final int START_ASSISTANT_NOT_ACTIVE_SESSION = FIRST_START_FATAL_ERROR_CODE + 11; 319 320 /** 321 * Result for IActivityManaqer.startActivity: the activity was started 322 * successfully as normal. 323 * @hide 324 */ 325 public static final int START_SUCCESS = FIRST_START_SUCCESS_CODE; 326 327 /** 328 * Result for IActivityManaqer.startActivity: the caller asked that the Intent not 329 * be executed if it is the recipient, and that is indeed the case. 330 * @hide 331 */ 332 public static final int START_RETURN_INTENT_TO_CALLER = FIRST_START_SUCCESS_CODE + 1; 333 334 /** 335 * Result for IActivityManaqer.startActivity: activity wasn't really started, but 336 * a task was simply brought to the foreground. 337 * @hide 338 */ 339 public static final int START_TASK_TO_FRONT = FIRST_START_SUCCESS_CODE + 2; 340 341 /** 342 * Result for IActivityManaqer.startActivity: activity wasn't really started, but 343 * the given Intent was given to the existing top activity. 344 * @hide 345 */ 346 public static final int START_DELIVERED_TO_TOP = FIRST_START_SUCCESS_CODE + 3; 347 348 /** 349 * Result for IActivityManaqer.startActivity: request was canceled because 350 * app switches are temporarily canceled to ensure the user's last request 351 * (such as pressing home) is performed. 352 * @hide 353 */ 354 public static final int START_SWITCHES_CANCELED = FIRST_START_NON_FATAL_ERROR_CODE; 355 356 /** 357 * Result for IActivityManaqer.startActivity: a new activity was attempted to be started 358 * while in Lock Task Mode. 359 * @hide 360 */ 361 public static final int START_RETURN_LOCK_TASK_MODE_VIOLATION = 362 FIRST_START_NON_FATAL_ERROR_CODE + 1; 363 364 /** 365 * Result for IActivityManaqer.startActivity: a new activity start was aborted. Never returned 366 * externally. 367 * @hide 368 */ 369 public static final int START_ABORTED = FIRST_START_NON_FATAL_ERROR_CODE + 2; 370 371 /** 372 * Flag for IActivityManaqer.startActivity: do special start mode where 373 * a new activity is launched only if it is needed. 374 * @hide 375 */ 376 public static final int START_FLAG_ONLY_IF_NEEDED = 1<<0; 377 378 /** 379 * Flag for IActivityManaqer.startActivity: launch the app for 380 * debugging. 381 * @hide 382 */ 383 public static final int START_FLAG_DEBUG = 1<<1; 384 385 /** 386 * Flag for IActivityManaqer.startActivity: launch the app for 387 * allocation tracking. 388 * @hide 389 */ 390 public static final int START_FLAG_TRACK_ALLOCATION = 1<<2; 391 392 /** 393 * Flag for IActivityManaqer.startActivity: launch the app with 394 * native debugging support. 395 * @hide 396 */ 397 public static final int START_FLAG_NATIVE_DEBUGGING = 1<<3; 398 399 /** 400 * Result for IActivityManaqer.broadcastIntent: success! 401 * @hide 402 */ 403 public static final int BROADCAST_SUCCESS = 0; 404 405 /** 406 * Result for IActivityManaqer.broadcastIntent: attempt to broadcast 407 * a sticky intent without appropriate permission. 408 * @hide 409 */ 410 public static final int BROADCAST_STICKY_CANT_HAVE_PERMISSION = -1; 411 412 /** 413 * Result for IActivityManager.broadcastIntent: trying to send a broadcast 414 * to a stopped user. Fail. 415 * @hide 416 */ 417 public static final int BROADCAST_FAILED_USER_STOPPED = -2; 418 419 /** 420 * Type for IActivityManaqer.getIntentSender: this PendingIntent is 421 * for a sendBroadcast operation. 422 * @hide 423 */ 424 public static final int INTENT_SENDER_BROADCAST = 1; 425 426 /** 427 * Type for IActivityManaqer.getIntentSender: this PendingIntent is 428 * for a startActivity operation. 429 * @hide 430 */ 431 public static final int INTENT_SENDER_ACTIVITY = 2; 432 433 /** 434 * Type for IActivityManaqer.getIntentSender: this PendingIntent is 435 * for an activity result operation. 436 * @hide 437 */ 438 public static final int INTENT_SENDER_ACTIVITY_RESULT = 3; 439 440 /** 441 * Type for IActivityManaqer.getIntentSender: this PendingIntent is 442 * for a startService operation. 443 * @hide 444 */ 445 public static final int INTENT_SENDER_SERVICE = 4; 446 447 /** 448 * Type for IActivityManaqer.getIntentSender: this PendingIntent is 449 * for a startForegroundService operation. 450 * @hide 451 */ 452 public static final int INTENT_SENDER_FOREGROUND_SERVICE = 5; 453 454 /** @hide User operation call: success! */ 455 public static final int USER_OP_SUCCESS = 0; 456 457 /** @hide User operation call: given user id is not known. */ 458 public static final int USER_OP_UNKNOWN_USER = -1; 459 460 /** @hide User operation call: given user id is the current user, can't be stopped. */ 461 public static final int USER_OP_IS_CURRENT = -2; 462 463 /** @hide User operation call: system user can't be stopped. */ 464 public static final int USER_OP_ERROR_IS_SYSTEM = -3; 465 466 /** @hide User operation call: one of related users cannot be stopped. */ 467 public static final int USER_OP_ERROR_RELATED_USERS_CANNOT_STOP = -4; 468 469 /** @hide Not a real process state. */ 470 public static final int PROCESS_STATE_UNKNOWN = -1; 471 472 /** @hide Process is a persistent system process. */ 473 public static final int PROCESS_STATE_PERSISTENT = 0; 474 475 /** @hide Process is a persistent system process and is doing UI. */ 476 public static final int PROCESS_STATE_PERSISTENT_UI = 1; 477 478 /** @hide Process is hosting the current top activities. Note that this covers 479 * all activities that are visible to the user. */ 480 public static final int PROCESS_STATE_TOP = 2; 481 482 /** @hide Process is hosting a foreground service due to a system binding. */ 483 public static final int PROCESS_STATE_BOUND_FOREGROUND_SERVICE = 3; 484 485 /** @hide Process is hosting a foreground service. */ 486 public static final int PROCESS_STATE_FOREGROUND_SERVICE = 4; 487 488 /** @hide Same as {@link #PROCESS_STATE_TOP} but while device is sleeping. */ 489 public static final int PROCESS_STATE_TOP_SLEEPING = 5; 490 491 /** @hide Process is important to the user, and something they are aware of. */ 492 public static final int PROCESS_STATE_IMPORTANT_FOREGROUND = 6; 493 494 /** @hide Process is important to the user, but not something they are aware of. */ 495 public static final int PROCESS_STATE_IMPORTANT_BACKGROUND = 7; 496 497 /** @hide Process is in the background transient so we will try to keep running. */ 498 public static final int PROCESS_STATE_TRANSIENT_BACKGROUND = 8; 499 500 /** @hide Process is in the background running a backup/restore operation. */ 501 public static final int PROCESS_STATE_BACKUP = 9; 502 503 /** @hide Process is in the background, but it can't restore its state so we want 504 * to try to avoid killing it. */ 505 public static final int PROCESS_STATE_HEAVY_WEIGHT = 10; 506 507 /** @hide Process is in the background running a service. Unlike oom_adj, this level 508 * is used for both the normal running in background state and the executing 509 * operations state. */ 510 public static final int PROCESS_STATE_SERVICE = 11; 511 512 /** @hide Process is in the background running a receiver. Note that from the 513 * perspective of oom_adj receivers run at a higher foreground level, but for our 514 * prioritization here that is not necessary and putting them below services means 515 * many fewer changes in some process states as they receive broadcasts. */ 516 public static final int PROCESS_STATE_RECEIVER = 12; 517 518 /** @hide Process is in the background but hosts the home activity. */ 519 public static final int PROCESS_STATE_HOME = 13; 520 521 /** @hide Process is in the background but hosts the last shown activity. */ 522 public static final int PROCESS_STATE_LAST_ACTIVITY = 14; 523 524 /** @hide Process is being cached for later use and contains activities. */ 525 public static final int PROCESS_STATE_CACHED_ACTIVITY = 15; 526 527 /** @hide Process is being cached for later use and is a client of another cached 528 * process that contains activities. */ 529 public static final int PROCESS_STATE_CACHED_ACTIVITY_CLIENT = 16; 530 531 /** @hide Process is being cached for later use and is empty. */ 532 public static final int PROCESS_STATE_CACHED_EMPTY = 17; 533 534 /** @hide Process does not exist. */ 535 public static final int PROCESS_STATE_NONEXISTENT = 18; 536 537 /** @hide The lowest process state number */ 538 public static final int MIN_PROCESS_STATE = PROCESS_STATE_PERSISTENT; 539 540 /** @hide The highest process state number */ 541 public static final int MAX_PROCESS_STATE = PROCESS_STATE_NONEXISTENT; 542 543 /** @hide Should this process state be considered a background state? */ isProcStateBackground(int procState)544 public static final boolean isProcStateBackground(int procState) { 545 return procState >= PROCESS_STATE_TRANSIENT_BACKGROUND; 546 } 547 548 /** @hide requestType for assist context: only basic information. */ 549 public static final int ASSIST_CONTEXT_BASIC = 0; 550 551 /** @hide requestType for assist context: generate full AssistStructure. */ 552 public static final int ASSIST_CONTEXT_FULL = 1; 553 554 /** @hide requestType for assist context: generate full AssistStructure for autofill. */ 555 public static final int ASSIST_CONTEXT_AUTOFILL = 2; 556 557 /** @hide Flag for registerUidObserver: report changes in process state. */ 558 public static final int UID_OBSERVER_PROCSTATE = 1<<0; 559 560 /** @hide Flag for registerUidObserver: report uid gone. */ 561 public static final int UID_OBSERVER_GONE = 1<<1; 562 563 /** @hide Flag for registerUidObserver: report uid has become idle. */ 564 public static final int UID_OBSERVER_IDLE = 1<<2; 565 566 /** @hide Flag for registerUidObserver: report uid has become active. */ 567 public static final int UID_OBSERVER_ACTIVE = 1<<3; 568 569 /** @hide Flag for registerUidObserver: report uid cached state has changed. */ 570 public static final int UID_OBSERVER_CACHED = 1<<4; 571 572 /** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: normal free-to-run operation. */ 573 public static final int APP_START_MODE_NORMAL = 0; 574 575 /** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: delay running until later. */ 576 public static final int APP_START_MODE_DELAYED = 1; 577 578 /** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: delay running until later, with 579 * rigid errors (throwing exception). */ 580 public static final int APP_START_MODE_DELAYED_RIGID = 2; 581 582 /** @hide Mode for {@link IActivityManager#isAppStartModeDisabled}: disable/cancel pending 583 * launches; this is the mode for ephemeral apps. */ 584 public static final int APP_START_MODE_DISABLED = 3; 585 586 /** 587 * Lock task mode is not active. 588 */ 589 public static final int LOCK_TASK_MODE_NONE = 0; 590 591 /** 592 * Full lock task mode is active. 593 */ 594 public static final int LOCK_TASK_MODE_LOCKED = 1; 595 596 /** 597 * App pinning mode is active. 598 */ 599 public static final int LOCK_TASK_MODE_PINNED = 2; 600 601 Point mAppTaskThumbnailSize; 602 ActivityManager(Context context, Handler handler)603 /*package*/ ActivityManager(Context context, Handler handler) { 604 mContext = context; 605 } 606 607 /** 608 * Returns whether the launch was successful. 609 * @hide 610 */ isStartResultSuccessful(int result)611 public static final boolean isStartResultSuccessful(int result) { 612 return FIRST_START_SUCCESS_CODE <= result && result <= LAST_START_SUCCESS_CODE; 613 } 614 615 /** 616 * Returns whether the launch result was a fatal error. 617 * @hide 618 */ isStartResultFatalError(int result)619 public static final boolean isStartResultFatalError(int result) { 620 return FIRST_START_FATAL_ERROR_CODE <= result && result <= LAST_START_FATAL_ERROR_CODE; 621 } 622 623 /** 624 * Screen compatibility mode: the application most always run in 625 * compatibility mode. 626 * @hide 627 */ 628 public static final int COMPAT_MODE_ALWAYS = -1; 629 630 /** 631 * Screen compatibility mode: the application can never run in 632 * compatibility mode. 633 * @hide 634 */ 635 public static final int COMPAT_MODE_NEVER = -2; 636 637 /** 638 * Screen compatibility mode: unknown. 639 * @hide 640 */ 641 public static final int COMPAT_MODE_UNKNOWN = -3; 642 643 /** 644 * Screen compatibility mode: the application currently has compatibility 645 * mode disabled. 646 * @hide 647 */ 648 public static final int COMPAT_MODE_DISABLED = 0; 649 650 /** 651 * Screen compatibility mode: the application currently has compatibility 652 * mode enabled. 653 * @hide 654 */ 655 public static final int COMPAT_MODE_ENABLED = 1; 656 657 /** 658 * Screen compatibility mode: request to toggle the application's 659 * compatibility mode. 660 * @hide 661 */ 662 public static final int COMPAT_MODE_TOGGLE = 2; 663 664 private static final boolean DEVELOPMENT_FORCE_LOW_RAM = 665 SystemProperties.getBoolean("debug.force_low_ram", false); 666 667 /** @hide */ 668 public static class StackId { 669 /** Invalid stack ID. */ 670 public static final int INVALID_STACK_ID = -1; 671 672 /** First static stack ID. */ 673 public static final int FIRST_STATIC_STACK_ID = 0; 674 675 /** Home activity stack ID. */ 676 public static final int HOME_STACK_ID = FIRST_STATIC_STACK_ID; 677 678 /** ID of stack where fullscreen activities are normally launched into. */ 679 public static final int FULLSCREEN_WORKSPACE_STACK_ID = 1; 680 681 /** ID of stack where freeform/resized activities are normally launched into. */ 682 public static final int FREEFORM_WORKSPACE_STACK_ID = FULLSCREEN_WORKSPACE_STACK_ID + 1; 683 684 /** ID of stack that occupies a dedicated region of the screen. */ 685 public static final int DOCKED_STACK_ID = FREEFORM_WORKSPACE_STACK_ID + 1; 686 687 /** ID of stack that always on top (always visible) when it exist. */ 688 public static final int PINNED_STACK_ID = DOCKED_STACK_ID + 1; 689 690 /** ID of stack that contains the Recents activity. */ 691 public static final int RECENTS_STACK_ID = PINNED_STACK_ID + 1; 692 693 /** ID of stack that contains activities launched by the assistant. */ 694 public static final int ASSISTANT_STACK_ID = RECENTS_STACK_ID + 1; 695 696 /** Last static stack stack ID. */ 697 public static final int LAST_STATIC_STACK_ID = ASSISTANT_STACK_ID; 698 699 /** Start of ID range used by stacks that are created dynamically. */ 700 public static final int FIRST_DYNAMIC_STACK_ID = LAST_STATIC_STACK_ID + 1; 701 isStaticStack(int stackId)702 public static boolean isStaticStack(int stackId) { 703 return stackId >= FIRST_STATIC_STACK_ID && stackId <= LAST_STATIC_STACK_ID; 704 } 705 isDynamicStack(int stackId)706 public static boolean isDynamicStack(int stackId) { 707 return stackId >= FIRST_DYNAMIC_STACK_ID; 708 } 709 710 /** 711 * Returns true if the activities contained in the input stack display a shadow around 712 * their border. 713 */ hasWindowShadow(int stackId)714 public static boolean hasWindowShadow(int stackId) { 715 return stackId == FREEFORM_WORKSPACE_STACK_ID || stackId == PINNED_STACK_ID; 716 } 717 718 /** 719 * Returns true if the activities contained in the input stack display a decor view. 720 */ hasWindowDecor(int stackId)721 public static boolean hasWindowDecor(int stackId) { 722 return stackId == FREEFORM_WORKSPACE_STACK_ID; 723 } 724 725 /** 726 * Returns true if the tasks contained in the stack can be resized independently of the 727 * stack. 728 */ isTaskResizeAllowed(int stackId)729 public static boolean isTaskResizeAllowed(int stackId) { 730 return stackId == FREEFORM_WORKSPACE_STACK_ID; 731 } 732 733 /** Returns true if the task bounds should persist across power cycles. */ persistTaskBounds(int stackId)734 public static boolean persistTaskBounds(int stackId) { 735 return stackId == FREEFORM_WORKSPACE_STACK_ID; 736 } 737 738 /** 739 * Returns true if dynamic stacks are allowed to be visible behind the input stack. 740 */ isDynamicStacksVisibleBehindAllowed(int stackId)741 public static boolean isDynamicStacksVisibleBehindAllowed(int stackId) { 742 return stackId == PINNED_STACK_ID || stackId == ASSISTANT_STACK_ID; 743 } 744 745 /** 746 * Returns true if we try to maintain focus in the current stack when the top activity 747 * finishes. 748 */ keepFocusInStackIfPossible(int stackId)749 public static boolean keepFocusInStackIfPossible(int stackId) { 750 return stackId == FREEFORM_WORKSPACE_STACK_ID 751 || stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID; 752 } 753 754 /** 755 * Returns true if Stack size is affected by the docked stack changing size. 756 */ isResizeableByDockedStack(int stackId)757 public static boolean isResizeableByDockedStack(int stackId) { 758 return isStaticStack(stackId) && stackId != DOCKED_STACK_ID 759 && stackId != PINNED_STACK_ID && stackId != ASSISTANT_STACK_ID; 760 } 761 762 /** 763 * Returns true if the size of tasks in the input stack are affected by the docked stack 764 * changing size. 765 */ isTaskResizeableByDockedStack(int stackId)766 public static boolean isTaskResizeableByDockedStack(int stackId) { 767 return isStaticStack(stackId) && stackId != FREEFORM_WORKSPACE_STACK_ID 768 && stackId != DOCKED_STACK_ID && stackId != PINNED_STACK_ID 769 && stackId != ASSISTANT_STACK_ID; 770 } 771 772 /** 773 * Returns true if the input stack is affected by drag resizing. 774 */ isStackAffectedByDragResizing(int stackId)775 public static boolean isStackAffectedByDragResizing(int stackId) { 776 return isStaticStack(stackId) && stackId != PINNED_STACK_ID 777 && stackId != ASSISTANT_STACK_ID; 778 } 779 780 /** 781 * Returns true if the windows of tasks being moved to the target stack from the source 782 * stack should be replaced, meaning that window manager will keep the old window around 783 * until the new is ready. 784 */ replaceWindowsOnTaskMove(int sourceStackId, int targetStackId)785 public static boolean replaceWindowsOnTaskMove(int sourceStackId, int targetStackId) { 786 return sourceStackId == FREEFORM_WORKSPACE_STACK_ID 787 || targetStackId == FREEFORM_WORKSPACE_STACK_ID; 788 } 789 790 /** 791 * Return whether a stackId is a stack containing floating windows. Floating windows 792 * are laid out differently as they are allowed to extend past the display bounds 793 * without overscan insets. 794 */ tasksAreFloating(int stackId)795 public static boolean tasksAreFloating(int stackId) { 796 return stackId == FREEFORM_WORKSPACE_STACK_ID 797 || stackId == PINNED_STACK_ID; 798 } 799 800 /** 801 * Return whether a stackId is a stack that be a backdrop to a translucent activity. These 802 * are generally fullscreen stacks. 803 */ isBackdropToTranslucentActivity(int stackId)804 public static boolean isBackdropToTranslucentActivity(int stackId) { 805 return stackId == FULLSCREEN_WORKSPACE_STACK_ID 806 || stackId == ASSISTANT_STACK_ID; 807 } 808 809 /** 810 * Returns true if animation specs should be constructed for app transition that moves 811 * the task to the specified stack. 812 */ useAnimationSpecForAppTransition(int stackId)813 public static boolean useAnimationSpecForAppTransition(int stackId) { 814 // TODO: INVALID_STACK_ID is also animated because we don't persist stack id's across 815 // reboots. 816 return stackId == FREEFORM_WORKSPACE_STACK_ID 817 || stackId == FULLSCREEN_WORKSPACE_STACK_ID 818 || stackId == ASSISTANT_STACK_ID 819 || stackId == DOCKED_STACK_ID 820 || stackId == INVALID_STACK_ID; 821 } 822 823 /** 824 * Returns true if the windows in the stack can receive input keys. 825 */ canReceiveKeys(int stackId)826 public static boolean canReceiveKeys(int stackId) { 827 return stackId != PINNED_STACK_ID; 828 } 829 830 /** 831 * Returns true if the stack can be visible above lockscreen. 832 */ isAllowedOverLockscreen(int stackId)833 public static boolean isAllowedOverLockscreen(int stackId) { 834 return stackId == HOME_STACK_ID || stackId == FULLSCREEN_WORKSPACE_STACK_ID || 835 stackId == ASSISTANT_STACK_ID; 836 } 837 838 /** 839 * Returns true if activities from stasks in the given {@param stackId} are allowed to 840 * enter picture-in-picture. 841 */ isAllowedToEnterPictureInPicture(int stackId)842 public static boolean isAllowedToEnterPictureInPicture(int stackId) { 843 return stackId != HOME_STACK_ID && stackId != ASSISTANT_STACK_ID && 844 stackId != RECENTS_STACK_ID; 845 } 846 isAlwaysOnTop(int stackId)847 public static boolean isAlwaysOnTop(int stackId) { 848 return stackId == PINNED_STACK_ID; 849 } 850 851 /** 852 * Returns true if the top task in the task is allowed to return home when finished and 853 * there are other tasks in the stack. 854 */ allowTopTaskToReturnHome(int stackId)855 public static boolean allowTopTaskToReturnHome(int stackId) { 856 return stackId != PINNED_STACK_ID; 857 } 858 859 /** 860 * Returns true if the stack should be resized to match the bounds specified by 861 * {@link ActivityOptions#setLaunchBounds} when launching an activity into the stack. 862 */ resizeStackWithLaunchBounds(int stackId)863 public static boolean resizeStackWithLaunchBounds(int stackId) { 864 return stackId == PINNED_STACK_ID; 865 } 866 867 /** 868 * Returns true if any visible windows belonging to apps in this stack should be kept on 869 * screen when the app is killed due to something like the low memory killer. 870 */ keepVisibleDeadAppWindowOnScreen(int stackId)871 public static boolean keepVisibleDeadAppWindowOnScreen(int stackId) { 872 return stackId != PINNED_STACK_ID; 873 } 874 875 /** 876 * Returns true if the backdrop on the client side should match the frame of the window. 877 * Returns false, if the backdrop should be fullscreen. 878 */ useWindowFrameForBackdrop(int stackId)879 public static boolean useWindowFrameForBackdrop(int stackId) { 880 return stackId == FREEFORM_WORKSPACE_STACK_ID || stackId == PINNED_STACK_ID; 881 } 882 883 /** 884 * Returns true if a window from the specified stack with {@param stackId} are normally 885 * fullscreen, i. e. they can become the top opaque fullscreen window, meaning that it 886 * controls system bars, lockscreen occluded/dismissing state, screen rotation animation, 887 * etc. 888 */ normallyFullscreenWindows(int stackId)889 public static boolean normallyFullscreenWindows(int stackId) { 890 return stackId != PINNED_STACK_ID && stackId != FREEFORM_WORKSPACE_STACK_ID 891 && stackId != DOCKED_STACK_ID; 892 } 893 894 /** 895 * Returns true if the input stack id should only be present on a device that supports 896 * multi-window mode. 897 * @see android.app.ActivityManager#supportsMultiWindow 898 */ isMultiWindowStack(int stackId)899 public static boolean isMultiWindowStack(int stackId) { 900 return stackId == PINNED_STACK_ID || stackId == FREEFORM_WORKSPACE_STACK_ID 901 || stackId == DOCKED_STACK_ID; 902 } 903 904 /** 905 * Returns true if the input {@param stackId} is HOME_STACK_ID or RECENTS_STACK_ID 906 */ isHomeOrRecentsStack(int stackId)907 public static boolean isHomeOrRecentsStack(int stackId) { 908 return stackId == HOME_STACK_ID || stackId == RECENTS_STACK_ID; 909 } 910 911 /** 912 * Returns true if this stack may be scaled without resizing, and windows within may need 913 * to be configured as such. 914 */ windowsAreScaleable(int stackId)915 public static boolean windowsAreScaleable(int stackId) { 916 return stackId == PINNED_STACK_ID; 917 } 918 919 /** 920 * Returns true if windows in this stack should be given move animations by default. 921 */ hasMovementAnimations(int stackId)922 public static boolean hasMovementAnimations(int stackId) { 923 return stackId != PINNED_STACK_ID; 924 } 925 926 /** Returns true if the input stack and its content can affect the device orientation. */ canSpecifyOrientation(int stackId)927 public static boolean canSpecifyOrientation(int stackId) { 928 return stackId == HOME_STACK_ID 929 || stackId == RECENTS_STACK_ID 930 || stackId == FULLSCREEN_WORKSPACE_STACK_ID 931 || stackId == ASSISTANT_STACK_ID 932 || isDynamicStack(stackId); 933 } 934 } 935 936 /** 937 * Input parameter to {@link android.app.IActivityManager#moveTaskToDockedStack} which 938 * specifies the position of the created docked stack at the top half of the screen if 939 * in portrait mode or at the left half of the screen if in landscape mode. 940 * @hide 941 */ 942 public static final int DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT = 0; 943 944 /** 945 * Input parameter to {@link android.app.IActivityManager#moveTaskToDockedStack} which 946 * specifies the position of the created docked stack at the bottom half of the screen if 947 * in portrait mode or at the right half of the screen if in landscape mode. 948 * @hide 949 */ 950 public static final int DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT = 1; 951 952 /** 953 * Input parameter to {@link android.app.IActivityManager#resizeTask} which indicates 954 * that the resize doesn't need to preserve the window, and can be skipped if bounds 955 * is unchanged. This mode is used by window manager in most cases. 956 * @hide 957 */ 958 public static final int RESIZE_MODE_SYSTEM = 0; 959 960 /** 961 * Input parameter to {@link android.app.IActivityManager#resizeTask} which indicates 962 * that the resize should preserve the window if possible. 963 * @hide 964 */ 965 public static final int RESIZE_MODE_PRESERVE_WINDOW = (0x1 << 0); 966 967 /** 968 * Input parameter to {@link android.app.IActivityManager#resizeTask} which indicates 969 * that the resize should be performed even if the bounds appears unchanged. 970 * @hide 971 */ 972 public static final int RESIZE_MODE_FORCED = (0x1 << 1); 973 974 /** 975 * Input parameter to {@link android.app.IActivityManager#resizeTask} used by window 976 * manager during a screen rotation. 977 * @hide 978 */ 979 public static final int RESIZE_MODE_SYSTEM_SCREEN_ROTATION = RESIZE_MODE_PRESERVE_WINDOW; 980 981 /** 982 * Input parameter to {@link android.app.IActivityManager#resizeTask} used when the 983 * resize is due to a drag action. 984 * @hide 985 */ 986 public static final int RESIZE_MODE_USER = RESIZE_MODE_PRESERVE_WINDOW; 987 988 /** 989 * Input parameter to {@link android.app.IActivityManager#resizeTask} which indicates 990 * that the resize should preserve the window if possible, and should not be skipped 991 * even if the bounds is unchanged. Usually used to force a resizing when a drag action 992 * is ending. 993 * @hide 994 */ 995 public static final int RESIZE_MODE_USER_FORCED = 996 RESIZE_MODE_PRESERVE_WINDOW | RESIZE_MODE_FORCED; 997 998 /** @hide */ getFrontActivityScreenCompatMode()999 public int getFrontActivityScreenCompatMode() { 1000 try { 1001 return getService().getFrontActivityScreenCompatMode(); 1002 } catch (RemoteException e) { 1003 throw e.rethrowFromSystemServer(); 1004 } 1005 } 1006 1007 /** @hide */ setFrontActivityScreenCompatMode(int mode)1008 public void setFrontActivityScreenCompatMode(int mode) { 1009 try { 1010 getService().setFrontActivityScreenCompatMode(mode); 1011 } catch (RemoteException e) { 1012 throw e.rethrowFromSystemServer(); 1013 } 1014 } 1015 1016 /** @hide */ getPackageScreenCompatMode(String packageName)1017 public int getPackageScreenCompatMode(String packageName) { 1018 try { 1019 return getService().getPackageScreenCompatMode(packageName); 1020 } catch (RemoteException e) { 1021 throw e.rethrowFromSystemServer(); 1022 } 1023 } 1024 1025 /** @hide */ setPackageScreenCompatMode(String packageName, int mode)1026 public void setPackageScreenCompatMode(String packageName, int mode) { 1027 try { 1028 getService().setPackageScreenCompatMode(packageName, mode); 1029 } catch (RemoteException e) { 1030 throw e.rethrowFromSystemServer(); 1031 } 1032 } 1033 1034 /** @hide */ getPackageAskScreenCompat(String packageName)1035 public boolean getPackageAskScreenCompat(String packageName) { 1036 try { 1037 return getService().getPackageAskScreenCompat(packageName); 1038 } catch (RemoteException e) { 1039 throw e.rethrowFromSystemServer(); 1040 } 1041 } 1042 1043 /** @hide */ setPackageAskScreenCompat(String packageName, boolean ask)1044 public void setPackageAskScreenCompat(String packageName, boolean ask) { 1045 try { 1046 getService().setPackageAskScreenCompat(packageName, ask); 1047 } catch (RemoteException e) { 1048 throw e.rethrowFromSystemServer(); 1049 } 1050 } 1051 1052 /** 1053 * Return the approximate per-application memory class of the current 1054 * device. This gives you an idea of how hard a memory limit you should 1055 * impose on your application to let the overall system work best. The 1056 * returned value is in megabytes; the baseline Android memory class is 1057 * 16 (which happens to be the Java heap limit of those devices); some 1058 * device with more memory may return 24 or even higher numbers. 1059 */ getMemoryClass()1060 public int getMemoryClass() { 1061 return staticGetMemoryClass(); 1062 } 1063 1064 /** @hide */ staticGetMemoryClass()1065 static public int staticGetMemoryClass() { 1066 // Really brain dead right now -- just take this from the configured 1067 // vm heap size, and assume it is in megabytes and thus ends with "m". 1068 String vmHeapSize = SystemProperties.get("dalvik.vm.heapgrowthlimit", ""); 1069 if (vmHeapSize != null && !"".equals(vmHeapSize)) { 1070 return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1)); 1071 } 1072 return staticGetLargeMemoryClass(); 1073 } 1074 1075 /** 1076 * Return the approximate per-application memory class of the current 1077 * device when an application is running with a large heap. This is the 1078 * space available for memory-intensive applications; most applications 1079 * should not need this amount of memory, and should instead stay with the 1080 * {@link #getMemoryClass()} limit. The returned value is in megabytes. 1081 * This may be the same size as {@link #getMemoryClass()} on memory 1082 * constrained devices, or it may be significantly larger on devices with 1083 * a large amount of available RAM. 1084 * 1085 * <p>The is the size of the application's Dalvik heap if it has 1086 * specified <code>android:largeHeap="true"</code> in its manifest. 1087 */ getLargeMemoryClass()1088 public int getLargeMemoryClass() { 1089 return staticGetLargeMemoryClass(); 1090 } 1091 1092 /** @hide */ staticGetLargeMemoryClass()1093 static public int staticGetLargeMemoryClass() { 1094 // Really brain dead right now -- just take this from the configured 1095 // vm heap size, and assume it is in megabytes and thus ends with "m". 1096 String vmHeapSize = SystemProperties.get("dalvik.vm.heapsize", "16m"); 1097 return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length() - 1)); 1098 } 1099 1100 /** 1101 * Returns true if this is a low-RAM device. Exactly whether a device is low-RAM 1102 * is ultimately up to the device configuration, but currently it generally means 1103 * something in the class of a 512MB device with about a 800x480 or less screen. 1104 * This is mostly intended to be used by apps to determine whether they should turn 1105 * off certain features that require more RAM. 1106 */ isLowRamDevice()1107 public boolean isLowRamDevice() { 1108 return isLowRamDeviceStatic(); 1109 } 1110 1111 /** @hide */ isLowRamDeviceStatic()1112 public static boolean isLowRamDeviceStatic() { 1113 return RoSystemProperties.CONFIG_LOW_RAM || 1114 (Build.IS_DEBUGGABLE && DEVELOPMENT_FORCE_LOW_RAM); 1115 } 1116 1117 /** 1118 * Returns true if this is a small battery device. Exactly whether a device is considered to be 1119 * small battery is ultimately up to the device configuration, but currently it generally means 1120 * something in the class of a device with 1000 mAh or less. This is mostly intended to be used 1121 * to determine whether certain features should be altered to account for a drastically smaller 1122 * battery. 1123 * @hide 1124 */ isSmallBatteryDevice()1125 public static boolean isSmallBatteryDevice() { 1126 return RoSystemProperties.CONFIG_SMALL_BATTERY; 1127 } 1128 1129 /** 1130 * Used by persistent processes to determine if they are running on a 1131 * higher-end device so should be okay using hardware drawing acceleration 1132 * (which tends to consume a lot more RAM). 1133 * @hide 1134 */ isHighEndGfx()1135 static public boolean isHighEndGfx() { 1136 return !isLowRamDeviceStatic() && 1137 !Resources.getSystem().getBoolean(com.android.internal.R.bool.config_avoidGfxAccel); 1138 } 1139 1140 /** 1141 * Return the maximum number of recents entries that we will maintain and show. 1142 * @hide 1143 */ getMaxRecentTasksStatic()1144 static public int getMaxRecentTasksStatic() { 1145 if (gMaxRecentTasks < 0) { 1146 return gMaxRecentTasks = isLowRamDeviceStatic() ? 36 : 48; 1147 } 1148 return gMaxRecentTasks; 1149 } 1150 1151 /** 1152 * Return the default limit on the number of recents that an app can make. 1153 * @hide 1154 */ getDefaultAppRecentsLimitStatic()1155 static public int getDefaultAppRecentsLimitStatic() { 1156 return getMaxRecentTasksStatic() / 6; 1157 } 1158 1159 /** 1160 * Return the maximum limit on the number of recents that an app can make. 1161 * @hide 1162 */ getMaxAppRecentsLimitStatic()1163 static public int getMaxAppRecentsLimitStatic() { 1164 return getMaxRecentTasksStatic() / 2; 1165 } 1166 1167 /** 1168 * Returns true if the system supports at least one form of multi-window. 1169 * E.g. freeform, split-screen, picture-in-picture. 1170 * @hide 1171 */ supportsMultiWindow(Context context)1172 static public boolean supportsMultiWindow(Context context) { 1173 // On watches, multi-window is used to present essential system UI, and thus it must be 1174 // supported regardless of device memory characteristics. 1175 boolean isWatch = context.getPackageManager().hasSystemFeature( 1176 PackageManager.FEATURE_WATCH); 1177 return (!isLowRamDeviceStatic() || isWatch) 1178 && Resources.getSystem().getBoolean( 1179 com.android.internal.R.bool.config_supportsMultiWindow); 1180 } 1181 1182 /** 1183 * Returns true if the system supports split screen multi-window. 1184 * @hide 1185 */ supportsSplitScreenMultiWindow(Context context)1186 static public boolean supportsSplitScreenMultiWindow(Context context) { 1187 return supportsMultiWindow(context) 1188 && Resources.getSystem().getBoolean( 1189 com.android.internal.R.bool.config_supportsSplitScreenMultiWindow); 1190 } 1191 1192 /** @removed */ 1193 @Deprecated getMaxNumPictureInPictureActions()1194 public static int getMaxNumPictureInPictureActions() { 1195 return 3; 1196 } 1197 1198 /** 1199 * Information you can set and retrieve about the current activity within the recent task list. 1200 */ 1201 public static class TaskDescription implements Parcelable { 1202 /** @hide */ 1203 public static final String ATTR_TASKDESCRIPTION_PREFIX = "task_description_"; 1204 private static final String ATTR_TASKDESCRIPTIONLABEL = 1205 ATTR_TASKDESCRIPTION_PREFIX + "label"; 1206 private static final String ATTR_TASKDESCRIPTIONCOLOR_PRIMARY = 1207 ATTR_TASKDESCRIPTION_PREFIX + "color"; 1208 private static final String ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND = 1209 ATTR_TASKDESCRIPTION_PREFIX + "colorBackground"; 1210 private static final String ATTR_TASKDESCRIPTIONICONFILENAME = 1211 ATTR_TASKDESCRIPTION_PREFIX + "icon_filename"; 1212 1213 private String mLabel; 1214 private Bitmap mIcon; 1215 private String mIconFilename; 1216 private int mColorPrimary; 1217 private int mColorBackground; 1218 private int mStatusBarColor; 1219 private int mNavigationBarColor; 1220 1221 /** 1222 * Creates the TaskDescription to the specified values. 1223 * 1224 * @param label A label and description of the current state of this task. 1225 * @param icon An icon that represents the current state of this task. 1226 * @param colorPrimary A color to override the theme's primary color. This color must be 1227 * opaque. 1228 */ TaskDescription(String label, Bitmap icon, int colorPrimary)1229 public TaskDescription(String label, Bitmap icon, int colorPrimary) { 1230 this(label, icon, null, colorPrimary, 0, 0, 0); 1231 if ((colorPrimary != 0) && (Color.alpha(colorPrimary) != 255)) { 1232 throw new RuntimeException("A TaskDescription's primary color should be opaque"); 1233 } 1234 } 1235 1236 /** 1237 * Creates the TaskDescription to the specified values. 1238 * 1239 * @param label A label and description of the current state of this activity. 1240 * @param icon An icon that represents the current state of this activity. 1241 */ TaskDescription(String label, Bitmap icon)1242 public TaskDescription(String label, Bitmap icon) { 1243 this(label, icon, null, 0, 0, 0, 0); 1244 } 1245 1246 /** 1247 * Creates the TaskDescription to the specified values. 1248 * 1249 * @param label A label and description of the current state of this activity. 1250 */ TaskDescription(String label)1251 public TaskDescription(String label) { 1252 this(label, null, null, 0, 0, 0, 0); 1253 } 1254 1255 /** 1256 * Creates an empty TaskDescription. 1257 */ TaskDescription()1258 public TaskDescription() { 1259 this(null, null, null, 0, 0, 0, 0); 1260 } 1261 1262 /** @hide */ TaskDescription(String label, Bitmap icon, String iconFilename, int colorPrimary, int colorBackground, int statusBarColor, int navigationBarColor)1263 public TaskDescription(String label, Bitmap icon, String iconFilename, int colorPrimary, 1264 int colorBackground, int statusBarColor, int navigationBarColor) { 1265 mLabel = label; 1266 mIcon = icon; 1267 mIconFilename = iconFilename; 1268 mColorPrimary = colorPrimary; 1269 mColorBackground = colorBackground; 1270 mStatusBarColor = statusBarColor; 1271 mNavigationBarColor = navigationBarColor; 1272 } 1273 1274 /** 1275 * Creates a copy of another TaskDescription. 1276 */ TaskDescription(TaskDescription td)1277 public TaskDescription(TaskDescription td) { 1278 copyFrom(td); 1279 } 1280 1281 /** 1282 * Copies this the values from another TaskDescription. 1283 * @hide 1284 */ copyFrom(TaskDescription other)1285 public void copyFrom(TaskDescription other) { 1286 mLabel = other.mLabel; 1287 mIcon = other.mIcon; 1288 mIconFilename = other.mIconFilename; 1289 mColorPrimary = other.mColorPrimary; 1290 mColorBackground = other.mColorBackground; 1291 mStatusBarColor = other.mStatusBarColor; 1292 mNavigationBarColor = other.mNavigationBarColor; 1293 } 1294 1295 /** 1296 * Copies this the values from another TaskDescription, but preserves the hidden fields 1297 * if they weren't set on {@code other} 1298 * @hide 1299 */ copyFromPreserveHiddenFields(TaskDescription other)1300 public void copyFromPreserveHiddenFields(TaskDescription other) { 1301 mLabel = other.mLabel; 1302 mIcon = other.mIcon; 1303 mIconFilename = other.mIconFilename; 1304 mColorPrimary = other.mColorPrimary; 1305 if (other.mColorBackground != 0) { 1306 mColorBackground = other.mColorBackground; 1307 } 1308 if (other.mStatusBarColor != 0) { 1309 mStatusBarColor = other.mStatusBarColor; 1310 } 1311 if (other.mNavigationBarColor != 0) { 1312 mNavigationBarColor = other.mNavigationBarColor; 1313 } 1314 } 1315 TaskDescription(Parcel source)1316 private TaskDescription(Parcel source) { 1317 readFromParcel(source); 1318 } 1319 1320 /** 1321 * Sets the label for this task description. 1322 * @hide 1323 */ setLabel(String label)1324 public void setLabel(String label) { 1325 mLabel = label; 1326 } 1327 1328 /** 1329 * Sets the primary color for this task description. 1330 * @hide 1331 */ setPrimaryColor(int primaryColor)1332 public void setPrimaryColor(int primaryColor) { 1333 // Ensure that the given color is valid 1334 if ((primaryColor != 0) && (Color.alpha(primaryColor) != 255)) { 1335 throw new RuntimeException("A TaskDescription's primary color should be opaque"); 1336 } 1337 mColorPrimary = primaryColor; 1338 } 1339 1340 /** 1341 * Sets the background color for this task description. 1342 * @hide 1343 */ setBackgroundColor(int backgroundColor)1344 public void setBackgroundColor(int backgroundColor) { 1345 // Ensure that the given color is valid 1346 if ((backgroundColor != 0) && (Color.alpha(backgroundColor) != 255)) { 1347 throw new RuntimeException("A TaskDescription's background color should be opaque"); 1348 } 1349 mColorBackground = backgroundColor; 1350 } 1351 1352 /** 1353 * @hide 1354 */ setStatusBarColor(int statusBarColor)1355 public void setStatusBarColor(int statusBarColor) { 1356 mStatusBarColor = statusBarColor; 1357 } 1358 1359 /** 1360 * @hide 1361 */ setNavigationBarColor(int navigationBarColor)1362 public void setNavigationBarColor(int navigationBarColor) { 1363 mNavigationBarColor = navigationBarColor; 1364 } 1365 1366 /** 1367 * Sets the icon for this task description. 1368 * @hide 1369 */ setIcon(Bitmap icon)1370 public void setIcon(Bitmap icon) { 1371 mIcon = icon; 1372 } 1373 1374 /** 1375 * Moves the icon bitmap reference from an actual Bitmap to a file containing the 1376 * bitmap. 1377 * @hide 1378 */ setIconFilename(String iconFilename)1379 public void setIconFilename(String iconFilename) { 1380 mIconFilename = iconFilename; 1381 mIcon = null; 1382 } 1383 1384 /** 1385 * @return The label and description of the current state of this task. 1386 */ getLabel()1387 public String getLabel() { 1388 return mLabel; 1389 } 1390 1391 /** 1392 * @return The icon that represents the current state of this task. 1393 */ getIcon()1394 public Bitmap getIcon() { 1395 if (mIcon != null) { 1396 return mIcon; 1397 } 1398 return loadTaskDescriptionIcon(mIconFilename, UserHandle.myUserId()); 1399 } 1400 1401 /** @hide */ getIconFilename()1402 public String getIconFilename() { 1403 return mIconFilename; 1404 } 1405 1406 /** @hide */ getInMemoryIcon()1407 public Bitmap getInMemoryIcon() { 1408 return mIcon; 1409 } 1410 1411 /** @hide */ loadTaskDescriptionIcon(String iconFilename, int userId)1412 public static Bitmap loadTaskDescriptionIcon(String iconFilename, int userId) { 1413 if (iconFilename != null) { 1414 try { 1415 return getService().getTaskDescriptionIcon(iconFilename, 1416 userId); 1417 } catch (RemoteException e) { 1418 throw e.rethrowFromSystemServer(); 1419 } 1420 } 1421 return null; 1422 } 1423 1424 /** 1425 * @return The color override on the theme's primary color. 1426 */ getPrimaryColor()1427 public int getPrimaryColor() { 1428 return mColorPrimary; 1429 } 1430 1431 /** 1432 * @return The background color. 1433 * @hide 1434 */ getBackgroundColor()1435 public int getBackgroundColor() { 1436 return mColorBackground; 1437 } 1438 1439 /** 1440 * @hide 1441 */ getStatusBarColor()1442 public int getStatusBarColor() { 1443 return mStatusBarColor; 1444 } 1445 1446 /** 1447 * @hide 1448 */ getNavigationBarColor()1449 public int getNavigationBarColor() { 1450 return mNavigationBarColor; 1451 } 1452 1453 /** @hide */ saveToXml(XmlSerializer out)1454 public void saveToXml(XmlSerializer out) throws IOException { 1455 if (mLabel != null) { 1456 out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, mLabel); 1457 } 1458 if (mColorPrimary != 0) { 1459 out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR_PRIMARY, 1460 Integer.toHexString(mColorPrimary)); 1461 } 1462 if (mColorBackground != 0) { 1463 out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND, 1464 Integer.toHexString(mColorBackground)); 1465 } 1466 if (mIconFilename != null) { 1467 out.attribute(null, ATTR_TASKDESCRIPTIONICONFILENAME, mIconFilename); 1468 } 1469 } 1470 1471 /** @hide */ restoreFromXml(String attrName, String attrValue)1472 public void restoreFromXml(String attrName, String attrValue) { 1473 if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) { 1474 setLabel(attrValue); 1475 } else if (ATTR_TASKDESCRIPTIONCOLOR_PRIMARY.equals(attrName)) { 1476 setPrimaryColor((int) Long.parseLong(attrValue, 16)); 1477 } else if (ATTR_TASKDESCRIPTIONCOLOR_BACKGROUND.equals(attrName)) { 1478 setBackgroundColor((int) Long.parseLong(attrValue, 16)); 1479 } else if (ATTR_TASKDESCRIPTIONICONFILENAME.equals(attrName)) { 1480 setIconFilename(attrValue); 1481 } 1482 } 1483 1484 @Override describeContents()1485 public int describeContents() { 1486 return 0; 1487 } 1488 1489 @Override writeToParcel(Parcel dest, int flags)1490 public void writeToParcel(Parcel dest, int flags) { 1491 if (mLabel == null) { 1492 dest.writeInt(0); 1493 } else { 1494 dest.writeInt(1); 1495 dest.writeString(mLabel); 1496 } 1497 if (mIcon == null) { 1498 dest.writeInt(0); 1499 } else { 1500 dest.writeInt(1); 1501 mIcon.writeToParcel(dest, 0); 1502 } 1503 dest.writeInt(mColorPrimary); 1504 dest.writeInt(mColorBackground); 1505 dest.writeInt(mStatusBarColor); 1506 dest.writeInt(mNavigationBarColor); 1507 if (mIconFilename == null) { 1508 dest.writeInt(0); 1509 } else { 1510 dest.writeInt(1); 1511 dest.writeString(mIconFilename); 1512 } 1513 } 1514 readFromParcel(Parcel source)1515 public void readFromParcel(Parcel source) { 1516 mLabel = source.readInt() > 0 ? source.readString() : null; 1517 mIcon = source.readInt() > 0 ? Bitmap.CREATOR.createFromParcel(source) : null; 1518 mColorPrimary = source.readInt(); 1519 mColorBackground = source.readInt(); 1520 mStatusBarColor = source.readInt(); 1521 mNavigationBarColor = source.readInt(); 1522 mIconFilename = source.readInt() > 0 ? source.readString() : null; 1523 } 1524 1525 public static final Creator<TaskDescription> CREATOR 1526 = new Creator<TaskDescription>() { 1527 public TaskDescription createFromParcel(Parcel source) { 1528 return new TaskDescription(source); 1529 } 1530 public TaskDescription[] newArray(int size) { 1531 return new TaskDescription[size]; 1532 } 1533 }; 1534 1535 @Override toString()1536 public String toString() { 1537 return "TaskDescription Label: " + mLabel + " Icon: " + mIcon + 1538 " IconFilename: " + mIconFilename + " colorPrimary: " + mColorPrimary + 1539 " colorBackground: " + mColorBackground + 1540 " statusBarColor: " + mColorBackground + 1541 " navigationBarColor: " + mNavigationBarColor; 1542 } 1543 } 1544 1545 /** 1546 * Information you can retrieve about tasks that the user has most recently 1547 * started or visited. 1548 */ 1549 public static class RecentTaskInfo implements Parcelable { 1550 /** 1551 * If this task is currently running, this is the identifier for it. 1552 * If it is not running, this will be -1. 1553 */ 1554 public int id; 1555 1556 /** 1557 * The true identifier of this task, valid even if it is not running. 1558 */ 1559 public int persistentId; 1560 1561 /** 1562 * The original Intent used to launch the task. You can use this 1563 * Intent to re-launch the task (if it is no longer running) or bring 1564 * the current task to the front. 1565 */ 1566 public Intent baseIntent; 1567 1568 /** 1569 * If this task was started from an alias, this is the actual 1570 * activity component that was initially started; the component of 1571 * the baseIntent in this case is the name of the actual activity 1572 * implementation that the alias referred to. Otherwise, this is null. 1573 */ 1574 public ComponentName origActivity; 1575 1576 /** 1577 * The actual activity component that started the task. 1578 * @hide 1579 */ 1580 @Nullable 1581 public ComponentName realActivity; 1582 1583 /** 1584 * Description of the task's last state. 1585 */ 1586 public CharSequence description; 1587 1588 /** 1589 * The id of the ActivityStack this Task was on most recently. 1590 * @hide 1591 */ 1592 public int stackId; 1593 1594 /** 1595 * The id of the user the task was running as. 1596 * @hide 1597 */ 1598 public int userId; 1599 1600 /** 1601 * The first time this task was active. 1602 * @hide 1603 */ 1604 public long firstActiveTime; 1605 1606 /** 1607 * The last time this task was active. 1608 * @hide 1609 */ 1610 public long lastActiveTime; 1611 1612 /** 1613 * The recent activity values for the highest activity in the stack to have set the values. 1614 * {@link Activity#setTaskDescription(android.app.ActivityManager.TaskDescription)}. 1615 */ 1616 public TaskDescription taskDescription; 1617 1618 /** 1619 * Task affiliation for grouping with other tasks. 1620 */ 1621 public int affiliatedTaskId; 1622 1623 /** 1624 * Task affiliation color of the source task with the affiliated task id. 1625 * 1626 * @hide 1627 */ 1628 public int affiliatedTaskColor; 1629 1630 /** 1631 * The component launched as the first activity in the task. 1632 * This can be considered the "application" of this task. 1633 */ 1634 public ComponentName baseActivity; 1635 1636 /** 1637 * The activity component at the top of the history stack of the task. 1638 * This is what the user is currently doing. 1639 */ 1640 public ComponentName topActivity; 1641 1642 /** 1643 * Number of activities in this task. 1644 */ 1645 public int numActivities; 1646 1647 /** 1648 * The bounds of the task. 1649 * @hide 1650 */ 1651 public Rect bounds; 1652 1653 /** 1654 * True if the task can go in the docked stack. 1655 * @hide 1656 */ 1657 public boolean supportsSplitScreenMultiWindow; 1658 1659 /** 1660 * The resize mode of the task. See {@link ActivityInfo#resizeMode}. 1661 * @hide 1662 */ 1663 public int resizeMode; 1664 RecentTaskInfo()1665 public RecentTaskInfo() { 1666 } 1667 1668 @Override describeContents()1669 public int describeContents() { 1670 return 0; 1671 } 1672 1673 @Override writeToParcel(Parcel dest, int flags)1674 public void writeToParcel(Parcel dest, int flags) { 1675 dest.writeInt(id); 1676 dest.writeInt(persistentId); 1677 if (baseIntent != null) { 1678 dest.writeInt(1); 1679 baseIntent.writeToParcel(dest, 0); 1680 } else { 1681 dest.writeInt(0); 1682 } 1683 ComponentName.writeToParcel(origActivity, dest); 1684 ComponentName.writeToParcel(realActivity, dest); 1685 TextUtils.writeToParcel(description, dest, 1686 Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 1687 if (taskDescription != null) { 1688 dest.writeInt(1); 1689 taskDescription.writeToParcel(dest, 0); 1690 } else { 1691 dest.writeInt(0); 1692 } 1693 dest.writeInt(stackId); 1694 dest.writeInt(userId); 1695 dest.writeLong(firstActiveTime); 1696 dest.writeLong(lastActiveTime); 1697 dest.writeInt(affiliatedTaskId); 1698 dest.writeInt(affiliatedTaskColor); 1699 ComponentName.writeToParcel(baseActivity, dest); 1700 ComponentName.writeToParcel(topActivity, dest); 1701 dest.writeInt(numActivities); 1702 if (bounds != null) { 1703 dest.writeInt(1); 1704 bounds.writeToParcel(dest, 0); 1705 } else { 1706 dest.writeInt(0); 1707 } 1708 dest.writeInt(supportsSplitScreenMultiWindow ? 1 : 0); 1709 dest.writeInt(resizeMode); 1710 } 1711 readFromParcel(Parcel source)1712 public void readFromParcel(Parcel source) { 1713 id = source.readInt(); 1714 persistentId = source.readInt(); 1715 baseIntent = source.readInt() > 0 ? Intent.CREATOR.createFromParcel(source) : null; 1716 origActivity = ComponentName.readFromParcel(source); 1717 realActivity = ComponentName.readFromParcel(source); 1718 description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); 1719 taskDescription = source.readInt() > 0 ? 1720 TaskDescription.CREATOR.createFromParcel(source) : null; 1721 stackId = source.readInt(); 1722 userId = source.readInt(); 1723 firstActiveTime = source.readLong(); 1724 lastActiveTime = source.readLong(); 1725 affiliatedTaskId = source.readInt(); 1726 affiliatedTaskColor = source.readInt(); 1727 baseActivity = ComponentName.readFromParcel(source); 1728 topActivity = ComponentName.readFromParcel(source); 1729 numActivities = source.readInt(); 1730 bounds = source.readInt() > 0 ? 1731 Rect.CREATOR.createFromParcel(source) : null; 1732 supportsSplitScreenMultiWindow = source.readInt() == 1; 1733 resizeMode = source.readInt(); 1734 } 1735 1736 public static final Creator<RecentTaskInfo> CREATOR 1737 = new Creator<RecentTaskInfo>() { 1738 public RecentTaskInfo createFromParcel(Parcel source) { 1739 return new RecentTaskInfo(source); 1740 } 1741 public RecentTaskInfo[] newArray(int size) { 1742 return new RecentTaskInfo[size]; 1743 } 1744 }; 1745 RecentTaskInfo(Parcel source)1746 private RecentTaskInfo(Parcel source) { 1747 readFromParcel(source); 1748 } 1749 } 1750 1751 /** 1752 * Flag for use with {@link #getRecentTasks}: return all tasks, even those 1753 * that have set their 1754 * {@link android.content.Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} flag. 1755 */ 1756 public static final int RECENT_WITH_EXCLUDED = 0x0001; 1757 1758 /** 1759 * Provides a list that does not contain any 1760 * recent tasks that currently are not available to the user. 1761 */ 1762 public static final int RECENT_IGNORE_UNAVAILABLE = 0x0002; 1763 1764 /** 1765 * Provides a list that contains recent tasks for all 1766 * profiles of a user. 1767 * @hide 1768 */ 1769 public static final int RECENT_INCLUDE_PROFILES = 0x0004; 1770 1771 /** 1772 * Ignores all tasks that are on the home stack. 1773 * @hide 1774 */ 1775 public static final int RECENT_IGNORE_HOME_AND_RECENTS_STACK_TASKS = 0x0008; 1776 1777 /** 1778 * Ignores the top task in the docked stack. 1779 * @hide 1780 */ 1781 public static final int RECENT_INGORE_DOCKED_STACK_TOP_TASK = 0x0010; 1782 1783 /** 1784 * Ignores all tasks that are on the pinned stack. 1785 * @hide 1786 */ 1787 public static final int RECENT_INGORE_PINNED_STACK_TASKS = 0x0020; 1788 1789 /** 1790 * <p></p>Return a list of the tasks that the user has recently launched, with 1791 * the most recent being first and older ones after in order. 1792 * 1793 * <p><b>Note: this method is only intended for debugging and presenting 1794 * task management user interfaces</b>. This should never be used for 1795 * core logic in an application, such as deciding between different 1796 * behaviors based on the information found here. Such uses are 1797 * <em>not</em> supported, and will likely break in the future. For 1798 * example, if multiple applications can be actively running at the 1799 * same time, assumptions made about the meaning of the data here for 1800 * purposes of control flow will be incorrect.</p> 1801 * 1802 * @deprecated As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method is 1803 * no longer available to third party applications: the introduction of 1804 * document-centric recents means 1805 * it can leak personal information to the caller. For backwards compatibility, 1806 * it will still return a small subset of its data: at least the caller's 1807 * own tasks (though see {@link #getAppTasks()} for the correct supported 1808 * way to retrieve that information), and possibly some other tasks 1809 * such as home that are known to not be sensitive. 1810 * 1811 * @param maxNum The maximum number of entries to return in the list. The 1812 * actual number returned may be smaller, depending on how many tasks the 1813 * user has started and the maximum number the system can remember. 1814 * @param flags Information about what to return. May be any combination 1815 * of {@link #RECENT_WITH_EXCLUDED} and {@link #RECENT_IGNORE_UNAVAILABLE}. 1816 * 1817 * @return Returns a list of RecentTaskInfo records describing each of 1818 * the recent tasks. 1819 */ 1820 @Deprecated getRecentTasks(int maxNum, int flags)1821 public List<RecentTaskInfo> getRecentTasks(int maxNum, int flags) 1822 throws SecurityException { 1823 try { 1824 return getService().getRecentTasks(maxNum, 1825 flags, UserHandle.myUserId()).getList(); 1826 } catch (RemoteException e) { 1827 throw e.rethrowFromSystemServer(); 1828 } 1829 } 1830 1831 /** 1832 * Same as {@link #getRecentTasks(int, int)} but returns the recent tasks for a 1833 * specific user. It requires holding 1834 * the {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission. 1835 * @param maxNum The maximum number of entries to return in the list. The 1836 * actual number returned may be smaller, depending on how many tasks the 1837 * user has started and the maximum number the system can remember. 1838 * @param flags Information about what to return. May be any combination 1839 * of {@link #RECENT_WITH_EXCLUDED} and {@link #RECENT_IGNORE_UNAVAILABLE}. 1840 * 1841 * @return Returns a list of RecentTaskInfo records describing each of 1842 * the recent tasks. Most recently activated tasks go first. 1843 * 1844 * @hide 1845 */ getRecentTasksForUser(int maxNum, int flags, int userId)1846 public List<RecentTaskInfo> getRecentTasksForUser(int maxNum, int flags, int userId) 1847 throws SecurityException { 1848 try { 1849 return getService().getRecentTasks(maxNum, 1850 flags, userId).getList(); 1851 } catch (RemoteException e) { 1852 throw e.rethrowFromSystemServer(); 1853 } 1854 } 1855 1856 /** 1857 * Information you can retrieve about a particular task that is currently 1858 * "running" in the system. Note that a running task does not mean the 1859 * given task actually has a process it is actively running in; it simply 1860 * means that the user has gone to it and never closed it, but currently 1861 * the system may have killed its process and is only holding on to its 1862 * last state in order to restart it when the user returns. 1863 */ 1864 public static class RunningTaskInfo implements Parcelable { 1865 /** 1866 * A unique identifier for this task. 1867 */ 1868 public int id; 1869 1870 /** 1871 * The stack that currently contains this task. 1872 * @hide 1873 */ 1874 public int stackId; 1875 1876 /** 1877 * The component launched as the first activity in the task. This can 1878 * be considered the "application" of this task. 1879 */ 1880 public ComponentName baseActivity; 1881 1882 /** 1883 * The activity component at the top of the history stack of the task. 1884 * This is what the user is currently doing. 1885 */ 1886 public ComponentName topActivity; 1887 1888 /** 1889 * Thumbnail representation of the task's current state. Currently 1890 * always null. 1891 */ 1892 public Bitmap thumbnail; 1893 1894 /** 1895 * Description of the task's current state. 1896 */ 1897 public CharSequence description; 1898 1899 /** 1900 * Number of activities in this task. 1901 */ 1902 public int numActivities; 1903 1904 /** 1905 * Number of activities that are currently running (not stopped 1906 * and persisted) in this task. 1907 */ 1908 public int numRunning; 1909 1910 /** 1911 * Last time task was run. For sorting. 1912 * @hide 1913 */ 1914 public long lastActiveTime; 1915 1916 /** 1917 * True if the task can go in the docked stack. 1918 * @hide 1919 */ 1920 public boolean supportsSplitScreenMultiWindow; 1921 1922 /** 1923 * The resize mode of the task. See {@link ActivityInfo#resizeMode}. 1924 * @hide 1925 */ 1926 public int resizeMode; 1927 RunningTaskInfo()1928 public RunningTaskInfo() { 1929 } 1930 describeContents()1931 public int describeContents() { 1932 return 0; 1933 } 1934 writeToParcel(Parcel dest, int flags)1935 public void writeToParcel(Parcel dest, int flags) { 1936 dest.writeInt(id); 1937 dest.writeInt(stackId); 1938 ComponentName.writeToParcel(baseActivity, dest); 1939 ComponentName.writeToParcel(topActivity, dest); 1940 if (thumbnail != null) { 1941 dest.writeInt(1); 1942 thumbnail.writeToParcel(dest, 0); 1943 } else { 1944 dest.writeInt(0); 1945 } 1946 TextUtils.writeToParcel(description, dest, 1947 Parcelable.PARCELABLE_WRITE_RETURN_VALUE); 1948 dest.writeInt(numActivities); 1949 dest.writeInt(numRunning); 1950 dest.writeInt(supportsSplitScreenMultiWindow ? 1 : 0); 1951 dest.writeInt(resizeMode); 1952 } 1953 readFromParcel(Parcel source)1954 public void readFromParcel(Parcel source) { 1955 id = source.readInt(); 1956 stackId = source.readInt(); 1957 baseActivity = ComponentName.readFromParcel(source); 1958 topActivity = ComponentName.readFromParcel(source); 1959 if (source.readInt() != 0) { 1960 thumbnail = Bitmap.CREATOR.createFromParcel(source); 1961 } else { 1962 thumbnail = null; 1963 } 1964 description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); 1965 numActivities = source.readInt(); 1966 numRunning = source.readInt(); 1967 supportsSplitScreenMultiWindow = source.readInt() != 0; 1968 resizeMode = source.readInt(); 1969 } 1970 1971 public static final Creator<RunningTaskInfo> CREATOR = new Creator<RunningTaskInfo>() { 1972 public RunningTaskInfo createFromParcel(Parcel source) { 1973 return new RunningTaskInfo(source); 1974 } 1975 public RunningTaskInfo[] newArray(int size) { 1976 return new RunningTaskInfo[size]; 1977 } 1978 }; 1979 RunningTaskInfo(Parcel source)1980 private RunningTaskInfo(Parcel source) { 1981 readFromParcel(source); 1982 } 1983 } 1984 1985 /** 1986 * Get the list of tasks associated with the calling application. 1987 * 1988 * @return The list of tasks associated with the application making this call. 1989 * @throws SecurityException 1990 */ getAppTasks()1991 public List<ActivityManager.AppTask> getAppTasks() { 1992 ArrayList<AppTask> tasks = new ArrayList<AppTask>(); 1993 List<IBinder> appTasks; 1994 try { 1995 appTasks = getService().getAppTasks(mContext.getPackageName()); 1996 } catch (RemoteException e) { 1997 throw e.rethrowFromSystemServer(); 1998 } 1999 int numAppTasks = appTasks.size(); 2000 for (int i = 0; i < numAppTasks; i++) { 2001 tasks.add(new AppTask(IAppTask.Stub.asInterface(appTasks.get(i)))); 2002 } 2003 return tasks; 2004 } 2005 2006 /** 2007 * Return the current design dimensions for {@link AppTask} thumbnails, for use 2008 * with {@link #addAppTask}. 2009 */ getAppTaskThumbnailSize()2010 public Size getAppTaskThumbnailSize() { 2011 synchronized (this) { 2012 ensureAppTaskThumbnailSizeLocked(); 2013 return new Size(mAppTaskThumbnailSize.x, mAppTaskThumbnailSize.y); 2014 } 2015 } 2016 ensureAppTaskThumbnailSizeLocked()2017 private void ensureAppTaskThumbnailSizeLocked() { 2018 if (mAppTaskThumbnailSize == null) { 2019 try { 2020 mAppTaskThumbnailSize = getService().getAppTaskThumbnailSize(); 2021 } catch (RemoteException e) { 2022 throw e.rethrowFromSystemServer(); 2023 } 2024 } 2025 } 2026 2027 /** 2028 * Add a new {@link AppTask} for the calling application. This will create a new 2029 * recents entry that is added to the <b>end</b> of all existing recents. 2030 * 2031 * @param activity The activity that is adding the entry. This is used to help determine 2032 * the context that the new recents entry will be in. 2033 * @param intent The Intent that describes the recents entry. This is the same Intent that 2034 * you would have used to launch the activity for it. In generally you will want to set 2035 * both {@link Intent#FLAG_ACTIVITY_NEW_DOCUMENT} and 2036 * {@link Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS}; the latter is required since this recents 2037 * entry will exist without an activity, so it doesn't make sense to not retain it when 2038 * its activity disappears. The given Intent here also must have an explicit ComponentName 2039 * set on it. 2040 * @param description Optional additional description information. 2041 * @param thumbnail Thumbnail to use for the recents entry. Should be the size given by 2042 * {@link #getAppTaskThumbnailSize()}. If the bitmap is not that exact size, it will be 2043 * recreated in your process, probably in a way you don't like, before the recents entry 2044 * is added. 2045 * 2046 * @return Returns the task id of the newly added app task, or -1 if the add failed. The 2047 * most likely cause of failure is that there is no more room for more tasks for your app. 2048 */ addAppTask(@onNull Activity activity, @NonNull Intent intent, @Nullable TaskDescription description, @NonNull Bitmap thumbnail)2049 public int addAppTask(@NonNull Activity activity, @NonNull Intent intent, 2050 @Nullable TaskDescription description, @NonNull Bitmap thumbnail) { 2051 Point size; 2052 synchronized (this) { 2053 ensureAppTaskThumbnailSizeLocked(); 2054 size = mAppTaskThumbnailSize; 2055 } 2056 final int tw = thumbnail.getWidth(); 2057 final int th = thumbnail.getHeight(); 2058 if (tw != size.x || th != size.y) { 2059 Bitmap bm = Bitmap.createBitmap(size.x, size.y, thumbnail.getConfig()); 2060 2061 // Use ScaleType.CENTER_CROP, except we leave the top edge at the top. 2062 float scale; 2063 float dx = 0, dy = 0; 2064 if (tw * size.x > size.y * th) { 2065 scale = (float) size.x / (float) th; 2066 dx = (size.y - tw * scale) * 0.5f; 2067 } else { 2068 scale = (float) size.y / (float) tw; 2069 dy = (size.x - th * scale) * 0.5f; 2070 } 2071 Matrix matrix = new Matrix(); 2072 matrix.setScale(scale, scale); 2073 matrix.postTranslate((int) (dx + 0.5f), 0); 2074 2075 Canvas canvas = new Canvas(bm); 2076 canvas.drawBitmap(thumbnail, matrix, null); 2077 canvas.setBitmap(null); 2078 2079 thumbnail = bm; 2080 } 2081 if (description == null) { 2082 description = new TaskDescription(); 2083 } 2084 try { 2085 return getService().addAppTask(activity.getActivityToken(), 2086 intent, description, thumbnail); 2087 } catch (RemoteException e) { 2088 throw e.rethrowFromSystemServer(); 2089 } 2090 } 2091 2092 /** 2093 * Return a list of the tasks that are currently running, with 2094 * the most recent being first and older ones after in order. Note that 2095 * "running" does not mean any of the task's code is currently loaded or 2096 * activity -- the task may have been frozen by the system, so that it 2097 * can be restarted in its previous state when next brought to the 2098 * foreground. 2099 * 2100 * <p><b>Note: this method is only intended for debugging and presenting 2101 * task management user interfaces</b>. This should never be used for 2102 * core logic in an application, such as deciding between different 2103 * behaviors based on the information found here. Such uses are 2104 * <em>not</em> supported, and will likely break in the future. For 2105 * example, if multiple applications can be actively running at the 2106 * same time, assumptions made about the meaning of the data here for 2107 * purposes of control flow will be incorrect.</p> 2108 * 2109 * @deprecated As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method 2110 * is no longer available to third party 2111 * applications: the introduction of document-centric recents means 2112 * it can leak person information to the caller. For backwards compatibility, 2113 * it will still retu rn a small subset of its data: at least the caller's 2114 * own tasks, and possibly some other tasks 2115 * such as home that are known to not be sensitive. 2116 * 2117 * @param maxNum The maximum number of entries to return in the list. The 2118 * actual number returned may be smaller, depending on how many tasks the 2119 * user has started. 2120 * 2121 * @return Returns a list of RunningTaskInfo records describing each of 2122 * the running tasks. 2123 */ 2124 @Deprecated getRunningTasks(int maxNum)2125 public List<RunningTaskInfo> getRunningTasks(int maxNum) 2126 throws SecurityException { 2127 try { 2128 return getService().getTasks(maxNum, 0); 2129 } catch (RemoteException e) { 2130 throw e.rethrowFromSystemServer(); 2131 } 2132 } 2133 2134 /** 2135 * Completely remove the given task. 2136 * 2137 * @param taskId Identifier of the task to be removed. 2138 * @return Returns true if the given task was found and removed. 2139 * 2140 * @hide 2141 */ removeTask(int taskId)2142 public boolean removeTask(int taskId) throws SecurityException { 2143 try { 2144 return getService().removeTask(taskId); 2145 } catch (RemoteException e) { 2146 throw e.rethrowFromSystemServer(); 2147 } 2148 } 2149 2150 /** 2151 * Metadata related to the {@link TaskThumbnail}. 2152 * 2153 * @hide 2154 */ 2155 public static class TaskThumbnailInfo implements Parcelable { 2156 /** @hide */ 2157 public static final String ATTR_TASK_THUMBNAILINFO_PREFIX = "task_thumbnailinfo_"; 2158 private static final String ATTR_TASK_WIDTH = 2159 ATTR_TASK_THUMBNAILINFO_PREFIX + "task_width"; 2160 private static final String ATTR_TASK_HEIGHT = 2161 ATTR_TASK_THUMBNAILINFO_PREFIX + "task_height"; 2162 private static final String ATTR_SCREEN_ORIENTATION = 2163 ATTR_TASK_THUMBNAILINFO_PREFIX + "screen_orientation"; 2164 2165 public int taskWidth; 2166 public int taskHeight; 2167 public int screenOrientation = Configuration.ORIENTATION_UNDEFINED; 2168 TaskThumbnailInfo()2169 public TaskThumbnailInfo() { 2170 // Do nothing 2171 } 2172 TaskThumbnailInfo(Parcel source)2173 private TaskThumbnailInfo(Parcel source) { 2174 readFromParcel(source); 2175 } 2176 2177 /** 2178 * Resets this info state to the initial state. 2179 * @hide 2180 */ reset()2181 public void reset() { 2182 taskWidth = 0; 2183 taskHeight = 0; 2184 screenOrientation = Configuration.ORIENTATION_UNDEFINED; 2185 } 2186 2187 /** 2188 * Copies from another ThumbnailInfo. 2189 */ copyFrom(TaskThumbnailInfo o)2190 public void copyFrom(TaskThumbnailInfo o) { 2191 taskWidth = o.taskWidth; 2192 taskHeight = o.taskHeight; 2193 screenOrientation = o.screenOrientation; 2194 } 2195 2196 /** @hide */ saveToXml(XmlSerializer out)2197 public void saveToXml(XmlSerializer out) throws IOException { 2198 out.attribute(null, ATTR_TASK_WIDTH, Integer.toString(taskWidth)); 2199 out.attribute(null, ATTR_TASK_HEIGHT, Integer.toString(taskHeight)); 2200 out.attribute(null, ATTR_SCREEN_ORIENTATION, Integer.toString(screenOrientation)); 2201 } 2202 2203 /** @hide */ restoreFromXml(String attrName, String attrValue)2204 public void restoreFromXml(String attrName, String attrValue) { 2205 if (ATTR_TASK_WIDTH.equals(attrName)) { 2206 taskWidth = Integer.parseInt(attrValue); 2207 } else if (ATTR_TASK_HEIGHT.equals(attrName)) { 2208 taskHeight = Integer.parseInt(attrValue); 2209 } else if (ATTR_SCREEN_ORIENTATION.equals(attrName)) { 2210 screenOrientation = Integer.parseInt(attrValue); 2211 } 2212 } 2213 describeContents()2214 public int describeContents() { 2215 return 0; 2216 } 2217 writeToParcel(Parcel dest, int flags)2218 public void writeToParcel(Parcel dest, int flags) { 2219 dest.writeInt(taskWidth); 2220 dest.writeInt(taskHeight); 2221 dest.writeInt(screenOrientation); 2222 } 2223 readFromParcel(Parcel source)2224 public void readFromParcel(Parcel source) { 2225 taskWidth = source.readInt(); 2226 taskHeight = source.readInt(); 2227 screenOrientation = source.readInt(); 2228 } 2229 2230 public static final Creator<TaskThumbnailInfo> CREATOR = new Creator<TaskThumbnailInfo>() { 2231 public TaskThumbnailInfo createFromParcel(Parcel source) { 2232 return new TaskThumbnailInfo(source); 2233 } 2234 public TaskThumbnailInfo[] newArray(int size) { 2235 return new TaskThumbnailInfo[size]; 2236 } 2237 }; 2238 } 2239 2240 /** @hide */ 2241 public static class TaskThumbnail implements Parcelable { 2242 public Bitmap mainThumbnail; 2243 public ParcelFileDescriptor thumbnailFileDescriptor; 2244 public TaskThumbnailInfo thumbnailInfo; 2245 TaskThumbnail()2246 public TaskThumbnail() { 2247 } 2248 TaskThumbnail(Parcel source)2249 private TaskThumbnail(Parcel source) { 2250 readFromParcel(source); 2251 } 2252 describeContents()2253 public int describeContents() { 2254 if (thumbnailFileDescriptor != null) { 2255 return thumbnailFileDescriptor.describeContents(); 2256 } 2257 return 0; 2258 } 2259 writeToParcel(Parcel dest, int flags)2260 public void writeToParcel(Parcel dest, int flags) { 2261 if (mainThumbnail != null) { 2262 dest.writeInt(1); 2263 mainThumbnail.writeToParcel(dest, flags); 2264 } else { 2265 dest.writeInt(0); 2266 } 2267 if (thumbnailFileDescriptor != null) { 2268 dest.writeInt(1); 2269 thumbnailFileDescriptor.writeToParcel(dest, flags); 2270 } else { 2271 dest.writeInt(0); 2272 } 2273 if (thumbnailInfo != null) { 2274 dest.writeInt(1); 2275 thumbnailInfo.writeToParcel(dest, flags); 2276 } else { 2277 dest.writeInt(0); 2278 } 2279 } 2280 readFromParcel(Parcel source)2281 public void readFromParcel(Parcel source) { 2282 if (source.readInt() != 0) { 2283 mainThumbnail = Bitmap.CREATOR.createFromParcel(source); 2284 } else { 2285 mainThumbnail = null; 2286 } 2287 if (source.readInt() != 0) { 2288 thumbnailFileDescriptor = ParcelFileDescriptor.CREATOR.createFromParcel(source); 2289 } else { 2290 thumbnailFileDescriptor = null; 2291 } 2292 if (source.readInt() != 0) { 2293 thumbnailInfo = TaskThumbnailInfo.CREATOR.createFromParcel(source); 2294 } else { 2295 thumbnailInfo = null; 2296 } 2297 } 2298 2299 public static final Creator<TaskThumbnail> CREATOR = new Creator<TaskThumbnail>() { 2300 public TaskThumbnail createFromParcel(Parcel source) { 2301 return new TaskThumbnail(source); 2302 } 2303 public TaskThumbnail[] newArray(int size) { 2304 return new TaskThumbnail[size]; 2305 } 2306 }; 2307 } 2308 2309 /** 2310 * Represents a task snapshot. 2311 * @hide 2312 */ 2313 public static class TaskSnapshot implements Parcelable { 2314 2315 private final GraphicBuffer mSnapshot; 2316 private final int mOrientation; 2317 private final Rect mContentInsets; 2318 private final boolean mReducedResolution; 2319 private final float mScale; 2320 TaskSnapshot(GraphicBuffer snapshot, int orientation, Rect contentInsets, boolean reducedResolution, float scale)2321 public TaskSnapshot(GraphicBuffer snapshot, int orientation, Rect contentInsets, 2322 boolean reducedResolution, float scale) { 2323 mSnapshot = snapshot; 2324 mOrientation = orientation; 2325 mContentInsets = new Rect(contentInsets); 2326 mReducedResolution = reducedResolution; 2327 mScale = scale; 2328 } 2329 TaskSnapshot(Parcel source)2330 private TaskSnapshot(Parcel source) { 2331 mSnapshot = source.readParcelable(null /* classLoader */); 2332 mOrientation = source.readInt(); 2333 mContentInsets = source.readParcelable(null /* classLoader */); 2334 mReducedResolution = source.readBoolean(); 2335 mScale = source.readFloat(); 2336 } 2337 2338 /** 2339 * @return The graphic buffer representing the screenshot. 2340 */ getSnapshot()2341 public GraphicBuffer getSnapshot() { 2342 return mSnapshot; 2343 } 2344 2345 /** 2346 * @return The screen orientation the screenshot was taken in. 2347 */ getOrientation()2348 public int getOrientation() { 2349 return mOrientation; 2350 } 2351 2352 /** 2353 * @return The system/content insets on the snapshot. These can be clipped off in order to 2354 * remove any areas behind system bars in the snapshot. 2355 */ getContentInsets()2356 public Rect getContentInsets() { 2357 return mContentInsets; 2358 } 2359 2360 /** 2361 * @return Whether this snapshot is a down-sampled version of the full resolution. 2362 */ isReducedResolution()2363 public boolean isReducedResolution() { 2364 return mReducedResolution; 2365 } 2366 2367 /** 2368 * @return The scale this snapshot was taken in. 2369 */ getScale()2370 public float getScale() { 2371 return mScale; 2372 } 2373 2374 @Override describeContents()2375 public int describeContents() { 2376 return 0; 2377 } 2378 2379 @Override writeToParcel(Parcel dest, int flags)2380 public void writeToParcel(Parcel dest, int flags) { 2381 dest.writeParcelable(mSnapshot, 0); 2382 dest.writeInt(mOrientation); 2383 dest.writeParcelable(mContentInsets, 0); 2384 dest.writeBoolean(mReducedResolution); 2385 dest.writeFloat(mScale); 2386 } 2387 2388 @Override toString()2389 public String toString() { 2390 return "TaskSnapshot{mSnapshot=" + mSnapshot + " mOrientation=" + mOrientation 2391 + " mContentInsets=" + mContentInsets.toShortString() 2392 + " mReducedResolution=" + mReducedResolution + " mScale=" + mScale; 2393 } 2394 2395 public static final Creator<TaskSnapshot> CREATOR = new Creator<TaskSnapshot>() { 2396 public TaskSnapshot createFromParcel(Parcel source) { 2397 return new TaskSnapshot(source); 2398 } 2399 public TaskSnapshot[] newArray(int size) { 2400 return new TaskSnapshot[size]; 2401 } 2402 }; 2403 } 2404 2405 /** @hide */ getTaskThumbnail(int id)2406 public TaskThumbnail getTaskThumbnail(int id) throws SecurityException { 2407 try { 2408 return getService().getTaskThumbnail(id); 2409 } catch (RemoteException e) { 2410 throw e.rethrowFromSystemServer(); 2411 } 2412 } 2413 2414 /** @hide */ 2415 @IntDef(flag = true, prefix = { "MOVE_TASK_" }, value = { 2416 MOVE_TASK_WITH_HOME, 2417 MOVE_TASK_NO_USER_ACTION, 2418 }) 2419 @Retention(RetentionPolicy.SOURCE) 2420 public @interface MoveTaskFlags {} 2421 2422 /** 2423 * Flag for {@link #moveTaskToFront(int, int)}: also move the "home" 2424 * activity along with the task, so it is positioned immediately behind 2425 * the task. 2426 */ 2427 public static final int MOVE_TASK_WITH_HOME = 0x00000001; 2428 2429 /** 2430 * Flag for {@link #moveTaskToFront(int, int)}: don't count this as a 2431 * user-instigated action, so the current activity will not receive a 2432 * hint that the user is leaving. 2433 */ 2434 public static final int MOVE_TASK_NO_USER_ACTION = 0x00000002; 2435 2436 /** 2437 * Equivalent to calling {@link #moveTaskToFront(int, int, Bundle)} 2438 * with a null options argument. 2439 * 2440 * @param taskId The identifier of the task to be moved, as found in 2441 * {@link RunningTaskInfo} or {@link RecentTaskInfo}. 2442 * @param flags Additional operational flags. 2443 */ 2444 @RequiresPermission(android.Manifest.permission.REORDER_TASKS) moveTaskToFront(int taskId, @MoveTaskFlags int flags)2445 public void moveTaskToFront(int taskId, @MoveTaskFlags int flags) { 2446 moveTaskToFront(taskId, flags, null); 2447 } 2448 2449 /** 2450 * Ask that the task associated with a given task ID be moved to the 2451 * front of the stack, so it is now visible to the user. 2452 * 2453 * @param taskId The identifier of the task to be moved, as found in 2454 * {@link RunningTaskInfo} or {@link RecentTaskInfo}. 2455 * @param flags Additional operational flags. 2456 * @param options Additional options for the operation, either null or 2457 * as per {@link Context#startActivity(Intent, android.os.Bundle) 2458 * Context.startActivity(Intent, Bundle)}. 2459 */ 2460 @RequiresPermission(android.Manifest.permission.REORDER_TASKS) moveTaskToFront(int taskId, @MoveTaskFlags int flags, Bundle options)2461 public void moveTaskToFront(int taskId, @MoveTaskFlags int flags, Bundle options) { 2462 try { 2463 getService().moveTaskToFront(taskId, flags, options); 2464 } catch (RemoteException e) { 2465 throw e.rethrowFromSystemServer(); 2466 } 2467 } 2468 2469 /** 2470 * Information you can retrieve about a particular Service that is 2471 * currently running in the system. 2472 */ 2473 public static class RunningServiceInfo implements Parcelable { 2474 /** 2475 * The service component. 2476 */ 2477 public ComponentName service; 2478 2479 /** 2480 * If non-zero, this is the process the service is running in. 2481 */ 2482 public int pid; 2483 2484 /** 2485 * The UID that owns this service. 2486 */ 2487 public int uid; 2488 2489 /** 2490 * The name of the process this service runs in. 2491 */ 2492 public String process; 2493 2494 /** 2495 * Set to true if the service has asked to run as a foreground process. 2496 */ 2497 public boolean foreground; 2498 2499 /** 2500 * The time when the service was first made active, either by someone 2501 * starting or binding to it. This 2502 * is in units of {@link android.os.SystemClock#elapsedRealtime()}. 2503 */ 2504 public long activeSince; 2505 2506 /** 2507 * Set to true if this service has been explicitly started. 2508 */ 2509 public boolean started; 2510 2511 /** 2512 * Number of clients connected to the service. 2513 */ 2514 public int clientCount; 2515 2516 /** 2517 * Number of times the service's process has crashed while the service 2518 * is running. 2519 */ 2520 public int crashCount; 2521 2522 /** 2523 * The time when there was last activity in the service (either 2524 * explicit requests to start it or clients binding to it). This 2525 * is in units of {@link android.os.SystemClock#uptimeMillis()}. 2526 */ 2527 public long lastActivityTime; 2528 2529 /** 2530 * If non-zero, this service is not currently running, but scheduled to 2531 * restart at the given time. 2532 */ 2533 public long restarting; 2534 2535 /** 2536 * Bit for {@link #flags}: set if this service has been 2537 * explicitly started. 2538 */ 2539 public static final int FLAG_STARTED = 1<<0; 2540 2541 /** 2542 * Bit for {@link #flags}: set if the service has asked to 2543 * run as a foreground process. 2544 */ 2545 public static final int FLAG_FOREGROUND = 1<<1; 2546 2547 /** 2548 * Bit for {@link #flags}: set if the service is running in a 2549 * core system process. 2550 */ 2551 public static final int FLAG_SYSTEM_PROCESS = 1<<2; 2552 2553 /** 2554 * Bit for {@link #flags}: set if the service is running in a 2555 * persistent process. 2556 */ 2557 public static final int FLAG_PERSISTENT_PROCESS = 1<<3; 2558 2559 /** 2560 * Running flags. 2561 */ 2562 public int flags; 2563 2564 /** 2565 * For special services that are bound to by system code, this is 2566 * the package that holds the binding. 2567 */ 2568 public String clientPackage; 2569 2570 /** 2571 * For special services that are bound to by system code, this is 2572 * a string resource providing a user-visible label for who the 2573 * client is. 2574 */ 2575 public int clientLabel; 2576 RunningServiceInfo()2577 public RunningServiceInfo() { 2578 } 2579 describeContents()2580 public int describeContents() { 2581 return 0; 2582 } 2583 writeToParcel(Parcel dest, int flags)2584 public void writeToParcel(Parcel dest, int flags) { 2585 ComponentName.writeToParcel(service, dest); 2586 dest.writeInt(pid); 2587 dest.writeInt(uid); 2588 dest.writeString(process); 2589 dest.writeInt(foreground ? 1 : 0); 2590 dest.writeLong(activeSince); 2591 dest.writeInt(started ? 1 : 0); 2592 dest.writeInt(clientCount); 2593 dest.writeInt(crashCount); 2594 dest.writeLong(lastActivityTime); 2595 dest.writeLong(restarting); 2596 dest.writeInt(this.flags); 2597 dest.writeString(clientPackage); 2598 dest.writeInt(clientLabel); 2599 } 2600 readFromParcel(Parcel source)2601 public void readFromParcel(Parcel source) { 2602 service = ComponentName.readFromParcel(source); 2603 pid = source.readInt(); 2604 uid = source.readInt(); 2605 process = source.readString(); 2606 foreground = source.readInt() != 0; 2607 activeSince = source.readLong(); 2608 started = source.readInt() != 0; 2609 clientCount = source.readInt(); 2610 crashCount = source.readInt(); 2611 lastActivityTime = source.readLong(); 2612 restarting = source.readLong(); 2613 flags = source.readInt(); 2614 clientPackage = source.readString(); 2615 clientLabel = source.readInt(); 2616 } 2617 2618 public static final Creator<RunningServiceInfo> CREATOR = new Creator<RunningServiceInfo>() { 2619 public RunningServiceInfo createFromParcel(Parcel source) { 2620 return new RunningServiceInfo(source); 2621 } 2622 public RunningServiceInfo[] newArray(int size) { 2623 return new RunningServiceInfo[size]; 2624 } 2625 }; 2626 RunningServiceInfo(Parcel source)2627 private RunningServiceInfo(Parcel source) { 2628 readFromParcel(source); 2629 } 2630 } 2631 2632 /** 2633 * Return a list of the services that are currently running. 2634 * 2635 * <p><b>Note: this method is only intended for debugging or implementing 2636 * service management type user interfaces.</b></p> 2637 * 2638 * @deprecated As of {@link android.os.Build.VERSION_CODES#O}, this method 2639 * is no longer available to third party applications. For backwards compatibility, 2640 * it will still return the caller's own services. 2641 * 2642 * @param maxNum The maximum number of entries to return in the list. The 2643 * actual number returned may be smaller, depending on how many services 2644 * are running. 2645 * 2646 * @return Returns a list of RunningServiceInfo records describing each of 2647 * the running tasks. 2648 */ 2649 @Deprecated getRunningServices(int maxNum)2650 public List<RunningServiceInfo> getRunningServices(int maxNum) 2651 throws SecurityException { 2652 try { 2653 return getService() 2654 .getServices(maxNum, 0); 2655 } catch (RemoteException e) { 2656 throw e.rethrowFromSystemServer(); 2657 } 2658 } 2659 2660 /** 2661 * Returns a PendingIntent you can start to show a control panel for the 2662 * given running service. If the service does not have a control panel, 2663 * null is returned. 2664 */ getRunningServiceControlPanel(ComponentName service)2665 public PendingIntent getRunningServiceControlPanel(ComponentName service) 2666 throws SecurityException { 2667 try { 2668 return getService() 2669 .getRunningServiceControlPanel(service); 2670 } catch (RemoteException e) { 2671 throw e.rethrowFromSystemServer(); 2672 } 2673 } 2674 2675 /** 2676 * Information you can retrieve about the available memory through 2677 * {@link ActivityManager#getMemoryInfo}. 2678 */ 2679 public static class MemoryInfo implements Parcelable { 2680 /** 2681 * The available memory on the system. This number should not 2682 * be considered absolute: due to the nature of the kernel, a significant 2683 * portion of this memory is actually in use and needed for the overall 2684 * system to run well. 2685 */ 2686 public long availMem; 2687 2688 /** 2689 * The total memory accessible by the kernel. This is basically the 2690 * RAM size of the device, not including below-kernel fixed allocations 2691 * like DMA buffers, RAM for the baseband CPU, etc. 2692 */ 2693 public long totalMem; 2694 2695 /** 2696 * The threshold of {@link #availMem} at which we consider memory to be 2697 * low and start killing background services and other non-extraneous 2698 * processes. 2699 */ 2700 public long threshold; 2701 2702 /** 2703 * Set to true if the system considers itself to currently be in a low 2704 * memory situation. 2705 */ 2706 public boolean lowMemory; 2707 2708 /** @hide */ 2709 public long hiddenAppThreshold; 2710 /** @hide */ 2711 public long secondaryServerThreshold; 2712 /** @hide */ 2713 public long visibleAppThreshold; 2714 /** @hide */ 2715 public long foregroundAppThreshold; 2716 MemoryInfo()2717 public MemoryInfo() { 2718 } 2719 describeContents()2720 public int describeContents() { 2721 return 0; 2722 } 2723 writeToParcel(Parcel dest, int flags)2724 public void writeToParcel(Parcel dest, int flags) { 2725 dest.writeLong(availMem); 2726 dest.writeLong(totalMem); 2727 dest.writeLong(threshold); 2728 dest.writeInt(lowMemory ? 1 : 0); 2729 dest.writeLong(hiddenAppThreshold); 2730 dest.writeLong(secondaryServerThreshold); 2731 dest.writeLong(visibleAppThreshold); 2732 dest.writeLong(foregroundAppThreshold); 2733 } 2734 readFromParcel(Parcel source)2735 public void readFromParcel(Parcel source) { 2736 availMem = source.readLong(); 2737 totalMem = source.readLong(); 2738 threshold = source.readLong(); 2739 lowMemory = source.readInt() != 0; 2740 hiddenAppThreshold = source.readLong(); 2741 secondaryServerThreshold = source.readLong(); 2742 visibleAppThreshold = source.readLong(); 2743 foregroundAppThreshold = source.readLong(); 2744 } 2745 2746 public static final Creator<MemoryInfo> CREATOR 2747 = new Creator<MemoryInfo>() { 2748 public MemoryInfo createFromParcel(Parcel source) { 2749 return new MemoryInfo(source); 2750 } 2751 public MemoryInfo[] newArray(int size) { 2752 return new MemoryInfo[size]; 2753 } 2754 }; 2755 MemoryInfo(Parcel source)2756 private MemoryInfo(Parcel source) { 2757 readFromParcel(source); 2758 } 2759 } 2760 2761 /** 2762 * Return general information about the memory state of the system. This 2763 * can be used to help decide how to manage your own memory, though note 2764 * that polling is not recommended and 2765 * {@link android.content.ComponentCallbacks2#onTrimMemory(int) 2766 * ComponentCallbacks2.onTrimMemory(int)} is the preferred way to do this. 2767 * Also see {@link #getMyMemoryState} for how to retrieve the current trim 2768 * level of your process as needed, which gives a better hint for how to 2769 * manage its memory. 2770 */ getMemoryInfo(MemoryInfo outInfo)2771 public void getMemoryInfo(MemoryInfo outInfo) { 2772 try { 2773 getService().getMemoryInfo(outInfo); 2774 } catch (RemoteException e) { 2775 throw e.rethrowFromSystemServer(); 2776 } 2777 } 2778 2779 /** 2780 * Information you can retrieve about an ActivityStack in the system. 2781 * @hide 2782 */ 2783 public static class StackInfo implements Parcelable { 2784 public int stackId; 2785 public Rect bounds = new Rect(); 2786 public int[] taskIds; 2787 public String[] taskNames; 2788 public Rect[] taskBounds; 2789 public int[] taskUserIds; 2790 public ComponentName topActivity; 2791 public int displayId; 2792 public int userId; 2793 public boolean visible; 2794 // Index of the stack in the display's stack list, can be used for comparison of stack order 2795 public int position; 2796 2797 @Override describeContents()2798 public int describeContents() { 2799 return 0; 2800 } 2801 2802 @Override writeToParcel(Parcel dest, int flags)2803 public void writeToParcel(Parcel dest, int flags) { 2804 dest.writeInt(stackId); 2805 dest.writeInt(bounds.left); 2806 dest.writeInt(bounds.top); 2807 dest.writeInt(bounds.right); 2808 dest.writeInt(bounds.bottom); 2809 dest.writeIntArray(taskIds); 2810 dest.writeStringArray(taskNames); 2811 final int boundsCount = taskBounds == null ? 0 : taskBounds.length; 2812 dest.writeInt(boundsCount); 2813 for (int i = 0; i < boundsCount; i++) { 2814 dest.writeInt(taskBounds[i].left); 2815 dest.writeInt(taskBounds[i].top); 2816 dest.writeInt(taskBounds[i].right); 2817 dest.writeInt(taskBounds[i].bottom); 2818 } 2819 dest.writeIntArray(taskUserIds); 2820 dest.writeInt(displayId); 2821 dest.writeInt(userId); 2822 dest.writeInt(visible ? 1 : 0); 2823 dest.writeInt(position); 2824 if (topActivity != null) { 2825 dest.writeInt(1); 2826 topActivity.writeToParcel(dest, 0); 2827 } else { 2828 dest.writeInt(0); 2829 } 2830 } 2831 readFromParcel(Parcel source)2832 public void readFromParcel(Parcel source) { 2833 stackId = source.readInt(); 2834 bounds = new Rect( 2835 source.readInt(), source.readInt(), source.readInt(), source.readInt()); 2836 taskIds = source.createIntArray(); 2837 taskNames = source.createStringArray(); 2838 final int boundsCount = source.readInt(); 2839 if (boundsCount > 0) { 2840 taskBounds = new Rect[boundsCount]; 2841 for (int i = 0; i < boundsCount; i++) { 2842 taskBounds[i] = new Rect(); 2843 taskBounds[i].set( 2844 source.readInt(), source.readInt(), source.readInt(), source.readInt()); 2845 } 2846 } else { 2847 taskBounds = null; 2848 } 2849 taskUserIds = source.createIntArray(); 2850 displayId = source.readInt(); 2851 userId = source.readInt(); 2852 visible = source.readInt() > 0; 2853 position = source.readInt(); 2854 if (source.readInt() > 0) { 2855 topActivity = ComponentName.readFromParcel(source); 2856 } 2857 } 2858 2859 public static final Creator<StackInfo> CREATOR = new Creator<StackInfo>() { 2860 @Override 2861 public StackInfo createFromParcel(Parcel source) { 2862 return new StackInfo(source); 2863 } 2864 @Override 2865 public StackInfo[] newArray(int size) { 2866 return new StackInfo[size]; 2867 } 2868 }; 2869 StackInfo()2870 public StackInfo() { 2871 } 2872 StackInfo(Parcel source)2873 private StackInfo(Parcel source) { 2874 readFromParcel(source); 2875 } 2876 toString(String prefix)2877 public String toString(String prefix) { 2878 StringBuilder sb = new StringBuilder(256); 2879 sb.append(prefix); sb.append("Stack id="); sb.append(stackId); 2880 sb.append(" bounds="); sb.append(bounds.toShortString()); 2881 sb.append(" displayId="); sb.append(displayId); 2882 sb.append(" userId="); sb.append(userId); 2883 sb.append("\n"); 2884 prefix = prefix + " "; 2885 for (int i = 0; i < taskIds.length; ++i) { 2886 sb.append(prefix); sb.append("taskId="); sb.append(taskIds[i]); 2887 sb.append(": "); sb.append(taskNames[i]); 2888 if (taskBounds != null) { 2889 sb.append(" bounds="); sb.append(taskBounds[i].toShortString()); 2890 } 2891 sb.append(" userId=").append(taskUserIds[i]); 2892 sb.append(" visible=").append(visible); 2893 if (topActivity != null) { 2894 sb.append(" topActivity=").append(topActivity); 2895 } 2896 sb.append("\n"); 2897 } 2898 return sb.toString(); 2899 } 2900 2901 @Override toString()2902 public String toString() { 2903 return toString(""); 2904 } 2905 } 2906 2907 /** 2908 * @hide 2909 */ 2910 @RequiresPermission(anyOf={Manifest.permission.CLEAR_APP_USER_DATA, 2911 Manifest.permission.ACCESS_INSTANT_APPS}) clearApplicationUserData(String packageName, IPackageDataObserver observer)2912 public boolean clearApplicationUserData(String packageName, IPackageDataObserver observer) { 2913 try { 2914 return getService().clearApplicationUserData(packageName, 2915 observer, UserHandle.myUserId()); 2916 } catch (RemoteException e) { 2917 throw e.rethrowFromSystemServer(); 2918 } 2919 } 2920 2921 /** 2922 * Permits an application to erase its own data from disk. This is equivalent to 2923 * the user choosing to clear the app's data from within the device settings UI. It 2924 * erases all dynamic data associated with the app -- its private data and data in its 2925 * private area on external storage -- but does not remove the installed application 2926 * itself, nor any OBB files. 2927 * 2928 * @return {@code true} if the application successfully requested that the application's 2929 * data be erased; {@code false} otherwise. 2930 */ clearApplicationUserData()2931 public boolean clearApplicationUserData() { 2932 return clearApplicationUserData(mContext.getPackageName(), null); 2933 } 2934 2935 2936 /** 2937 * Permits an application to get the persistent URI permissions granted to another. 2938 * 2939 * <p>Typically called by Settings. 2940 * 2941 * @param packageName application to look for the granted permissions 2942 * @return list of granted URI permissions 2943 * 2944 * @hide 2945 */ getGrantedUriPermissions(String packageName)2946 public ParceledListSlice<UriPermission> getGrantedUriPermissions(String packageName) { 2947 try { 2948 return getService().getGrantedUriPermissions(packageName, 2949 UserHandle.myUserId()); 2950 } catch (RemoteException e) { 2951 throw e.rethrowFromSystemServer(); 2952 } 2953 } 2954 2955 /** 2956 * Permits an application to clear the persistent URI permissions granted to another. 2957 * 2958 * <p>Typically called by Settings. 2959 * 2960 * @param packageName application to clear its granted permissions 2961 * 2962 * @hide 2963 */ clearGrantedUriPermissions(String packageName)2964 public void clearGrantedUriPermissions(String packageName) { 2965 try { 2966 getService().clearGrantedUriPermissions(packageName, 2967 UserHandle.myUserId()); 2968 } catch (RemoteException e) { 2969 throw e.rethrowFromSystemServer(); 2970 } 2971 } 2972 2973 /** 2974 * Information you can retrieve about any processes that are in an error condition. 2975 */ 2976 public static class ProcessErrorStateInfo implements Parcelable { 2977 /** 2978 * Condition codes 2979 */ 2980 public static final int NO_ERROR = 0; 2981 public static final int CRASHED = 1; 2982 public static final int NOT_RESPONDING = 2; 2983 2984 /** 2985 * The condition that the process is in. 2986 */ 2987 public int condition; 2988 2989 /** 2990 * The process name in which the crash or error occurred. 2991 */ 2992 public String processName; 2993 2994 /** 2995 * The pid of this process; 0 if none 2996 */ 2997 public int pid; 2998 2999 /** 3000 * The kernel user-ID that has been assigned to this process; 3001 * currently this is not a unique ID (multiple applications can have 3002 * the same uid). 3003 */ 3004 public int uid; 3005 3006 /** 3007 * The activity name associated with the error, if known. May be null. 3008 */ 3009 public String tag; 3010 3011 /** 3012 * A short message describing the error condition. 3013 */ 3014 public String shortMsg; 3015 3016 /** 3017 * A long message describing the error condition. 3018 */ 3019 public String longMsg; 3020 3021 /** 3022 * The stack trace where the error originated. May be null. 3023 */ 3024 public String stackTrace; 3025 3026 /** 3027 * to be deprecated: This value will always be null. 3028 */ 3029 public byte[] crashData = null; 3030 ProcessErrorStateInfo()3031 public ProcessErrorStateInfo() { 3032 } 3033 3034 @Override describeContents()3035 public int describeContents() { 3036 return 0; 3037 } 3038 3039 @Override writeToParcel(Parcel dest, int flags)3040 public void writeToParcel(Parcel dest, int flags) { 3041 dest.writeInt(condition); 3042 dest.writeString(processName); 3043 dest.writeInt(pid); 3044 dest.writeInt(uid); 3045 dest.writeString(tag); 3046 dest.writeString(shortMsg); 3047 dest.writeString(longMsg); 3048 dest.writeString(stackTrace); 3049 } 3050 readFromParcel(Parcel source)3051 public void readFromParcel(Parcel source) { 3052 condition = source.readInt(); 3053 processName = source.readString(); 3054 pid = source.readInt(); 3055 uid = source.readInt(); 3056 tag = source.readString(); 3057 shortMsg = source.readString(); 3058 longMsg = source.readString(); 3059 stackTrace = source.readString(); 3060 } 3061 3062 public static final Creator<ProcessErrorStateInfo> CREATOR = 3063 new Creator<ProcessErrorStateInfo>() { 3064 public ProcessErrorStateInfo createFromParcel(Parcel source) { 3065 return new ProcessErrorStateInfo(source); 3066 } 3067 public ProcessErrorStateInfo[] newArray(int size) { 3068 return new ProcessErrorStateInfo[size]; 3069 } 3070 }; 3071 ProcessErrorStateInfo(Parcel source)3072 private ProcessErrorStateInfo(Parcel source) { 3073 readFromParcel(source); 3074 } 3075 } 3076 3077 /** 3078 * Returns a list of any processes that are currently in an error condition. The result 3079 * will be null if all processes are running properly at this time. 3080 * 3081 * @return Returns a list of ProcessErrorStateInfo records, or null if there are no 3082 * current error conditions (it will not return an empty list). This list ordering is not 3083 * specified. 3084 */ getProcessesInErrorState()3085 public List<ProcessErrorStateInfo> getProcessesInErrorState() { 3086 try { 3087 return getService().getProcessesInErrorState(); 3088 } catch (RemoteException e) { 3089 throw e.rethrowFromSystemServer(); 3090 } 3091 } 3092 3093 /** 3094 * Information you can retrieve about a running process. 3095 */ 3096 public static class RunningAppProcessInfo implements Parcelable { 3097 /** 3098 * The name of the process that this object is associated with 3099 */ 3100 public String processName; 3101 3102 /** 3103 * The pid of this process; 0 if none 3104 */ 3105 public int pid; 3106 3107 /** 3108 * The user id of this process. 3109 */ 3110 public int uid; 3111 3112 /** 3113 * All packages that have been loaded into the process. 3114 */ 3115 public String pkgList[]; 3116 3117 /** 3118 * Constant for {@link #flags}: this is an app that is unable to 3119 * correctly save its state when going to the background, 3120 * so it can not be killed while in the background. 3121 * @hide 3122 */ 3123 public static final int FLAG_CANT_SAVE_STATE = 1<<0; 3124 3125 /** 3126 * Constant for {@link #flags}: this process is associated with a 3127 * persistent system app. 3128 * @hide 3129 */ 3130 public static final int FLAG_PERSISTENT = 1<<1; 3131 3132 /** 3133 * Constant for {@link #flags}: this process is associated with a 3134 * persistent system app. 3135 * @hide 3136 */ 3137 public static final int FLAG_HAS_ACTIVITIES = 1<<2; 3138 3139 /** 3140 * Flags of information. May be any of 3141 * {@link #FLAG_CANT_SAVE_STATE}. 3142 * @hide 3143 */ 3144 public int flags; 3145 3146 /** 3147 * Last memory trim level reported to the process: corresponds to 3148 * the values supplied to {@link android.content.ComponentCallbacks2#onTrimMemory(int) 3149 * ComponentCallbacks2.onTrimMemory(int)}. 3150 */ 3151 public int lastTrimLevel; 3152 3153 /** @hide */ 3154 @IntDef(prefix = { "IMPORTANCE_" }, value = { 3155 IMPORTANCE_FOREGROUND, 3156 IMPORTANCE_FOREGROUND_SERVICE, 3157 IMPORTANCE_TOP_SLEEPING, 3158 IMPORTANCE_VISIBLE, 3159 IMPORTANCE_PERCEPTIBLE, 3160 IMPORTANCE_CANT_SAVE_STATE, 3161 IMPORTANCE_SERVICE, 3162 IMPORTANCE_CACHED, 3163 IMPORTANCE_GONE, 3164 }) 3165 @Retention(RetentionPolicy.SOURCE) 3166 public @interface Importance {} 3167 3168 /** 3169 * Constant for {@link #importance}: This process is running the 3170 * foreground UI; that is, it is the thing currently at the top of the screen 3171 * that the user is interacting with. 3172 */ 3173 public static final int IMPORTANCE_FOREGROUND = 100; 3174 3175 /** 3176 * Constant for {@link #importance}: This process is running a foreground 3177 * service, for example to perform music playback even while the user is 3178 * not immediately in the app. This generally indicates that the process 3179 * is doing something the user actively cares about. 3180 */ 3181 public static final int IMPORTANCE_FOREGROUND_SERVICE = 125; 3182 3183 /** 3184 * Constant for {@link #importance}: This process is running the foreground 3185 * UI, but the device is asleep so it is not visible to the user. This means 3186 * the user is not really aware of the process, because they can not see or 3187 * interact with it, but it is quite important because it what they expect to 3188 * return to once unlocking the device. 3189 */ 3190 public static final int IMPORTANCE_TOP_SLEEPING = 150; 3191 3192 /** 3193 * Constant for {@link #importance}: This process is running something 3194 * that is actively visible to the user, though not in the immediate 3195 * foreground. This may be running a window that is behind the current 3196 * foreground (so paused and with its state saved, not interacting with 3197 * the user, but visible to them to some degree); it may also be running 3198 * other services under the system's control that it inconsiders important. 3199 */ 3200 public static final int IMPORTANCE_VISIBLE = 200; 3201 3202 /** 3203 * Constant for {@link #importance}: {@link #IMPORTANCE_PERCEPTIBLE} had this wrong value 3204 * before {@link Build.VERSION_CODES#O}. Since the {@link Build.VERSION_CODES#O} SDK, 3205 * the value of {@link #IMPORTANCE_PERCEPTIBLE} has been fixed. 3206 * 3207 * <p>The system will return this value instead of {@link #IMPORTANCE_PERCEPTIBLE} 3208 * on Android versions below {@link Build.VERSION_CODES#O}. 3209 * 3210 * <p>On Android version {@link Build.VERSION_CODES#O} and later, this value will still be 3211 * returned for apps with the target API level below {@link Build.VERSION_CODES#O}. 3212 * For apps targeting version {@link Build.VERSION_CODES#O} and later, 3213 * the correct value {@link #IMPORTANCE_PERCEPTIBLE} will be returned. 3214 */ 3215 public static final int IMPORTANCE_PERCEPTIBLE_PRE_26 = 130; 3216 3217 /** 3218 * Constant for {@link #importance}: This process is not something the user 3219 * is directly aware of, but is otherwise perceptible to them to some degree. 3220 */ 3221 public static final int IMPORTANCE_PERCEPTIBLE = 230; 3222 3223 /** 3224 * Constant for {@link #importance}: {@link #IMPORTANCE_CANT_SAVE_STATE} had 3225 * this wrong value 3226 * before {@link Build.VERSION_CODES#O}. Since the {@link Build.VERSION_CODES#O} SDK, 3227 * the value of {@link #IMPORTANCE_CANT_SAVE_STATE} has been fixed. 3228 * 3229 * <p>The system will return this value instead of {@link #IMPORTANCE_CANT_SAVE_STATE} 3230 * on Android versions below {@link Build.VERSION_CODES#O}. 3231 * 3232 * <p>On Android version {@link Build.VERSION_CODES#O} after, this value will still be 3233 * returned for apps with the target API level below {@link Build.VERSION_CODES#O}. 3234 * For apps targeting version {@link Build.VERSION_CODES#O} and later, 3235 * the correct value {@link #IMPORTANCE_CANT_SAVE_STATE} will be returned. 3236 * 3237 * @hide 3238 */ 3239 public static final int IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170; 3240 3241 /** 3242 * Constant for {@link #importance}: This process is running an 3243 * application that can not save its state, and thus can't be killed 3244 * while in the background. 3245 * @hide 3246 */ 3247 public static final int IMPORTANCE_CANT_SAVE_STATE= 270; 3248 3249 /** 3250 * Constant for {@link #importance}: This process is contains services 3251 * that should remain running. These are background services apps have 3252 * started, not something the user is aware of, so they may be killed by 3253 * the system relatively freely (though it is generally desired that they 3254 * stay running as long as they want to). 3255 */ 3256 public static final int IMPORTANCE_SERVICE = 300; 3257 3258 /** 3259 * Constant for {@link #importance}: This process process contains 3260 * cached code that is expendable, not actively running any app components 3261 * we care about. 3262 */ 3263 public static final int IMPORTANCE_CACHED = 400; 3264 3265 /** 3266 * @deprecated Renamed to {@link #IMPORTANCE_CACHED}. 3267 */ 3268 public static final int IMPORTANCE_BACKGROUND = IMPORTANCE_CACHED; 3269 3270 /** 3271 * Constant for {@link #importance}: This process is empty of any 3272 * actively running code. 3273 * @deprecated This value is no longer reported, use {@link #IMPORTANCE_CACHED} instead. 3274 */ 3275 @Deprecated 3276 public static final int IMPORTANCE_EMPTY = 500; 3277 3278 /** 3279 * Constant for {@link #importance}: This process does not exist. 3280 */ 3281 public static final int IMPORTANCE_GONE = 1000; 3282 3283 /** 3284 * Convert a proc state to the correspondent IMPORTANCE_* constant. If the return value 3285 * will be passed to a client, use {@link #procStateToImportanceForClient}. 3286 * @hide 3287 */ procStateToImportance(int procState)3288 public static @Importance int procStateToImportance(int procState) { 3289 if (procState == PROCESS_STATE_NONEXISTENT) { 3290 return IMPORTANCE_GONE; 3291 } else if (procState >= PROCESS_STATE_HOME) { 3292 return IMPORTANCE_CACHED; 3293 } else if (procState >= PROCESS_STATE_SERVICE) { 3294 return IMPORTANCE_SERVICE; 3295 } else if (procState > PROCESS_STATE_HEAVY_WEIGHT) { 3296 return IMPORTANCE_CANT_SAVE_STATE; 3297 } else if (procState >= PROCESS_STATE_TRANSIENT_BACKGROUND) { 3298 return IMPORTANCE_PERCEPTIBLE; 3299 } else if (procState >= PROCESS_STATE_IMPORTANT_FOREGROUND) { 3300 return IMPORTANCE_VISIBLE; 3301 } else if (procState >= PROCESS_STATE_TOP_SLEEPING) { 3302 return IMPORTANCE_TOP_SLEEPING; 3303 } else if (procState >= PROCESS_STATE_FOREGROUND_SERVICE) { 3304 return IMPORTANCE_FOREGROUND_SERVICE; 3305 } else { 3306 return IMPORTANCE_FOREGROUND; 3307 } 3308 } 3309 3310 /** 3311 * Convert a proc state to the correspondent IMPORTANCE_* constant for a client represented 3312 * by a given {@link Context}, with converting {@link #IMPORTANCE_PERCEPTIBLE} 3313 * and {@link #IMPORTANCE_CANT_SAVE_STATE} to the corresponding "wrong" value if the 3314 * client's target SDK < {@link VERSION_CODES#O}. 3315 * @hide 3316 */ procStateToImportanceForClient(int procState, Context clientContext)3317 public static @Importance int procStateToImportanceForClient(int procState, 3318 Context clientContext) { 3319 return procStateToImportanceForTargetSdk(procState, 3320 clientContext.getApplicationInfo().targetSdkVersion); 3321 } 3322 3323 /** 3324 * See {@link #procStateToImportanceForClient}. 3325 * @hide 3326 */ procStateToImportanceForTargetSdk(int procState, int targetSdkVersion)3327 public static @Importance int procStateToImportanceForTargetSdk(int procState, 3328 int targetSdkVersion) { 3329 final int importance = procStateToImportance(procState); 3330 3331 // For pre O apps, convert to the old, wrong values. 3332 if (targetSdkVersion < VERSION_CODES.O) { 3333 switch (importance) { 3334 case IMPORTANCE_PERCEPTIBLE: 3335 return IMPORTANCE_PERCEPTIBLE_PRE_26; 3336 case IMPORTANCE_CANT_SAVE_STATE: 3337 return IMPORTANCE_CANT_SAVE_STATE_PRE_26; 3338 } 3339 } 3340 return importance; 3341 } 3342 3343 /** @hide */ importanceToProcState(@mportance int importance)3344 public static int importanceToProcState(@Importance int importance) { 3345 if (importance == IMPORTANCE_GONE) { 3346 return PROCESS_STATE_NONEXISTENT; 3347 } else if (importance >= IMPORTANCE_CACHED) { 3348 return PROCESS_STATE_HOME; 3349 } else if (importance >= IMPORTANCE_SERVICE) { 3350 return PROCESS_STATE_SERVICE; 3351 } else if (importance > IMPORTANCE_CANT_SAVE_STATE) { 3352 return PROCESS_STATE_HEAVY_WEIGHT; 3353 } else if (importance >= IMPORTANCE_PERCEPTIBLE) { 3354 return PROCESS_STATE_TRANSIENT_BACKGROUND; 3355 } else if (importance >= IMPORTANCE_VISIBLE) { 3356 return PROCESS_STATE_IMPORTANT_FOREGROUND; 3357 } else if (importance >= IMPORTANCE_TOP_SLEEPING) { 3358 return PROCESS_STATE_TOP_SLEEPING; 3359 } else if (importance >= IMPORTANCE_FOREGROUND_SERVICE) { 3360 return PROCESS_STATE_FOREGROUND_SERVICE; 3361 } else { 3362 return PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 3363 } 3364 } 3365 3366 /** 3367 * The relative importance level that the system places on this process. 3368 * These constants are numbered so that "more important" values are 3369 * always smaller than "less important" values. 3370 */ 3371 public @Importance int importance; 3372 3373 /** 3374 * An additional ordering within a particular {@link #importance} 3375 * category, providing finer-grained information about the relative 3376 * utility of processes within a category. This number means nothing 3377 * except that a smaller values are more recently used (and thus 3378 * more important). Currently an LRU value is only maintained for 3379 * the {@link #IMPORTANCE_CACHED} category, though others may 3380 * be maintained in the future. 3381 */ 3382 public int lru; 3383 3384 /** 3385 * Constant for {@link #importanceReasonCode}: nothing special has 3386 * been specified for the reason for this level. 3387 */ 3388 public static final int REASON_UNKNOWN = 0; 3389 3390 /** 3391 * Constant for {@link #importanceReasonCode}: one of the application's 3392 * content providers is being used by another process. The pid of 3393 * the client process is in {@link #importanceReasonPid} and the 3394 * target provider in this process is in 3395 * {@link #importanceReasonComponent}. 3396 */ 3397 public static final int REASON_PROVIDER_IN_USE = 1; 3398 3399 /** 3400 * Constant for {@link #importanceReasonCode}: one of the application's 3401 * content providers is being used by another process. The pid of 3402 * the client process is in {@link #importanceReasonPid} and the 3403 * target provider in this process is in 3404 * {@link #importanceReasonComponent}. 3405 */ 3406 public static final int REASON_SERVICE_IN_USE = 2; 3407 3408 /** 3409 * The reason for {@link #importance}, if any. 3410 */ 3411 public int importanceReasonCode; 3412 3413 /** 3414 * For the specified values of {@link #importanceReasonCode}, this 3415 * is the process ID of the other process that is a client of this 3416 * process. This will be 0 if no other process is using this one. 3417 */ 3418 public int importanceReasonPid; 3419 3420 /** 3421 * For the specified values of {@link #importanceReasonCode}, this 3422 * is the name of the component that is being used in this process. 3423 */ 3424 public ComponentName importanceReasonComponent; 3425 3426 /** 3427 * When {@link #importanceReasonPid} is non-0, this is the importance 3428 * of the other pid. @hide 3429 */ 3430 public int importanceReasonImportance; 3431 3432 /** 3433 * Current process state, as per PROCESS_STATE_* constants. 3434 * @hide 3435 */ 3436 public int processState; 3437 RunningAppProcessInfo()3438 public RunningAppProcessInfo() { 3439 importance = IMPORTANCE_FOREGROUND; 3440 importanceReasonCode = REASON_UNKNOWN; 3441 processState = PROCESS_STATE_IMPORTANT_FOREGROUND; 3442 } 3443 RunningAppProcessInfo(String pProcessName, int pPid, String pArr[])3444 public RunningAppProcessInfo(String pProcessName, int pPid, String pArr[]) { 3445 processName = pProcessName; 3446 pid = pPid; 3447 pkgList = pArr; 3448 } 3449 describeContents()3450 public int describeContents() { 3451 return 0; 3452 } 3453 writeToParcel(Parcel dest, int flags)3454 public void writeToParcel(Parcel dest, int flags) { 3455 dest.writeString(processName); 3456 dest.writeInt(pid); 3457 dest.writeInt(uid); 3458 dest.writeStringArray(pkgList); 3459 dest.writeInt(this.flags); 3460 dest.writeInt(lastTrimLevel); 3461 dest.writeInt(importance); 3462 dest.writeInt(lru); 3463 dest.writeInt(importanceReasonCode); 3464 dest.writeInt(importanceReasonPid); 3465 ComponentName.writeToParcel(importanceReasonComponent, dest); 3466 dest.writeInt(importanceReasonImportance); 3467 dest.writeInt(processState); 3468 } 3469 readFromParcel(Parcel source)3470 public void readFromParcel(Parcel source) { 3471 processName = source.readString(); 3472 pid = source.readInt(); 3473 uid = source.readInt(); 3474 pkgList = source.readStringArray(); 3475 flags = source.readInt(); 3476 lastTrimLevel = source.readInt(); 3477 importance = source.readInt(); 3478 lru = source.readInt(); 3479 importanceReasonCode = source.readInt(); 3480 importanceReasonPid = source.readInt(); 3481 importanceReasonComponent = ComponentName.readFromParcel(source); 3482 importanceReasonImportance = source.readInt(); 3483 processState = source.readInt(); 3484 } 3485 3486 public static final Creator<RunningAppProcessInfo> CREATOR = 3487 new Creator<RunningAppProcessInfo>() { 3488 public RunningAppProcessInfo createFromParcel(Parcel source) { 3489 return new RunningAppProcessInfo(source); 3490 } 3491 public RunningAppProcessInfo[] newArray(int size) { 3492 return new RunningAppProcessInfo[size]; 3493 } 3494 }; 3495 RunningAppProcessInfo(Parcel source)3496 private RunningAppProcessInfo(Parcel source) { 3497 readFromParcel(source); 3498 } 3499 } 3500 3501 /** 3502 * Returns a list of application processes installed on external media 3503 * that are running on the device. 3504 * 3505 * <p><b>Note: this method is only intended for debugging or building 3506 * a user-facing process management UI.</b></p> 3507 * 3508 * @return Returns a list of ApplicationInfo records, or null if none 3509 * This list ordering is not specified. 3510 * @hide 3511 */ getRunningExternalApplications()3512 public List<ApplicationInfo> getRunningExternalApplications() { 3513 try { 3514 return getService().getRunningExternalApplications(); 3515 } catch (RemoteException e) { 3516 throw e.rethrowFromSystemServer(); 3517 } 3518 } 3519 3520 /** 3521 * Sets the memory trim mode for a process and schedules a memory trim operation. 3522 * 3523 * <p><b>Note: this method is only intended for testing framework.</b></p> 3524 * 3525 * @return Returns true if successful. 3526 * @hide 3527 */ setProcessMemoryTrimLevel(String process, int userId, int level)3528 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) { 3529 try { 3530 return getService().setProcessMemoryTrimLevel(process, userId, 3531 level); 3532 } catch (RemoteException e) { 3533 throw e.rethrowFromSystemServer(); 3534 } 3535 } 3536 3537 /** 3538 * Returns a list of application processes that are running on the device. 3539 * 3540 * <p><b>Note: this method is only intended for debugging or building 3541 * a user-facing process management UI.</b></p> 3542 * 3543 * @return Returns a list of RunningAppProcessInfo records, or null if there are no 3544 * running processes (it will not return an empty list). This list ordering is not 3545 * specified. 3546 */ getRunningAppProcesses()3547 public List<RunningAppProcessInfo> getRunningAppProcesses() { 3548 try { 3549 return getService().getRunningAppProcesses(); 3550 } catch (RemoteException e) { 3551 throw e.rethrowFromSystemServer(); 3552 } 3553 } 3554 3555 /** 3556 * Return the importance of a given package name, based on the processes that are 3557 * currently running. The return value is one of the importance constants defined 3558 * in {@link RunningAppProcessInfo}, giving you the highest importance of all the 3559 * processes that this package has code running inside of. If there are no processes 3560 * running its code, {@link RunningAppProcessInfo#IMPORTANCE_GONE} is returned. 3561 * @hide 3562 */ 3563 @SystemApi @TestApi 3564 @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS) getPackageImportance(String packageName)3565 public @RunningAppProcessInfo.Importance int getPackageImportance(String packageName) { 3566 try { 3567 int procState = getService().getPackageProcessState(packageName, 3568 mContext.getOpPackageName()); 3569 return RunningAppProcessInfo.procStateToImportanceForClient(procState, mContext); 3570 } catch (RemoteException e) { 3571 throw e.rethrowFromSystemServer(); 3572 } 3573 } 3574 3575 /** 3576 * Return the importance of a given uid, based on the processes that are 3577 * currently running. The return value is one of the importance constants defined 3578 * in {@link RunningAppProcessInfo}, giving you the highest importance of all the 3579 * processes that this uid has running. If there are no processes 3580 * running its code, {@link RunningAppProcessInfo#IMPORTANCE_GONE} is returned. 3581 * @hide 3582 */ 3583 @SystemApi @TestApi 3584 @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS) getUidImportance(int uid)3585 public @RunningAppProcessInfo.Importance int getUidImportance(int uid) { 3586 try { 3587 int procState = getService().getUidProcessState(uid, 3588 mContext.getOpPackageName()); 3589 return RunningAppProcessInfo.procStateToImportanceForClient(procState, mContext); 3590 } catch (RemoteException e) { 3591 throw e.rethrowFromSystemServer(); 3592 } 3593 } 3594 3595 /** 3596 * Callback to get reports about changes to the importance of a uid. Use with 3597 * {@link #addOnUidImportanceListener}. 3598 * @hide 3599 */ 3600 @SystemApi @TestApi 3601 public interface OnUidImportanceListener { 3602 /** 3603 * The importance if a given uid has changed. Will be one of the importance 3604 * values in {@link RunningAppProcessInfo}; 3605 * {@link RunningAppProcessInfo#IMPORTANCE_GONE IMPORTANCE_GONE} will be reported 3606 * when the uid is no longer running at all. This callback will happen on a thread 3607 * from a thread pool, not the main UI thread. 3608 * @param uid The uid whose importance has changed. 3609 * @param importance The new importance value as per {@link RunningAppProcessInfo}. 3610 */ onUidImportance(int uid, @RunningAppProcessInfo.Importance int importance)3611 void onUidImportance(int uid, @RunningAppProcessInfo.Importance int importance); 3612 } 3613 3614 /** 3615 * Start monitoring changes to the imoportance of uids running in the system. 3616 * @param listener The listener callback that will receive change reports. 3617 * @param importanceCutpoint The level of importance in which the caller is interested 3618 * in differences. For example, if {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE} 3619 * is used here, you will receive a call each time a uids importance transitions between 3620 * being <= {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE} and 3621 * > {@link RunningAppProcessInfo#IMPORTANCE_PERCEPTIBLE}. 3622 * 3623 * <p>The caller must hold the {@link android.Manifest.permission#PACKAGE_USAGE_STATS} 3624 * permission to use this feature.</p> 3625 * 3626 * @throws IllegalArgumentException If the listener is already registered. 3627 * @throws SecurityException If the caller does not hold 3628 * {@link android.Manifest.permission#PACKAGE_USAGE_STATS}. 3629 * @hide 3630 */ 3631 @SystemApi @TestApi 3632 @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS) addOnUidImportanceListener(OnUidImportanceListener listener, @RunningAppProcessInfo.Importance int importanceCutpoint)3633 public void addOnUidImportanceListener(OnUidImportanceListener listener, 3634 @RunningAppProcessInfo.Importance int importanceCutpoint) { 3635 synchronized (this) { 3636 if (mImportanceListeners.containsKey(listener)) { 3637 throw new IllegalArgumentException("Listener already registered: " + listener); 3638 } 3639 // TODO: implement the cut point in the system process to avoid IPCs. 3640 UidObserver observer = new UidObserver(listener, mContext); 3641 try { 3642 getService().registerUidObserver(observer, 3643 UID_OBSERVER_PROCSTATE | UID_OBSERVER_GONE, 3644 RunningAppProcessInfo.importanceToProcState(importanceCutpoint), 3645 mContext.getOpPackageName()); 3646 } catch (RemoteException e) { 3647 throw e.rethrowFromSystemServer(); 3648 } 3649 mImportanceListeners.put(listener, observer); 3650 } 3651 } 3652 3653 /** 3654 * Remove an importance listener that was previously registered with 3655 * {@link #addOnUidImportanceListener}. 3656 * 3657 * @throws IllegalArgumentException If the listener is not registered. 3658 * @hide 3659 */ 3660 @SystemApi @TestApi 3661 @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS) removeOnUidImportanceListener(OnUidImportanceListener listener)3662 public void removeOnUidImportanceListener(OnUidImportanceListener listener) { 3663 synchronized (this) { 3664 UidObserver observer = mImportanceListeners.remove(listener); 3665 if (observer == null) { 3666 throw new IllegalArgumentException("Listener not registered: " + listener); 3667 } 3668 try { 3669 getService().unregisterUidObserver(observer); 3670 } catch (RemoteException e) { 3671 throw e.rethrowFromSystemServer(); 3672 } 3673 } 3674 } 3675 3676 /** 3677 * Return global memory state information for the calling process. This 3678 * does not fill in all fields of the {@link RunningAppProcessInfo}. The 3679 * only fields that will be filled in are 3680 * {@link RunningAppProcessInfo#pid}, 3681 * {@link RunningAppProcessInfo#uid}, 3682 * {@link RunningAppProcessInfo#lastTrimLevel}, 3683 * {@link RunningAppProcessInfo#importance}, 3684 * {@link RunningAppProcessInfo#lru}, and 3685 * {@link RunningAppProcessInfo#importanceReasonCode}. 3686 */ getMyMemoryState(RunningAppProcessInfo outState)3687 static public void getMyMemoryState(RunningAppProcessInfo outState) { 3688 try { 3689 getService().getMyMemoryState(outState); 3690 } catch (RemoteException e) { 3691 throw e.rethrowFromSystemServer(); 3692 } 3693 } 3694 3695 /** 3696 * Return information about the memory usage of one or more processes. 3697 * 3698 * <p><b>Note: this method is only intended for debugging or building 3699 * a user-facing process management UI.</b></p> 3700 * 3701 * @param pids The pids of the processes whose memory usage is to be 3702 * retrieved. 3703 * @return Returns an array of memory information, one for each 3704 * requested pid. 3705 */ getProcessMemoryInfo(int[] pids)3706 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 3707 try { 3708 return getService().getProcessMemoryInfo(pids); 3709 } catch (RemoteException e) { 3710 throw e.rethrowFromSystemServer(); 3711 } 3712 } 3713 3714 /** 3715 * @deprecated This is now just a wrapper for 3716 * {@link #killBackgroundProcesses(String)}; the previous behavior here 3717 * is no longer available to applications because it allows them to 3718 * break other applications by removing their alarms, stopping their 3719 * services, etc. 3720 */ 3721 @Deprecated restartPackage(String packageName)3722 public void restartPackage(String packageName) { 3723 killBackgroundProcesses(packageName); 3724 } 3725 3726 /** 3727 * Have the system immediately kill all background processes associated 3728 * with the given package. This is the same as the kernel killing those 3729 * processes to reclaim memory; the system will take care of restarting 3730 * these processes in the future as needed. 3731 * 3732 * @param packageName The name of the package whose processes are to 3733 * be killed. 3734 */ 3735 @RequiresPermission(Manifest.permission.KILL_BACKGROUND_PROCESSES) killBackgroundProcesses(String packageName)3736 public void killBackgroundProcesses(String packageName) { 3737 try { 3738 getService().killBackgroundProcesses(packageName, 3739 UserHandle.myUserId()); 3740 } catch (RemoteException e) { 3741 throw e.rethrowFromSystemServer(); 3742 } 3743 } 3744 3745 /** 3746 * Kills the specified UID. 3747 * @param uid The UID to kill. 3748 * @param reason The reason for the kill. 3749 * 3750 * @hide 3751 */ 3752 @SystemApi 3753 @RequiresPermission(Manifest.permission.KILL_UID) killUid(int uid, String reason)3754 public void killUid(int uid, String reason) { 3755 try { 3756 getService().killUid(UserHandle.getAppId(uid), 3757 UserHandle.getUserId(uid), reason); 3758 } catch (RemoteException e) { 3759 throw e.rethrowFromSystemServer(); 3760 } 3761 } 3762 3763 /** 3764 * Have the system perform a force stop of everything associated with 3765 * the given application package. All processes that share its uid 3766 * will be killed, all services it has running stopped, all activities 3767 * removed, etc. In addition, a {@link Intent#ACTION_PACKAGE_RESTARTED} 3768 * broadcast will be sent, so that any of its registered alarms can 3769 * be stopped, notifications removed, etc. 3770 * 3771 * <p>You must hold the permission 3772 * {@link android.Manifest.permission#FORCE_STOP_PACKAGES} to be able to 3773 * call this method. 3774 * 3775 * @param packageName The name of the package to be stopped. 3776 * @param userId The user for which the running package is to be stopped. 3777 * 3778 * @hide This is not available to third party applications due to 3779 * it allowing them to break other applications by stopping their 3780 * services, removing their alarms, etc. 3781 */ forceStopPackageAsUser(String packageName, int userId)3782 public void forceStopPackageAsUser(String packageName, int userId) { 3783 try { 3784 getService().forceStopPackage(packageName, userId); 3785 } catch (RemoteException e) { 3786 throw e.rethrowFromSystemServer(); 3787 } 3788 } 3789 3790 /** 3791 * @see #forceStopPackageAsUser(String, int) 3792 * @hide 3793 */ 3794 @SystemApi 3795 @RequiresPermission(Manifest.permission.FORCE_STOP_PACKAGES) forceStopPackage(String packageName)3796 public void forceStopPackage(String packageName) { 3797 forceStopPackageAsUser(packageName, UserHandle.myUserId()); 3798 } 3799 3800 /** 3801 * Get the device configuration attributes. 3802 */ getDeviceConfigurationInfo()3803 public ConfigurationInfo getDeviceConfigurationInfo() { 3804 try { 3805 return getService().getDeviceConfigurationInfo(); 3806 } catch (RemoteException e) { 3807 throw e.rethrowFromSystemServer(); 3808 } 3809 } 3810 3811 /** 3812 * Get the preferred density of icons for the launcher. This is used when 3813 * custom drawables are created (e.g., for shortcuts). 3814 * 3815 * @return density in terms of DPI 3816 */ getLauncherLargeIconDensity()3817 public int getLauncherLargeIconDensity() { 3818 final Resources res = mContext.getResources(); 3819 final int density = res.getDisplayMetrics().densityDpi; 3820 final int sw = res.getConfiguration().smallestScreenWidthDp; 3821 3822 if (sw < 600) { 3823 // Smaller than approx 7" tablets, use the regular icon size. 3824 return density; 3825 } 3826 3827 switch (density) { 3828 case DisplayMetrics.DENSITY_LOW: 3829 return DisplayMetrics.DENSITY_MEDIUM; 3830 case DisplayMetrics.DENSITY_MEDIUM: 3831 return DisplayMetrics.DENSITY_HIGH; 3832 case DisplayMetrics.DENSITY_TV: 3833 return DisplayMetrics.DENSITY_XHIGH; 3834 case DisplayMetrics.DENSITY_HIGH: 3835 return DisplayMetrics.DENSITY_XHIGH; 3836 case DisplayMetrics.DENSITY_XHIGH: 3837 return DisplayMetrics.DENSITY_XXHIGH; 3838 case DisplayMetrics.DENSITY_XXHIGH: 3839 return DisplayMetrics.DENSITY_XHIGH * 2; 3840 default: 3841 // The density is some abnormal value. Return some other 3842 // abnormal value that is a reasonable scaling of it. 3843 return (int)((density*1.5f)+.5f); 3844 } 3845 } 3846 3847 /** 3848 * Get the preferred launcher icon size. This is used when custom drawables 3849 * are created (e.g., for shortcuts). 3850 * 3851 * @return dimensions of square icons in terms of pixels 3852 */ getLauncherLargeIconSize()3853 public int getLauncherLargeIconSize() { 3854 return getLauncherLargeIconSizeInner(mContext); 3855 } 3856 getLauncherLargeIconSizeInner(Context context)3857 static int getLauncherLargeIconSizeInner(Context context) { 3858 final Resources res = context.getResources(); 3859 final int size = res.getDimensionPixelSize(android.R.dimen.app_icon_size); 3860 final int sw = res.getConfiguration().smallestScreenWidthDp; 3861 3862 if (sw < 600) { 3863 // Smaller than approx 7" tablets, use the regular icon size. 3864 return size; 3865 } 3866 3867 final int density = res.getDisplayMetrics().densityDpi; 3868 3869 switch (density) { 3870 case DisplayMetrics.DENSITY_LOW: 3871 return (size * DisplayMetrics.DENSITY_MEDIUM) / DisplayMetrics.DENSITY_LOW; 3872 case DisplayMetrics.DENSITY_MEDIUM: 3873 return (size * DisplayMetrics.DENSITY_HIGH) / DisplayMetrics.DENSITY_MEDIUM; 3874 case DisplayMetrics.DENSITY_TV: 3875 return (size * DisplayMetrics.DENSITY_XHIGH) / DisplayMetrics.DENSITY_HIGH; 3876 case DisplayMetrics.DENSITY_HIGH: 3877 return (size * DisplayMetrics.DENSITY_XHIGH) / DisplayMetrics.DENSITY_HIGH; 3878 case DisplayMetrics.DENSITY_XHIGH: 3879 return (size * DisplayMetrics.DENSITY_XXHIGH) / DisplayMetrics.DENSITY_XHIGH; 3880 case DisplayMetrics.DENSITY_XXHIGH: 3881 return (size * DisplayMetrics.DENSITY_XHIGH*2) / DisplayMetrics.DENSITY_XXHIGH; 3882 default: 3883 // The density is some abnormal value. Return some other 3884 // abnormal value that is a reasonable scaling of it. 3885 return (int)((size*1.5f) + .5f); 3886 } 3887 } 3888 3889 /** 3890 * Returns "true" if the user interface is currently being messed with 3891 * by a monkey. 3892 */ isUserAMonkey()3893 public static boolean isUserAMonkey() { 3894 try { 3895 return getService().isUserAMonkey(); 3896 } catch (RemoteException e) { 3897 throw e.rethrowFromSystemServer(); 3898 } 3899 } 3900 3901 /** 3902 * Returns "true" if device is running in a test harness. 3903 */ isRunningInTestHarness()3904 public static boolean isRunningInTestHarness() { 3905 return SystemProperties.getBoolean("ro.test_harness", false); 3906 } 3907 3908 /** 3909 * Returns the launch count of each installed package. 3910 * 3911 * @hide 3912 */ 3913 /*public Map<String, Integer> getAllPackageLaunchCounts() { 3914 try { 3915 IUsageStats usageStatsService = IUsageStats.Stub.asInterface( 3916 ServiceManager.getService("usagestats")); 3917 if (usageStatsService == null) { 3918 return new HashMap<String, Integer>(); 3919 } 3920 3921 UsageStats.PackageStats[] allPkgUsageStats = usageStatsService.getAllPkgUsageStats( 3922 ActivityThread.currentPackageName()); 3923 if (allPkgUsageStats == null) { 3924 return new HashMap<String, Integer>(); 3925 } 3926 3927 Map<String, Integer> launchCounts = new HashMap<String, Integer>(); 3928 for (UsageStats.PackageStats pkgUsageStats : allPkgUsageStats) { 3929 launchCounts.put(pkgUsageStats.getPackageName(), pkgUsageStats.getLaunchCount()); 3930 } 3931 3932 return launchCounts; 3933 } catch (RemoteException e) { 3934 Log.w(TAG, "Could not query launch counts", e); 3935 return new HashMap<String, Integer>(); 3936 } 3937 }*/ 3938 3939 /** @hide */ checkComponentPermission(String permission, int uid, int owningUid, boolean exported)3940 public static int checkComponentPermission(String permission, int uid, 3941 int owningUid, boolean exported) { 3942 // Root, system server get to do everything. 3943 final int appId = UserHandle.getAppId(uid); 3944 if (appId == Process.ROOT_UID || appId == Process.SYSTEM_UID) { 3945 return PackageManager.PERMISSION_GRANTED; 3946 } 3947 // Isolated processes don't get any permissions. 3948 if (UserHandle.isIsolated(uid)) { 3949 return PackageManager.PERMISSION_DENIED; 3950 } 3951 // If there is a uid that owns whatever is being accessed, it has 3952 // blanket access to it regardless of the permissions it requires. 3953 if (owningUid >= 0 && UserHandle.isSameApp(uid, owningUid)) { 3954 return PackageManager.PERMISSION_GRANTED; 3955 } 3956 // If the target is not exported, then nobody else can get to it. 3957 if (!exported) { 3958 /* 3959 RuntimeException here = new RuntimeException("here"); 3960 here.fillInStackTrace(); 3961 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid, 3962 here); 3963 */ 3964 return PackageManager.PERMISSION_DENIED; 3965 } 3966 if (permission == null) { 3967 return PackageManager.PERMISSION_GRANTED; 3968 } 3969 try { 3970 return AppGlobals.getPackageManager() 3971 .checkUidPermission(permission, uid); 3972 } catch (RemoteException e) { 3973 throw e.rethrowFromSystemServer(); 3974 } 3975 } 3976 3977 /** @hide */ checkUidPermission(String permission, int uid)3978 public static int checkUidPermission(String permission, int uid) { 3979 try { 3980 return AppGlobals.getPackageManager() 3981 .checkUidPermission(permission, uid); 3982 } catch (RemoteException e) { 3983 throw e.rethrowFromSystemServer(); 3984 } 3985 } 3986 3987 /** 3988 * @hide 3989 * Helper for dealing with incoming user arguments to system service calls. 3990 * Takes care of checking permissions and converting USER_CURRENT to the 3991 * actual current user. 3992 * 3993 * @param callingPid The pid of the incoming call, as per Binder.getCallingPid(). 3994 * @param callingUid The uid of the incoming call, as per Binder.getCallingUid(). 3995 * @param userId The user id argument supplied by the caller -- this is the user 3996 * they want to run as. 3997 * @param allowAll If true, we will allow USER_ALL. This means you must be prepared 3998 * to get a USER_ALL returned and deal with it correctly. If false, 3999 * an exception will be thrown if USER_ALL is supplied. 4000 * @param requireFull If true, the caller must hold 4001 * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} to be able to run as a 4002 * different user than their current process; otherwise they must hold 4003 * {@link android.Manifest.permission#INTERACT_ACROSS_USERS}. 4004 * @param name Optional textual name of the incoming call; only for generating error messages. 4005 * @param callerPackage Optional package name of caller; only for error messages. 4006 * 4007 * @return Returns the user ID that the call should run as. Will always be a concrete 4008 * user number, unless <var>allowAll</var> is true in which case it could also be 4009 * USER_ALL. 4010 */ handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, boolean requireFull, String name, String callerPackage)4011 public static int handleIncomingUser(int callingPid, int callingUid, int userId, 4012 boolean allowAll, boolean requireFull, String name, String callerPackage) { 4013 if (UserHandle.getUserId(callingUid) == userId) { 4014 return userId; 4015 } 4016 try { 4017 return getService().handleIncomingUser(callingPid, 4018 callingUid, userId, allowAll, requireFull, name, callerPackage); 4019 } catch (RemoteException e) { 4020 throw e.rethrowFromSystemServer(); 4021 } 4022 } 4023 4024 /** 4025 * Gets the userId of the current foreground user. Requires system permissions. 4026 * @hide 4027 */ 4028 @SystemApi 4029 @RequiresPermission(anyOf = { 4030 "android.permission.INTERACT_ACROSS_USERS", 4031 "android.permission.INTERACT_ACROSS_USERS_FULL" 4032 }) getCurrentUser()4033 public static int getCurrentUser() { 4034 UserInfo ui; 4035 try { 4036 ui = getService().getCurrentUser(); 4037 return ui != null ? ui.id : 0; 4038 } catch (RemoteException e) { 4039 throw e.rethrowFromSystemServer(); 4040 } 4041 } 4042 4043 /** 4044 * @param userid the user's id. Zero indicates the default user. 4045 * @hide 4046 */ switchUser(int userid)4047 public boolean switchUser(int userid) { 4048 try { 4049 return getService().switchUser(userid); 4050 } catch (RemoteException e) { 4051 throw e.rethrowFromSystemServer(); 4052 } 4053 } 4054 4055 /** 4056 * Logs out current current foreground user by switching to the system user and stopping the 4057 * user being switched from. 4058 * @hide 4059 */ logoutCurrentUser()4060 public static void logoutCurrentUser() { 4061 int currentUser = ActivityManager.getCurrentUser(); 4062 if (currentUser != UserHandle.USER_SYSTEM) { 4063 try { 4064 getService().switchUser(UserHandle.USER_SYSTEM); 4065 getService().stopUser(currentUser, /* force= */ false, null); 4066 } catch (RemoteException e) { 4067 e.rethrowFromSystemServer(); 4068 } 4069 } 4070 } 4071 4072 /** {@hide} */ 4073 public static final int FLAG_OR_STOPPED = 1 << 0; 4074 /** {@hide} */ 4075 public static final int FLAG_AND_LOCKED = 1 << 1; 4076 /** {@hide} */ 4077 public static final int FLAG_AND_UNLOCKED = 1 << 2; 4078 /** {@hide} */ 4079 public static final int FLAG_AND_UNLOCKING_OR_UNLOCKED = 1 << 3; 4080 4081 /** 4082 * Return whether the given user is actively running. This means that 4083 * the user is in the "started" state, not "stopped" -- it is currently 4084 * allowed to run code through scheduled alarms, receiving broadcasts, 4085 * etc. A started user may be either the current foreground user or a 4086 * background user; the result here does not distinguish between the two. 4087 * @param userId the user's id. Zero indicates the default user. 4088 * @hide 4089 */ isUserRunning(int userId)4090 public boolean isUserRunning(int userId) { 4091 try { 4092 return getService().isUserRunning(userId, 0); 4093 } catch (RemoteException e) { 4094 throw e.rethrowFromSystemServer(); 4095 } 4096 } 4097 4098 /** {@hide} */ isVrModePackageEnabled(ComponentName component)4099 public boolean isVrModePackageEnabled(ComponentName component) { 4100 try { 4101 return getService().isVrModePackageEnabled(component); 4102 } catch (RemoteException e) { 4103 throw e.rethrowFromSystemServer(); 4104 } 4105 } 4106 4107 /** 4108 * Perform a system dump of various state associated with the given application 4109 * package name. This call blocks while the dump is being performed, so should 4110 * not be done on a UI thread. The data will be written to the given file 4111 * descriptor as text. 4112 * @param fd The file descriptor that the dump should be written to. The file 4113 * descriptor is <em>not</em> closed by this function; the caller continues to 4114 * own it. 4115 * @param packageName The name of the package that is to be dumped. 4116 */ 4117 @RequiresPermission(Manifest.permission.DUMP) dumpPackageState(FileDescriptor fd, String packageName)4118 public void dumpPackageState(FileDescriptor fd, String packageName) { 4119 dumpPackageStateStatic(fd, packageName); 4120 } 4121 4122 /** 4123 * @hide 4124 */ dumpPackageStateStatic(FileDescriptor fd, String packageName)4125 public static void dumpPackageStateStatic(FileDescriptor fd, String packageName) { 4126 FileOutputStream fout = new FileOutputStream(fd); 4127 PrintWriter pw = new FastPrintWriter(fout); 4128 dumpService(pw, fd, "package", new String[] { packageName }); 4129 pw.println(); 4130 dumpService(pw, fd, Context.ACTIVITY_SERVICE, new String[] { 4131 "-a", "package", packageName }); 4132 pw.println(); 4133 dumpService(pw, fd, "meminfo", new String[] { "--local", "--package", packageName }); 4134 pw.println(); 4135 dumpService(pw, fd, ProcessStats.SERVICE_NAME, new String[] { packageName }); 4136 pw.println(); 4137 dumpService(pw, fd, "usagestats", new String[] { "--packages", packageName }); 4138 pw.println(); 4139 dumpService(pw, fd, BatteryStats.SERVICE_NAME, new String[] { packageName }); 4140 pw.flush(); 4141 } 4142 4143 /** 4144 * @hide 4145 */ isSystemReady()4146 public static boolean isSystemReady() { 4147 if (!sSystemReady) { 4148 if (ActivityThread.isSystem()) { 4149 sSystemReady = 4150 LocalServices.getService(ActivityManagerInternal.class).isSystemReady(); 4151 } else { 4152 // Since this is being called from outside system server, system should be 4153 // ready by now. 4154 sSystemReady = true; 4155 } 4156 } 4157 return sSystemReady; 4158 } 4159 4160 /** 4161 * @hide 4162 */ broadcastStickyIntent(Intent intent, int userId)4163 public static void broadcastStickyIntent(Intent intent, int userId) { 4164 broadcastStickyIntent(intent, AppOpsManager.OP_NONE, userId); 4165 } 4166 4167 /** 4168 * Convenience for sending a sticky broadcast. For internal use only. 4169 * 4170 * @hide 4171 */ broadcastStickyIntent(Intent intent, int appOp, int userId)4172 public static void broadcastStickyIntent(Intent intent, int appOp, int userId) { 4173 try { 4174 getService().broadcastIntent( 4175 null, intent, null, null, Activity.RESULT_OK, null, null, 4176 null /*permission*/, appOp, null, false, true, userId); 4177 } catch (RemoteException ex) { 4178 } 4179 } 4180 4181 /** 4182 * @hide 4183 */ noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg, String tag)4184 public static void noteWakeupAlarm(PendingIntent ps, int sourceUid, String sourcePkg, 4185 String tag) { 4186 try { 4187 getService().noteWakeupAlarm((ps != null) ? ps.getTarget() : null, 4188 sourceUid, sourcePkg, tag); 4189 } catch (RemoteException ex) { 4190 } 4191 } 4192 4193 /** 4194 * @hide 4195 */ noteAlarmStart(PendingIntent ps, int sourceUid, String tag)4196 public static void noteAlarmStart(PendingIntent ps, int sourceUid, String tag) { 4197 try { 4198 getService().noteAlarmStart((ps != null) ? ps.getTarget() : null, sourceUid, tag); 4199 } catch (RemoteException ex) { 4200 } 4201 } 4202 4203 /** 4204 * @hide 4205 */ noteAlarmFinish(PendingIntent ps, int sourceUid, String tag)4206 public static void noteAlarmFinish(PendingIntent ps, int sourceUid, String tag) { 4207 try { 4208 getService().noteAlarmFinish((ps != null) ? ps.getTarget() : null, sourceUid, tag); 4209 } catch (RemoteException ex) { 4210 } 4211 } 4212 4213 /** 4214 * @hide 4215 */ getService()4216 public static IActivityManager getService() { 4217 return IActivityManagerSingleton.get(); 4218 } 4219 4220 private static final Singleton<IActivityManager> IActivityManagerSingleton = 4221 new Singleton<IActivityManager>() { 4222 @Override 4223 protected IActivityManager create() { 4224 final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); 4225 final IActivityManager am = IActivityManager.Stub.asInterface(b); 4226 return am; 4227 } 4228 }; 4229 dumpService(PrintWriter pw, FileDescriptor fd, String name, String[] args)4230 private static void dumpService(PrintWriter pw, FileDescriptor fd, String name, String[] args) { 4231 pw.print("DUMP OF SERVICE "); pw.print(name); pw.println(":"); 4232 IBinder service = ServiceManager.checkService(name); 4233 if (service == null) { 4234 pw.println(" (Service not found)"); 4235 return; 4236 } 4237 TransferPipe tp = null; 4238 try { 4239 pw.flush(); 4240 tp = new TransferPipe(); 4241 tp.setBufferPrefix(" "); 4242 service.dumpAsync(tp.getWriteFd().getFileDescriptor(), args); 4243 tp.go(fd, 10000); 4244 } catch (Throwable e) { 4245 if (tp != null) { 4246 tp.kill(); 4247 } 4248 pw.println("Failure dumping service:"); 4249 e.printStackTrace(pw); 4250 } 4251 } 4252 4253 /** 4254 * Request that the system start watching for the calling process to exceed a pss 4255 * size as given here. Once called, the system will look for any occasions where it 4256 * sees the associated process with a larger pss size and, when this happens, automatically 4257 * pull a heap dump from it and allow the user to share the data. Note that this request 4258 * continues running even if the process is killed and restarted. To remove the watch, 4259 * use {@link #clearWatchHeapLimit()}. 4260 * 4261 * <p>This API only work if the calling process has been marked as 4262 * {@link ApplicationInfo#FLAG_DEBUGGABLE} or this is running on a debuggable 4263 * (userdebug or eng) build.</p> 4264 * 4265 * <p>Callers can optionally implement {@link #ACTION_REPORT_HEAP_LIMIT} to directly 4266 * handle heap limit reports themselves.</p> 4267 * 4268 * @param pssSize The size in bytes to set the limit at. 4269 */ setWatchHeapLimit(long pssSize)4270 public void setWatchHeapLimit(long pssSize) { 4271 try { 4272 getService().setDumpHeapDebugLimit(null, 0, pssSize, 4273 mContext.getPackageName()); 4274 } catch (RemoteException e) { 4275 throw e.rethrowFromSystemServer(); 4276 } 4277 } 4278 4279 /** 4280 * Action an app can implement to handle reports from {@link #setWatchHeapLimit(long)}. 4281 * If your package has an activity handling this action, it will be launched with the 4282 * heap data provided to it the same way as {@link Intent#ACTION_SEND}. Note that to 4283 * match the activty must support this action and a MIME type of "*/*". 4284 */ 4285 public static final String ACTION_REPORT_HEAP_LIMIT = "android.app.action.REPORT_HEAP_LIMIT"; 4286 4287 /** 4288 * Clear a heap watch limit previously set by {@link #setWatchHeapLimit(long)}. 4289 */ clearWatchHeapLimit()4290 public void clearWatchHeapLimit() { 4291 try { 4292 getService().setDumpHeapDebugLimit(null, 0, 0, null); 4293 } catch (RemoteException e) { 4294 throw e.rethrowFromSystemServer(); 4295 } 4296 } 4297 4298 /** 4299 * @hide 4300 */ startLockTaskMode(int taskId)4301 public void startLockTaskMode(int taskId) { 4302 try { 4303 getService().startLockTaskModeById(taskId); 4304 } catch (RemoteException e) { 4305 throw e.rethrowFromSystemServer(); 4306 } 4307 } 4308 4309 /** 4310 * @hide 4311 */ stopLockTaskMode()4312 public void stopLockTaskMode() { 4313 try { 4314 getService().stopLockTaskMode(); 4315 } catch (RemoteException e) { 4316 throw e.rethrowFromSystemServer(); 4317 } 4318 } 4319 4320 /** 4321 * Return whether currently in lock task mode. When in this mode 4322 * no new tasks can be created or switched to. 4323 * 4324 * @see Activity#startLockTask() 4325 * 4326 * @deprecated Use {@link #getLockTaskModeState} instead. 4327 */ 4328 @Deprecated isInLockTaskMode()4329 public boolean isInLockTaskMode() { 4330 return getLockTaskModeState() != LOCK_TASK_MODE_NONE; 4331 } 4332 4333 /** 4334 * Return the current state of task locking. The three possible outcomes 4335 * are {@link #LOCK_TASK_MODE_NONE}, {@link #LOCK_TASK_MODE_LOCKED} 4336 * and {@link #LOCK_TASK_MODE_PINNED}. 4337 * 4338 * @see Activity#startLockTask() 4339 */ getLockTaskModeState()4340 public int getLockTaskModeState() { 4341 try { 4342 return getService().getLockTaskModeState(); 4343 } catch (RemoteException e) { 4344 throw e.rethrowFromSystemServer(); 4345 } 4346 } 4347 4348 /** 4349 * Enable more aggressive scheduling for latency-sensitive low-runtime VR threads. Only one 4350 * thread can be a VR thread in a process at a time, and that thread may be subject to 4351 * restrictions on the amount of time it can run. 4352 * 4353 * If persistent VR mode is set, whatever thread has been granted aggressive scheduling via this 4354 * method will return to normal operation, and calling this method will do nothing while 4355 * persistent VR mode is enabled. 4356 * 4357 * To reset the VR thread for an application, a tid of 0 can be passed. 4358 * 4359 * @see android.os.Process#myTid() 4360 * @param tid tid of the VR thread 4361 */ setVrThread(int tid)4362 public static void setVrThread(int tid) { 4363 try { 4364 getService().setVrThread(tid); 4365 } catch (RemoteException e) { 4366 // pass 4367 } 4368 } 4369 4370 /** 4371 * Enable more aggressive scheduling for latency-sensitive low-runtime VR threads that persist 4372 * beyond a single process. Only one thread can be a 4373 * persistent VR thread at a time, and that thread may be subject to restrictions on the amount 4374 * of time it can run. Calling this method will disable aggressive scheduling for non-persistent 4375 * VR threads set via {@link #setVrThread}. If persistent VR mode is disabled then the 4376 * persistent VR thread loses its new scheduling priority; this method must be called again to 4377 * set the persistent thread. 4378 * 4379 * To reset the persistent VR thread, a tid of 0 can be passed. 4380 * 4381 * @see android.os.Process#myTid() 4382 * @param tid tid of the VR thread 4383 * @hide 4384 */ 4385 @RequiresPermission(Manifest.permission.RESTRICTED_VR_ACCESS) setPersistentVrThread(int tid)4386 public static void setPersistentVrThread(int tid) { 4387 try { 4388 getService().setPersistentVrThread(tid); 4389 } catch (RemoteException e) { 4390 // pass 4391 } 4392 } 4393 4394 /** 4395 * The AppTask allows you to manage your own application's tasks. 4396 * See {@link android.app.ActivityManager#getAppTasks()} 4397 */ 4398 public static class AppTask { 4399 private IAppTask mAppTaskImpl; 4400 4401 /** @hide */ AppTask(IAppTask task)4402 public AppTask(IAppTask task) { 4403 mAppTaskImpl = task; 4404 } 4405 4406 /** 4407 * Finishes all activities in this task and removes it from the recent tasks list. 4408 */ finishAndRemoveTask()4409 public void finishAndRemoveTask() { 4410 try { 4411 mAppTaskImpl.finishAndRemoveTask(); 4412 } catch (RemoteException e) { 4413 throw e.rethrowFromSystemServer(); 4414 } 4415 } 4416 4417 /** 4418 * Get the RecentTaskInfo associated with this task. 4419 * 4420 * @return The RecentTaskInfo for this task, or null if the task no longer exists. 4421 */ getTaskInfo()4422 public RecentTaskInfo getTaskInfo() { 4423 try { 4424 return mAppTaskImpl.getTaskInfo(); 4425 } catch (RemoteException e) { 4426 throw e.rethrowFromSystemServer(); 4427 } 4428 } 4429 4430 /** 4431 * Bring this task to the foreground. If it contains activities, they will be 4432 * brought to the foreground with it and their instances re-created if needed. 4433 * If it doesn't contain activities, the root activity of the task will be 4434 * re-launched. 4435 */ moveToFront()4436 public void moveToFront() { 4437 try { 4438 mAppTaskImpl.moveToFront(); 4439 } catch (RemoteException e) { 4440 throw e.rethrowFromSystemServer(); 4441 } 4442 } 4443 4444 /** 4445 * Start an activity in this task. Brings the task to the foreground. If this task 4446 * is not currently active (that is, its id < 0), then a new activity for the given 4447 * Intent will be launched as the root of the task and the task brought to the 4448 * foreground. Otherwise, if this task is currently active and the Intent does not specify 4449 * an activity to launch in a new task, then a new activity for the given Intent will 4450 * be launched on top of the task and the task brought to the foreground. If this 4451 * task is currently active and the Intent specifies {@link Intent#FLAG_ACTIVITY_NEW_TASK} 4452 * or would otherwise be launched in to a new task, then the activity not launched but 4453 * this task be brought to the foreground and a new intent delivered to the top 4454 * activity if appropriate. 4455 * 4456 * <p>In other words, you generally want to use an Intent here that does not specify 4457 * {@link Intent#FLAG_ACTIVITY_NEW_TASK} or {@link Intent#FLAG_ACTIVITY_NEW_DOCUMENT}, 4458 * and let the system do the right thing.</p> 4459 * 4460 * @param intent The Intent describing the new activity to be launched on the task. 4461 * @param options Optional launch options. 4462 * 4463 * @see Activity#startActivity(android.content.Intent, android.os.Bundle) 4464 */ startActivity(Context context, Intent intent, Bundle options)4465 public void startActivity(Context context, Intent intent, Bundle options) { 4466 ActivityThread thread = ActivityThread.currentActivityThread(); 4467 thread.getInstrumentation().execStartActivityFromAppTask(context, 4468 thread.getApplicationThread(), mAppTaskImpl, intent, options); 4469 } 4470 4471 /** 4472 * Modify the {@link Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} flag in the root 4473 * Intent of this AppTask. 4474 * 4475 * @param exclude If true, {@link Intent#FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS} will 4476 * be set; otherwise, it will be cleared. 4477 */ setExcludeFromRecents(boolean exclude)4478 public void setExcludeFromRecents(boolean exclude) { 4479 try { 4480 mAppTaskImpl.setExcludeFromRecents(exclude); 4481 } catch (RemoteException e) { 4482 throw e.rethrowFromSystemServer(); 4483 } 4484 } 4485 } 4486 } 4487