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