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 ystem 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 // If there is any OEM code which involves additional app kill reasons, it should 329 // be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000. 330 331 /** 332 * @see #getPid 333 */ 334 private int mPid; 335 336 /** 337 * @see #getRealUid 338 */ 339 private int mRealUid; 340 341 /** 342 * @see #getPackageUid 343 */ 344 private int mPackageUid; 345 346 /** 347 * @see #getDefiningUid 348 */ 349 private int mDefiningUid; 350 351 /** 352 * @see #getProcessName 353 */ 354 private String mProcessName; 355 356 /** 357 * @see #getReason 358 */ 359 private @Reason int mReason; 360 361 /** 362 * @see #getStatus 363 */ 364 private int mStatus; 365 366 /** 367 * @see #getImportance 368 */ 369 private @Importance int mImportance; 370 371 /** 372 * @see #getPss 373 */ 374 private long mPss; 375 376 /** 377 * @see #getRss 378 */ 379 private long mRss; 380 381 /** 382 * @see #getTimestamp 383 */ 384 private @CurrentTimeMillisLong long mTimestamp; 385 386 /** 387 * @see #getDescription 388 */ 389 private @Nullable String mDescription; 390 391 /** 392 * @see #getSubReason 393 */ 394 private @SubReason int mSubReason; 395 396 /** 397 * @see #getConnectionGroup 398 */ 399 private int mConnectionGroup; 400 401 /** 402 * @see #getPackageName 403 */ 404 private String mPackageName; 405 406 /** 407 * @see #getPackageList 408 */ 409 private String[] mPackageList; 410 411 /** 412 * @see #getProcessStateSummary 413 */ 414 private byte[] mState; 415 416 /** 417 * The file to the trace file in the storage; 418 * 419 * for system internal use only, will not retain across processes. 420 * 421 * @see #getTraceInputStream 422 */ 423 private File mTraceFile; 424 425 /** 426 * The Binder interface to retrieve the file descriptor to 427 * the trace file from the system. 428 */ 429 private IAppTraceRetriever mAppTraceRetriever; 430 431 /** @hide */ 432 @IntDef(prefix = { "REASON_" }, value = { 433 REASON_UNKNOWN, 434 REASON_EXIT_SELF, 435 REASON_SIGNALED, 436 REASON_LOW_MEMORY, 437 REASON_CRASH, 438 REASON_CRASH_NATIVE, 439 REASON_ANR, 440 REASON_INITIALIZATION_FAILURE, 441 REASON_PERMISSION_CHANGE, 442 REASON_EXCESSIVE_RESOURCE_USAGE, 443 REASON_USER_REQUESTED, 444 REASON_USER_STOPPED, 445 REASON_DEPENDENCY_DIED, 446 REASON_OTHER, 447 }) 448 @Retention(RetentionPolicy.SOURCE) 449 public @interface Reason {} 450 451 /** @hide */ 452 @IntDef(prefix = { "SUBREASON_" }, value = { 453 SUBREASON_UNKNOWN, 454 SUBREASON_WAIT_FOR_DEBUGGER, 455 SUBREASON_TOO_MANY_CACHED, 456 SUBREASON_TOO_MANY_EMPTY, 457 SUBREASON_TRIM_EMPTY, 458 SUBREASON_LARGE_CACHED, 459 SUBREASON_MEMORY_PRESSURE, 460 SUBREASON_EXCESSIVE_CPU, 461 SUBREASON_SYSTEM_UPDATE_DONE, 462 SUBREASON_KILL_ALL_FG, 463 SUBREASON_KILL_ALL_BG_EXCEPT, 464 SUBREASON_KILL_UID, 465 SUBREASON_KILL_PID, 466 SUBREASON_INVALID_START, 467 SUBREASON_INVALID_STATE, 468 SUBREASON_IMPERCEPTIBLE, 469 SUBREASON_REMOVE_LRU, 470 SUBREASON_ISOLATED_NOT_NEEDED, 471 }) 472 @Retention(RetentionPolicy.SOURCE) 473 public @interface SubReason {} 474 475 /** 476 * The process id of the process that died. 477 */ getPid()478 public int getPid() { 479 return mPid; 480 } 481 482 /** 483 * The kernel user identifier of the process, most of the time the system uses this 484 * to do access control checks. It's typically the uid of the package where the component is 485 * running from, except the case of isolated process, where this field identifies the kernel 486 * user identifier that this process is actually running with, while the {@link #getPackageUid} 487 * identifies the kernel user identifier that is assigned at the package installation time. 488 */ getRealUid()489 public int getRealUid() { 490 return mRealUid; 491 } 492 493 /** 494 * Similar to {@link #getRealUid}, it's the kernel user identifier that is assigned at the 495 * package installation time. 496 */ getPackageUid()497 public int getPackageUid() { 498 return mPackageUid; 499 } 500 501 /** 502 * Return the defining kernel user identifier, maybe different from {@link #getRealUid} and 503 * {@link #getPackageUid}, if an external service has the 504 * {@link android.R.styleable#AndroidManifestService_useAppZygote android:useAppZygote} set 505 * to <code>true</code> and was bound with the flag 506 * {@link android.content.Context#BIND_EXTERNAL_SERVICE} - in this case, this field here will 507 * be the kernel user identifier of the external service provider. 508 */ getDefiningUid()509 public int getDefiningUid() { 510 return mDefiningUid; 511 } 512 513 /** 514 * The actual process name it was running with. 515 */ getProcessName()516 public @NonNull String getProcessName() { 517 return mProcessName; 518 } 519 520 /** 521 * The reason code of the process's death. 522 */ getReason()523 public @Reason int getReason() { 524 return mReason; 525 } 526 527 /** 528 * The exit status argument of exit() if the application calls it, or the signal 529 * number if the application is signaled. 530 */ getStatus()531 public int getStatus() { 532 return mStatus; 533 } 534 535 /** 536 * The importance of the process that it used to have before the death. 537 */ getImportance()538 public @Importance int getImportance() { 539 return mImportance; 540 } 541 542 /** 543 * Last proportional set size of the memory that the process had used in kB. 544 * 545 * <p class="note">Note: This is the value from last sampling on the process, 546 * it's NOT the exact memory information prior to its death; and it'll be zero 547 * if the process died before system had a chance to take the sample. </p> 548 */ getPss()549 public long getPss() { 550 return mPss; 551 } 552 553 /** 554 * Last resident set size of the memory that the process had used in kB. 555 * 556 * <p class="note">Note: This is the value from last sampling on the process, 557 * it's NOT the exact memory information prior to its death; and it'll be zero 558 * if the process died before system had a chance to take the sample. </p> 559 */ getRss()560 public long getRss() { 561 return mRss; 562 } 563 564 /** 565 * The timestamp of the process's death, in milliseconds since the epoch, 566 * as returned by {@link java.lang.System#currentTimeMillis() System.currentTimeMillis()}. 567 */ getTimestamp()568 public @CurrentTimeMillisLong long getTimestamp() { 569 return mTimestamp; 570 } 571 572 /** 573 * The human readable description of the process's death, given by the system; could be null. 574 * 575 * <p class="note">Note: only intended to be human-readable and the system provides no 576 * guarantees that the format is stable across devices or Android releases.</p> 577 */ getDescription()578 public @Nullable String getDescription() { 579 return mDescription; 580 } 581 582 /** 583 * Return the user id of the record on a multi-user system. 584 */ getUserHandle()585 public @NonNull UserHandle getUserHandle() { 586 return UserHandle.of(UserHandle.getUserId(mRealUid)); 587 } 588 589 /** 590 * Return the state data set by calling 591 * {@link android.app.ActivityManager#setProcessStateSummary(byte[]) 592 * ActivityManager.setProcessStateSummary(byte[])} from the process before its death. 593 * 594 * @return The process-customized data 595 * @see ActivityManager#setProcessStateSummary(byte[]) 596 */ getProcessStateSummary()597 public @Nullable byte[] getProcessStateSummary() { 598 return mState; 599 } 600 601 /** 602 * Return the InputStream to the traces that was taken by the system 603 * prior to the death of the process; typically it'll be available when 604 * the reason is {@link #REASON_ANR}, though if the process gets an ANR 605 * but recovers, and dies for another reason later, this trace will be included 606 * in the record of {@link ApplicationExitInfo} still. 607 * 608 * @return The input stream to the traces that was taken by the system 609 * prior to the death of the process. 610 */ getTraceInputStream()611 public @Nullable InputStream getTraceInputStream() throws IOException { 612 if (mAppTraceRetriever == null) { 613 return null; 614 } 615 try { 616 final ParcelFileDescriptor fd = mAppTraceRetriever.getTraceFileDescriptor( 617 mPackageName, mPackageUid, mPid); 618 if (fd == null) { 619 return null; 620 } 621 return new GZIPInputStream(new ParcelFileDescriptor.AutoCloseInputStream(fd)); 622 } catch (RemoteException e) { 623 return null; 624 } 625 } 626 627 /** 628 * Similar to {@link #getTraceInputStream} but return the File object. 629 * 630 * For internal use only. 631 * 632 * @hide 633 */ getTraceFile()634 public @Nullable File getTraceFile() { 635 return mTraceFile; 636 } 637 638 /** 639 * A subtype reason in conjunction with {@link #mReason}. 640 * 641 * For internal use only. 642 * 643 * @hide 644 */ getSubReason()645 public @SubReason int getSubReason() { 646 return mSubReason; 647 } 648 649 /** 650 * The connection group this process belongs to, if there is any. 651 * @see android.content.Context#updateServiceGroup 652 * 653 * For internal use only. 654 * 655 * @hide 656 */ getConnectionGroup()657 public int getConnectionGroup() { 658 return mConnectionGroup; 659 } 660 661 /** 662 * Name of first package running in this process; 663 * 664 * @hide 665 */ getPackageName()666 public String getPackageName() { 667 return mPackageName; 668 } 669 670 /** 671 * List of packages running in this process; 672 * 673 * For system internal use only, will not retain across processes. 674 * 675 * @hide 676 */ getPackageList()677 public String[] getPackageList() { 678 return mPackageList; 679 } 680 681 /** 682 * @see #getPid 683 * 684 * @hide 685 */ setPid(final int pid)686 public void setPid(final int pid) { 687 mPid = pid; 688 } 689 690 /** 691 * @see #getRealUid 692 * 693 * @hide 694 */ setRealUid(final int uid)695 public void setRealUid(final int uid) { 696 mRealUid = uid; 697 } 698 699 /** 700 * @see #getPackageUid 701 * 702 * @hide 703 */ setPackageUid(final int uid)704 public void setPackageUid(final int uid) { 705 mPackageUid = uid; 706 } 707 708 /** 709 * @see #getDefiningUid 710 * 711 * @hide 712 */ setDefiningUid(final int uid)713 public void setDefiningUid(final int uid) { 714 mDefiningUid = uid; 715 } 716 717 /** 718 * @see #getProcessName 719 * 720 * @hide 721 */ setProcessName(final String processName)722 public void setProcessName(final String processName) { 723 mProcessName = processName; 724 } 725 726 /** 727 * @see #getReason 728 * 729 * @hide 730 */ setReason(final @Reason int reason)731 public void setReason(final @Reason int reason) { 732 mReason = reason; 733 } 734 735 /** 736 * @see #getStatus 737 * 738 * @hide 739 */ setStatus(final int status)740 public void setStatus(final int status) { 741 mStatus = status; 742 } 743 744 /** 745 * @see #getImportance 746 * 747 * @hide 748 */ setImportance(final @Importance int importance)749 public void setImportance(final @Importance int importance) { 750 mImportance = importance; 751 } 752 753 /** 754 * @see #getPss 755 * 756 * @hide 757 */ setPss(final long pss)758 public void setPss(final long pss) { 759 mPss = pss; 760 } 761 762 /** 763 * @see #getRss 764 * 765 * @hide 766 */ setRss(final long rss)767 public void setRss(final long rss) { 768 mRss = rss; 769 } 770 771 /** 772 * @see #getTimestamp 773 * 774 * @hide 775 */ setTimestamp(final @CurrentTimeMillisLong long timestamp)776 public void setTimestamp(final @CurrentTimeMillisLong long timestamp) { 777 mTimestamp = timestamp; 778 } 779 780 /** 781 * @see #getDescription 782 * 783 * @hide 784 */ setDescription(final String description)785 public void setDescription(final String description) { 786 mDescription = description; 787 } 788 789 /** 790 * @see #getSubReason 791 * 792 * @hide 793 */ setSubReason(final @SubReason int subReason)794 public void setSubReason(final @SubReason int subReason) { 795 mSubReason = subReason; 796 } 797 798 /** 799 * @see #getConnectionGroup 800 * 801 * @hide 802 */ setConnectionGroup(final int connectionGroup)803 public void setConnectionGroup(final int connectionGroup) { 804 mConnectionGroup = connectionGroup; 805 } 806 807 /** 808 * @see #getPackageName 809 * 810 * @hide 811 */ setPackageName(final String packageName)812 public void setPackageName(final String packageName) { 813 mPackageName = packageName; 814 } 815 816 /** 817 * @see #getPackageList 818 * 819 * @hide 820 */ setPackageList(final String[] packageList)821 public void setPackageList(final String[] packageList) { 822 mPackageList = packageList; 823 } 824 825 /** 826 * @see #getProcessStateSummary 827 * 828 * @hide 829 */ setProcessStateSummary(final byte[] state)830 public void setProcessStateSummary(final byte[] state) { 831 mState = state; 832 } 833 834 /** 835 * @see #getTraceFile 836 * 837 * @hide 838 */ setTraceFile(final File traceFile)839 public void setTraceFile(final File traceFile) { 840 mTraceFile = traceFile; 841 } 842 843 /** 844 * @see #mAppTraceRetriever 845 * 846 * @hide 847 */ setAppTraceRetriever(final IAppTraceRetriever retriever)848 public void setAppTraceRetriever(final IAppTraceRetriever retriever) { 849 mAppTraceRetriever = retriever; 850 } 851 852 @Override describeContents()853 public int describeContents() { 854 return 0; 855 } 856 857 @Override writeToParcel(@onNull Parcel dest, int flags)858 public void writeToParcel(@NonNull Parcel dest, int flags) { 859 dest.writeInt(mPid); 860 dest.writeInt(mRealUid); 861 dest.writeInt(mPackageUid); 862 dest.writeInt(mDefiningUid); 863 dest.writeString(mProcessName); 864 dest.writeString(mPackageName); 865 dest.writeInt(mConnectionGroup); 866 dest.writeInt(mReason); 867 dest.writeInt(mSubReason); 868 dest.writeInt(mStatus); 869 dest.writeInt(mImportance); 870 dest.writeLong(mPss); 871 dest.writeLong(mRss); 872 dest.writeLong(mTimestamp); 873 dest.writeString(mDescription); 874 dest.writeByteArray(mState); 875 if (mAppTraceRetriever != null) { 876 dest.writeInt(1); 877 dest.writeStrongBinder(mAppTraceRetriever.asBinder()); 878 } else { 879 dest.writeInt(0); 880 } 881 } 882 883 /** @hide */ ApplicationExitInfo()884 public ApplicationExitInfo() { 885 } 886 887 /** @hide */ ApplicationExitInfo(ApplicationExitInfo other)888 public ApplicationExitInfo(ApplicationExitInfo other) { 889 mPid = other.mPid; 890 mRealUid = other.mRealUid; 891 mPackageUid = other.mPackageUid; 892 mDefiningUid = other.mDefiningUid; 893 mProcessName = other.mProcessName; 894 mPackageName = other.mPackageName; 895 mConnectionGroup = other.mConnectionGroup; 896 mReason = other.mReason; 897 mStatus = other.mStatus; 898 mSubReason = other.mSubReason; 899 mImportance = other.mImportance; 900 mPss = other.mPss; 901 mRss = other.mRss; 902 mTimestamp = other.mTimestamp; 903 mDescription = other.mDescription; 904 mPackageName = other.mPackageName; 905 mPackageList = other.mPackageList; 906 mState = other.mState; 907 mTraceFile = other.mTraceFile; 908 mAppTraceRetriever = other.mAppTraceRetriever; 909 } 910 ApplicationExitInfo(@onNull Parcel in)911 private ApplicationExitInfo(@NonNull Parcel in) { 912 mPid = in.readInt(); 913 mRealUid = in.readInt(); 914 mPackageUid = in.readInt(); 915 mDefiningUid = in.readInt(); 916 mProcessName = in.readString(); 917 mPackageName = in.readString(); 918 mConnectionGroup = in.readInt(); 919 mReason = in.readInt(); 920 mSubReason = in.readInt(); 921 mStatus = in.readInt(); 922 mImportance = in.readInt(); 923 mPss = in.readLong(); 924 mRss = in.readLong(); 925 mTimestamp = in.readLong(); 926 mDescription = in.readString(); 927 mState = in.createByteArray(); 928 if (in.readInt() == 1) { 929 mAppTraceRetriever = IAppTraceRetriever.Stub.asInterface(in.readStrongBinder()); 930 } 931 } 932 933 public @NonNull static final Creator<ApplicationExitInfo> CREATOR = 934 new Creator<ApplicationExitInfo>() { 935 @Override 936 public ApplicationExitInfo createFromParcel(Parcel in) { 937 return new ApplicationExitInfo(in); 938 } 939 940 @Override 941 public ApplicationExitInfo[] newArray(int size) { 942 return new ApplicationExitInfo[size]; 943 } 944 }; 945 946 /** @hide */ dump(@onNull PrintWriter pw, @Nullable String prefix, @Nullable String seqSuffix, @NonNull SimpleDateFormat sdf)947 public void dump(@NonNull PrintWriter pw, @Nullable String prefix, @Nullable String seqSuffix, 948 @NonNull SimpleDateFormat sdf) { 949 pw.println(prefix + "ApplicationExitInfo " + seqSuffix + ":"); 950 pw.println(prefix + " timestamp=" + sdf.format(new Date(mTimestamp))); 951 pw.println(prefix + " pid=" + mPid); 952 pw.println(prefix + " realUid=" + mRealUid); 953 pw.println(prefix + " packageUid=" + mPackageUid); 954 pw.println(prefix + " definingUid=" + mDefiningUid); 955 pw.println(prefix + " user=" + UserHandle.getUserId(mPackageUid)); 956 pw.println(prefix + " process=" + mProcessName); 957 pw.println(prefix + " reason=" + mReason + " (" + reasonCodeToString(mReason) + ")"); 958 pw.println(prefix + " status=" + mStatus); 959 pw.println(prefix + " importance=" + mImportance); 960 pw.print(prefix + " pss="); DebugUtils.printSizeValue(pw, mPss << 10); pw.println(); 961 pw.print(prefix + " rss="); DebugUtils.printSizeValue(pw, mRss << 10); pw.println(); 962 pw.println(prefix + " description=" + mDescription); 963 pw.println(prefix + " state=" + (ArrayUtils.isEmpty(mState) 964 ? "empty" : Integer.toString(mState.length) + " bytes")); 965 pw.println(prefix + " trace=" + mTraceFile); 966 } 967 968 @Override toString()969 public String toString() { 970 StringBuilder sb = new StringBuilder(); 971 sb.append("ApplicationExitInfo(timestamp="); 972 sb.append(new SimpleDateFormat().format(new Date(mTimestamp))); 973 sb.append(" pid=").append(mPid); 974 sb.append(" realUid=").append(mRealUid); 975 sb.append(" packageUid=").append(mPackageUid); 976 sb.append(" definingUid=").append(mDefiningUid); 977 sb.append(" user=").append(UserHandle.getUserId(mPackageUid)); 978 sb.append(" process=").append(mProcessName); 979 sb.append(" reason=").append(mReason).append(" (") 980 .append(reasonCodeToString(mReason)).append(")"); 981 sb.append(" status=").append(mStatus); 982 sb.append(" importance=").append(mImportance); 983 sb.append(" pss="); DebugUtils.sizeValueToString(mPss << 10, sb); 984 sb.append(" rss="); DebugUtils.sizeValueToString(mRss << 10, sb); 985 sb.append(" description=").append(mDescription); 986 sb.append(" state=").append(ArrayUtils.isEmpty(mState) 987 ? "empty" : Integer.toString(mState.length) + " bytes"); 988 sb.append(" trace=").append(mTraceFile); 989 return sb.toString(); 990 } 991 reasonCodeToString(@eason int reason)992 private static String reasonCodeToString(@Reason int reason) { 993 switch (reason) { 994 case REASON_EXIT_SELF: 995 return "EXIT_SELF"; 996 case REASON_SIGNALED: 997 return "SIGNALED"; 998 case REASON_LOW_MEMORY: 999 return "LOW_MEMORY"; 1000 case REASON_CRASH: 1001 return "APP CRASH(EXCEPTION)"; 1002 case REASON_CRASH_NATIVE: 1003 return "APP CRASH(NATIVE)"; 1004 case REASON_ANR: 1005 return "ANR"; 1006 case REASON_INITIALIZATION_FAILURE: 1007 return "INITIALIZATION FAILURE"; 1008 case REASON_PERMISSION_CHANGE: 1009 return "PERMISSION CHANGE"; 1010 case REASON_EXCESSIVE_RESOURCE_USAGE: 1011 return "EXCESSIVE RESOURCE USAGE"; 1012 case REASON_USER_REQUESTED: 1013 return "USER REQUESTED"; 1014 case REASON_USER_STOPPED: 1015 return "USER STOPPED"; 1016 case REASON_DEPENDENCY_DIED: 1017 return "DEPENDENCY DIED"; 1018 case REASON_OTHER: 1019 return "OTHER KILLS BY SYSTEM"; 1020 default: 1021 return "UNKNOWN"; 1022 } 1023 } 1024 1025 /** @hide */ subreasonToString(@ubReason int subreason)1026 public static String subreasonToString(@SubReason int subreason) { 1027 switch (subreason) { 1028 case SUBREASON_WAIT_FOR_DEBUGGER: 1029 return "WAIT FOR DEBUGGER"; 1030 case SUBREASON_TOO_MANY_CACHED: 1031 return "TOO MANY CACHED PROCS"; 1032 case SUBREASON_TOO_MANY_EMPTY: 1033 return "TOO MANY EMPTY PROCS"; 1034 case SUBREASON_TRIM_EMPTY: 1035 return "TRIM EMPTY"; 1036 case SUBREASON_LARGE_CACHED: 1037 return "LARGE CACHED"; 1038 case SUBREASON_MEMORY_PRESSURE: 1039 return "MEMORY PRESSURE"; 1040 case SUBREASON_EXCESSIVE_CPU: 1041 return "EXCESSIVE CPU USAGE"; 1042 case SUBREASON_SYSTEM_UPDATE_DONE: 1043 return "SYSTEM UPDATE_DONE"; 1044 case SUBREASON_KILL_ALL_FG: 1045 return "KILL ALL FG"; 1046 case SUBREASON_KILL_ALL_BG_EXCEPT: 1047 return "KILL ALL BG EXCEPT"; 1048 case SUBREASON_KILL_UID: 1049 return "KILL UID"; 1050 case SUBREASON_KILL_PID: 1051 return "KILL PID"; 1052 case SUBREASON_INVALID_START: 1053 return "INVALID START"; 1054 case SUBREASON_INVALID_STATE: 1055 return "INVALID STATE"; 1056 case SUBREASON_IMPERCEPTIBLE: 1057 return "IMPERCEPTIBLE"; 1058 case SUBREASON_REMOVE_LRU: 1059 return "REMOVE LRU"; 1060 case SUBREASON_ISOLATED_NOT_NEEDED: 1061 return "ISOLATED NOT NEEDED"; 1062 default: 1063 return "UNKNOWN"; 1064 } 1065 } 1066 1067 /** 1068 * Write to a protocol buffer output stream. 1069 * Protocol buffer message definition at {@link android.app.ApplicationExitInfoProto} 1070 * 1071 * @param proto Stream to write the ApplicationExitInfo object to. 1072 * @param fieldId Field Id of the ApplicationExitInfo as defined in the parent message 1073 * @hide 1074 */ writeToProto(ProtoOutputStream proto, long fieldId)1075 public void writeToProto(ProtoOutputStream proto, long fieldId) { 1076 final long token = proto.start(fieldId); 1077 proto.write(ApplicationExitInfoProto.PID, mPid); 1078 proto.write(ApplicationExitInfoProto.REAL_UID, mRealUid); 1079 proto.write(ApplicationExitInfoProto.PACKAGE_UID, mPackageUid); 1080 proto.write(ApplicationExitInfoProto.DEFINING_UID, mDefiningUid); 1081 proto.write(ApplicationExitInfoProto.PROCESS_NAME, mProcessName); 1082 proto.write(ApplicationExitInfoProto.CONNECTION_GROUP, mConnectionGroup); 1083 proto.write(ApplicationExitInfoProto.REASON, mReason); 1084 proto.write(ApplicationExitInfoProto.SUB_REASON, mSubReason); 1085 proto.write(ApplicationExitInfoProto.STATUS, mStatus); 1086 proto.write(ApplicationExitInfoProto.IMPORTANCE, mImportance); 1087 proto.write(ApplicationExitInfoProto.PSS, mPss); 1088 proto.write(ApplicationExitInfoProto.RSS, mRss); 1089 proto.write(ApplicationExitInfoProto.TIMESTAMP, mTimestamp); 1090 proto.write(ApplicationExitInfoProto.DESCRIPTION, mDescription); 1091 proto.write(ApplicationExitInfoProto.STATE, mState); 1092 proto.write(ApplicationExitInfoProto.TRACE_FILE, 1093 mTraceFile == null ? null : mTraceFile.getAbsolutePath()); 1094 proto.end(token); 1095 } 1096 1097 /** 1098 * Read from a protocol buffer input stream. 1099 * Protocol buffer message definition at {@link android.app.ApplicationExitInfoProto} 1100 * 1101 * @param proto Stream to read the ApplicationExitInfo object from. 1102 * @param fieldId Field Id of the ApplicationExitInfo as defined in the parent message 1103 * @hide 1104 */ readFromProto(ProtoInputStream proto, long fieldId)1105 public void readFromProto(ProtoInputStream proto, long fieldId) 1106 throws IOException, WireTypeMismatchException { 1107 final long token = proto.start(fieldId); 1108 while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) { 1109 switch (proto.getFieldNumber()) { 1110 case (int) ApplicationExitInfoProto.PID: 1111 mPid = proto.readInt(ApplicationExitInfoProto.PID); 1112 break; 1113 case (int) ApplicationExitInfoProto.REAL_UID: 1114 mRealUid = proto.readInt(ApplicationExitInfoProto.REAL_UID); 1115 break; 1116 case (int) ApplicationExitInfoProto.PACKAGE_UID: 1117 mPackageUid = proto.readInt(ApplicationExitInfoProto.PACKAGE_UID); 1118 break; 1119 case (int) ApplicationExitInfoProto.DEFINING_UID: 1120 mDefiningUid = proto.readInt(ApplicationExitInfoProto.DEFINING_UID); 1121 break; 1122 case (int) ApplicationExitInfoProto.PROCESS_NAME: 1123 mProcessName = proto.readString(ApplicationExitInfoProto.PROCESS_NAME); 1124 break; 1125 case (int) ApplicationExitInfoProto.CONNECTION_GROUP: 1126 mConnectionGroup = proto.readInt(ApplicationExitInfoProto.CONNECTION_GROUP); 1127 break; 1128 case (int) ApplicationExitInfoProto.REASON: 1129 mReason = proto.readInt(ApplicationExitInfoProto.REASON); 1130 break; 1131 case (int) ApplicationExitInfoProto.SUB_REASON: 1132 mSubReason = proto.readInt(ApplicationExitInfoProto.SUB_REASON); 1133 break; 1134 case (int) ApplicationExitInfoProto.STATUS: 1135 mStatus = proto.readInt(ApplicationExitInfoProto.STATUS); 1136 break; 1137 case (int) ApplicationExitInfoProto.IMPORTANCE: 1138 mImportance = proto.readInt(ApplicationExitInfoProto.IMPORTANCE); 1139 break; 1140 case (int) ApplicationExitInfoProto.PSS: 1141 mPss = proto.readLong(ApplicationExitInfoProto.PSS); 1142 break; 1143 case (int) ApplicationExitInfoProto.RSS: 1144 mRss = proto.readLong(ApplicationExitInfoProto.RSS); 1145 break; 1146 case (int) ApplicationExitInfoProto.TIMESTAMP: 1147 mTimestamp = proto.readLong(ApplicationExitInfoProto.TIMESTAMP); 1148 break; 1149 case (int) ApplicationExitInfoProto.DESCRIPTION: 1150 mDescription = proto.readString(ApplicationExitInfoProto.DESCRIPTION); 1151 break; 1152 case (int) ApplicationExitInfoProto.STATE: 1153 mState = proto.readBytes(ApplicationExitInfoProto.STATE); 1154 break; 1155 case (int) ApplicationExitInfoProto.TRACE_FILE: 1156 final String path = proto.readString(ApplicationExitInfoProto.TRACE_FILE); 1157 if (!TextUtils.isEmpty(path)) { 1158 mTraceFile = new File(path); 1159 } 1160 break; 1161 } 1162 } 1163 proto.end(token); 1164 } 1165 1166 @Override equals(Object other)1167 public boolean equals(Object other) { 1168 if (other == null || !(other instanceof ApplicationExitInfo)) { 1169 return false; 1170 } 1171 ApplicationExitInfo o = (ApplicationExitInfo) other; 1172 return mPid == o.mPid && mRealUid == o.mRealUid && mPackageUid == o.mPackageUid 1173 && mDefiningUid == o.mDefiningUid 1174 && mConnectionGroup == o.mConnectionGroup && mReason == o.mReason 1175 && mSubReason == o.mSubReason && mImportance == o.mImportance 1176 && mStatus == o.mStatus && mTimestamp == o.mTimestamp 1177 && mPss == o.mPss && mRss == o.mRss 1178 && TextUtils.equals(mProcessName, o.mProcessName) 1179 && TextUtils.equals(mDescription, o.mDescription); 1180 } 1181 1182 @Override hashCode()1183 public int hashCode() { 1184 int result = mPid; 1185 result = 31 * result + mRealUid; 1186 result = 31 * result + mPackageUid; 1187 result = 31 * result + mDefiningUid; 1188 result = 31 * result + mConnectionGroup; 1189 result = 31 * result + mReason; 1190 result = 31 * result + mSubReason; 1191 result = 31 * result + mImportance; 1192 result = 31 * result + mStatus; 1193 result = 31 * result + (int) mPss; 1194 result = 31 * result + (int) mRss; 1195 result = 31 * result + Long.hashCode(mTimestamp); 1196 result = 31 * result + Objects.hashCode(mProcessName); 1197 result = 31 * result + Objects.hashCode(mDescription); 1198 return result; 1199 } 1200 } 1201