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 /** 491 * The process was killed because it was sending too many broadcasts while it is in the 492 * Cached state. This would be set only when the reason is {@link #REASON_OTHER}. 493 * 494 * For internal use only. 495 * @hide 496 */ 497 public static final int SUBREASON_EXCESSIVE_OUTGOING_BROADCASTS_WHILE_CACHED = 32; 498 499 // If there is any OEM code which involves additional app kill reasons, it should 500 // be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000. 501 502 /** 503 * @see #getPid 504 */ 505 private int mPid; 506 507 /** 508 * @see #getRealUid 509 */ 510 private int mRealUid; 511 512 /** 513 * @see #getPackageUid 514 */ 515 private int mPackageUid; 516 517 /** 518 * @see #getDefiningUid 519 */ 520 private int mDefiningUid; 521 522 /** 523 * @see #getProcessName 524 */ 525 private String mProcessName; 526 527 /** 528 * @see #getReason 529 */ 530 private @Reason int mReason; 531 532 /** 533 * @see #getStatus 534 */ 535 private int mStatus; 536 537 /** 538 * @see #getImportance 539 */ 540 private @Importance int mImportance; 541 542 /** 543 * @see #getPss 544 */ 545 private long mPss; 546 547 /** 548 * @see #getRss 549 */ 550 private long mRss; 551 552 /** 553 * @see #getTimestamp 554 */ 555 private @CurrentTimeMillisLong long mTimestamp; 556 557 /** 558 * @see #getDescription 559 */ 560 private @Nullable String mDescription; 561 562 /** 563 * @see #getSubReason 564 */ 565 private @SubReason int mSubReason; 566 567 /** 568 * @see #getConnectionGroup 569 */ 570 private int mConnectionGroup; 571 572 /** 573 * @see #getPackageName 574 */ 575 private String mPackageName; 576 577 /** 578 * @see #getPackageList 579 */ 580 private String[] mPackageList; 581 582 /** 583 * @see #getProcessStateSummary 584 */ 585 private byte[] mState; 586 587 /** 588 * The file to the trace file in the storage; 589 * 590 * for system internal use only, will not retain across processes. 591 * 592 * @see #getTraceInputStream 593 */ 594 private File mTraceFile; 595 596 /** 597 * The Binder interface to retrieve the file descriptor to 598 * the trace file from the system. 599 */ 600 private IAppTraceRetriever mAppTraceRetriever; 601 602 /** 603 * ParcelFileDescriptor pointing to a native tombstone. 604 * 605 * @see #getTraceInputStream 606 */ 607 private IParcelFileDescriptorRetriever mNativeTombstoneRetriever; 608 609 /** 610 * Whether or not we've logged this into the statsd. 611 * 612 * for system internal use only, will not retain across processes. 613 */ 614 private boolean mLoggedInStatsd; 615 616 /** 617 * Whether or not this process hosts one or more foreground services. 618 * 619 * for system internal use only, will not retain across processes. 620 */ 621 private boolean mHasForegroundServices; 622 623 /** @hide */ 624 @IntDef(prefix = { "REASON_" }, value = { 625 REASON_UNKNOWN, 626 REASON_EXIT_SELF, 627 REASON_SIGNALED, 628 REASON_LOW_MEMORY, 629 REASON_CRASH, 630 REASON_CRASH_NATIVE, 631 REASON_ANR, 632 REASON_INITIALIZATION_FAILURE, 633 REASON_PERMISSION_CHANGE, 634 REASON_EXCESSIVE_RESOURCE_USAGE, 635 REASON_USER_REQUESTED, 636 REASON_USER_STOPPED, 637 REASON_DEPENDENCY_DIED, 638 REASON_OTHER, 639 REASON_FREEZER, 640 REASON_PACKAGE_STATE_CHANGE, 641 REASON_PACKAGE_UPDATED, 642 }) 643 @Retention(RetentionPolicy.SOURCE) 644 public @interface Reason {} 645 646 /** @hide */ 647 @IntDef(prefix = { "SUBREASON_" }, value = { 648 SUBREASON_UNKNOWN, 649 SUBREASON_WAIT_FOR_DEBUGGER, 650 SUBREASON_TOO_MANY_CACHED, 651 SUBREASON_TOO_MANY_EMPTY, 652 SUBREASON_TRIM_EMPTY, 653 SUBREASON_LARGE_CACHED, 654 SUBREASON_MEMORY_PRESSURE, 655 SUBREASON_EXCESSIVE_CPU, 656 SUBREASON_SYSTEM_UPDATE_DONE, 657 SUBREASON_KILL_ALL_FG, 658 SUBREASON_KILL_ALL_BG_EXCEPT, 659 SUBREASON_KILL_UID, 660 SUBREASON_KILL_PID, 661 SUBREASON_INVALID_START, 662 SUBREASON_INVALID_STATE, 663 SUBREASON_IMPERCEPTIBLE, 664 SUBREASON_REMOVE_LRU, 665 SUBREASON_ISOLATED_NOT_NEEDED, 666 SUBREASON_FREEZER_BINDER_IOCTL, 667 SUBREASON_FREEZER_BINDER_TRANSACTION, 668 SUBREASON_FORCE_STOP, 669 SUBREASON_REMOVE_TASK, 670 SUBREASON_STOP_APP, 671 SUBREASON_KILL_BACKGROUND, 672 SUBREASON_PACKAGE_UPDATE, 673 SUBREASON_UNDELIVERED_BROADCAST, 674 SUBREASON_EXCESSIVE_BINDER_OBJECTS, 675 SUBREASON_OOM_KILL, 676 SUBREASON_FREEZER_BINDER_ASYNC_FULL, 677 SUBREASON_EXCESSIVE_OUTGOING_BROADCASTS_WHILE_CACHED, 678 }) 679 @Retention(RetentionPolicy.SOURCE) 680 public @interface SubReason {} 681 682 /** 683 * The process id of the process that died. 684 */ getPid()685 public int getPid() { 686 return mPid; 687 } 688 689 /** 690 * The kernel user identifier of the process, most of the time the system uses this 691 * to do access control checks. It's typically the uid of the package where the component is 692 * running from, except the case of isolated process, where this field identifies the kernel 693 * user identifier that this process is actually running with, while the {@link #getPackageUid} 694 * identifies the kernel user identifier that is assigned at the package installation time. 695 */ getRealUid()696 public int getRealUid() { 697 return mRealUid; 698 } 699 700 /** 701 * Similar to {@link #getRealUid}, it's the kernel user identifier that is assigned at the 702 * package installation time. 703 */ getPackageUid()704 public int getPackageUid() { 705 return mPackageUid; 706 } 707 708 /** 709 * Return the defining kernel user identifier, maybe different from {@link #getRealUid} and 710 * {@link #getPackageUid}, if an external service has the 711 * {@link android.R.styleable#AndroidManifestService_useAppZygote android:useAppZygote} set 712 * to <code>true</code> and was bound with the flag 713 * {@link android.content.Context#BIND_EXTERNAL_SERVICE} - in this case, this field here will 714 * be the kernel user identifier of the external service provider. 715 */ getDefiningUid()716 public int getDefiningUid() { 717 return mDefiningUid; 718 } 719 720 /** 721 * The actual process name it was running with. 722 */ getProcessName()723 public @NonNull String getProcessName() { 724 return mProcessName; 725 } 726 727 /** 728 * The reason code of the process's death. 729 */ getReason()730 public @Reason int getReason() { 731 return mReason; 732 } 733 734 /** 735 * The exit status argument of exit() if the application calls it, or the signal 736 * number if the application is signaled. 737 */ getStatus()738 public int getStatus() { 739 return mStatus; 740 } 741 742 /** 743 * The importance of the process that it used to have before the death. 744 */ getImportance()745 public @Importance int getImportance() { 746 return mImportance; 747 } 748 749 /** 750 * Last proportional set size of the memory that the process had used in kB. 751 * 752 * <p class="note">Note: This is the value from last sampling on the process, 753 * it's NOT the exact memory information prior to its death; and it'll be zero 754 * if the process died before system had a chance to take the sample. </p> 755 */ getPss()756 public long getPss() { 757 return mPss; 758 } 759 760 /** 761 * Last resident set size of the memory that the process had used in kB. 762 * 763 * <p class="note">Note: This is the value from last sampling on the process, 764 * it's NOT the exact memory information prior to its death; and it'll be zero 765 * if the process died before system had a chance to take the sample. </p> 766 */ getRss()767 public long getRss() { 768 return mRss; 769 } 770 771 /** 772 * The timestamp of the process's death, in milliseconds since the epoch, 773 * as returned by {@link java.lang.System#currentTimeMillis() System.currentTimeMillis()}. 774 */ getTimestamp()775 public @CurrentTimeMillisLong long getTimestamp() { 776 return mTimestamp; 777 } 778 779 /** 780 * The human readable description of the process's death, given by the system; could be null. 781 * 782 * <p class="note">Note: only intended to be human-readable and the system provides no 783 * guarantees that the format is stable across devices or Android releases.</p> 784 */ getDescription()785 public @Nullable String getDescription() { 786 final StringBuilder sb = new StringBuilder(); 787 788 if (mSubReason != SUBREASON_UNKNOWN) { 789 sb.append("["); 790 sb.append(subreasonToString(mSubReason)); 791 sb.append("]"); 792 } 793 794 if (!TextUtils.isEmpty(mDescription)) { 795 if (sb.length() > 0) { 796 sb.append(" "); 797 } 798 sb.append(mDescription); 799 } 800 801 return sb.toString(); 802 } 803 804 /** 805 * Return the user id of the record on a multi-user system. 806 */ getUserHandle()807 public @NonNull UserHandle getUserHandle() { 808 return UserHandle.of(UserHandle.getUserId(mRealUid)); 809 } 810 811 /** 812 * Return the state data set by calling 813 * {@link android.app.ActivityManager#setProcessStateSummary(byte[]) 814 * ActivityManager.setProcessStateSummary(byte[])} from the process before its death. 815 * 816 * @return The process-customized data 817 * @see ActivityManager#setProcessStateSummary(byte[]) 818 */ getProcessStateSummary()819 public @Nullable byte[] getProcessStateSummary() { 820 return mState; 821 } 822 823 /** 824 * Return the InputStream to the traces that was taken by the system 825 * prior to the death of the process; typically it'll be available when 826 * the reason is {@link #REASON_ANR}, though if the process gets an ANR 827 * but recovers, and dies for another reason later, this trace will be included 828 * in the record of {@link ApplicationExitInfo} still. Beginning with API 31, 829 * tombstone traces will be returned for 830 * {@link #REASON_CRASH_NATIVE}, with an InputStream containing a protobuf with 831 * <a href="https://android.googlesource.com/platform/system/core/+/refs/heads/master/debuggerd/proto/tombstone.proto">this schema</a>. 832 * Note that because these traces are kept in a separate global circular buffer, crashes may be 833 * overwritten by newer crashes (including from other applications), so this may still return 834 * null. 835 * 836 * @return The input stream to the traces that was taken by the system 837 * prior to the death of the process. 838 */ getTraceInputStream()839 public @Nullable InputStream getTraceInputStream() throws IOException { 840 if (mAppTraceRetriever == null && mNativeTombstoneRetriever == null) { 841 return null; 842 } 843 844 try { 845 if (mNativeTombstoneRetriever != null) { 846 final ParcelFileDescriptor pfd = mNativeTombstoneRetriever.getPfd(); 847 if (pfd == null) { 848 return null; 849 } 850 851 return new ParcelFileDescriptor.AutoCloseInputStream(pfd); 852 } else { 853 final ParcelFileDescriptor fd = mAppTraceRetriever.getTraceFileDescriptor( 854 mPackageName, mPackageUid, mPid); 855 if (fd == null) { 856 return null; 857 } 858 return new GZIPInputStream(new ParcelFileDescriptor.AutoCloseInputStream(fd)); 859 } 860 } catch (RemoteException e) { 861 return null; 862 } 863 } 864 865 /** 866 * Similar to {@link #getTraceInputStream} but return the File object. 867 * 868 * For internal use only. 869 * 870 * @hide 871 */ getTraceFile()872 public @Nullable File getTraceFile() { 873 return mTraceFile; 874 } 875 876 /** 877 * A subtype reason in conjunction with {@link #mReason}. 878 * 879 * For internal use only. 880 * 881 * @hide 882 */ getSubReason()883 public @SubReason int getSubReason() { 884 return mSubReason; 885 } 886 887 /** 888 * The connection group this process belongs to, if there is any. 889 * @see android.content.Context#updateServiceGroup 890 * 891 * For internal use only. 892 * 893 * @hide 894 */ getConnectionGroup()895 public int getConnectionGroup() { 896 return mConnectionGroup; 897 } 898 899 /** 900 * Name of first package running in this process; 901 * 902 * @hide 903 */ getPackageName()904 public String getPackageName() { 905 return mPackageName; 906 } 907 908 /** 909 * List of packages running in this process; 910 * 911 * For system internal use only, will not retain across processes. 912 * 913 * @hide 914 */ getPackageList()915 public String[] getPackageList() { 916 return mPackageList; 917 } 918 919 /** 920 * @see #getPid 921 * 922 * @hide 923 */ setPid(final int pid)924 public void setPid(final int pid) { 925 mPid = pid; 926 } 927 928 /** 929 * @see #getRealUid 930 * 931 * @hide 932 */ setRealUid(final int uid)933 public void setRealUid(final int uid) { 934 mRealUid = uid; 935 } 936 937 /** 938 * @see #getPackageUid 939 * 940 * @hide 941 */ setPackageUid(final int uid)942 public void setPackageUid(final int uid) { 943 mPackageUid = uid; 944 } 945 946 /** 947 * @see #getDefiningUid 948 * 949 * @hide 950 */ setDefiningUid(final int uid)951 public void setDefiningUid(final int uid) { 952 mDefiningUid = uid; 953 } 954 955 /** 956 * @see #getProcessName 957 * 958 * @hide 959 */ setProcessName(final String processName)960 public void setProcessName(final String processName) { 961 mProcessName = intern(processName); 962 } 963 964 /** 965 * @see #getReason 966 * 967 * @hide 968 */ setReason(final @Reason int reason)969 public void setReason(final @Reason int reason) { 970 mReason = reason; 971 } 972 973 /** 974 * @see #getStatus 975 * 976 * @hide 977 */ setStatus(final int status)978 public void setStatus(final int status) { 979 mStatus = status; 980 } 981 982 /** 983 * @see #getImportance 984 * 985 * @hide 986 */ setImportance(final @Importance int importance)987 public void setImportance(final @Importance int importance) { 988 mImportance = importance; 989 } 990 991 /** 992 * @see #getPss 993 * 994 * @hide 995 */ setPss(final long pss)996 public void setPss(final long pss) { 997 mPss = pss; 998 } 999 1000 /** 1001 * @see #getRss 1002 * 1003 * @hide 1004 */ setRss(final long rss)1005 public void setRss(final long rss) { 1006 mRss = rss; 1007 } 1008 1009 /** 1010 * @see #getTimestamp 1011 * 1012 * @hide 1013 */ setTimestamp(final @CurrentTimeMillisLong long timestamp)1014 public void setTimestamp(final @CurrentTimeMillisLong long timestamp) { 1015 mTimestamp = timestamp; 1016 } 1017 1018 /** 1019 * @see #getDescription 1020 * 1021 * @hide 1022 */ setDescription(final String description)1023 public void setDescription(final String description) { 1024 mDescription = intern(description); 1025 } 1026 1027 /** 1028 * @see #getSubReason 1029 * 1030 * @hide 1031 */ setSubReason(final @SubReason int subReason)1032 public void setSubReason(final @SubReason int subReason) { 1033 mSubReason = subReason; 1034 } 1035 1036 /** 1037 * @see #getConnectionGroup 1038 * 1039 * @hide 1040 */ setConnectionGroup(final int connectionGroup)1041 public void setConnectionGroup(final int connectionGroup) { 1042 mConnectionGroup = connectionGroup; 1043 } 1044 1045 /** 1046 * @see #getPackageName 1047 * 1048 * @hide 1049 */ setPackageName(final String packageName)1050 public void setPackageName(final String packageName) { 1051 mPackageName = intern(packageName); 1052 } 1053 1054 /** 1055 * @see #getPackageList 1056 * 1057 * @hide 1058 */ setPackageList(final String[] packageList)1059 public void setPackageList(final String[] packageList) { 1060 mPackageList = packageList; 1061 } 1062 1063 /** 1064 * @see #getProcessStateSummary 1065 * 1066 * @hide 1067 */ setProcessStateSummary(final byte[] state)1068 public void setProcessStateSummary(final byte[] state) { 1069 mState = state; 1070 } 1071 1072 /** 1073 * @see #getTraceFile 1074 * 1075 * @hide 1076 */ setTraceFile(final File traceFile)1077 public void setTraceFile(final File traceFile) { 1078 mTraceFile = traceFile; 1079 } 1080 1081 /** 1082 * @see #mAppTraceRetriever 1083 * 1084 * @hide 1085 */ setAppTraceRetriever(final IAppTraceRetriever retriever)1086 public void setAppTraceRetriever(final IAppTraceRetriever retriever) { 1087 mAppTraceRetriever = retriever; 1088 } 1089 1090 /** 1091 * @see mNativeTombstoneRetriever 1092 * 1093 * @hide 1094 */ setNativeTombstoneRetriever(final IParcelFileDescriptorRetriever retriever)1095 public void setNativeTombstoneRetriever(final IParcelFileDescriptorRetriever retriever) { 1096 mNativeTombstoneRetriever = retriever; 1097 } 1098 1099 /** 1100 * @see #mLoggedInStatsd 1101 * 1102 * @hide 1103 */ isLoggedInStatsd()1104 public boolean isLoggedInStatsd() { 1105 return mLoggedInStatsd; 1106 } 1107 1108 /** 1109 * @see #mLoggedInStatsd 1110 * 1111 * @hide 1112 */ setLoggedInStatsd(boolean loggedInStatsd)1113 public void setLoggedInStatsd(boolean loggedInStatsd) { 1114 mLoggedInStatsd = loggedInStatsd; 1115 } 1116 1117 /** 1118 * @see #mHasForegroundServices 1119 * 1120 * @hide 1121 */ hasForegroundServices()1122 public boolean hasForegroundServices() { 1123 return mHasForegroundServices; 1124 } 1125 1126 /** 1127 * @see #mHasForegroundServices 1128 * 1129 * @hide 1130 */ setHasForegroundServices(boolean hasForegroundServices)1131 public void setHasForegroundServices(boolean hasForegroundServices) { 1132 mHasForegroundServices = hasForegroundServices; 1133 } 1134 1135 @Override describeContents()1136 public int describeContents() { 1137 return 0; 1138 } 1139 1140 @Override writeToParcel(@onNull Parcel dest, int flags)1141 public void writeToParcel(@NonNull Parcel dest, int flags) { 1142 dest.writeInt(mPid); 1143 dest.writeInt(mRealUid); 1144 dest.writeInt(mPackageUid); 1145 dest.writeInt(mDefiningUid); 1146 dest.writeString(mProcessName); 1147 dest.writeString(mPackageName); 1148 dest.writeInt(mConnectionGroup); 1149 dest.writeInt(mReason); 1150 dest.writeInt(mSubReason); 1151 dest.writeInt(mStatus); 1152 dest.writeInt(mImportance); 1153 dest.writeLong(mPss); 1154 dest.writeLong(mRss); 1155 dest.writeLong(mTimestamp); 1156 dest.writeString(mDescription); 1157 dest.writeByteArray(mState); 1158 if (mAppTraceRetriever != null) { 1159 dest.writeInt(1); 1160 dest.writeStrongBinder(mAppTraceRetriever.asBinder()); 1161 } else { 1162 dest.writeInt(0); 1163 } 1164 if (mNativeTombstoneRetriever != null) { 1165 dest.writeInt(1); 1166 dest.writeStrongBinder(mNativeTombstoneRetriever.asBinder()); 1167 } else { 1168 dest.writeInt(0); 1169 } 1170 } 1171 1172 /** @hide */ ApplicationExitInfo()1173 public ApplicationExitInfo() { 1174 } 1175 1176 /** @hide */ ApplicationExitInfo(ApplicationExitInfo other)1177 public ApplicationExitInfo(ApplicationExitInfo other) { 1178 mPid = other.mPid; 1179 mRealUid = other.mRealUid; 1180 mPackageUid = other.mPackageUid; 1181 mDefiningUid = other.mDefiningUid; 1182 mProcessName = other.mProcessName; 1183 mPackageName = other.mPackageName; 1184 mConnectionGroup = other.mConnectionGroup; 1185 mReason = other.mReason; 1186 mStatus = other.mStatus; 1187 mSubReason = other.mSubReason; 1188 mImportance = other.mImportance; 1189 mPss = other.mPss; 1190 mRss = other.mRss; 1191 mTimestamp = other.mTimestamp; 1192 mDescription = other.mDescription; 1193 mPackageName = other.mPackageName; 1194 mPackageList = other.mPackageList; 1195 mState = other.mState; 1196 mTraceFile = other.mTraceFile; 1197 mAppTraceRetriever = other.mAppTraceRetriever; 1198 mNativeTombstoneRetriever = other.mNativeTombstoneRetriever; 1199 mLoggedInStatsd = other.mLoggedInStatsd; 1200 mHasForegroundServices = other.mHasForegroundServices; 1201 } 1202 ApplicationExitInfo(@onNull Parcel in)1203 private ApplicationExitInfo(@NonNull Parcel in) { 1204 mPid = in.readInt(); 1205 mRealUid = in.readInt(); 1206 mPackageUid = in.readInt(); 1207 mDefiningUid = in.readInt(); 1208 mProcessName = intern(in.readString()); 1209 mPackageName = intern(in.readString()); 1210 mConnectionGroup = in.readInt(); 1211 mReason = in.readInt(); 1212 mSubReason = in.readInt(); 1213 mStatus = in.readInt(); 1214 mImportance = in.readInt(); 1215 mPss = in.readLong(); 1216 mRss = in.readLong(); 1217 mTimestamp = in.readLong(); 1218 mDescription = intern(in.readString()); 1219 mState = in.createByteArray(); 1220 if (in.readInt() == 1) { 1221 mAppTraceRetriever = IAppTraceRetriever.Stub.asInterface(in.readStrongBinder()); 1222 } 1223 if (in.readInt() == 1) { 1224 mNativeTombstoneRetriever = IParcelFileDescriptorRetriever.Stub.asInterface( 1225 in.readStrongBinder()); 1226 } 1227 } 1228 intern(@ullable String source)1229 private static String intern(@Nullable String source) { 1230 return source != null ? source.intern() : null; 1231 } 1232 1233 public @NonNull static final Creator<ApplicationExitInfo> CREATOR = 1234 new Creator<ApplicationExitInfo>() { 1235 @Override 1236 public ApplicationExitInfo createFromParcel(Parcel in) { 1237 return new ApplicationExitInfo(in); 1238 } 1239 1240 @Override 1241 public ApplicationExitInfo[] newArray(int size) { 1242 return new ApplicationExitInfo[size]; 1243 } 1244 }; 1245 1246 /** @hide */ dump(@onNull PrintWriter pw, @Nullable String prefix, @Nullable String seqSuffix, @NonNull SimpleDateFormat sdf)1247 public void dump(@NonNull PrintWriter pw, @Nullable String prefix, @Nullable String seqSuffix, 1248 @NonNull SimpleDateFormat sdf) { 1249 StringBuilder sb = new StringBuilder(); 1250 sb.append(prefix) 1251 .append("ApplicationExitInfo ").append(seqSuffix).append(':') 1252 .append('\n'); 1253 sb.append(prefix).append(' ') 1254 .append(" timestamp=").append(sdf.format(new Date(mTimestamp))) 1255 .append(" pid=").append(mPid) 1256 .append(" realUid=").append(mRealUid) 1257 .append(" packageUid=").append(mPackageUid) 1258 .append(" definingUid=").append(mDefiningUid) 1259 .append(" user=").append(UserHandle.getUserId(mPackageUid)) 1260 .append('\n'); 1261 sb.append(prefix).append(' ') 1262 .append(" process=").append(mProcessName) 1263 .append(" reason=").append(mReason) 1264 .append(" (").append(reasonCodeToString(mReason)).append(")") 1265 .append(" subreason=").append(mSubReason) 1266 .append(" (").append(subreasonToString(mSubReason)).append(")") 1267 .append(" status=").append(mStatus) 1268 .append('\n'); 1269 sb.append(prefix).append(' ') 1270 .append(" importance=").append(mImportance) 1271 .append(" pss="); 1272 DebugUtils.sizeValueToString(mPss << 10, sb); 1273 sb.append(" rss="); 1274 DebugUtils.sizeValueToString(mRss << 10, sb); 1275 sb.append(" description=").append(mDescription) 1276 .append(" state=").append((ArrayUtils.isEmpty(mState) 1277 ? "empty" : Integer.toString(mState.length) + " bytes")) 1278 .append(" trace=").append(mTraceFile) 1279 .append('\n'); 1280 pw.print(sb.toString()); 1281 } 1282 1283 @Override toString()1284 public String toString() { 1285 StringBuilder sb = new StringBuilder(); 1286 sb.append("ApplicationExitInfo(timestamp="); 1287 sb.append(new SimpleDateFormat().format(new Date(mTimestamp))); 1288 sb.append(" pid=").append(mPid); 1289 sb.append(" realUid=").append(mRealUid); 1290 sb.append(" packageUid=").append(mPackageUid); 1291 sb.append(" definingUid=").append(mDefiningUid); 1292 sb.append(" user=").append(UserHandle.getUserId(mPackageUid)); 1293 sb.append(" process=").append(mProcessName); 1294 sb.append(" reason=").append(mReason).append(" (") 1295 .append(reasonCodeToString(mReason)).append(")"); 1296 sb.append(" subreason=").append(mSubReason).append(" (") 1297 .append(subreasonToString(mSubReason)).append(")"); 1298 sb.append(" status=").append(mStatus); 1299 sb.append(" importance=").append(mImportance); 1300 sb.append(" pss="); DebugUtils.sizeValueToString(mPss << 10, sb); 1301 sb.append(" rss="); DebugUtils.sizeValueToString(mRss << 10, sb); 1302 sb.append(" description=").append(mDescription); 1303 sb.append(" state=").append(ArrayUtils.isEmpty(mState) 1304 ? "empty" : Integer.toString(mState.length) + " bytes"); 1305 sb.append(" trace=").append(mTraceFile); 1306 1307 return sb.toString(); 1308 } 1309 1310 /** @hide */ reasonCodeToString(@eason int reason)1311 public static String reasonCodeToString(@Reason int reason) { 1312 switch (reason) { 1313 case REASON_EXIT_SELF: 1314 return "EXIT_SELF"; 1315 case REASON_SIGNALED: 1316 return "SIGNALED"; 1317 case REASON_LOW_MEMORY: 1318 return "LOW_MEMORY"; 1319 case REASON_CRASH: 1320 return "APP CRASH(EXCEPTION)"; 1321 case REASON_CRASH_NATIVE: 1322 return "APP CRASH(NATIVE)"; 1323 case REASON_ANR: 1324 return "ANR"; 1325 case REASON_INITIALIZATION_FAILURE: 1326 return "INITIALIZATION FAILURE"; 1327 case REASON_PERMISSION_CHANGE: 1328 return "PERMISSION CHANGE"; 1329 case REASON_EXCESSIVE_RESOURCE_USAGE: 1330 return "EXCESSIVE RESOURCE USAGE"; 1331 case REASON_USER_REQUESTED: 1332 return "USER REQUESTED"; 1333 case REASON_USER_STOPPED: 1334 return "USER STOPPED"; 1335 case REASON_DEPENDENCY_DIED: 1336 return "DEPENDENCY DIED"; 1337 case REASON_OTHER: 1338 return "OTHER KILLS BY SYSTEM"; 1339 case REASON_FREEZER: 1340 return "FREEZER"; 1341 case REASON_PACKAGE_STATE_CHANGE: 1342 return "STATE CHANGE"; 1343 case REASON_PACKAGE_UPDATED: 1344 return "PACKAGE UPDATED"; 1345 default: 1346 return "UNKNOWN"; 1347 } 1348 } 1349 1350 /** @hide */ subreasonToString(@ubReason int subreason)1351 public static String subreasonToString(@SubReason int subreason) { 1352 switch (subreason) { 1353 case SUBREASON_WAIT_FOR_DEBUGGER: 1354 return "WAIT FOR DEBUGGER"; 1355 case SUBREASON_TOO_MANY_CACHED: 1356 return "TOO MANY CACHED PROCS"; 1357 case SUBREASON_TOO_MANY_EMPTY: 1358 return "TOO MANY EMPTY PROCS"; 1359 case SUBREASON_TRIM_EMPTY: 1360 return "TRIM EMPTY"; 1361 case SUBREASON_LARGE_CACHED: 1362 return "LARGE CACHED"; 1363 case SUBREASON_MEMORY_PRESSURE: 1364 return "MEMORY PRESSURE"; 1365 case SUBREASON_EXCESSIVE_CPU: 1366 return "EXCESSIVE CPU USAGE"; 1367 case SUBREASON_SYSTEM_UPDATE_DONE: 1368 return "SYSTEM UPDATE_DONE"; 1369 case SUBREASON_KILL_ALL_FG: 1370 return "KILL ALL FG"; 1371 case SUBREASON_KILL_ALL_BG_EXCEPT: 1372 return "KILL ALL BG EXCEPT"; 1373 case SUBREASON_KILL_UID: 1374 return "KILL UID"; 1375 case SUBREASON_KILL_PID: 1376 return "KILL PID"; 1377 case SUBREASON_INVALID_START: 1378 return "INVALID START"; 1379 case SUBREASON_INVALID_STATE: 1380 return "INVALID STATE"; 1381 case SUBREASON_IMPERCEPTIBLE: 1382 return "IMPERCEPTIBLE"; 1383 case SUBREASON_REMOVE_LRU: 1384 return "REMOVE LRU"; 1385 case SUBREASON_ISOLATED_NOT_NEEDED: 1386 return "ISOLATED NOT NEEDED"; 1387 case SUBREASON_FREEZER_BINDER_IOCTL: 1388 return "FREEZER BINDER IOCTL"; 1389 case SUBREASON_FREEZER_BINDER_TRANSACTION: 1390 return "FREEZER BINDER TRANSACTION"; 1391 case SUBREASON_FORCE_STOP: 1392 return "FORCE STOP"; 1393 case SUBREASON_REMOVE_TASK: 1394 return "REMOVE TASK"; 1395 case SUBREASON_STOP_APP: 1396 return "STOP APP"; 1397 case SUBREASON_KILL_BACKGROUND: 1398 return "KILL BACKGROUND"; 1399 case SUBREASON_PACKAGE_UPDATE: 1400 return "PACKAGE UPDATE"; 1401 case SUBREASON_UNDELIVERED_BROADCAST: 1402 return "UNDELIVERED BROADCAST"; 1403 case SUBREASON_EXCESSIVE_BINDER_OBJECTS: 1404 return "EXCESSIVE BINDER OBJECTS"; 1405 case SUBREASON_OOM_KILL: 1406 return "OOM KILL"; 1407 case SUBREASON_FREEZER_BINDER_ASYNC_FULL: 1408 return "FREEZER BINDER ASYNC FULL"; 1409 case SUBREASON_EXCESSIVE_OUTGOING_BROADCASTS_WHILE_CACHED: 1410 return "EXCESSIVE_OUTGOING_BROADCASTS_WHILE_CACHED"; 1411 default: 1412 return "UNKNOWN"; 1413 } 1414 } 1415 1416 /** 1417 * Write to a protocol buffer output stream. 1418 * Protocol buffer message definition at {@link android.app.ApplicationExitInfoProto} 1419 * 1420 * @param proto Stream to write the ApplicationExitInfo object to. 1421 * @param fieldId Field Id of the ApplicationExitInfo as defined in the parent message 1422 * @hide 1423 */ writeToProto(ProtoOutputStream proto, long fieldId)1424 public void writeToProto(ProtoOutputStream proto, long fieldId) { 1425 final long token = proto.start(fieldId); 1426 proto.write(ApplicationExitInfoProto.PID, mPid); 1427 proto.write(ApplicationExitInfoProto.REAL_UID, mRealUid); 1428 proto.write(ApplicationExitInfoProto.PACKAGE_UID, mPackageUid); 1429 proto.write(ApplicationExitInfoProto.DEFINING_UID, mDefiningUid); 1430 proto.write(ApplicationExitInfoProto.PROCESS_NAME, mProcessName); 1431 proto.write(ApplicationExitInfoProto.CONNECTION_GROUP, mConnectionGroup); 1432 proto.write(ApplicationExitInfoProto.REASON, mReason); 1433 proto.write(ApplicationExitInfoProto.SUB_REASON, mSubReason); 1434 proto.write(ApplicationExitInfoProto.STATUS, mStatus); 1435 proto.write(ApplicationExitInfoProto.IMPORTANCE, mImportance); 1436 proto.write(ApplicationExitInfoProto.PSS, mPss); 1437 proto.write(ApplicationExitInfoProto.RSS, mRss); 1438 proto.write(ApplicationExitInfoProto.TIMESTAMP, mTimestamp); 1439 proto.write(ApplicationExitInfoProto.DESCRIPTION, mDescription); 1440 proto.write(ApplicationExitInfoProto.STATE, mState); 1441 proto.write(ApplicationExitInfoProto.TRACE_FILE, 1442 mTraceFile == null ? null : mTraceFile.getAbsolutePath()); 1443 proto.end(token); 1444 } 1445 1446 /** 1447 * Read from a protocol buffer input stream. 1448 * Protocol buffer message definition at {@link android.app.ApplicationExitInfoProto} 1449 * 1450 * @param proto Stream to read the ApplicationExitInfo object from. 1451 * @param fieldId Field Id of the ApplicationExitInfo as defined in the parent message 1452 * @hide 1453 */ readFromProto(ProtoInputStream proto, long fieldId)1454 public void readFromProto(ProtoInputStream proto, long fieldId) 1455 throws IOException, WireTypeMismatchException { 1456 final long token = proto.start(fieldId); 1457 while (proto.nextField() != ProtoInputStream.NO_MORE_FIELDS) { 1458 switch (proto.getFieldNumber()) { 1459 case (int) ApplicationExitInfoProto.PID: 1460 mPid = proto.readInt(ApplicationExitInfoProto.PID); 1461 break; 1462 case (int) ApplicationExitInfoProto.REAL_UID: 1463 mRealUid = proto.readInt(ApplicationExitInfoProto.REAL_UID); 1464 break; 1465 case (int) ApplicationExitInfoProto.PACKAGE_UID: 1466 mPackageUid = proto.readInt(ApplicationExitInfoProto.PACKAGE_UID); 1467 break; 1468 case (int) ApplicationExitInfoProto.DEFINING_UID: 1469 mDefiningUid = proto.readInt(ApplicationExitInfoProto.DEFINING_UID); 1470 break; 1471 case (int) ApplicationExitInfoProto.PROCESS_NAME: 1472 mProcessName = intern(proto.readString(ApplicationExitInfoProto.PROCESS_NAME)); 1473 break; 1474 case (int) ApplicationExitInfoProto.CONNECTION_GROUP: 1475 mConnectionGroup = proto.readInt(ApplicationExitInfoProto.CONNECTION_GROUP); 1476 break; 1477 case (int) ApplicationExitInfoProto.REASON: 1478 mReason = proto.readInt(ApplicationExitInfoProto.REASON); 1479 break; 1480 case (int) ApplicationExitInfoProto.SUB_REASON: 1481 mSubReason = proto.readInt(ApplicationExitInfoProto.SUB_REASON); 1482 break; 1483 case (int) ApplicationExitInfoProto.STATUS: 1484 mStatus = proto.readInt(ApplicationExitInfoProto.STATUS); 1485 break; 1486 case (int) ApplicationExitInfoProto.IMPORTANCE: 1487 mImportance = proto.readInt(ApplicationExitInfoProto.IMPORTANCE); 1488 break; 1489 case (int) ApplicationExitInfoProto.PSS: 1490 mPss = proto.readLong(ApplicationExitInfoProto.PSS); 1491 break; 1492 case (int) ApplicationExitInfoProto.RSS: 1493 mRss = proto.readLong(ApplicationExitInfoProto.RSS); 1494 break; 1495 case (int) ApplicationExitInfoProto.TIMESTAMP: 1496 mTimestamp = proto.readLong(ApplicationExitInfoProto.TIMESTAMP); 1497 break; 1498 case (int) ApplicationExitInfoProto.DESCRIPTION: 1499 mDescription = intern(proto.readString(ApplicationExitInfoProto.DESCRIPTION)); 1500 break; 1501 case (int) ApplicationExitInfoProto.STATE: 1502 mState = proto.readBytes(ApplicationExitInfoProto.STATE); 1503 break; 1504 case (int) ApplicationExitInfoProto.TRACE_FILE: 1505 final String path = proto.readString(ApplicationExitInfoProto.TRACE_FILE); 1506 if (!TextUtils.isEmpty(path)) { 1507 mTraceFile = new File(path); 1508 } 1509 break; 1510 } 1511 } 1512 proto.end(token); 1513 } 1514 1515 @Override equals(@ullable Object other)1516 public boolean equals(@Nullable Object other) { 1517 if (other == null || !(other instanceof ApplicationExitInfo)) { 1518 return false; 1519 } 1520 ApplicationExitInfo o = (ApplicationExitInfo) other; 1521 return mPid == o.mPid && mRealUid == o.mRealUid && mPackageUid == o.mPackageUid 1522 && mDefiningUid == o.mDefiningUid 1523 && mConnectionGroup == o.mConnectionGroup && mReason == o.mReason 1524 && mSubReason == o.mSubReason && mImportance == o.mImportance 1525 && mStatus == o.mStatus && mTimestamp == o.mTimestamp 1526 && mPss == o.mPss && mRss == o.mRss 1527 && TextUtils.equals(mProcessName, o.mProcessName) 1528 && TextUtils.equals(mDescription, o.mDescription); 1529 } 1530 1531 @Override hashCode()1532 public int hashCode() { 1533 int result = mPid; 1534 result = 31 * result + mRealUid; 1535 result = 31 * result + mPackageUid; 1536 result = 31 * result + mDefiningUid; 1537 result = 31 * result + mConnectionGroup; 1538 result = 31 * result + mReason; 1539 result = 31 * result + mSubReason; 1540 result = 31 * result + mImportance; 1541 result = 31 * result + mStatus; 1542 result = 31 * result + (int) mPss; 1543 result = 31 * result + (int) mRss; 1544 result = 31 * result + Long.hashCode(mTimestamp); 1545 result = 31 * result + Objects.hashCode(mProcessName); 1546 result = 31 * result + Objects.hashCode(mDescription); 1547 return result; 1548 } 1549 } 1550