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 * <p> 137 * Prior to {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, one of the uses of this 138 * reason was to indicate that an app was killed due to it being updated or any of its component 139 * states have changed without {@link android.content.pm.PackageManager#DONT_KILL_APP} 140 */ 141 public static final int REASON_USER_REQUESTED = 10; 142 143 /** 144 * Application process was killed, because the user it is running as on devices 145 * with mutlple users, was stopped. 146 */ 147 public static final int REASON_USER_STOPPED = 11; 148 149 /** 150 * Application process was killed because its dependency was going away, for example, 151 * a stable content provider connection's client will be killed if the provider is killed. 152 */ 153 public static final int REASON_DEPENDENCY_DIED = 12; 154 155 /** 156 * Application process was killed by the system for various other reasons which are 157 * not by problems in apps and not actionable by apps, for example, the system just 158 * finished updates; {@link #getDescription} will specify the cause given by the system. 159 */ 160 public static final int REASON_OTHER = 13; 161 162 /** 163 * Application process was killed by App Freezer, for example, because it receives 164 * sync binder transactions while being frozen. 165 */ 166 public static final int REASON_FREEZER = 14; 167 168 /** 169 * Application process was killed because the app was disabled, or any of its 170 * component states have changed without {@link android.content.pm.PackageManager#DONT_KILL_APP} 171 * <p> 172 * Prior to {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, 173 * {@link #REASON_USER_REQUESTED} was used to indicate that an app was updated. 174 */ 175 public static final int REASON_PACKAGE_STATE_CHANGE = 15; 176 177 /** 178 * Application process was killed because it was updated. 179 * <p> 180 * Prior to {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, 181 * {@link #REASON_USER_REQUESTED} was used to indicate that an app was updated. 182 */ 183 public static final int REASON_PACKAGE_UPDATED = 16; 184 185 /** 186 * Application process kills subreason is unknown. 187 * 188 * For internal use only. 189 * @hide 190 */ 191 public static final int SUBREASON_UNKNOWN = 0; 192 193 /** 194 * Application process was killed because user quit it on the "wait for debugger" dialog; 195 * this would be set when the reason is {@link #REASON_OTHER}. 196 * 197 * For internal use only. 198 * @hide 199 */ 200 public static final int SUBREASON_WAIT_FOR_DEBUGGER = 1; 201 202 /** 203 * Application process was killed by the activity manager because there were too many cached 204 * processes; this would be set only when the reason is {@link #REASON_OTHER}. 205 * 206 * For internal use only. 207 * @hide 208 */ 209 public static final int SUBREASON_TOO_MANY_CACHED = 2; 210 211 /** 212 * Application process was killed by the activity manager because there were too many empty 213 * processes; this would be set only when the reason is {@link #REASON_OTHER}. 214 * 215 * For internal use only. 216 * @hide 217 */ 218 public static final int SUBREASON_TOO_MANY_EMPTY = 3; 219 220 /** 221 * Application process was killed by the activity manager because there were too many cached 222 * processes and this process had been in empty state for a long time; 223 * this would be set only when the reason is {@link #REASON_OTHER}. 224 * 225 * For internal use only. 226 * @hide 227 */ 228 public static final int SUBREASON_TRIM_EMPTY = 4; 229 230 /** 231 * Application process was killed by the activity manager because system was on memory pressure 232 * and this process took large amount of cached memory; 233 * this would be set only when the reason is {@link #REASON_OTHER}. 234 * 235 * For internal use only. 236 * @hide 237 */ 238 public static final int SUBREASON_LARGE_CACHED = 5; 239 240 /** 241 * Application process was killed by the activity manager because the system was on low memory 242 * pressure for a significant amount of time since last idle; 243 * this would be set only when the reason is {@link #REASON_OTHER}. 244 * 245 * For internal use only. 246 * @hide 247 */ 248 public static final int SUBREASON_MEMORY_PRESSURE = 6; 249 250 /** 251 * Application process was killed by the activity manager due to excessive CPU usage; 252 * this would be set only when the reason is {@link #REASON_EXCESSIVE_RESOURCE_USAGE}. 253 * 254 * For internal use only. 255 * @hide 256 */ 257 public static final int SUBREASON_EXCESSIVE_CPU = 7; 258 259 /** 260 * System update has done (so the system update process should be killed); 261 * this would be set only when the reason is {@link #REASON_OTHER}. 262 * 263 * For internal use only. 264 * @hide 265 */ 266 public static final int SUBREASON_SYSTEM_UPDATE_DONE = 8; 267 268 /** 269 * Kill all foreground services, for now it only occurs when enabling the quiet 270 * mode for the managed profile; 271 * this would be set only when the reason is {@link #REASON_OTHER}. 272 * 273 * For internal use only. 274 * @hide 275 */ 276 public static final int SUBREASON_KILL_ALL_FG = 9; 277 278 /** 279 * All background processes except certain ones were killed, for now it only occurs 280 * when the density of the default display is changed; 281 * this would be set only when the reason is {@link #REASON_OTHER}. 282 * 283 * For internal use only. 284 * @hide 285 */ 286 public static final int SUBREASON_KILL_ALL_BG_EXCEPT = 10; 287 288 /** 289 * The process associated with the UID was explicitly killed, for example, 290 * it could be because of platform compatibility overrides; 291 * this would be set only when the reason is {@link #REASON_OTHER}. 292 * 293 * For internal use only. 294 * @hide 295 */ 296 public static final int SUBREASON_KILL_UID = 11; 297 298 /** 299 * The process was explicitly killed with its PID, typically because of 300 * the low memory for surfaces; 301 * this would be set only when the reason is {@link #REASON_OTHER}. 302 * 303 * For internal use only. 304 * @hide 305 */ 306 public static final int SUBREASON_KILL_PID = 12; 307 308 /** 309 * The start of the process was invalid; 310 * this would be set only when the reason is {@link #REASON_OTHER}. 311 * 312 * For internal use only. 313 * @hide 314 */ 315 public static final int SUBREASON_INVALID_START = 13; 316 317 /** 318 * The process was killed because it's in an invalid state, typically 319 * it's triggered from SHELL; 320 * this would be set only when the reason is {@link #REASON_OTHER}. 321 * 322 * For internal use only. 323 * @hide 324 */ 325 public static final int SUBREASON_INVALID_STATE = 14; 326 327 /** 328 * The process was killed when it's imperceptible to user, because it was 329 * in a bad state; 330 * 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_IMPERCEPTIBLE = 15; 336 337 /** 338 * The process was killed because it's being moved out from LRU list; 339 * this would be set only when the reason is {@link #REASON_OTHER}. 340 * 341 * For internal use only. 342 * @hide 343 */ 344 public static final int SUBREASON_REMOVE_LRU = 16; 345 346 /** 347 * The process was killed because it's isolated and was in a cached state; 348 * this would be set only when the reason is {@link #REASON_OTHER}. 349 * 350 * For internal use only. 351 * @hide 352 */ 353 public static final int SUBREASON_ISOLATED_NOT_NEEDED = 17; 354 355 /** 356 * The process was killed because it's in forced-app-standby state, and it's cached and 357 * its uid state is idle; this would be set only when the reason is {@link #REASON_OTHER}. 358 * 359 * For internal use only. 360 * @hide 361 */ 362 public static final int SUBREASON_CACHED_IDLE_FORCED_APP_STANDBY = 18; 363 364 /** 365 * The process was killed because it fails to freeze/unfreeze binder 366 * or query binder frozen info while being frozen. 367 * this would be set only when the reason is {@link #REASON_FREEZER}. 368 * 369 * For internal use only. 370 * @hide 371 */ 372 public static final int SUBREASON_FREEZER_BINDER_IOCTL = 19; 373 374 /** 375 * The process was killed because it receives sync binder transactions 376 * while being frozen. 377 * this would be set only when the reason is {@link #REASON_FREEZER}. 378 * 379 * For internal use only. 380 * @hide 381 */ 382 public static final int SUBREASON_FREEZER_BINDER_TRANSACTION = 20; 383 384 /** 385 * The process was killed because of force-stop, it could be due to that 386 * the user clicked the "Force stop" button of the application in the Settings; 387 * this would be set only when the reason is {@link #REASON_USER_REQUESTED}. 388 * 389 * For internal use only. 390 * @hide 391 */ 392 public static final int SUBREASON_FORCE_STOP = 21; 393 394 /** 395 * The process was killed because the user removed the application away from Recents; 396 * this would be set only when the reason is {@link #REASON_USER_REQUESTED}. 397 * 398 * For internal use only. 399 * @hide 400 */ 401 public static final int SUBREASON_REMOVE_TASK = 22; 402 403 /** 404 * The process was killed because the user stopped the application from the task manager; 405 * this would be set only when the reason is {@link #REASON_USER_REQUESTED}. 406 * 407 * For internal use only. 408 * @hide 409 */ 410 public static final int SUBREASON_STOP_APP = 23; 411 412 /** 413 * The process was killed because the user stopped the application from developer options, 414 * or via the adb shell commmand interface; this would be set only when the reason is 415 * {@link #REASON_USER_REQUESTED}. 416 * 417 * For internal use only. 418 * @hide 419 */ 420 public static final int SUBREASON_KILL_BACKGROUND = 24; 421 422 /** 423 * The process was killed because of package update; this would be set only when the reason is 424 * {@link #REASON_USER_REQUESTED}. 425 * 426 * For internal use only. 427 * 428 * @deprecated starting {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, 429 * an app being killed due to a package update will have the reason 430 * {@link #REASON_PACKAGE_UPDATED} 431 * 432 * @hide 433 */ 434 public static final int SUBREASON_PACKAGE_UPDATE = 25; 435 436 /** 437 * The process was killed because of undelivered broadcasts; this would be set only when the 438 * reason is {@link #REASON_OTHER}. 439 * 440 * For internal use only. 441 * @hide 442 */ 443 public static final int SUBREASON_UNDELIVERED_BROADCAST = 26; 444 445 /** 446 * The process was killed because its associated SDK sandbox process (where it had loaded SDKs) 447 * had died; this would be set only when the reason is {@link #REASON_DEPENDENCY_DIED}. 448 * 449 * For internal use only. 450 * @hide 451 */ 452 public static final int SUBREASON_SDK_SANDBOX_DIED = 27; 453 454 /** 455 * The process was killed because it was an SDK sandbox process that was either not usable or 456 * was no longer being used; this would be set only when the reason is {@link #REASON_OTHER}. 457 * 458 * For internal use only. 459 * @hide 460 */ 461 public static final int SUBREASON_SDK_SANDBOX_NOT_NEEDED = 28; 462 463 /** 464 * The process was killed because the binder proxy limit for system server was exceeded. 465 * 466 * For internal use only. 467 * @hide 468 */ 469 public static final int SUBREASON_EXCESSIVE_BINDER_OBJECTS = 29; 470 471 /** 472 * The process was killed by the [kernel] Out-of-memory (OOM) killer; this 473 * would be set only when the reason is {@link #REASON_LOW_MEMORY}. 474 * 475 * For internal use only. 476 * @hide 477 */ 478 public static final int SUBREASON_OOM_KILL = 30; 479 480 /** 481 * The process was killed because its async kernel binder buffer is running out 482 * while being frozen. 483 * this would be set only when the reason is {@link #REASON_FREEZER}. 484 * 485 * For internal use only. 486 * @hide 487 */ 488 public static final int SUBREASON_FREEZER_BINDER_ASYNC_FULL = 31; 489 490 // If there is any OEM code which involves additional app kill reasons, it should 491 // be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000. 492 493 /** 494 * @see #getPid 495 */ 496 private int mPid; 497 498 /** 499 * @see #getRealUid 500 */ 501 private int mRealUid; 502 503 /** 504 * @see #getPackageUid 505 */ 506 private int mPackageUid; 507 508 /** 509 * @see #getDefiningUid 510 */ 511 private int mDefiningUid; 512 513 /** 514 * @see #getProcessName 515 */ 516 private String mProcessName; 517 518 /** 519 * @see #getReason 520 */ 521 private @Reason int mReason; 522 523 /** 524 * @see #getStatus 525 */ 526 private int mStatus; 527 528 /** 529 * @see #getImportance 530 */ 531 private @Importance int mImportance; 532 533 /** 534 * @see #getPss 535 */ 536 private long mPss; 537 538 /** 539 * @see #getRss 540 */ 541 private long mRss; 542 543 /** 544 * @see #getTimestamp 545 */ 546 private @CurrentTimeMillisLong long mTimestamp; 547 548 /** 549 * @see #getDescription 550 */ 551 private @Nullable String mDescription; 552 553 /** 554 * @see #getSubReason 555 */ 556 private @SubReason int mSubReason; 557 558 /** 559 * @see #getConnectionGroup 560 */ 561 private int mConnectionGroup; 562 563 /** 564 * @see #getPackageName 565 */ 566 private String mPackageName; 567 568 /** 569 * @see #getPackageList 570 */ 571 private String[] mPackageList; 572 573 /** 574 * @see #getProcessStateSummary 575 */ 576 private byte[] mState; 577 578 /** 579 * The file to the trace file in the storage; 580 * 581 * for system internal use only, will not retain across processes. 582 * 583 * @see #getTraceInputStream 584 */ 585 private File mTraceFile; 586 587 /** 588 * The Binder interface to retrieve the file descriptor to 589 * the trace file from the system. 590 */ 591 private IAppTraceRetriever mAppTraceRetriever; 592 593 /** 594 * ParcelFileDescriptor pointing to a native tombstone. 595 * 596 * @see #getTraceInputStream 597 */ 598 private IParcelFileDescriptorRetriever mNativeTombstoneRetriever; 599 600 /** 601 * Whether or not we've logged this into the statsd. 602 * 603 * for system internal use only, will not retain across processes. 604 */ 605 private boolean mLoggedInStatsd; 606 607 /** 608 * Whether or not this process hosts one or more foreground services. 609 * 610 * for system internal use only, will not retain across processes. 611 */ 612 private boolean mHasForegroundServices; 613 614 /** @hide */ 615 @IntDef(prefix = { "REASON_" }, value = { 616 REASON_UNKNOWN, 617 REASON_EXIT_SELF, 618 REASON_SIGNALED, 619 REASON_LOW_MEMORY, 620 REASON_CRASH, 621 REASON_CRASH_NATIVE, 622 REASON_ANR, 623 REASON_INITIALIZATION_FAILURE, 624 REASON_PERMISSION_CHANGE, 625 REASON_EXCESSIVE_RESOURCE_USAGE, 626 REASON_USER_REQUESTED, 627 REASON_USER_STOPPED, 628 REASON_DEPENDENCY_DIED, 629 REASON_OTHER, 630 REASON_FREEZER, 631 REASON_PACKAGE_STATE_CHANGE, 632 REASON_PACKAGE_UPDATED, 633 }) 634 @Retention(RetentionPolicy.SOURCE) 635 public @interface Reason {} 636 637 /** @hide */ 638 @IntDef(prefix = { "SUBREASON_" }, value = { 639 SUBREASON_UNKNOWN, 640 SUBREASON_WAIT_FOR_DEBUGGER, 641 SUBREASON_TOO_MANY_CACHED, 642 SUBREASON_TOO_MANY_EMPTY, 643 SUBREASON_TRIM_EMPTY, 644 SUBREASON_LARGE_CACHED, 645 SUBREASON_MEMORY_PRESSURE, 646 SUBREASON_EXCESSIVE_CPU, 647 SUBREASON_SYSTEM_UPDATE_DONE, 648 SUBREASON_KILL_ALL_FG, 649 SUBREASON_KILL_ALL_BG_EXCEPT, 650 SUBREASON_KILL_UID, 651 SUBREASON_KILL_PID, 652 SUBREASON_INVALID_START, 653 SUBREASON_INVALID_STATE, 654 SUBREASON_IMPERCEPTIBLE, 655 SUBREASON_REMOVE_LRU, 656 SUBREASON_ISOLATED_NOT_NEEDED, 657 SUBREASON_FREEZER_BINDER_IOCTL, 658 SUBREASON_FREEZER_BINDER_TRANSACTION, 659 SUBREASON_FORCE_STOP, 660 SUBREASON_REMOVE_TASK, 661 SUBREASON_STOP_APP, 662 SUBREASON_KILL_BACKGROUND, 663 SUBREASON_PACKAGE_UPDATE, 664 SUBREASON_UNDELIVERED_BROADCAST, 665 SUBREASON_EXCESSIVE_BINDER_OBJECTS, 666 SUBREASON_OOM_KILL, 667 SUBREASON_FREEZER_BINDER_ASYNC_FULL, 668 }) 669 @Retention(RetentionPolicy.SOURCE) 670 public @interface SubReason {} 671 672 /** 673 * The process id of the process that died. 674 */ getPid()675 public int getPid() { 676 return mPid; 677 } 678 679 /** 680 * The kernel user identifier of the process, most of the time the system uses this 681 * to do access control checks. It's typically the uid of the package where the component is 682 * running from, except the case of isolated process, where this field identifies the kernel 683 * user identifier that this process is actually running with, while the {@link #getPackageUid} 684 * identifies the kernel user identifier that is assigned at the package installation time. 685 */ getRealUid()686 public int getRealUid() { 687 return mRealUid; 688 } 689 690 /** 691 * Similar to {@link #getRealUid}, it's the kernel user identifier that is assigned at the 692 * package installation time. 693 */ getPackageUid()694 public int getPackageUid() { 695 return mPackageUid; 696 } 697 698 /** 699 * Return the defining kernel user identifier, maybe different from {@link #getRealUid} and 700 * {@link #getPackageUid}, if an external service has the 701 * {@link android.R.styleable#AndroidManifestService_useAppZygote android:useAppZygote} set 702 * to <code>true</code> and was bound with the flag 703 * {@link android.content.Context#BIND_EXTERNAL_SERVICE} - in this case, this field here will 704 * be the kernel user identifier of the external service provider. 705 */ getDefiningUid()706 public int getDefiningUid() { 707 return mDefiningUid; 708 } 709 710 /** 711 * The actual process name it was running with. 712 */ getProcessName()713 public @NonNull String getProcessName() { 714 return mProcessName; 715 } 716 717 /** 718 * The reason code of the process's death. 719 */ getReason()720 public @Reason int getReason() { 721 return mReason; 722 } 723 724 /** 725 * The exit status argument of exit() if the application calls it, or the signal 726 * number if the application is signaled. 727 */ getStatus()728 public int getStatus() { 729 return mStatus; 730 } 731 732 /** 733 * The importance of the process that it used to have before the death. 734 */ getImportance()735 public @Importance int getImportance() { 736 return mImportance; 737 } 738 739 /** 740 * Last proportional set size of the memory that the process had used in kB. 741 * 742 * <p class="note">Note: This is the value from last sampling on the process, 743 * it's NOT the exact memory information prior to its death; and it'll be zero 744 * if the process died before system had a chance to take the sample. </p> 745 */ getPss()746 public long getPss() { 747 return mPss; 748 } 749 750 /** 751 * Last resident set size of the memory that the process had used in kB. 752 * 753 * <p class="note">Note: This is the value from last sampling on the process, 754 * it's NOT the exact memory information prior to its death; and it'll be zero 755 * if the process died before system had a chance to take the sample. </p> 756 */ getRss()757 public long getRss() { 758 return mRss; 759 } 760 761 /** 762 * The timestamp of the process's death, in milliseconds since the epoch, 763 * as returned by {@link java.lang.System#currentTimeMillis() System.currentTimeMillis()}. 764 */ getTimestamp()765 public @CurrentTimeMillisLong long getTimestamp() { 766 return mTimestamp; 767 } 768 769 /** 770 * The human readable description of the process's death, given by the system; could be null. 771 * 772 * <p class="note">Note: only intended to be human-readable and the system provides no 773 * guarantees that the format is stable across devices or Android releases.</p> 774 */ getDescription()775 public @Nullable String getDescription() { 776 final StringBuilder sb = new StringBuilder(); 777 778 if (mSubReason != SUBREASON_UNKNOWN) { 779 sb.append("["); 780 sb.append(subreasonToString(mSubReason)); 781 sb.append("]"); 782 } 783 784 if (!TextUtils.isEmpty(mDescription)) { 785 if (sb.length() > 0) { 786 sb.append(" "); 787 } 788 sb.append(mDescription); 789 } 790 791 return sb.toString(); 792 } 793 794 /** 795 * Return the user id of the record on a multi-user system. 796 */ getUserHandle()797 public @NonNull UserHandle getUserHandle() { 798 return UserHandle.of(UserHandle.getUserId(mRealUid)); 799 } 800 801 /** 802 * Return the state data set by calling 803 * {@link android.app.ActivityManager#setProcessStateSummary(byte[]) 804 * ActivityManager.setProcessStateSummary(byte[])} from the process before its death. 805 * 806 * @return The process-customized data 807 * @see ActivityManager#setProcessStateSummary(byte[]) 808 */ getProcessStateSummary()809 public @Nullable byte[] getProcessStateSummary() { 810 return mState; 811 } 812 813 /** 814 * Return the InputStream to the traces that was taken by the system 815 * prior to the death of the process; typically it'll be available when 816 * the reason is {@link #REASON_ANR}, though if the process gets an ANR 817 * but recovers, and dies for another reason later, this trace will be included 818 * in the record of {@link ApplicationExitInfo} still. Beginning with API 31, 819 * tombstone traces will be returned for 820 * {@link #REASON_CRASH_NATIVE}, with an InputStream containing a protobuf with 821 * <a href="https://android.googlesource.com/platform/system/core/+/refs/heads/master/debuggerd/proto/tombstone.proto">this schema</a>. 822 * Note that because these traces are kept in a separate global circular buffer, crashes may be 823 * overwritten by newer crashes (including from other applications), so this may still return 824 * null. 825 * 826 * @return The input stream to the traces that was taken by the system 827 * prior to the death of the process. 828 */ getTraceInputStream()829 public @Nullable InputStream getTraceInputStream() throws IOException { 830 if (mAppTraceRetriever == null && mNativeTombstoneRetriever == null) { 831 return null; 832 } 833 834 try { 835 if (mNativeTombstoneRetriever != null) { 836 final ParcelFileDescriptor pfd = mNativeTombstoneRetriever.getPfd(); 837 if (pfd == null) { 838 return null; 839 } 840 841 return new ParcelFileDescriptor.AutoCloseInputStream(pfd); 842 } else { 843 final ParcelFileDescriptor fd = mAppTraceRetriever.getTraceFileDescriptor( 844 mPackageName, mPackageUid, mPid); 845 if (fd == null) { 846 return null; 847 } 848 return new GZIPInputStream(new ParcelFileDescriptor.AutoCloseInputStream(fd)); 849 } 850 } catch (RemoteException e) { 851 return null; 852 } 853 } 854 855 /** 856 * Similar to {@link #getTraceInputStream} but return the File object. 857 * 858 * For internal use only. 859 * 860 * @hide 861 */ getTraceFile()862 public @Nullable File getTraceFile() { 863 return mTraceFile; 864 } 865 866 /** 867 * A subtype reason in conjunction with {@link #mReason}. 868 * 869 * For internal use only. 870 * 871 * @hide 872 */ getSubReason()873 public @SubReason int getSubReason() { 874 return mSubReason; 875 } 876 877 /** 878 * The connection group this process belongs to, if there is any. 879 * @see android.content.Context#updateServiceGroup 880 * 881 * For internal use only. 882 * 883 * @hide 884 */ getConnectionGroup()885 public int getConnectionGroup() { 886 return mConnectionGroup; 887 } 888 889 /** 890 * Name of first package running in this process; 891 * 892 * @hide 893 */ getPackageName()894 public String getPackageName() { 895 return mPackageName; 896 } 897 898 /** 899 * List of packages running in this process; 900 * 901 * For system internal use only, will not retain across processes. 902 * 903 * @hide 904 */ getPackageList()905 public String[] getPackageList() { 906 return mPackageList; 907 } 908 909 /** 910 * @see #getPid 911 * 912 * @hide 913 */ setPid(final int pid)914 public void setPid(final int pid) { 915 mPid = pid; 916 } 917 918 /** 919 * @see #getRealUid 920 * 921 * @hide 922 */ setRealUid(final int uid)923 public void setRealUid(final int uid) { 924 mRealUid = uid; 925 } 926 927 /** 928 * @see #getPackageUid 929 * 930 * @hide 931 */ setPackageUid(final int uid)932 public void setPackageUid(final int uid) { 933 mPackageUid = uid; 934 } 935 936 /** 937 * @see #getDefiningUid 938 * 939 * @hide 940 */ setDefiningUid(final int uid)941 public void setDefiningUid(final int uid) { 942 mDefiningUid = uid; 943 } 944 945 /** 946 * @see #getProcessName 947 * 948 * @hide 949 */ setProcessName(final String processName)950 public void setProcessName(final String processName) { 951 mProcessName = intern(processName); 952 } 953 954 /** 955 * @see #getReason 956 * 957 * @hide 958 */ setReason(final @Reason int reason)959 public void setReason(final @Reason int reason) { 960 mReason = reason; 961 } 962 963 /** 964 * @see #getStatus 965 * 966 * @hide 967 */ setStatus(final int status)968 public void setStatus(final int status) { 969 mStatus = status; 970 } 971 972 /** 973 * @see #getImportance 974 * 975 * @hide 976 */ setImportance(final @Importance int importance)977 public void setImportance(final @Importance int importance) { 978 mImportance = importance; 979 } 980 981 /** 982 * @see #getPss 983 * 984 * @hide 985 */ setPss(final long pss)986 public void setPss(final long pss) { 987 mPss = pss; 988 } 989 990 /** 991 * @see #getRss 992 * 993 * @hide 994 */ setRss(final long rss)995 public void setRss(final long rss) { 996 mRss = rss; 997 } 998 999 /** 1000 * @see #getTimestamp 1001 * 1002 * @hide 1003 */ setTimestamp(final @CurrentTimeMillisLong long timestamp)1004 public void setTimestamp(final @CurrentTimeMillisLong long timestamp) { 1005 mTimestamp = timestamp; 1006 } 1007 1008 /** 1009 * @see #getDescription 1010 * 1011 * @hide 1012 */ setDescription(final String description)1013 public void setDescription(final String description) { 1014 mDescription = intern(description); 1015 } 1016 1017 /** 1018 * @see #getSubReason 1019 * 1020 * @hide 1021 */ setSubReason(final @SubReason int subReason)1022 public void setSubReason(final @SubReason int subReason) { 1023 mSubReason = subReason; 1024 } 1025 1026 /** 1027 * @see #getConnectionGroup 1028 * 1029 * @hide 1030 */ setConnectionGroup(final int connectionGroup)1031 public void setConnectionGroup(final int connectionGroup) { 1032 mConnectionGroup = connectionGroup; 1033 } 1034 1035 /** 1036 * @see #getPackageName 1037 * 1038 * @hide 1039 */ setPackageName(final String packageName)1040 public void setPackageName(final String packageName) { 1041 mPackageName = intern(packageName); 1042 } 1043 1044 /** 1045 * @see #getPackageList 1046 * 1047 * @hide 1048 */ setPackageList(final String[] packageList)1049 public void setPackageList(final String[] packageList) { 1050 mPackageList = packageList; 1051 } 1052 1053 /** 1054 * @see #getProcessStateSummary 1055 * 1056 * @hide 1057 */ setProcessStateSummary(final byte[] state)1058 public void setProcessStateSummary(final byte[] state) { 1059 mState = state; 1060 } 1061 1062 /** 1063 * @see #getTraceFile 1064 * 1065 * @hide 1066 */ setTraceFile(final File traceFile)1067 public void setTraceFile(final File traceFile) { 1068 mTraceFile = traceFile; 1069 } 1070 1071 /** 1072 * @see #mAppTraceRetriever 1073 * 1074 * @hide 1075 */ setAppTraceRetriever(final IAppTraceRetriever retriever)1076 public void setAppTraceRetriever(final IAppTraceRetriever retriever) { 1077 mAppTraceRetriever = retriever; 1078 } 1079 1080 /** 1081 * @see mNativeTombstoneRetriever 1082 * 1083 * @hide 1084 */ setNativeTombstoneRetriever(final IParcelFileDescriptorRetriever retriever)1085 public void setNativeTombstoneRetriever(final IParcelFileDescriptorRetriever retriever) { 1086 mNativeTombstoneRetriever = retriever; 1087 } 1088 1089 /** 1090 * @see #mLoggedInStatsd 1091 * 1092 * @hide 1093 */ isLoggedInStatsd()1094 public boolean isLoggedInStatsd() { 1095 return mLoggedInStatsd; 1096 } 1097 1098 /** 1099 * @see #mLoggedInStatsd 1100 * 1101 * @hide 1102 */ setLoggedInStatsd(boolean loggedInStatsd)1103 public void setLoggedInStatsd(boolean loggedInStatsd) { 1104 mLoggedInStatsd = loggedInStatsd; 1105 } 1106 1107 /** 1108 * @see #mHasForegroundServices 1109 * 1110 * @hide 1111 */ hasForegroundServices()1112 public boolean hasForegroundServices() { 1113 return mHasForegroundServices; 1114 } 1115 1116 /** 1117 * @see #mHasForegroundServices 1118 * 1119 * @hide 1120 */ setHasForegroundServices(boolean hasForegroundServices)1121 public void setHasForegroundServices(boolean hasForegroundServices) { 1122 mHasForegroundServices = hasForegroundServices; 1123 } 1124 1125 @Override describeContents()1126 public int describeContents() { 1127 return 0; 1128 } 1129 1130 @Override writeToParcel(@onNull Parcel dest, int flags)1131 public void writeToParcel(@NonNull Parcel dest, int flags) { 1132 dest.writeInt(mPid); 1133 dest.writeInt(mRealUid); 1134 dest.writeInt(mPackageUid); 1135 dest.writeInt(mDefiningUid); 1136 dest.writeString(mProcessName); 1137 dest.writeString(mPackageName); 1138 dest.writeInt(mConnectionGroup); 1139 dest.writeInt(mReason); 1140 dest.writeInt(mSubReason); 1141 dest.writeInt(mStatus); 1142 dest.writeInt(mImportance); 1143 dest.writeLong(mPss); 1144 dest.writeLong(mRss); 1145 dest.writeLong(mTimestamp); 1146 dest.writeString(mDescription); 1147 dest.writeByteArray(mState); 1148 if (mAppTraceRetriever != null) { 1149 dest.writeInt(1); 1150 dest.writeStrongBinder(mAppTraceRetriever.asBinder()); 1151 } else { 1152 dest.writeInt(0); 1153 } 1154 if (mNativeTombstoneRetriever != null) { 1155 dest.writeInt(1); 1156 dest.writeStrongBinder(mNativeTombstoneRetriever.asBinder()); 1157 } else { 1158 dest.writeInt(0); 1159 } 1160 } 1161 1162 /** @hide */ ApplicationExitInfo()1163 public ApplicationExitInfo() { 1164 } 1165 1166 /** @hide */ ApplicationExitInfo(ApplicationExitInfo other)1167 public ApplicationExitInfo(ApplicationExitInfo other) { 1168 mPid = other.mPid; 1169 mRealUid = other.mRealUid; 1170 mPackageUid = other.mPackageUid; 1171 mDefiningUid = other.mDefiningUid; 1172 mProcessName = other.mProcessName; 1173 mPackageName = other.mPackageName; 1174 mConnectionGroup = other.mConnectionGroup; 1175 mReason = other.mReason; 1176 mStatus = other.mStatus; 1177 mSubReason = other.mSubReason; 1178 mImportance = other.mImportance; 1179 mPss = other.mPss; 1180 mRss = other.mRss; 1181 mTimestamp = other.mTimestamp; 1182 mDescription = other.mDescription; 1183 mPackageName = other.mPackageName; 1184 mPackageList = other.mPackageList; 1185 mState = other.mState; 1186 mTraceFile = other.mTraceFile; 1187 mAppTraceRetriever = other.mAppTraceRetriever; 1188 mNativeTombstoneRetriever = other.mNativeTombstoneRetriever; 1189 mLoggedInStatsd = other.mLoggedInStatsd; 1190 mHasForegroundServices = other.mHasForegroundServices; 1191 } 1192 ApplicationExitInfo(@onNull Parcel in)1193 private ApplicationExitInfo(@NonNull Parcel in) { 1194 mPid = in.readInt(); 1195 mRealUid = in.readInt(); 1196 mPackageUid = in.readInt(); 1197 mDefiningUid = in.readInt(); 1198 mProcessName = intern(in.readString()); 1199 mPackageName = intern(in.readString()); 1200 mConnectionGroup = in.readInt(); 1201 mReason = in.readInt(); 1202 mSubReason = in.readInt(); 1203 mStatus = in.readInt(); 1204 mImportance = in.readInt(); 1205 mPss = in.readLong(); 1206 mRss = in.readLong(); 1207 mTimestamp = in.readLong(); 1208 mDescription = intern(in.readString()); 1209 mState = in.createByteArray(); 1210 if (in.readInt() == 1) { 1211 mAppTraceRetriever = IAppTraceRetriever.Stub.asInterface(in.readStrongBinder()); 1212 } 1213 if (in.readInt() == 1) { 1214 mNativeTombstoneRetriever = IParcelFileDescriptorRetriever.Stub.asInterface( 1215 in.readStrongBinder()); 1216 } 1217 } 1218 intern(@ullable String source)1219 private static String intern(@Nullable String source) { 1220 return source != null ? source.intern() : null; 1221 } 1222 1223 public @NonNull static final Creator<ApplicationExitInfo> CREATOR = 1224 new Creator<ApplicationExitInfo>() { 1225 @Override 1226 public ApplicationExitInfo createFromParcel(Parcel in) { 1227 return new ApplicationExitInfo(in); 1228 } 1229 1230 @Override 1231 public ApplicationExitInfo[] newArray(int size) { 1232 return new ApplicationExitInfo[size]; 1233 } 1234 }; 1235 1236 /** @hide */ dump(@onNull PrintWriter pw, @Nullable String prefix, @Nullable String seqSuffix, @NonNull SimpleDateFormat sdf)1237 public void dump(@NonNull PrintWriter pw, @Nullable String prefix, @Nullable String seqSuffix, 1238 @NonNull SimpleDateFormat sdf) { 1239 StringBuilder sb = new StringBuilder(); 1240 sb.append(prefix) 1241 .append("ApplicationExitInfo ").append(seqSuffix).append(':') 1242 .append('\n'); 1243 sb.append(prefix).append(' ') 1244 .append(" timestamp=").append(sdf.format(new Date(mTimestamp))) 1245 .append(" pid=").append(mPid) 1246 .append(" realUid=").append(mRealUid) 1247 .append(" packageUid=").append(mPackageUid) 1248 .append(" definingUid=").append(mDefiningUid) 1249 .append(" user=").append(UserHandle.getUserId(mPackageUid)) 1250 .append('\n'); 1251 sb.append(prefix).append(' ') 1252 .append(" process=").append(mProcessName) 1253 .append(" reason=").append(mReason) 1254 .append(" (").append(reasonCodeToString(mReason)).append(")") 1255 .append(" subreason=").append(mSubReason) 1256 .append(" (").append(subreasonToString(mSubReason)).append(")") 1257 .append(" status=").append(mStatus) 1258 .append('\n'); 1259 sb.append(prefix).append(' ') 1260 .append(" importance=").append(mImportance) 1261 .append(" pss="); 1262 DebugUtils.sizeValueToString(mPss << 10, sb); 1263 sb.append(" rss="); 1264 DebugUtils.sizeValueToString(mRss << 10, sb); 1265 sb.append(" description=").append(mDescription) 1266 .append(" state=").append((ArrayUtils.isEmpty(mState) 1267 ? "empty" : Integer.toString(mState.length) + " bytes")) 1268 .append(" trace=").append(mTraceFile) 1269 .append('\n'); 1270 pw.print(sb.toString()); 1271 } 1272 1273 @Override toString()1274 public String toString() { 1275 StringBuilder sb = new StringBuilder(); 1276 sb.append("ApplicationExitInfo(timestamp="); 1277 sb.append(new SimpleDateFormat().format(new Date(mTimestamp))); 1278 sb.append(" pid=").append(mPid); 1279 sb.append(" realUid=").append(mRealUid); 1280 sb.append(" packageUid=").append(mPackageUid); 1281 sb.append(" definingUid=").append(mDefiningUid); 1282 sb.append(" user=").append(UserHandle.getUserId(mPackageUid)); 1283 sb.append(" process=").append(mProcessName); 1284 sb.append(" reason=").append(mReason).append(" (") 1285 .append(reasonCodeToString(mReason)).append(")"); 1286 sb.append(" subreason=").append(mSubReason).append(" (") 1287 .append(subreasonToString(mSubReason)).append(")"); 1288 sb.append(" status=").append(mStatus); 1289 sb.append(" importance=").append(mImportance); 1290 sb.append(" pss="); DebugUtils.sizeValueToString(mPss << 10, sb); 1291 sb.append(" rss="); DebugUtils.sizeValueToString(mRss << 10, sb); 1292 sb.append(" description=").append(mDescription); 1293 sb.append(" state=").append(ArrayUtils.isEmpty(mState) 1294 ? "empty" : Integer.toString(mState.length) + " bytes"); 1295 sb.append(" trace=").append(mTraceFile); 1296 1297 return sb.toString(); 1298 } 1299 1300 /** @hide */ reasonCodeToString(@eason int reason)1301 public static String reasonCodeToString(@Reason int reason) { 1302 switch (reason) { 1303 case REASON_EXIT_SELF: 1304 return "EXIT_SELF"; 1305 case REASON_SIGNALED: 1306 return "SIGNALED"; 1307 case REASON_LOW_MEMORY: 1308 return "LOW_MEMORY"; 1309 case REASON_CRASH: 1310 return "APP CRASH(EXCEPTION)"; 1311 case REASON_CRASH_NATIVE: 1312 return "APP CRASH(NATIVE)"; 1313 case REASON_ANR: 1314 return "ANR"; 1315 case REASON_INITIALIZATION_FAILURE: 1316 return "INITIALIZATION FAILURE"; 1317 case REASON_PERMISSION_CHANGE: 1318 return "PERMISSION CHANGE"; 1319 case REASON_EXCESSIVE_RESOURCE_USAGE: 1320 return "EXCESSIVE RESOURCE USAGE"; 1321 case REASON_USER_REQUESTED: 1322 return "USER REQUESTED"; 1323 case REASON_USER_STOPPED: 1324 return "USER STOPPED"; 1325 case REASON_DEPENDENCY_DIED: 1326 return "DEPENDENCY DIED"; 1327 case REASON_OTHER: 1328 return "OTHER KILLS BY SYSTEM"; 1329 case REASON_FREEZER: 1330 return "FREEZER"; 1331 case REASON_PACKAGE_STATE_CHANGE: 1332 return "STATE CHANGE"; 1333 case REASON_PACKAGE_UPDATED: 1334 return "PACKAGE UPDATED"; 1335 default: 1336 return "UNKNOWN"; 1337 } 1338 } 1339 1340 /** @hide */ subreasonToString(@ubReason int subreason)1341 public static String subreasonToString(@SubReason int subreason) { 1342 switch (subreason) { 1343 case SUBREASON_WAIT_FOR_DEBUGGER: 1344 return "WAIT FOR DEBUGGER"; 1345 case SUBREASON_TOO_MANY_CACHED: 1346 return "TOO MANY CACHED PROCS"; 1347 case SUBREASON_TOO_MANY_EMPTY: 1348 return "TOO MANY EMPTY PROCS"; 1349 case SUBREASON_TRIM_EMPTY: 1350 return "TRIM EMPTY"; 1351 case SUBREASON_LARGE_CACHED: 1352 return "LARGE CACHED"; 1353 case SUBREASON_MEMORY_PRESSURE: 1354 return "MEMORY PRESSURE"; 1355 case SUBREASON_EXCESSIVE_CPU: 1356 return "EXCESSIVE CPU USAGE"; 1357 case SUBREASON_SYSTEM_UPDATE_DONE: 1358 return "SYSTEM UPDATE_DONE"; 1359 case SUBREASON_KILL_ALL_FG: 1360 return "KILL ALL FG"; 1361 case SUBREASON_KILL_ALL_BG_EXCEPT: 1362 return "KILL ALL BG EXCEPT"; 1363 case SUBREASON_KILL_UID: 1364 return "KILL UID"; 1365 case SUBREASON_KILL_PID: 1366 return "KILL PID"; 1367 case SUBREASON_INVALID_START: 1368 return "INVALID START"; 1369 case SUBREASON_INVALID_STATE: 1370 return "INVALID STATE"; 1371 case SUBREASON_IMPERCEPTIBLE: 1372 return "IMPERCEPTIBLE"; 1373 case SUBREASON_REMOVE_LRU: 1374 return "REMOVE LRU"; 1375 case SUBREASON_ISOLATED_NOT_NEEDED: 1376 return "ISOLATED NOT NEEDED"; 1377 case SUBREASON_FREEZER_BINDER_IOCTL: 1378 return "FREEZER BINDER IOCTL"; 1379 case SUBREASON_FREEZER_BINDER_TRANSACTION: 1380 return "FREEZER BINDER TRANSACTION"; 1381 case SUBREASON_FORCE_STOP: 1382 return "FORCE STOP"; 1383 case SUBREASON_REMOVE_TASK: 1384 return "REMOVE TASK"; 1385 case SUBREASON_STOP_APP: 1386 return "STOP APP"; 1387 case SUBREASON_KILL_BACKGROUND: 1388 return "KILL BACKGROUND"; 1389 case SUBREASON_PACKAGE_UPDATE: 1390 return "PACKAGE UPDATE"; 1391 case SUBREASON_UNDELIVERED_BROADCAST: 1392 return "UNDELIVERED BROADCAST"; 1393 case SUBREASON_EXCESSIVE_BINDER_OBJECTS: 1394 return "EXCESSIVE BINDER OBJECTS"; 1395 case SUBREASON_OOM_KILL: 1396 return "OOM KILL"; 1397 case SUBREASON_FREEZER_BINDER_ASYNC_FULL: 1398 return "FREEZER BINDER ASYNC FULL"; 1399 default: 1400 return "UNKNOWN"; 1401 } 1402 } 1403 1404 /** 1405 * Write to a protocol buffer output stream. 1406 * Protocol buffer message definition at {@link android.app.ApplicationExitInfoProto} 1407 * 1408 * @param proto Stream to write the ApplicationExitInfo object to. 1409 * @param fieldId Field Id of the ApplicationExitInfo as defined in the parent message 1410 * @hide 1411 */ writeToProto(ProtoOutputStream proto, long fieldId)1412 public void writeToProto(ProtoOutputStream proto, long fieldId) { 1413 final long token = proto.start(fieldId); 1414 proto.write(ApplicationExitInfoProto.PID, mPid); 1415 proto.write(ApplicationExitInfoProto.REAL_UID, mRealUid); 1416 proto.write(ApplicationExitInfoProto.PACKAGE_UID, mPackageUid); 1417 proto.write(ApplicationExitInfoProto.DEFINING_UID, mDefiningUid); 1418 proto.write(ApplicationExitInfoProto.PROCESS_NAME, mProcessName); 1419 proto.write(ApplicationExitInfoProto.CONNECTION_GROUP, mConnectionGroup); 1420 proto.write(ApplicationExitInfoProto.REASON, mReason); 1421 proto.write(ApplicationExitInfoProto.SUB_REASON, mSubReason); 1422 proto.write(ApplicationExitInfoProto.STATUS, mStatus); 1423 proto.write(ApplicationExitInfoProto.IMPORTANCE, mImportance); 1424 proto.write(ApplicationExitInfoProto.PSS, mPss); 1425 proto.write(ApplicationExitInfoProto.RSS, mRss); 1426 proto.write(ApplicationExitInfoProto.TIMESTAMP, mTimestamp); 1427 proto.write(ApplicationExitInfoProto.DESCRIPTION, mDescription); 1428 proto.write(ApplicationExitInfoProto.STATE, mState); 1429 proto.write(ApplicationExitInfoProto.TRACE_FILE, 1430 mTraceFile == null ? null : mTraceFile.getAbsolutePath()); 1431 proto.end(token); 1432 } 1433 1434 /** 1435 * Read from a protocol buffer input stream. 1436 * Protocol buffer message definition at {@link android.app.ApplicationExitInfoProto} 1437 * 1438 * @param proto Stream to read the ApplicationExitInfo object from. 1439 * @param fieldId Field Id of the ApplicationExitInfo as defined in the parent message 1440 * @hide 1441 */ readFromProto(ProtoInputStream proto, long fieldId)1442 public void readFromProto(ProtoInputStream proto, long fieldId) 1443 throws IOException, WireTypeMismatchException { 1444 final long token = proto.start(fieldId); 1445 while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) { 1446 switch (proto.getFieldNumber()) { 1447 case (int) ApplicationExitInfoProto.PID: 1448 mPid = proto.readInt(ApplicationExitInfoProto.PID); 1449 break; 1450 case (int) ApplicationExitInfoProto.REAL_UID: 1451 mRealUid = proto.readInt(ApplicationExitInfoProto.REAL_UID); 1452 break; 1453 case (int) ApplicationExitInfoProto.PACKAGE_UID: 1454 mPackageUid = proto.readInt(ApplicationExitInfoProto.PACKAGE_UID); 1455 break; 1456 case (int) ApplicationExitInfoProto.DEFINING_UID: 1457 mDefiningUid = proto.readInt(ApplicationExitInfoProto.DEFINING_UID); 1458 break; 1459 case (int) ApplicationExitInfoProto.PROCESS_NAME: 1460 mProcessName = intern(proto.readString(ApplicationExitInfoProto.PROCESS_NAME)); 1461 break; 1462 case (int) ApplicationExitInfoProto.CONNECTION_GROUP: 1463 mConnectionGroup = proto.readInt(ApplicationExitInfoProto.CONNECTION_GROUP); 1464 break; 1465 case (int) ApplicationExitInfoProto.REASON: 1466 mReason = proto.readInt(ApplicationExitInfoProto.REASON); 1467 break; 1468 case (int) ApplicationExitInfoProto.SUB_REASON: 1469 mSubReason = proto.readInt(ApplicationExitInfoProto.SUB_REASON); 1470 break; 1471 case (int) ApplicationExitInfoProto.STATUS: 1472 mStatus = proto.readInt(ApplicationExitInfoProto.STATUS); 1473 break; 1474 case (int) ApplicationExitInfoProto.IMPORTANCE: 1475 mImportance = proto.readInt(ApplicationExitInfoProto.IMPORTANCE); 1476 break; 1477 case (int) ApplicationExitInfoProto.PSS: 1478 mPss = proto.readLong(ApplicationExitInfoProto.PSS); 1479 break; 1480 case (int) ApplicationExitInfoProto.RSS: 1481 mRss = proto.readLong(ApplicationExitInfoProto.RSS); 1482 break; 1483 case (int) ApplicationExitInfoProto.TIMESTAMP: 1484 mTimestamp = proto.readLong(ApplicationExitInfoProto.TIMESTAMP); 1485 break; 1486 case (int) ApplicationExitInfoProto.DESCRIPTION: 1487 mDescription = intern(proto.readString(ApplicationExitInfoProto.DESCRIPTION)); 1488 break; 1489 case (int) ApplicationExitInfoProto.STATE: 1490 mState = proto.readBytes(ApplicationExitInfoProto.STATE); 1491 break; 1492 case (int) ApplicationExitInfoProto.TRACE_FILE: 1493 final String path = proto.readString(ApplicationExitInfoProto.TRACE_FILE); 1494 if (!TextUtils.isEmpty(path)) { 1495 mTraceFile = new File(path); 1496 } 1497 break; 1498 } 1499 } 1500 proto.end(token); 1501 } 1502 1503 @Override equals(@ullable Object other)1504 public boolean equals(@Nullable Object other) { 1505 if (other == null || !(other instanceof ApplicationExitInfo)) { 1506 return false; 1507 } 1508 ApplicationExitInfo o = (ApplicationExitInfo) other; 1509 return mPid == o.mPid && mRealUid == o.mRealUid && mPackageUid == o.mPackageUid 1510 && mDefiningUid == o.mDefiningUid 1511 && mConnectionGroup == o.mConnectionGroup && mReason == o.mReason 1512 && mSubReason == o.mSubReason && mImportance == o.mImportance 1513 && mStatus == o.mStatus && mTimestamp == o.mTimestamp 1514 && mPss == o.mPss && mRss == o.mRss 1515 && TextUtils.equals(mProcessName, o.mProcessName) 1516 && TextUtils.equals(mDescription, o.mDescription); 1517 } 1518 1519 @Override hashCode()1520 public int hashCode() { 1521 int result = mPid; 1522 result = 31 * result + mRealUid; 1523 result = 31 * result + mPackageUid; 1524 result = 31 * result + mDefiningUid; 1525 result = 31 * result + mConnectionGroup; 1526 result = 31 * result + mReason; 1527 result = 31 * result + mSubReason; 1528 result = 31 * result + mImportance; 1529 result = 31 * result + mStatus; 1530 result = 31 * result + (int) mPss; 1531 result = 31 * result + (int) mRss; 1532 result = 31 * result + Long.hashCode(mTimestamp); 1533 result = 31 * result + Objects.hashCode(mProcessName); 1534 result = 31 * result + Objects.hashCode(mDescription); 1535 return result; 1536 } 1537 } 1538