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