1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.app; 18 19 import android.annotation.CurrentTimeMillisLong; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.app.ActivityManager.RunningAppProcessInfo.Importance; 24 import android.icu.text.SimpleDateFormat; 25 import android.os.Parcel; 26 import android.os.ParcelFileDescriptor; 27 import android.os.Parcelable; 28 import android.os.RemoteException; 29 import android.os.UserHandle; 30 import android.text.TextUtils; 31 import android.util.DebugUtils; 32 import android.util.proto.ProtoInputStream; 33 import android.util.proto.ProtoOutputStream; 34 import android.util.proto.WireTypeMismatchException; 35 36 import com.android.internal.util.ArrayUtils; 37 38 import java.io.File; 39 import java.io.IOException; 40 import java.io.InputStream; 41 import java.io.PrintWriter; 42 import java.lang.annotation.Retention; 43 import java.lang.annotation.RetentionPolicy; 44 import java.util.Date; 45 import java.util.Objects; 46 import java.util.zip.GZIPInputStream; 47 48 /** 49 * Describes the information of an application process's death. 50 * 51 * <p> 52 * Application process could die for many reasons, for example {@link #REASON_LOW_MEMORY} 53 * when it was killed by the system because it was running low on memory. Reason 54 * of the death can be retrieved via {@link #getReason}. Besides the reason, there are a few other 55 * auxiliary APIs like {@link #getStatus} and {@link #getImportance} to help the caller with 56 * additional diagnostic information. 57 * </p> 58 * 59 */ 60 public final class ApplicationExitInfo implements Parcelable { 61 62 /** 63 * Application process died due to unknown reason. 64 */ 65 public static final int REASON_UNKNOWN = 0; 66 67 /** 68 * Application process exit normally by itself, for example, 69 * via {@link java.lang.System#exit}; {@link #getStatus} will specify the exit code. 70 * 71 * <p>Applications should normally not do this, as the system has a better knowledge 72 * in terms of process management.</p> 73 */ 74 public static final int REASON_EXIT_SELF = 1; 75 76 /** 77 * Application process died due to the result of an OS signal; for example, 78 * {@link android.system.OsConstants#SIGKILL}; {@link #getStatus} will specify the signal 79 * number. 80 */ 81 public static final int REASON_SIGNALED = 2; 82 83 /** 84 * Application process was killed by the system low memory killer, meaning the system was 85 * under memory pressure at the time of kill. 86 * 87 * <p class="note"> 88 * Not all devices support reporting {@link #REASON_LOW_MEMORY}; on a device with no such 89 * support, when a process is killed due to memory pressure, the {@link #getReason} will return 90 * {@link #REASON_SIGNALED} and {@link #getStatus} will return 91 * the value {@link android.system.OsConstants#SIGKILL}. 92 * 93 * Application should use {@link android.app.ActivityManager#isLowMemoryKillReportSupported() 94 * ActivityManager.isLowMemoryKillReportSupported()} to check 95 * if the device supports reporting {@link #REASON_LOW_MEMORY} or not. 96 * </p> 97 */ 98 public static final int REASON_LOW_MEMORY = 3; 99 100 /** 101 * Application process died because of an unhandled exception in Java code. 102 */ 103 public static final int REASON_CRASH = 4; 104 105 /** 106 * Application process died because of a native code crash. 107 */ 108 public static final int REASON_CRASH_NATIVE = 5; 109 110 /** 111 * Application process was killed due to being unresponsive (ANR). 112 */ 113 public static final int REASON_ANR = 6; 114 115 /** 116 * Application process was killed because of initialization failure, 117 * for example, it took too long to attach to the system during the start, 118 * or there was an error during initialization. 119 */ 120 public static final int REASON_INITIALIZATION_FAILURE = 7; 121 122 /** 123 * Application process was killed due to a runtime permission change. 124 */ 125 public static final int REASON_PERMISSION_CHANGE = 8; 126 127 /** 128 * Application process was killed by the system due to excessive resource usage. 129 */ 130 public static final int REASON_EXCESSIVE_RESOURCE_USAGE = 9; 131 132 /** 133 * Application process was killed because of the user request, for example, 134 * user clicked the "Force stop" button of the application in the Settings, 135 * or removed the application away from Recents. 136 */ 137 public static final int REASON_USER_REQUESTED = 10; 138 139 /** 140 * Application process was killed, because the user it is running as on devices 141 * with mutlple users, was stopped. 142 */ 143 public static final int REASON_USER_STOPPED = 11; 144 145 /** 146 * Application process was killed because its dependency was going away, for example, 147 * a stable content provider connection's client will be killed if the provider is killed. 148 */ 149 public static final int REASON_DEPENDENCY_DIED = 12; 150 151 /** 152 * Application process was killed by the system for various other reasons which are 153 * not by problems in apps and not actionable by apps, for example, the system just 154 * finished updates; {@link #getDescription} will specify the cause given by the system. 155 */ 156 public static final int REASON_OTHER = 13; 157 158 /** 159 * Application process kills subreason is unknown. 160 * 161 * For internal use only. 162 * @hide 163 */ 164 public static final int SUBREASON_UNKNOWN = 0; 165 166 /** 167 * Application process was killed because user quit it on the "wait for debugger" dialog; 168 * this would be set when the reason is {@link #REASON_OTHER}. 169 * 170 * For internal use only. 171 * @hide 172 */ 173 public static final int SUBREASON_WAIT_FOR_DEBUGGER = 1; 174 175 /** 176 * Application process was killed by the activity manager because there were too many cached 177 * processes; this would be set only when the reason is {@link #REASON_OTHER}. 178 * 179 * For internal use only. 180 * @hide 181 */ 182 public static final int SUBREASON_TOO_MANY_CACHED = 2; 183 184 /** 185 * Application process was killed by the activity manager because there were too many empty 186 * processes; this would be set only when the reason is {@link #REASON_OTHER}. 187 * 188 * For internal use only. 189 * @hide 190 */ 191 public static final int SUBREASON_TOO_MANY_EMPTY = 3; 192 193 /** 194 * Application process was killed by the activity manager because there were too many cached 195 * processes and this process had been in empty state for a long time; 196 * this would be set only when the reason is {@link #REASON_OTHER}. 197 * 198 * For internal use only. 199 * @hide 200 */ 201 public static final int SUBREASON_TRIM_EMPTY = 4; 202 203 /** 204 * Application process was killed by the activity manager because system was on memory pressure 205 * and this process took large amount of cached memory; 206 * this would be set only when the reason is {@link #REASON_OTHER}. 207 * 208 * For internal use only. 209 * @hide 210 */ 211 public static final int SUBREASON_LARGE_CACHED = 5; 212 213 /** 214 * Application process was killed by the activity manager because the system was on low memory 215 * pressure for a significant amount of time since last idle; 216 * this would be set only when the reason is {@link #REASON_OTHER}. 217 * 218 * For internal use only. 219 * @hide 220 */ 221 public static final int SUBREASON_MEMORY_PRESSURE = 6; 222 223 /** 224 * Application process was killed by the activity manager due to excessive CPU usage; 225 * this would be set only when the reason is {@link #REASON_EXCESSIVE_RESOURCE_USAGE}. 226 * 227 * For internal use only. 228 * @hide 229 */ 230 public static final int SUBREASON_EXCESSIVE_CPU = 7; 231 232 /** 233 * System update has done (so the system update process should be killed); 234 * this would be set only when the reason is {@link #REASON_OTHER}. 235 * 236 * For internal use only. 237 * @hide 238 */ 239 public static final int SUBREASON_SYSTEM_UPDATE_DONE = 8; 240 241 /** 242 * Kill all foreground services, for now it only occurs when enabling the quiet 243 * mode for the managed profile; 244 * this would be set only when the reason is {@link #REASON_OTHER}. 245 * 246 * For internal use only. 247 * @hide 248 */ 249 public static final int SUBREASON_KILL_ALL_FG = 9; 250 251 /** 252 * All background processes except certain ones were killed, for now it only occurs 253 * when the density of the default display is changed; 254 * this would be set only when the reason is {@link #REASON_OTHER}. 255 * 256 * For internal use only. 257 * @hide 258 */ 259 public static final int SUBREASON_KILL_ALL_BG_EXCEPT = 10; 260 261 /** 262 * The process associated with the UID was explicitly killed, for example, 263 * it could be because of platform compatibility overrides; 264 * this would be set only when the reason is {@link #REASON_OTHER}. 265 * 266 * For internal use only. 267 * @hide 268 */ 269 public static final int SUBREASON_KILL_UID = 11; 270 271 /** 272 * The process was explicitly killed with its PID, typically because of 273 * the low memory for surfaces; 274 * this would be set only when the reason is {@link #REASON_OTHER}. 275 * 276 * For internal use only. 277 * @hide 278 */ 279 public static final int SUBREASON_KILL_PID = 12; 280 281 /** 282 * The start of the process was invalid; 283 * this would be set only when the reason is {@link #REASON_OTHER}. 284 * 285 * For internal use only. 286 * @hide 287 */ 288 public static final int SUBREASON_INVALID_START = 13; 289 290 /** 291 * The process was killed because it's in an invalid state, typically 292 * it's triggered from SHELL; 293 * this would be set only when the reason is {@link #REASON_OTHER}. 294 * 295 * For internal use only. 296 * @hide 297 */ 298 public static final int SUBREASON_INVALID_STATE = 14; 299 300 /** 301 * The process was killed when it's imperceptible to user, because it was 302 * in a bad state; 303 * this would be set only when the reason is {@link #REASON_OTHER}. 304 * 305 * For internal use only. 306 * @hide 307 */ 308 public static final int SUBREASON_IMPERCEPTIBLE = 15; 309 310 /** 311 * The process was killed because it's being moved out from LRU list; 312 * this would be set only when the reason is {@link #REASON_OTHER}. 313 * 314 * For internal use only. 315 * @hide 316 */ 317 public static final int SUBREASON_REMOVE_LRU = 16; 318 319 /** 320 * The process was killed because it's isolated and was in a cached state; 321 * this would be set only when the reason is {@link #REASON_OTHER}. 322 * 323 * For internal use only. 324 * @hide 325 */ 326 public static final int SUBREASON_ISOLATED_NOT_NEEDED = 17; 327 328 /** 329 * The process was killed because it's in forced-app-standby state, and it's cached and 330 * its uid state is idle; this would be set only when the reason is {@link #REASON_OTHER}. 331 * 332 * For internal use only. 333 * @hide 334 */ 335 public static final int SUBREASON_CACHED_IDLE_FORCED_APP_STANDBY = 18; 336 337 /** 338 * The process was killed because it fails to freeze/unfreeze binder 339 * or query binder frozen info while being frozen. 340 * this would be set only when the reason is {@link #REASON_FREEZER}. 341 * 342 * For internal use only. 343 * @hide 344 */ 345 public static final int SUBREASON_FREEZER_BINDER_IOCTL = 19; 346 347 /** 348 * The process was killed because it receives sync binder transactions 349 * while being frozen. 350 * this would be set only when the reason is {@link #REASON_FREEZER}. 351 * 352 * For internal use only. 353 * @hide 354 */ 355 public static final int SUBREASON_FREEZER_BINDER_TRANSACTION = 20; 356 357 // If there is any OEM code which involves additional app kill reasons, it should 358 // be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000. 359 360 /** 361 * @see #getPid 362 */ 363 private int mPid; 364 365 /** 366 * @see #getRealUid 367 */ 368 private int mRealUid; 369 370 /** 371 * @see #getPackageUid 372 */ 373 private int mPackageUid; 374 375 /** 376 * @see #getDefiningUid 377 */ 378 private int mDefiningUid; 379 380 /** 381 * @see #getProcessName 382 */ 383 private String mProcessName; 384 385 /** 386 * @see #getReason 387 */ 388 private @Reason int mReason; 389 390 /** 391 * @see #getStatus 392 */ 393 private int mStatus; 394 395 /** 396 * @see #getImportance 397 */ 398 private @Importance int mImportance; 399 400 /** 401 * @see #getPss 402 */ 403 private long mPss; 404 405 /** 406 * @see #getRss 407 */ 408 private long mRss; 409 410 /** 411 * @see #getTimestamp 412 */ 413 private @CurrentTimeMillisLong long mTimestamp; 414 415 /** 416 * @see #getDescription 417 */ 418 private @Nullable String mDescription; 419 420 /** 421 * @see #getSubReason 422 */ 423 private @SubReason int mSubReason; 424 425 /** 426 * @see #getConnectionGroup 427 */ 428 private int mConnectionGroup; 429 430 /** 431 * @see #getPackageName 432 */ 433 private String mPackageName; 434 435 /** 436 * @see #getPackageList 437 */ 438 private String[] mPackageList; 439 440 /** 441 * @see #getProcessStateSummary 442 */ 443 private byte[] mState; 444 445 /** 446 * The file to the trace file in the storage; 447 * 448 * for system internal use only, will not retain across processes. 449 * 450 * @see #getTraceInputStream 451 */ 452 private File mTraceFile; 453 454 /** 455 * The Binder interface to retrieve the file descriptor to 456 * the trace file from the system. 457 */ 458 private IAppTraceRetriever mAppTraceRetriever; 459 460 /** 461 * ParcelFileDescriptor pointing to a native tombstone. 462 * 463 * @see #getTraceInputStream 464 */ 465 private IParcelFileDescriptorRetriever mNativeTombstoneRetriever; 466 467 /** 468 * Whether or not we've logged this into the statsd. 469 * 470 * for system internal use only, will not retain across processes. 471 */ 472 private boolean mLoggedInStatsd; 473 474 /** @hide */ 475 @IntDef(prefix = { "REASON_" }, value = { 476 REASON_UNKNOWN, 477 REASON_EXIT_SELF, 478 REASON_SIGNALED, 479 REASON_LOW_MEMORY, 480 REASON_CRASH, 481 REASON_CRASH_NATIVE, 482 REASON_ANR, 483 REASON_INITIALIZATION_FAILURE, 484 REASON_PERMISSION_CHANGE, 485 REASON_EXCESSIVE_RESOURCE_USAGE, 486 REASON_USER_REQUESTED, 487 REASON_USER_STOPPED, 488 REASON_DEPENDENCY_DIED, 489 REASON_OTHER, 490 }) 491 @Retention(RetentionPolicy.SOURCE) 492 public @interface Reason {} 493 494 /** @hide */ 495 @IntDef(prefix = { "SUBREASON_" }, value = { 496 SUBREASON_UNKNOWN, 497 SUBREASON_WAIT_FOR_DEBUGGER, 498 SUBREASON_TOO_MANY_CACHED, 499 SUBREASON_TOO_MANY_EMPTY, 500 SUBREASON_TRIM_EMPTY, 501 SUBREASON_LARGE_CACHED, 502 SUBREASON_MEMORY_PRESSURE, 503 SUBREASON_EXCESSIVE_CPU, 504 SUBREASON_SYSTEM_UPDATE_DONE, 505 SUBREASON_KILL_ALL_FG, 506 SUBREASON_KILL_ALL_BG_EXCEPT, 507 SUBREASON_KILL_UID, 508 SUBREASON_KILL_PID, 509 SUBREASON_INVALID_START, 510 SUBREASON_INVALID_STATE, 511 SUBREASON_IMPERCEPTIBLE, 512 SUBREASON_REMOVE_LRU, 513 SUBREASON_ISOLATED_NOT_NEEDED, 514 SUBREASON_FREEZER_BINDER_IOCTL, 515 SUBREASON_FREEZER_BINDER_TRANSACTION, 516 }) 517 @Retention(RetentionPolicy.SOURCE) 518 public @interface SubReason {} 519 520 /** 521 * The process id of the process that died. 522 */ getPid()523 public int getPid() { 524 return mPid; 525 } 526 527 /** 528 * The kernel user identifier of the process, most of the time the system uses this 529 * to do access control checks. It's typically the uid of the package where the component is 530 * running from, except the case of isolated process, where this field identifies the kernel 531 * user identifier that this process is actually running with, while the {@link #getPackageUid} 532 * identifies the kernel user identifier that is assigned at the package installation time. 533 */ getRealUid()534 public int getRealUid() { 535 return mRealUid; 536 } 537 538 /** 539 * Similar to {@link #getRealUid}, it's the kernel user identifier that is assigned at the 540 * package installation time. 541 */ getPackageUid()542 public int getPackageUid() { 543 return mPackageUid; 544 } 545 546 /** 547 * Return the defining kernel user identifier, maybe different from {@link #getRealUid} and 548 * {@link #getPackageUid}, if an external service has the 549 * {@link android.R.styleable#AndroidManifestService_useAppZygote android:useAppZygote} set 550 * to <code>true</code> and was bound with the flag 551 * {@link android.content.Context#BIND_EXTERNAL_SERVICE} - in this case, this field here will 552 * be the kernel user identifier of the external service provider. 553 */ getDefiningUid()554 public int getDefiningUid() { 555 return mDefiningUid; 556 } 557 558 /** 559 * The actual process name it was running with. 560 */ getProcessName()561 public @NonNull String getProcessName() { 562 return mProcessName; 563 } 564 565 /** 566 * The reason code of the process's death. 567 */ getReason()568 public @Reason int getReason() { 569 return mReason; 570 } 571 572 /** 573 * The exit status argument of exit() if the application calls it, or the signal 574 * number if the application is signaled. 575 */ getStatus()576 public int getStatus() { 577 return mStatus; 578 } 579 580 /** 581 * The importance of the process that it used to have before the death. 582 */ getImportance()583 public @Importance int getImportance() { 584 return mImportance; 585 } 586 587 /** 588 * Last proportional set size of the memory that the process had used in kB. 589 * 590 * <p class="note">Note: This is the value from last sampling on the process, 591 * it's NOT the exact memory information prior to its death; and it'll be zero 592 * if the process died before system had a chance to take the sample. </p> 593 */ getPss()594 public long getPss() { 595 return mPss; 596 } 597 598 /** 599 * Last resident set size of the memory that the process had used in kB. 600 * 601 * <p class="note">Note: This is the value from last sampling on the process, 602 * it's NOT the exact memory information prior to its death; and it'll be zero 603 * if the process died before system had a chance to take the sample. </p> 604 */ getRss()605 public long getRss() { 606 return mRss; 607 } 608 609 /** 610 * The timestamp of the process's death, in milliseconds since the epoch, 611 * as returned by {@link java.lang.System#currentTimeMillis() System.currentTimeMillis()}. 612 */ getTimestamp()613 public @CurrentTimeMillisLong long getTimestamp() { 614 return mTimestamp; 615 } 616 617 /** 618 * The human readable description of the process's death, given by the system; could be null. 619 * 620 * <p class="note">Note: only intended to be human-readable and the system provides no 621 * guarantees that the format is stable across devices or Android releases.</p> 622 */ getDescription()623 public @Nullable String getDescription() { 624 return mDescription; 625 } 626 627 /** 628 * Return the user id of the record on a multi-user system. 629 */ getUserHandle()630 public @NonNull UserHandle getUserHandle() { 631 return UserHandle.of(UserHandle.getUserId(mRealUid)); 632 } 633 634 /** 635 * Return the state data set by calling 636 * {@link android.app.ActivityManager#setProcessStateSummary(byte[]) 637 * ActivityManager.setProcessStateSummary(byte[])} from the process before its death. 638 * 639 * @return The process-customized data 640 * @see ActivityManager#setProcessStateSummary(byte[]) 641 */ getProcessStateSummary()642 public @Nullable byte[] getProcessStateSummary() { 643 return mState; 644 } 645 646 /** 647 * Return the InputStream to the traces that was taken by the system 648 * prior to the death of the process; typically it'll be available when 649 * the reason is {@link #REASON_ANR}, though if the process gets an ANR 650 * but recovers, and dies for another reason later, this trace will be included 651 * in the record of {@link ApplicationExitInfo} still. Beginning with API 31, 652 * tombstone traces will be returned for 653 * {@link #REASON_CRASH_NATIVE}, with an InputStream containing a protobuf with 654 * <a href="https://android.googlesource.com/platform/system/core/+/refs/heads/master/debuggerd/proto/tombstone.proto">this schema</a>. 655 * Note that because these traces are kept in a separate global circular buffer, crashes may be 656 * overwritten by newer crashes (including from other applications), so this may still return 657 * null. 658 * 659 * @return The input stream to the traces that was taken by the system 660 * prior to the death of the process. 661 */ getTraceInputStream()662 public @Nullable InputStream getTraceInputStream() throws IOException { 663 if (mAppTraceRetriever == null && mNativeTombstoneRetriever == null) { 664 return null; 665 } 666 667 try { 668 if (mNativeTombstoneRetriever != null) { 669 final ParcelFileDescriptor pfd = mNativeTombstoneRetriever.getPfd(); 670 if (pfd == null) { 671 return null; 672 } 673 674 return new ParcelFileDescriptor.AutoCloseInputStream(pfd); 675 } else { 676 final ParcelFileDescriptor fd = mAppTraceRetriever.getTraceFileDescriptor( 677 mPackageName, mPackageUid, mPid); 678 if (fd == null) { 679 return null; 680 } 681 return new GZIPInputStream(new ParcelFileDescriptor.AutoCloseInputStream(fd)); 682 } 683 } catch (RemoteException e) { 684 return null; 685 } 686 } 687 688 /** 689 * Similar to {@link #getTraceInputStream} but return the File object. 690 * 691 * For internal use only. 692 * 693 * @hide 694 */ getTraceFile()695 public @Nullable File getTraceFile() { 696 return mTraceFile; 697 } 698 699 /** 700 * A subtype reason in conjunction with {@link #mReason}. 701 * 702 * For internal use only. 703 * 704 * @hide 705 */ getSubReason()706 public @SubReason int getSubReason() { 707 return mSubReason; 708 } 709 710 /** 711 * The connection group this process belongs to, if there is any. 712 * @see android.content.Context#updateServiceGroup 713 * 714 * For internal use only. 715 * 716 * @hide 717 */ getConnectionGroup()718 public int getConnectionGroup() { 719 return mConnectionGroup; 720 } 721 722 /** 723 * Name of first package running in this process; 724 * 725 * @hide 726 */ getPackageName()727 public String getPackageName() { 728 return mPackageName; 729 } 730 731 /** 732 * List of packages running in this process; 733 * 734 * For system internal use only, will not retain across processes. 735 * 736 * @hide 737 */ getPackageList()738 public String[] getPackageList() { 739 return mPackageList; 740 } 741 742 /** 743 * @see #getPid 744 * 745 * @hide 746 */ setPid(final int pid)747 public void setPid(final int pid) { 748 mPid = pid; 749 } 750 751 /** 752 * @see #getRealUid 753 * 754 * @hide 755 */ setRealUid(final int uid)756 public void setRealUid(final int uid) { 757 mRealUid = uid; 758 } 759 760 /** 761 * @see #getPackageUid 762 * 763 * @hide 764 */ setPackageUid(final int uid)765 public void setPackageUid(final int uid) { 766 mPackageUid = uid; 767 } 768 769 /** 770 * @see #getDefiningUid 771 * 772 * @hide 773 */ setDefiningUid(final int uid)774 public void setDefiningUid(final int uid) { 775 mDefiningUid = uid; 776 } 777 778 /** 779 * @see #getProcessName 780 * 781 * @hide 782 */ setProcessName(final String processName)783 public void setProcessName(final String processName) { 784 mProcessName = processName; 785 } 786 787 /** 788 * @see #getReason 789 * 790 * @hide 791 */ setReason(final @Reason int reason)792 public void setReason(final @Reason int reason) { 793 mReason = reason; 794 } 795 796 /** 797 * @see #getStatus 798 * 799 * @hide 800 */ setStatus(final int status)801 public void setStatus(final int status) { 802 mStatus = status; 803 } 804 805 /** 806 * @see #getImportance 807 * 808 * @hide 809 */ setImportance(final @Importance int importance)810 public void setImportance(final @Importance int importance) { 811 mImportance = importance; 812 } 813 814 /** 815 * @see #getPss 816 * 817 * @hide 818 */ setPss(final long pss)819 public void setPss(final long pss) { 820 mPss = pss; 821 } 822 823 /** 824 * @see #getRss 825 * 826 * @hide 827 */ setRss(final long rss)828 public void setRss(final long rss) { 829 mRss = rss; 830 } 831 832 /** 833 * @see #getTimestamp 834 * 835 * @hide 836 */ setTimestamp(final @CurrentTimeMillisLong long timestamp)837 public void setTimestamp(final @CurrentTimeMillisLong long timestamp) { 838 mTimestamp = timestamp; 839 } 840 841 /** 842 * @see #getDescription 843 * 844 * @hide 845 */ setDescription(final String description)846 public void setDescription(final String description) { 847 mDescription = description; 848 } 849 850 /** 851 * @see #getSubReason 852 * 853 * @hide 854 */ setSubReason(final @SubReason int subReason)855 public void setSubReason(final @SubReason int subReason) { 856 mSubReason = subReason; 857 } 858 859 /** 860 * @see #getConnectionGroup 861 * 862 * @hide 863 */ setConnectionGroup(final int connectionGroup)864 public void setConnectionGroup(final int connectionGroup) { 865 mConnectionGroup = connectionGroup; 866 } 867 868 /** 869 * @see #getPackageName 870 * 871 * @hide 872 */ setPackageName(final String packageName)873 public void setPackageName(final String packageName) { 874 mPackageName = packageName; 875 } 876 877 /** 878 * @see #getPackageList 879 * 880 * @hide 881 */ setPackageList(final String[] packageList)882 public void setPackageList(final String[] packageList) { 883 mPackageList = packageList; 884 } 885 886 /** 887 * @see #getProcessStateSummary 888 * 889 * @hide 890 */ setProcessStateSummary(final byte[] state)891 public void setProcessStateSummary(final byte[] state) { 892 mState = state; 893 } 894 895 /** 896 * @see #getTraceFile 897 * 898 * @hide 899 */ setTraceFile(final File traceFile)900 public void setTraceFile(final File traceFile) { 901 mTraceFile = traceFile; 902 } 903 904 /** 905 * @see #mAppTraceRetriever 906 * 907 * @hide 908 */ setAppTraceRetriever(final IAppTraceRetriever retriever)909 public void setAppTraceRetriever(final IAppTraceRetriever retriever) { 910 mAppTraceRetriever = retriever; 911 } 912 913 /** 914 * @see mNativeTombstoneRetriever 915 * 916 * @hide 917 */ setNativeTombstoneRetriever(final IParcelFileDescriptorRetriever retriever)918 public void setNativeTombstoneRetriever(final IParcelFileDescriptorRetriever retriever) { 919 mNativeTombstoneRetriever = retriever; 920 } 921 922 /** 923 * @see #mLoggedInStatsd 924 * 925 * @hide 926 */ isLoggedInStatsd()927 public boolean isLoggedInStatsd() { 928 return mLoggedInStatsd; 929 } 930 931 /** 932 * @see #mLoggedInStatsd 933 * 934 * @hide 935 */ setLoggedInStatsd(boolean loggedInStatsd)936 public void setLoggedInStatsd(boolean loggedInStatsd) { 937 mLoggedInStatsd = loggedInStatsd; 938 } 939 940 @Override describeContents()941 public int describeContents() { 942 return 0; 943 } 944 945 @Override writeToParcel(@onNull Parcel dest, int flags)946 public void writeToParcel(@NonNull Parcel dest, int flags) { 947 dest.writeInt(mPid); 948 dest.writeInt(mRealUid); 949 dest.writeInt(mPackageUid); 950 dest.writeInt(mDefiningUid); 951 dest.writeString(mProcessName); 952 dest.writeString(mPackageName); 953 dest.writeInt(mConnectionGroup); 954 dest.writeInt(mReason); 955 dest.writeInt(mSubReason); 956 dest.writeInt(mStatus); 957 dest.writeInt(mImportance); 958 dest.writeLong(mPss); 959 dest.writeLong(mRss); 960 dest.writeLong(mTimestamp); 961 dest.writeString(mDescription); 962 dest.writeByteArray(mState); 963 if (mAppTraceRetriever != null) { 964 dest.writeInt(1); 965 dest.writeStrongBinder(mAppTraceRetriever.asBinder()); 966 } else { 967 dest.writeInt(0); 968 } 969 if (mNativeTombstoneRetriever != null) { 970 dest.writeInt(1); 971 dest.writeStrongBinder(mNativeTombstoneRetriever.asBinder()); 972 } else { 973 dest.writeInt(0); 974 } 975 } 976 977 /** @hide */ ApplicationExitInfo()978 public ApplicationExitInfo() { 979 } 980 981 /** @hide */ ApplicationExitInfo(ApplicationExitInfo other)982 public ApplicationExitInfo(ApplicationExitInfo other) { 983 mPid = other.mPid; 984 mRealUid = other.mRealUid; 985 mPackageUid = other.mPackageUid; 986 mDefiningUid = other.mDefiningUid; 987 mProcessName = other.mProcessName; 988 mPackageName = other.mPackageName; 989 mConnectionGroup = other.mConnectionGroup; 990 mReason = other.mReason; 991 mStatus = other.mStatus; 992 mSubReason = other.mSubReason; 993 mImportance = other.mImportance; 994 mPss = other.mPss; 995 mRss = other.mRss; 996 mTimestamp = other.mTimestamp; 997 mDescription = other.mDescription; 998 mPackageName = other.mPackageName; 999 mPackageList = other.mPackageList; 1000 mState = other.mState; 1001 mTraceFile = other.mTraceFile; 1002 mAppTraceRetriever = other.mAppTraceRetriever; 1003 mNativeTombstoneRetriever = other.mNativeTombstoneRetriever; 1004 } 1005 ApplicationExitInfo(@onNull Parcel in)1006 private ApplicationExitInfo(@NonNull Parcel in) { 1007 mPid = in.readInt(); 1008 mRealUid = in.readInt(); 1009 mPackageUid = in.readInt(); 1010 mDefiningUid = in.readInt(); 1011 mProcessName = in.readString(); 1012 mPackageName = in.readString(); 1013 mConnectionGroup = in.readInt(); 1014 mReason = in.readInt(); 1015 mSubReason = in.readInt(); 1016 mStatus = in.readInt(); 1017 mImportance = in.readInt(); 1018 mPss = in.readLong(); 1019 mRss = in.readLong(); 1020 mTimestamp = in.readLong(); 1021 mDescription = in.readString(); 1022 mState = in.createByteArray(); 1023 if (in.readInt() == 1) { 1024 mAppTraceRetriever = IAppTraceRetriever.Stub.asInterface(in.readStrongBinder()); 1025 } 1026 if (in.readInt() == 1) { 1027 mNativeTombstoneRetriever = IParcelFileDescriptorRetriever.Stub.asInterface( 1028 in.readStrongBinder()); 1029 } 1030 } 1031 1032 public @NonNull static final Creator<ApplicationExitInfo> CREATOR = 1033 new Creator<ApplicationExitInfo>() { 1034 @Override 1035 public ApplicationExitInfo createFromParcel(Parcel in) { 1036 return new ApplicationExitInfo(in); 1037 } 1038 1039 @Override 1040 public ApplicationExitInfo[] newArray(int size) { 1041 return new ApplicationExitInfo[size]; 1042 } 1043 }; 1044 1045 /** @hide */ dump(@onNull PrintWriter pw, @Nullable String prefix, @Nullable String seqSuffix, @NonNull SimpleDateFormat sdf)1046 public void dump(@NonNull PrintWriter pw, @Nullable String prefix, @Nullable String seqSuffix, 1047 @NonNull SimpleDateFormat sdf) { 1048 pw.println(prefix + "ApplicationExitInfo " + seqSuffix + ":"); 1049 pw.println(prefix + " timestamp=" + sdf.format(new Date(mTimestamp))); 1050 pw.println(prefix + " pid=" + mPid); 1051 pw.println(prefix + " realUid=" + mRealUid); 1052 pw.println(prefix + " packageUid=" + mPackageUid); 1053 pw.println(prefix + " definingUid=" + mDefiningUid); 1054 pw.println(prefix + " user=" + UserHandle.getUserId(mPackageUid)); 1055 pw.println(prefix + " process=" + mProcessName); 1056 pw.println(prefix + " reason=" + mReason + " (" + reasonCodeToString(mReason) + ")"); 1057 pw.println(prefix + " subreason=" + mSubReason + " (" + subreasonToString(mSubReason) 1058 + ")"); 1059 pw.println(prefix + " status=" + mStatus); 1060 pw.println(prefix + " importance=" + mImportance); 1061 pw.print(prefix + " pss="); DebugUtils.printSizeValue(pw, mPss << 10); pw.println(); 1062 pw.print(prefix + " rss="); DebugUtils.printSizeValue(pw, mRss << 10); pw.println(); 1063 pw.println(prefix + " description=" + mDescription); 1064 pw.println(prefix + " state=" + (ArrayUtils.isEmpty(mState) 1065 ? "empty" : Integer.toString(mState.length) + " bytes")); 1066 pw.println(prefix + " trace=" + mTraceFile); 1067 } 1068 1069 @Override toString()1070 public String toString() { 1071 StringBuilder sb = new StringBuilder(); 1072 sb.append("ApplicationExitInfo(timestamp="); 1073 sb.append(new SimpleDateFormat().format(new Date(mTimestamp))); 1074 sb.append(" pid=").append(mPid); 1075 sb.append(" realUid=").append(mRealUid); 1076 sb.append(" packageUid=").append(mPackageUid); 1077 sb.append(" definingUid=").append(mDefiningUid); 1078 sb.append(" user=").append(UserHandle.getUserId(mPackageUid)); 1079 sb.append(" process=").append(mProcessName); 1080 sb.append(" reason=").append(mReason).append(" (") 1081 .append(reasonCodeToString(mReason)).append(")"); 1082 sb.append(" subreason=").append(mSubReason).append(" (") 1083 .append(subreasonToString(mSubReason)).append(")"); 1084 sb.append(" status=").append(mStatus); 1085 sb.append(" importance=").append(mImportance); 1086 sb.append(" pss="); DebugUtils.sizeValueToString(mPss << 10, sb); 1087 sb.append(" rss="); DebugUtils.sizeValueToString(mRss << 10, sb); 1088 sb.append(" description=").append(mDescription); 1089 sb.append(" state=").append(ArrayUtils.isEmpty(mState) 1090 ? "empty" : Integer.toString(mState.length) + " bytes"); 1091 sb.append(" trace=").append(mTraceFile); 1092 1093 return sb.toString(); 1094 } 1095 reasonCodeToString(@eason int reason)1096 private static String reasonCodeToString(@Reason int reason) { 1097 switch (reason) { 1098 case REASON_EXIT_SELF: 1099 return "EXIT_SELF"; 1100 case REASON_SIGNALED: 1101 return "SIGNALED"; 1102 case REASON_LOW_MEMORY: 1103 return "LOW_MEMORY"; 1104 case REASON_CRASH: 1105 return "APP CRASH(EXCEPTION)"; 1106 case REASON_CRASH_NATIVE: 1107 return "APP CRASH(NATIVE)"; 1108 case REASON_ANR: 1109 return "ANR"; 1110 case REASON_INITIALIZATION_FAILURE: 1111 return "INITIALIZATION FAILURE"; 1112 case REASON_PERMISSION_CHANGE: 1113 return "PERMISSION CHANGE"; 1114 case REASON_EXCESSIVE_RESOURCE_USAGE: 1115 return "EXCESSIVE RESOURCE USAGE"; 1116 case REASON_USER_REQUESTED: 1117 return "USER REQUESTED"; 1118 case REASON_USER_STOPPED: 1119 return "USER STOPPED"; 1120 case REASON_DEPENDENCY_DIED: 1121 return "DEPENDENCY DIED"; 1122 case REASON_OTHER: 1123 return "OTHER KILLS BY SYSTEM"; 1124 default: 1125 return "UNKNOWN"; 1126 } 1127 } 1128 1129 /** @hide */ subreasonToString(@ubReason int subreason)1130 public static String subreasonToString(@SubReason int subreason) { 1131 switch (subreason) { 1132 case SUBREASON_WAIT_FOR_DEBUGGER: 1133 return "WAIT FOR DEBUGGER"; 1134 case SUBREASON_TOO_MANY_CACHED: 1135 return "TOO MANY CACHED PROCS"; 1136 case SUBREASON_TOO_MANY_EMPTY: 1137 return "TOO MANY EMPTY PROCS"; 1138 case SUBREASON_TRIM_EMPTY: 1139 return "TRIM EMPTY"; 1140 case SUBREASON_LARGE_CACHED: 1141 return "LARGE CACHED"; 1142 case SUBREASON_MEMORY_PRESSURE: 1143 return "MEMORY PRESSURE"; 1144 case SUBREASON_EXCESSIVE_CPU: 1145 return "EXCESSIVE CPU USAGE"; 1146 case SUBREASON_SYSTEM_UPDATE_DONE: 1147 return "SYSTEM UPDATE_DONE"; 1148 case SUBREASON_KILL_ALL_FG: 1149 return "KILL ALL FG"; 1150 case SUBREASON_KILL_ALL_BG_EXCEPT: 1151 return "KILL ALL BG EXCEPT"; 1152 case SUBREASON_KILL_UID: 1153 return "KILL UID"; 1154 case SUBREASON_KILL_PID: 1155 return "KILL PID"; 1156 case SUBREASON_INVALID_START: 1157 return "INVALID START"; 1158 case SUBREASON_INVALID_STATE: 1159 return "INVALID STATE"; 1160 case SUBREASON_IMPERCEPTIBLE: 1161 return "IMPERCEPTIBLE"; 1162 case SUBREASON_REMOVE_LRU: 1163 return "REMOVE LRU"; 1164 case SUBREASON_ISOLATED_NOT_NEEDED: 1165 return "ISOLATED NOT NEEDED"; 1166 case SUBREASON_FREEZER_BINDER_IOCTL: 1167 return "FREEZER BINDER IOCTL"; 1168 case SUBREASON_FREEZER_BINDER_TRANSACTION: 1169 return "FREEZER BINDER TRANSACTION"; 1170 default: 1171 return "UNKNOWN"; 1172 } 1173 } 1174 1175 /** 1176 * Write to a protocol buffer output stream. 1177 * Protocol buffer message definition at {@link android.app.ApplicationExitInfoProto} 1178 * 1179 * @param proto Stream to write the ApplicationExitInfo object to. 1180 * @param fieldId Field Id of the ApplicationExitInfo as defined in the parent message 1181 * @hide 1182 */ writeToProto(ProtoOutputStream proto, long fieldId)1183 public void writeToProto(ProtoOutputStream proto, long fieldId) { 1184 final long token = proto.start(fieldId); 1185 proto.write(ApplicationExitInfoProto.PID, mPid); 1186 proto.write(ApplicationExitInfoProto.REAL_UID, mRealUid); 1187 proto.write(ApplicationExitInfoProto.PACKAGE_UID, mPackageUid); 1188 proto.write(ApplicationExitInfoProto.DEFINING_UID, mDefiningUid); 1189 proto.write(ApplicationExitInfoProto.PROCESS_NAME, mProcessName); 1190 proto.write(ApplicationExitInfoProto.CONNECTION_GROUP, mConnectionGroup); 1191 proto.write(ApplicationExitInfoProto.REASON, mReason); 1192 proto.write(ApplicationExitInfoProto.SUB_REASON, mSubReason); 1193 proto.write(ApplicationExitInfoProto.STATUS, mStatus); 1194 proto.write(ApplicationExitInfoProto.IMPORTANCE, mImportance); 1195 proto.write(ApplicationExitInfoProto.PSS, mPss); 1196 proto.write(ApplicationExitInfoProto.RSS, mRss); 1197 proto.write(ApplicationExitInfoProto.TIMESTAMP, mTimestamp); 1198 proto.write(ApplicationExitInfoProto.DESCRIPTION, mDescription); 1199 proto.write(ApplicationExitInfoProto.STATE, mState); 1200 proto.write(ApplicationExitInfoProto.TRACE_FILE, 1201 mTraceFile == null ? null : mTraceFile.getAbsolutePath()); 1202 proto.end(token); 1203 } 1204 1205 /** 1206 * Read from a protocol buffer input stream. 1207 * Protocol buffer message definition at {@link android.app.ApplicationExitInfoProto} 1208 * 1209 * @param proto Stream to read the ApplicationExitInfo object from. 1210 * @param fieldId Field Id of the ApplicationExitInfo as defined in the parent message 1211 * @hide 1212 */ readFromProto(ProtoInputStream proto, long fieldId)1213 public void readFromProto(ProtoInputStream proto, long fieldId) 1214 throws IOException, WireTypeMismatchException { 1215 final long token = proto.start(fieldId); 1216 while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) { 1217 switch (proto.getFieldNumber()) { 1218 case (int) ApplicationExitInfoProto.PID: 1219 mPid = proto.readInt(ApplicationExitInfoProto.PID); 1220 break; 1221 case (int) ApplicationExitInfoProto.REAL_UID: 1222 mRealUid = proto.readInt(ApplicationExitInfoProto.REAL_UID); 1223 break; 1224 case (int) ApplicationExitInfoProto.PACKAGE_UID: 1225 mPackageUid = proto.readInt(ApplicationExitInfoProto.PACKAGE_UID); 1226 break; 1227 case (int) ApplicationExitInfoProto.DEFINING_UID: 1228 mDefiningUid = proto.readInt(ApplicationExitInfoProto.DEFINING_UID); 1229 break; 1230 case (int) ApplicationExitInfoProto.PROCESS_NAME: 1231 mProcessName = proto.readString(ApplicationExitInfoProto.PROCESS_NAME); 1232 break; 1233 case (int) ApplicationExitInfoProto.CONNECTION_GROUP: 1234 mConnectionGroup = proto.readInt(ApplicationExitInfoProto.CONNECTION_GROUP); 1235 break; 1236 case (int) ApplicationExitInfoProto.REASON: 1237 mReason = proto.readInt(ApplicationExitInfoProto.REASON); 1238 break; 1239 case (int) ApplicationExitInfoProto.SUB_REASON: 1240 mSubReason = proto.readInt(ApplicationExitInfoProto.SUB_REASON); 1241 break; 1242 case (int) ApplicationExitInfoProto.STATUS: 1243 mStatus = proto.readInt(ApplicationExitInfoProto.STATUS); 1244 break; 1245 case (int) ApplicationExitInfoProto.IMPORTANCE: 1246 mImportance = proto.readInt(ApplicationExitInfoProto.IMPORTANCE); 1247 break; 1248 case (int) ApplicationExitInfoProto.PSS: 1249 mPss = proto.readLong(ApplicationExitInfoProto.PSS); 1250 break; 1251 case (int) ApplicationExitInfoProto.RSS: 1252 mRss = proto.readLong(ApplicationExitInfoProto.RSS); 1253 break; 1254 case (int) ApplicationExitInfoProto.TIMESTAMP: 1255 mTimestamp = proto.readLong(ApplicationExitInfoProto.TIMESTAMP); 1256 break; 1257 case (int) ApplicationExitInfoProto.DESCRIPTION: 1258 mDescription = proto.readString(ApplicationExitInfoProto.DESCRIPTION); 1259 break; 1260 case (int) ApplicationExitInfoProto.STATE: 1261 mState = proto.readBytes(ApplicationExitInfoProto.STATE); 1262 break; 1263 case (int) ApplicationExitInfoProto.TRACE_FILE: 1264 final String path = proto.readString(ApplicationExitInfoProto.TRACE_FILE); 1265 if (!TextUtils.isEmpty(path)) { 1266 mTraceFile = new File(path); 1267 } 1268 break; 1269 } 1270 } 1271 proto.end(token); 1272 } 1273 1274 @Override equals(@ullable Object other)1275 public boolean equals(@Nullable Object other) { 1276 if (other == null || !(other instanceof ApplicationExitInfo)) { 1277 return false; 1278 } 1279 ApplicationExitInfo o = (ApplicationExitInfo) other; 1280 return mPid == o.mPid && mRealUid == o.mRealUid && mPackageUid == o.mPackageUid 1281 && mDefiningUid == o.mDefiningUid 1282 && mConnectionGroup == o.mConnectionGroup && mReason == o.mReason 1283 && mSubReason == o.mSubReason && mImportance == o.mImportance 1284 && mStatus == o.mStatus && mTimestamp == o.mTimestamp 1285 && mPss == o.mPss && mRss == o.mRss 1286 && TextUtils.equals(mProcessName, o.mProcessName) 1287 && TextUtils.equals(mDescription, o.mDescription); 1288 } 1289 1290 @Override hashCode()1291 public int hashCode() { 1292 int result = mPid; 1293 result = 31 * result + mRealUid; 1294 result = 31 * result + mPackageUid; 1295 result = 31 * result + mDefiningUid; 1296 result = 31 * result + mConnectionGroup; 1297 result = 31 * result + mReason; 1298 result = 31 * result + mSubReason; 1299 result = 31 * result + mImportance; 1300 result = 31 * result + mStatus; 1301 result = 31 * result + (int) mPss; 1302 result = 31 * result + (int) mRss; 1303 result = 31 * result + Long.hashCode(mTimestamp); 1304 result = 31 * result + Objects.hashCode(mProcessName); 1305 result = 31 * result + Objects.hashCode(mDescription); 1306 return result; 1307 } 1308 } 1309