ApplicationErrorReport.java revision e0ee6efb1e5bc6cf219555e333635ce98531bc85
1/*
2 * Copyright (C) 2008 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
17package android.app;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21import android.util.Printer;
22import java.io.PrintWriter;
23import java.io.StringWriter;
24
25/**
26 * Describes an application error.
27 *
28 * A report has a type, which is one of
29 * <ul>
30 * <li> {@link #TYPE_CRASH} application crash. Information about the crash
31 * is stored in {@link #crashInfo}.
32 * <li> {@link #TYPE_ANR} application not responding. Information about the
33 * ANR is stored in {@link #anrInfo}.
34 * <li> {@link #TYPE_NONE} uninitialized instance of {@link ApplicationErrorReport}.
35 * </ul>
36 *
37 * @hide
38 */
39
40public class ApplicationErrorReport implements Parcelable {
41    /**
42     * Uninitialized error report.
43     */
44    public static final int TYPE_NONE = 0;
45
46    /**
47     * An error report about an application crash.
48     */
49    public static final int TYPE_CRASH = 1;
50
51    /**
52     * An error report about an application that's not responding.
53     */
54    public static final int TYPE_ANR = 2;
55
56    /**
57     * Type of this report. Can be one of {@link #TYPE_NONE},
58     * {@link #TYPE_CRASH} or {@link #TYPE_ANR}.
59     */
60    public int type;
61
62    /**
63     * Package name of the application.
64     */
65    public String packageName;
66
67    /**
68     * Package name of the application which installed the application this
69     * report pertains to.
70     * This identifies which Market the application came from.
71     */
72    public String installerPackageName;
73
74    /**
75     * Process name of the application.
76     */
77    public String processName;
78
79    /**
80     * Time at which the error occurred.
81     */
82    public long time;
83
84    /**
85     * Set if the app is on the system image.
86     */
87    public boolean systemApp;
88
89    /**
90     * If this report is of type {@link #TYPE_CRASH}, contains an instance
91     * of CrashInfo describing the crash; otherwise null.
92     */
93    public CrashInfo crashInfo;
94
95    /**
96     * If this report is of type {@link #TYPE_ANR}, contains an instance
97     * of AnrInfo describing the ANR; otherwise null.
98     */
99    public AnrInfo anrInfo;
100
101    /**
102     * Create an uninitialized instance of {@link ApplicationErrorReport}.
103     */
104    public ApplicationErrorReport() {
105    }
106
107    /**
108     * Create an instance of {@link ApplicationErrorReport} initialized from
109     * a parcel.
110     */
111    ApplicationErrorReport(Parcel in) {
112        readFromParcel(in);
113    }
114
115    public void writeToParcel(Parcel dest, int flags) {
116        dest.writeInt(type);
117        dest.writeString(packageName);
118        dest.writeString(installerPackageName);
119        dest.writeString(processName);
120        dest.writeLong(time);
121        dest.writeInt(systemApp ? 1 : 0);
122
123        switch (type) {
124            case TYPE_CRASH:
125                crashInfo.writeToParcel(dest, flags);
126                break;
127            case TYPE_ANR:
128                anrInfo.writeToParcel(dest, flags);
129                break;
130        }
131    }
132
133    public void readFromParcel(Parcel in) {
134        type = in.readInt();
135        packageName = in.readString();
136        installerPackageName = in.readString();
137        processName = in.readString();
138        time = in.readLong();
139        systemApp = in.readInt() == 1;
140
141        switch (type) {
142            case TYPE_CRASH:
143                crashInfo = new CrashInfo(in);
144                anrInfo = null;
145                break;
146            case TYPE_ANR:
147                anrInfo = new AnrInfo(in);
148                crashInfo = null;
149                break;
150        }
151    }
152
153    /**
154     * Describes an application crash.
155     */
156    public static class CrashInfo {
157        /**
158         * Class name of the exception that caused the crash.
159         */
160        public String exceptionClassName;
161
162        /**
163         * Message stored in the exception.
164         */
165        public String exceptionMessage;
166
167        /**
168         * File which the exception was thrown from.
169         */
170        public String throwFileName;
171
172        /**
173         * Class which the exception was thrown from.
174         */
175        public String throwClassName;
176
177        /**
178         * Method which the exception was thrown from.
179         */
180        public String throwMethodName;
181
182        /**
183         * Line number the exception was thrown from.
184         */
185        public int throwLineNumber;
186
187        /**
188         * Stack trace.
189         */
190        public String stackTrace;
191
192        /**
193         * Create an uninitialized instance of CrashInfo.
194         */
195        public CrashInfo() {
196        }
197
198        /**
199         * Create an instance of CrashInfo initialized from an exception.
200         */
201        public CrashInfo(Throwable tr) {
202            StringWriter sw = new StringWriter();
203            tr.printStackTrace(new PrintWriter(sw));
204            stackTrace = sw.toString();
205            exceptionMessage = tr.getMessage();
206
207            // Populate fields with the "root cause" exception
208            while (tr.getCause() != null) {
209                tr = tr.getCause();
210                String msg = tr.getMessage();
211                if (msg != null && msg.length() > 0) {
212                    exceptionMessage = msg;
213                }
214            }
215
216            exceptionClassName = tr.getClass().getName();
217            StackTraceElement trace = tr.getStackTrace()[0];
218            throwFileName = trace.getFileName();
219            throwClassName = trace.getClassName();
220            throwMethodName = trace.getMethodName();
221            throwLineNumber = trace.getLineNumber();
222        }
223
224        /**
225         * Create an instance of CrashInfo initialized from a Parcel.
226         */
227        public CrashInfo(Parcel in) {
228            exceptionClassName = in.readString();
229            exceptionMessage = in.readString();
230            throwFileName = in.readString();
231            throwClassName = in.readString();
232            throwMethodName = in.readString();
233            throwLineNumber = in.readInt();
234            stackTrace = in.readString();
235        }
236
237        /**
238         * Save a CrashInfo instance to a parcel.
239         */
240        public void writeToParcel(Parcel dest, int flags) {
241            dest.writeString(exceptionClassName);
242            dest.writeString(exceptionMessage);
243            dest.writeString(throwFileName);
244            dest.writeString(throwClassName);
245            dest.writeString(throwMethodName);
246            dest.writeInt(throwLineNumber);
247            dest.writeString(stackTrace);
248        }
249
250        /**
251         * Dump a CrashInfo instance to a Printer.
252         */
253        public void dump(Printer pw, String prefix) {
254            pw.println(prefix + "exceptionClassName: " + exceptionClassName);
255            pw.println(prefix + "exceptionMessage: " + exceptionMessage);
256            pw.println(prefix + "throwFileName: " + throwFileName);
257            pw.println(prefix + "throwClassName: " + throwClassName);
258            pw.println(prefix + "throwMethodName: " + throwMethodName);
259            pw.println(prefix + "throwLineNumber: " + throwLineNumber);
260            pw.println(prefix + "stackTrace: " + stackTrace);
261        }
262    }
263
264    /**
265     * Describes an application not responding error.
266     */
267    public static class AnrInfo {
268        /**
269         * Activity name.
270         */
271        public String activity;
272
273        /**
274         * Description of the operation that timed out.
275         */
276        public String cause;
277
278        /**
279         * Additional info, including CPU stats.
280         */
281        public String info;
282
283        /**
284         * Create an uninitialized instance of AnrInfo.
285         */
286        public AnrInfo() {
287        }
288
289        /**
290         * Create an instance of AnrInfo initialized from a Parcel.
291         */
292        public AnrInfo(Parcel in) {
293            activity = in.readString();
294            cause = in.readString();
295            info = in.readString();
296        }
297
298        /**
299         * Save an AnrInfo instance to a parcel.
300         */
301        public void writeToParcel(Parcel dest, int flags) {
302            dest.writeString(activity);
303            dest.writeString(cause);
304            dest.writeString(info);
305        }
306
307        /**
308         * Dump an AnrInfo instance to a Printer.
309         */
310        public void dump(Printer pw, String prefix) {
311            pw.println(prefix + "activity: " + activity);
312            pw.println(prefix + "cause: " + cause);
313            pw.println(prefix + "info: " + info);
314        }
315    }
316
317    public static final Parcelable.Creator<ApplicationErrorReport> CREATOR
318            = new Parcelable.Creator<ApplicationErrorReport>() {
319        public ApplicationErrorReport createFromParcel(Parcel source) {
320            return new ApplicationErrorReport(source);
321        }
322
323        public ApplicationErrorReport[] newArray(int size) {
324            return new ApplicationErrorReport[size];
325        }
326    };
327
328    public int describeContents() {
329        return 0;
330    }
331
332    /**
333     * Dump the report to a Printer.
334     */
335    public void dump(Printer pw, String prefix) {
336        pw.println(prefix + "type: " + type);
337        pw.println(prefix + "packageName: " + packageName);
338        pw.println(prefix + "installerPackageName: " + installerPackageName);
339        pw.println(prefix + "processName: " + processName);
340        pw.println(prefix + "time: " + time);
341        pw.println(prefix + "systemApp: " + systemApp);
342
343        switch (type) {
344            case TYPE_CRASH:
345                crashInfo.dump(pw, prefix);
346                break;
347            case TYPE_ANR:
348                anrInfo.dump(pw, prefix);
349                break;
350        }
351    }
352}
353