blob: 8692336439f91dda4f000393e6e56ed123c36307 [file] [log] [blame]
Jacek Surazskif5b9c722009-05-18 12:09:59 +02001/*
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
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080019import android.content.ComponentName;
20import android.content.Context;
21import android.content.Intent;
22import android.content.pm.ApplicationInfo;
23import android.content.pm.PackageManager;
24import android.content.pm.ResolveInfo;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020025import android.os.Parcel;
26import android.os.Parcelable;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080027import android.os.SystemProperties;
28import android.provider.Settings;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020029import android.util.Printer;
Dianne Hackborn73d6a822014-09-29 10:52:47 -070030import android.util.Slog;
Dianne Hackborn8c841092013-06-24 13:46:13 -070031import com.android.internal.util.FastPrintWriter;
Brad Fitzpatrick5b747192010-07-12 11:05:38 -070032
Dan Egnorb7f03672009-12-09 16:22:32 -080033import java.io.PrintWriter;
34import java.io.StringWriter;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020035
36/**
37 * Describes an application error.
38 *
39 * A report has a type, which is one of
40 * <ul>
Dianne Hackborn271c2fe2011-08-09 19:35:13 -070041 * <li> {@link #TYPE_NONE} uninitialized instance of {@link ApplicationErrorReport}.
Jacek Surazskif5b9c722009-05-18 12:09:59 +020042 * <li> {@link #TYPE_CRASH} application crash. Information about the crash
43 * is stored in {@link #crashInfo}.
44 * <li> {@link #TYPE_ANR} application not responding. Information about the
45 * ANR is stored in {@link #anrInfo}.
Dianne Hackborn271c2fe2011-08-09 19:35:13 -070046 * <li> {@link #TYPE_BATTERY} user reported application is using too much
47 * battery. Information about the battery use is stored in {@link #batteryInfo}.
48 * <li> {@link #TYPE_RUNNING_SERVICE} user reported application is leaving an
49 * unneeded serive running. Information about the battery use is stored in
50 * {@link #runningServiceInfo}.
Jacek Surazskif5b9c722009-05-18 12:09:59 +020051 * </ul>
Jacek Surazskif5b9c722009-05-18 12:09:59 +020052 */
53
54public class ApplicationErrorReport implements Parcelable {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055 // System property defining error report receiver for system apps
56 static final String SYSTEM_APPS_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.system.apps";
57
58 // System property defining default error report receiver
59 static final String DEFAULT_ERROR_RECEIVER_PROPERTY = "ro.error.receiver.default";
60
Jacek Surazskif5b9c722009-05-18 12:09:59 +020061 /**
62 * Uninitialized error report.
63 */
64 public static final int TYPE_NONE = 0;
65
66 /**
67 * An error report about an application crash.
68 */
69 public static final int TYPE_CRASH = 1;
70
71 /**
72 * An error report about an application that's not responding.
73 */
74 public static final int TYPE_ANR = 2;
75
76 /**
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080077 * An error report about an application that's consuming too much battery.
78 */
79 public static final int TYPE_BATTERY = 3;
80
81 /**
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -070082 * A report from a user to a developer about a running service that the
83 * user doesn't think should be running.
Dianne Hackborn14bfa392010-07-24 19:58:06 -070084 */
85 public static final int TYPE_RUNNING_SERVICE = 5;
86
87 /**
Jacek Surazskif5b9c722009-05-18 12:09:59 +020088 * Type of this report. Can be one of {@link #TYPE_NONE},
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -070089 * {@link #TYPE_CRASH}, {@link #TYPE_ANR}, {@link #TYPE_BATTERY},
90 * or {@link #TYPE_RUNNING_SERVICE}.
Jacek Surazskif5b9c722009-05-18 12:09:59 +020091 */
92 public int type;
93
94 /**
95 * Package name of the application.
96 */
97 public String packageName;
98
99 /**
100 * Package name of the application which installed the application this
101 * report pertains to.
Dirk Dougherty4d7bc6552012-01-27 17:56:49 -0800102 * This identifies which market the application came from.
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200103 */
104 public String installerPackageName;
105
106 /**
107 * Process name of the application.
108 */
109 public String processName;
110
111 /**
112 * Time at which the error occurred.
113 */
114 public long time;
115
116 /**
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +0100117 * Set if the app is on the system image.
118 */
119 public boolean systemApp;
120
121 /**
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200122 * If this report is of type {@link #TYPE_CRASH}, contains an instance
123 * of CrashInfo describing the crash; otherwise null.
124 */
125 public CrashInfo crashInfo;
126
127 /**
128 * If this report is of type {@link #TYPE_ANR}, contains an instance
129 * of AnrInfo describing the ANR; otherwise null.
130 */
131 public AnrInfo anrInfo;
132
133 /**
Jacek Surazski151de3d2010-02-26 22:52:44 +0100134 * If this report is of type {@link #TYPE_BATTERY}, contains an instance
135 * of BatteryInfo; otherwise null.
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800136 */
Jacek Surazski151de3d2010-02-26 22:52:44 +0100137 public BatteryInfo batteryInfo;
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -0700138
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800139 /**
Dianne Hackborn14bfa392010-07-24 19:58:06 -0700140 * If this report is of type {@link #TYPE_RUNNING_SERVICE}, contains an instance
141 * of RunningServiceInfo; otherwise null.
142 */
143 public RunningServiceInfo runningServiceInfo;
144
145 /**
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200146 * Create an uninitialized instance of {@link ApplicationErrorReport}.
147 */
148 public ApplicationErrorReport() {
149 }
150
151 /**
152 * Create an instance of {@link ApplicationErrorReport} initialized from
153 * a parcel.
154 */
155 ApplicationErrorReport(Parcel in) {
Jacek Surazski28b0e5d2009-05-25 17:56:41 +0200156 readFromParcel(in);
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200157 }
158
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800159 public static ComponentName getErrorReportReceiver(Context context,
160 String packageName, int appFlags) {
161 // check if error reporting is enabled in secure settings
Jeff Sharkey625239a2012-09-26 22:03:49 -0700162 int enabled = Settings.Global.getInt(context.getContentResolver(),
163 Settings.Global.SEND_ACTION_APP_ERROR, 0);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800164 if (enabled == 0) {
165 return null;
166 }
167
168 PackageManager pm = context.getPackageManager();
169
170 // look for receiver in the installer package
louis_changbd4a9a02014-07-31 10:47:45 +0800171 String candidate = null;
172 ComponentName result = null;
173
174 try {
175 candidate = pm.getInstallerPackageName(packageName);
176 } catch (IllegalArgumentException e) {
177 // the package could already removed
178 }
179
180 if (candidate != null) {
181 result = getErrorReportReceiver(pm, packageName, candidate);
182 if (result != null) {
183 return result;
184 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800185 }
186
187 // if the error app is on the system image, look for system apps
188 // error receiver
189 if ((appFlags&ApplicationInfo.FLAG_SYSTEM) != 0) {
190 candidate = SystemProperties.get(SYSTEM_APPS_ERROR_RECEIVER_PROPERTY);
191 result = getErrorReportReceiver(pm, packageName, candidate);
192 if (result != null) {
193 return result;
194 }
195 }
196
197 // if there is a default receiver, try that
198 candidate = SystemProperties.get(DEFAULT_ERROR_RECEIVER_PROPERTY);
199 return getErrorReportReceiver(pm, packageName, candidate);
200 }
Jacek Surazski87d0b2f2010-08-02 13:03:35 +0200201
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800202 /**
203 * Return activity in receiverPackage that handles ACTION_APP_ERROR.
204 *
Madan Ankapuraae96f632010-06-18 18:16:58 -0700205 * @param pm PackageManager instance
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800206 * @param errorPackage package which caused the error
207 * @param receiverPackage candidate package to receive the error
208 * @return activity component within receiverPackage which handles
209 * ACTION_APP_ERROR, or null if not found
210 */
211 static ComponentName getErrorReportReceiver(PackageManager pm, String errorPackage,
212 String receiverPackage) {
213 if (receiverPackage == null || receiverPackage.length() == 0) {
214 return null;
215 }
216
217 // break the loop if it's the error report receiver package that crashed
218 if (receiverPackage.equals(errorPackage)) {
219 return null;
220 }
221
222 Intent intent = new Intent(Intent.ACTION_APP_ERROR);
223 intent.setPackage(receiverPackage);
224 ResolveInfo info = pm.resolveActivity(intent, 0);
225 if (info == null || info.activityInfo == null) {
226 return null;
227 }
228 return new ComponentName(receiverPackage, info.activityInfo.name);
229 }
230
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200231 public void writeToParcel(Parcel dest, int flags) {
232 dest.writeInt(type);
233 dest.writeString(packageName);
234 dest.writeString(installerPackageName);
235 dest.writeString(processName);
236 dest.writeLong(time);
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +0100237 dest.writeInt(systemApp ? 1 : 0);
louis_chang3d86b882015-04-08 18:04:11 +0800238 dest.writeInt(crashInfo != null ? 1 : 0);
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200239
240 switch (type) {
241 case TYPE_CRASH:
louis_chang3d86b882015-04-08 18:04:11 +0800242 if (crashInfo != null) {
243 crashInfo.writeToParcel(dest, flags);
244 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200245 break;
246 case TYPE_ANR:
247 anrInfo.writeToParcel(dest, flags);
248 break;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800249 case TYPE_BATTERY:
Jacek Surazski151de3d2010-02-26 22:52:44 +0100250 batteryInfo.writeToParcel(dest, flags);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800251 break;
Dianne Hackborn14bfa392010-07-24 19:58:06 -0700252 case TYPE_RUNNING_SERVICE:
253 runningServiceInfo.writeToParcel(dest, flags);
254 break;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200255 }
256 }
257
Jacek Surazskifd0bdcc2009-05-27 14:45:48 +0200258 public void readFromParcel(Parcel in) {
Jacek Surazski28b0e5d2009-05-25 17:56:41 +0200259 type = in.readInt();
260 packageName = in.readString();
261 installerPackageName = in.readString();
262 processName = in.readString();
263 time = in.readLong();
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +0100264 systemApp = in.readInt() == 1;
louis_chang3d86b882015-04-08 18:04:11 +0800265 boolean hasCrashInfo = in.readInt() == 1;
Jacek Surazski28b0e5d2009-05-25 17:56:41 +0200266
267 switch (type) {
268 case TYPE_CRASH:
louis_chang3d86b882015-04-08 18:04:11 +0800269 crashInfo = hasCrashInfo ? new CrashInfo(in) : null;
Jacek Surazski28b0e5d2009-05-25 17:56:41 +0200270 anrInfo = null;
Jacek Surazski151de3d2010-02-26 22:52:44 +0100271 batteryInfo = null;
Dianne Hackborn14bfa392010-07-24 19:58:06 -0700272 runningServiceInfo = null;
Jacek Surazski28b0e5d2009-05-25 17:56:41 +0200273 break;
274 case TYPE_ANR:
275 anrInfo = new AnrInfo(in);
276 crashInfo = null;
Jacek Surazski151de3d2010-02-26 22:52:44 +0100277 batteryInfo = null;
Dianne Hackborn14bfa392010-07-24 19:58:06 -0700278 runningServiceInfo = null;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800279 break;
280 case TYPE_BATTERY:
Jacek Surazski151de3d2010-02-26 22:52:44 +0100281 batteryInfo = new BatteryInfo(in);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800282 anrInfo = null;
283 crashInfo = null;
Dianne Hackborn14bfa392010-07-24 19:58:06 -0700284 runningServiceInfo = null;
285 break;
286 case TYPE_RUNNING_SERVICE:
287 batteryInfo = null;
288 anrInfo = null;
289 crashInfo = null;
290 runningServiceInfo = new RunningServiceInfo(in);
Jacek Surazski28b0e5d2009-05-25 17:56:41 +0200291 break;
292 }
293 }
294
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200295 /**
296 * Describes an application crash.
297 */
298 public static class CrashInfo {
299 /**
300 * Class name of the exception that caused the crash.
301 */
302 public String exceptionClassName;
303
304 /**
Jacek Surazskif829a782009-06-11 22:47:02 +0200305 * Message stored in the exception.
306 */
307 public String exceptionMessage;
308
309 /**
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200310 * File which the exception was thrown from.
311 */
312 public String throwFileName;
313
314 /**
315 * Class which the exception was thrown from.
316 */
317 public String throwClassName;
318
319 /**
320 * Method which the exception was thrown from.
321 */
322 public String throwMethodName;
323
324 /**
Jacek Surazski5a123732009-06-23 14:57:08 +0200325 * Line number the exception was thrown from.
326 */
327 public int throwLineNumber;
328
329 /**
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200330 * Stack trace.
331 */
332 public String stackTrace;
333
334 /**
335 * Create an uninitialized instance of CrashInfo.
336 */
337 public CrashInfo() {
338 }
339
340 /**
Dan Egnorb7f03672009-12-09 16:22:32 -0800341 * Create an instance of CrashInfo initialized from an exception.
342 */
343 public CrashInfo(Throwable tr) {
344 StringWriter sw = new StringWriter();
Dianne Hackborn8c841092013-06-24 13:46:13 -0700345 PrintWriter pw = new FastPrintWriter(sw, false, 256);
346 tr.printStackTrace(pw);
347 pw.flush();
Dan Egnorb7f03672009-12-09 16:22:32 -0800348 stackTrace = sw.toString();
Dan Egnor60d87622009-12-16 16:32:58 -0800349 exceptionMessage = tr.getMessage();
Dan Egnorb7f03672009-12-09 16:22:32 -0800350
351 // Populate fields with the "root cause" exception
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -0700352 Throwable rootTr = tr;
Dan Egnorb7f03672009-12-09 16:22:32 -0800353 while (tr.getCause() != null) {
354 tr = tr.getCause();
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -0700355 if (tr.getStackTrace() != null && tr.getStackTrace().length > 0) {
356 rootTr = tr;
357 }
Dan Egnorb7f03672009-12-09 16:22:32 -0800358 String msg = tr.getMessage();
359 if (msg != null && msg.length() > 0) {
360 exceptionMessage = msg;
361 }
362 }
363
Dianne Hackborn8e8d65f2011-08-11 19:36:18 -0700364 exceptionClassName = rootTr.getClass().getName();
365 if (rootTr.getStackTrace().length > 0) {
366 StackTraceElement trace = rootTr.getStackTrace()[0];
367 throwFileName = trace.getFileName();
368 throwClassName = trace.getClassName();
369 throwMethodName = trace.getMethodName();
370 throwLineNumber = trace.getLineNumber();
371 } else {
372 throwFileName = "unknown";
373 throwClassName = "unknown";
374 throwMethodName = "unknown";
375 throwLineNumber = 0;
376 }
Dan Egnorb7f03672009-12-09 16:22:32 -0800377 }
378
379 /**
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200380 * Create an instance of CrashInfo initialized from a Parcel.
381 */
382 public CrashInfo(Parcel in) {
383 exceptionClassName = in.readString();
Jacek Surazskif829a782009-06-11 22:47:02 +0200384 exceptionMessage = in.readString();
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200385 throwFileName = in.readString();
386 throwClassName = in.readString();
387 throwMethodName = in.readString();
Jacek Surazski5a123732009-06-23 14:57:08 +0200388 throwLineNumber = in.readInt();
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200389 stackTrace = in.readString();
390 }
391
392 /**
393 * Save a CrashInfo instance to a parcel.
394 */
395 public void writeToParcel(Parcel dest, int flags) {
Dianne Hackborn73d6a822014-09-29 10:52:47 -0700396 int start = dest.dataPosition();
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200397 dest.writeString(exceptionClassName);
Jacek Surazskif829a782009-06-11 22:47:02 +0200398 dest.writeString(exceptionMessage);
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200399 dest.writeString(throwFileName);
400 dest.writeString(throwClassName);
401 dest.writeString(throwMethodName);
Jacek Surazski5a123732009-06-23 14:57:08 +0200402 dest.writeInt(throwLineNumber);
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200403 dest.writeString(stackTrace);
Dianne Hackborn73d6a822014-09-29 10:52:47 -0700404 int total = dest.dataPosition()-start;
Dianne Hackbornf85e7af2014-10-14 10:43:43 -0700405 if (total > 20*1024) {
Dianne Hackborn73d6a822014-09-29 10:52:47 -0700406 Slog.d("Error", "ERR: exClass=" + exceptionClassName);
407 Slog.d("Error", "ERR: exMsg=" + exceptionMessage);
408 Slog.d("Error", "ERR: file=" + throwFileName);
409 Slog.d("Error", "ERR: class=" + throwClassName);
410 Slog.d("Error", "ERR: method=" + throwMethodName + " line=" + throwLineNumber);
411 Slog.d("Error", "ERR: stack=" + stackTrace);
412 Slog.d("Error", "ERR: TOTAL BYTES WRITTEN: " + (dest.dataPosition()-start));
413 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200414 }
415
416 /**
417 * Dump a CrashInfo instance to a Printer.
418 */
419 public void dump(Printer pw, String prefix) {
420 pw.println(prefix + "exceptionClassName: " + exceptionClassName);
Jacek Surazskif829a782009-06-11 22:47:02 +0200421 pw.println(prefix + "exceptionMessage: " + exceptionMessage);
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200422 pw.println(prefix + "throwFileName: " + throwFileName);
423 pw.println(prefix + "throwClassName: " + throwClassName);
424 pw.println(prefix + "throwMethodName: " + throwMethodName);
Jacek Surazski5a123732009-06-23 14:57:08 +0200425 pw.println(prefix + "throwLineNumber: " + throwLineNumber);
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200426 pw.println(prefix + "stackTrace: " + stackTrace);
427 }
428 }
429
430 /**
431 * Describes an application not responding error.
432 */
433 public static class AnrInfo {
434 /**
435 * Activity name.
436 */
437 public String activity;
438
439 /**
440 * Description of the operation that timed out.
441 */
442 public String cause;
443
444 /**
445 * Additional info, including CPU stats.
446 */
447 public String info;
448
449 /**
450 * Create an uninitialized instance of AnrInfo.
451 */
452 public AnrInfo() {
453 }
454
455 /**
456 * Create an instance of AnrInfo initialized from a Parcel.
457 */
458 public AnrInfo(Parcel in) {
459 activity = in.readString();
460 cause = in.readString();
461 info = in.readString();
462 }
463
464 /**
465 * Save an AnrInfo instance to a parcel.
466 */
467 public void writeToParcel(Parcel dest, int flags) {
468 dest.writeString(activity);
469 dest.writeString(cause);
470 dest.writeString(info);
471 }
472
473 /**
474 * Dump an AnrInfo instance to a Printer.
475 */
476 public void dump(Printer pw, String prefix) {
477 pw.println(prefix + "activity: " + activity);
478 pw.println(prefix + "cause: " + cause);
479 pw.println(prefix + "info: " + info);
480 }
481 }
482
Jacek Surazski151de3d2010-02-26 22:52:44 +0100483 /**
484 * Describes a battery usage report.
485 */
486 public static class BatteryInfo {
487 /**
488 * Percentage of the battery that was used up by the process.
489 */
490 public int usagePercent;
491
492 /**
493 * Duration in microseconds over which the process used the above
494 * percentage of battery.
495 */
496 public long durationMicros;
497
498 /**
499 * Dump of various info impacting battery use.
500 */
501 public String usageDetails;
502
503 /**
504 * Checkin details.
505 */
506 public String checkinDetails;
507
508 /**
509 * Create an uninitialized instance of BatteryInfo.
510 */
511 public BatteryInfo() {
512 }
513
514 /**
515 * Create an instance of BatteryInfo initialized from a Parcel.
516 */
517 public BatteryInfo(Parcel in) {
518 usagePercent = in.readInt();
519 durationMicros = in.readLong();
520 usageDetails = in.readString();
521 checkinDetails = in.readString();
522 }
523
524 /**
525 * Save a BatteryInfo instance to a parcel.
526 */
527 public void writeToParcel(Parcel dest, int flags) {
528 dest.writeInt(usagePercent);
529 dest.writeLong(durationMicros);
530 dest.writeString(usageDetails);
531 dest.writeString(checkinDetails);
532 }
533
534 /**
535 * Dump a BatteryInfo instance to a Printer.
536 */
537 public void dump(Printer pw, String prefix) {
538 pw.println(prefix + "usagePercent: " + usagePercent);
539 pw.println(prefix + "durationMicros: " + durationMicros);
540 pw.println(prefix + "usageDetails: " + usageDetails);
541 pw.println(prefix + "checkinDetails: " + checkinDetails);
542 }
543 }
544
Dianne Hackborn14bfa392010-07-24 19:58:06 -0700545 /**
546 * Describes a running service report.
547 */
548 public static class RunningServiceInfo {
549 /**
550 * Duration in milliseconds that the service has been running.
551 */
552 public long durationMillis;
553
554 /**
555 * Dump of debug information about the service.
556 */
557 public String serviceDetails;
558
559 /**
560 * Create an uninitialized instance of RunningServiceInfo.
561 */
562 public RunningServiceInfo() {
563 }
564
565 /**
566 * Create an instance of RunningServiceInfo initialized from a Parcel.
567 */
568 public RunningServiceInfo(Parcel in) {
569 durationMillis = in.readLong();
570 serviceDetails = in.readString();
571 }
572
573 /**
574 * Save a RunningServiceInfo instance to a parcel.
575 */
576 public void writeToParcel(Parcel dest, int flags) {
577 dest.writeLong(durationMillis);
578 dest.writeString(serviceDetails);
579 }
580
581 /**
582 * Dump a BatteryInfo instance to a Printer.
583 */
584 public void dump(Printer pw, String prefix) {
585 pw.println(prefix + "durationMillis: " + durationMillis);
586 pw.println(prefix + "serviceDetails: " + serviceDetails);
587 }
588 }
589
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200590 public static final Parcelable.Creator<ApplicationErrorReport> CREATOR
591 = new Parcelable.Creator<ApplicationErrorReport>() {
592 public ApplicationErrorReport createFromParcel(Parcel source) {
593 return new ApplicationErrorReport(source);
594 }
595
596 public ApplicationErrorReport[] newArray(int size) {
597 return new ApplicationErrorReport[size];
598 }
599 };
600
601 public int describeContents() {
602 return 0;
603 }
604
605 /**
606 * Dump the report to a Printer.
607 */
608 public void dump(Printer pw, String prefix) {
609 pw.println(prefix + "type: " + type);
610 pw.println(prefix + "packageName: " + packageName);
611 pw.println(prefix + "installerPackageName: " + installerPackageName);
612 pw.println(prefix + "processName: " + processName);
613 pw.println(prefix + "time: " + time);
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +0100614 pw.println(prefix + "systemApp: " + systemApp);
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200615
616 switch (type) {
617 case TYPE_CRASH:
618 crashInfo.dump(pw, prefix);
619 break;
620 case TYPE_ANR:
621 anrInfo.dump(pw, prefix);
622 break;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800623 case TYPE_BATTERY:
Jacek Surazski151de3d2010-02-26 22:52:44 +0100624 batteryInfo.dump(pw, prefix);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800625 break;
Jacek Surazski87d0b2f2010-08-02 13:03:35 +0200626 case TYPE_RUNNING_SERVICE:
627 runningServiceInfo.dump(pw, prefix);
628 break;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200629 }
630 }
631}