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