blob: 9fa8a5d2faee06e9c597a4626afab450954c0ea4 [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();
Adrian Roos732ae952016-07-01 13:11:18 -0700348 stackTrace = sanitizeString(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 }
Adrian Roos732ae952016-07-01 13:11:18 -0700377
378 exceptionMessage = sanitizeString(exceptionMessage);
379 }
380
381 /**
382 * Ensure that the string is of reasonable size, truncating from the middle if needed.
383 */
384 private String sanitizeString(String s) {
385 int prefixLength = 10 * 1024;
386 int suffixLength = 10 * 1024;
387 int acceptableLength = prefixLength + suffixLength;
388
389 if (s != null && s.length() > acceptableLength) {
390 String replacement =
391 "\n[TRUNCATED " + (s.length() - acceptableLength) + " CHARS]\n";
392
393 StringBuilder sb = new StringBuilder(acceptableLength + replacement.length());
394 sb.append(s.substring(0, prefixLength));
395 sb.append(replacement);
396 sb.append(s.substring(s.length() - suffixLength));
397 return sb.toString();
398 }
399 return s;
Dan Egnorb7f03672009-12-09 16:22:32 -0800400 }
401
402 /**
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200403 * Create an instance of CrashInfo initialized from a Parcel.
404 */
405 public CrashInfo(Parcel in) {
406 exceptionClassName = in.readString();
Jacek Surazskif829a782009-06-11 22:47:02 +0200407 exceptionMessage = in.readString();
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200408 throwFileName = in.readString();
409 throwClassName = in.readString();
410 throwMethodName = in.readString();
Jacek Surazski5a123732009-06-23 14:57:08 +0200411 throwLineNumber = in.readInt();
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200412 stackTrace = in.readString();
413 }
414
415 /**
416 * Save a CrashInfo instance to a parcel.
417 */
418 public void writeToParcel(Parcel dest, int flags) {
Dianne Hackborn73d6a822014-09-29 10:52:47 -0700419 int start = dest.dataPosition();
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200420 dest.writeString(exceptionClassName);
Jacek Surazskif829a782009-06-11 22:47:02 +0200421 dest.writeString(exceptionMessage);
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200422 dest.writeString(throwFileName);
423 dest.writeString(throwClassName);
424 dest.writeString(throwMethodName);
Jacek Surazski5a123732009-06-23 14:57:08 +0200425 dest.writeInt(throwLineNumber);
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200426 dest.writeString(stackTrace);
Dianne Hackborn73d6a822014-09-29 10:52:47 -0700427 int total = dest.dataPosition()-start;
Dianne Hackbornf85e7af2014-10-14 10:43:43 -0700428 if (total > 20*1024) {
Dianne Hackborn73d6a822014-09-29 10:52:47 -0700429 Slog.d("Error", "ERR: exClass=" + exceptionClassName);
430 Slog.d("Error", "ERR: exMsg=" + exceptionMessage);
431 Slog.d("Error", "ERR: file=" + throwFileName);
432 Slog.d("Error", "ERR: class=" + throwClassName);
433 Slog.d("Error", "ERR: method=" + throwMethodName + " line=" + throwLineNumber);
434 Slog.d("Error", "ERR: stack=" + stackTrace);
435 Slog.d("Error", "ERR: TOTAL BYTES WRITTEN: " + (dest.dataPosition()-start));
436 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200437 }
438
439 /**
440 * Dump a CrashInfo instance to a Printer.
441 */
442 public void dump(Printer pw, String prefix) {
443 pw.println(prefix + "exceptionClassName: " + exceptionClassName);
Jacek Surazskif829a782009-06-11 22:47:02 +0200444 pw.println(prefix + "exceptionMessage: " + exceptionMessage);
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200445 pw.println(prefix + "throwFileName: " + throwFileName);
446 pw.println(prefix + "throwClassName: " + throwClassName);
447 pw.println(prefix + "throwMethodName: " + throwMethodName);
Jacek Surazski5a123732009-06-23 14:57:08 +0200448 pw.println(prefix + "throwLineNumber: " + throwLineNumber);
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200449 pw.println(prefix + "stackTrace: " + stackTrace);
450 }
451 }
452
453 /**
454 * Describes an application not responding error.
455 */
456 public static class AnrInfo {
457 /**
458 * Activity name.
459 */
460 public String activity;
461
462 /**
463 * Description of the operation that timed out.
464 */
465 public String cause;
466
467 /**
468 * Additional info, including CPU stats.
469 */
470 public String info;
471
472 /**
473 * Create an uninitialized instance of AnrInfo.
474 */
475 public AnrInfo() {
476 }
477
478 /**
479 * Create an instance of AnrInfo initialized from a Parcel.
480 */
481 public AnrInfo(Parcel in) {
482 activity = in.readString();
483 cause = in.readString();
484 info = in.readString();
485 }
486
487 /**
488 * Save an AnrInfo instance to a parcel.
489 */
490 public void writeToParcel(Parcel dest, int flags) {
491 dest.writeString(activity);
492 dest.writeString(cause);
493 dest.writeString(info);
494 }
495
496 /**
497 * Dump an AnrInfo instance to a Printer.
498 */
499 public void dump(Printer pw, String prefix) {
500 pw.println(prefix + "activity: " + activity);
501 pw.println(prefix + "cause: " + cause);
502 pw.println(prefix + "info: " + info);
503 }
504 }
505
Jacek Surazski151de3d2010-02-26 22:52:44 +0100506 /**
507 * Describes a battery usage report.
508 */
509 public static class BatteryInfo {
510 /**
511 * Percentage of the battery that was used up by the process.
512 */
513 public int usagePercent;
514
515 /**
516 * Duration in microseconds over which the process used the above
517 * percentage of battery.
518 */
519 public long durationMicros;
520
521 /**
522 * Dump of various info impacting battery use.
523 */
524 public String usageDetails;
525
526 /**
527 * Checkin details.
528 */
529 public String checkinDetails;
530
531 /**
532 * Create an uninitialized instance of BatteryInfo.
533 */
534 public BatteryInfo() {
535 }
536
537 /**
538 * Create an instance of BatteryInfo initialized from a Parcel.
539 */
540 public BatteryInfo(Parcel in) {
541 usagePercent = in.readInt();
542 durationMicros = in.readLong();
543 usageDetails = in.readString();
544 checkinDetails = in.readString();
545 }
546
547 /**
548 * Save a BatteryInfo instance to a parcel.
549 */
550 public void writeToParcel(Parcel dest, int flags) {
551 dest.writeInt(usagePercent);
552 dest.writeLong(durationMicros);
553 dest.writeString(usageDetails);
554 dest.writeString(checkinDetails);
555 }
556
557 /**
558 * Dump a BatteryInfo instance to a Printer.
559 */
560 public void dump(Printer pw, String prefix) {
561 pw.println(prefix + "usagePercent: " + usagePercent);
562 pw.println(prefix + "durationMicros: " + durationMicros);
563 pw.println(prefix + "usageDetails: " + usageDetails);
564 pw.println(prefix + "checkinDetails: " + checkinDetails);
565 }
566 }
567
Dianne Hackborn14bfa392010-07-24 19:58:06 -0700568 /**
569 * Describes a running service report.
570 */
571 public static class RunningServiceInfo {
572 /**
573 * Duration in milliseconds that the service has been running.
574 */
575 public long durationMillis;
576
577 /**
578 * Dump of debug information about the service.
579 */
580 public String serviceDetails;
581
582 /**
583 * Create an uninitialized instance of RunningServiceInfo.
584 */
585 public RunningServiceInfo() {
586 }
587
588 /**
589 * Create an instance of RunningServiceInfo initialized from a Parcel.
590 */
591 public RunningServiceInfo(Parcel in) {
592 durationMillis = in.readLong();
593 serviceDetails = in.readString();
594 }
595
596 /**
597 * Save a RunningServiceInfo instance to a parcel.
598 */
599 public void writeToParcel(Parcel dest, int flags) {
600 dest.writeLong(durationMillis);
601 dest.writeString(serviceDetails);
602 }
603
604 /**
605 * Dump a BatteryInfo instance to a Printer.
606 */
607 public void dump(Printer pw, String prefix) {
608 pw.println(prefix + "durationMillis: " + durationMillis);
609 pw.println(prefix + "serviceDetails: " + serviceDetails);
610 }
611 }
612
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200613 public static final Parcelable.Creator<ApplicationErrorReport> CREATOR
614 = new Parcelable.Creator<ApplicationErrorReport>() {
615 public ApplicationErrorReport createFromParcel(Parcel source) {
616 return new ApplicationErrorReport(source);
617 }
618
619 public ApplicationErrorReport[] newArray(int size) {
620 return new ApplicationErrorReport[size];
621 }
622 };
623
624 public int describeContents() {
625 return 0;
626 }
627
628 /**
629 * Dump the report to a Printer.
630 */
631 public void dump(Printer pw, String prefix) {
632 pw.println(prefix + "type: " + type);
633 pw.println(prefix + "packageName: " + packageName);
634 pw.println(prefix + "installerPackageName: " + installerPackageName);
635 pw.println(prefix + "processName: " + processName);
636 pw.println(prefix + "time: " + time);
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +0100637 pw.println(prefix + "systemApp: " + systemApp);
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200638
639 switch (type) {
640 case TYPE_CRASH:
641 crashInfo.dump(pw, prefix);
642 break;
643 case TYPE_ANR:
644 anrInfo.dump(pw, prefix);
645 break;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800646 case TYPE_BATTERY:
Jacek Surazski151de3d2010-02-26 22:52:44 +0100647 batteryInfo.dump(pw, prefix);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -0800648 break;
Jacek Surazski87d0b2f2010-08-02 13:03:35 +0200649 case TYPE_RUNNING_SERVICE:
650 runningServiceInfo.dump(pw, prefix);
651 break;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200652 }
653 }
654}