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