• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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