Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 14bfa398 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Infrastructure to report running services to developer.

Change-Id: Id1aae61323e7b8357c5fcc4bc641aaa57f3b6fde
parent 3ac8eb72
Loading
Loading
Loading
Loading
+68 −0
Original line number Diff line number Diff line
@@ -78,6 +78,11 @@ public class ApplicationErrorReport implements Parcelable {
     */
    public static final int TYPE_STRICT_MODE_VIOLATION = 4;

    /**
     * An error report about a StrictMode violation.
     */
    public static final int TYPE_RUNNING_SERVICE = 5;

    /**
     * Type of this report. Can be one of {@link #TYPE_NONE},
     * {@link #TYPE_CRASH}, {@link #TYPE_ANR}, or {@link #TYPE_BATTERY}.
@@ -129,6 +134,12 @@ public class ApplicationErrorReport implements Parcelable {
     */
    public BatteryInfo batteryInfo;
    
    /**
     * If this report is of type {@link #TYPE_RUNNING_SERVICE}, contains an instance
     * of RunningServiceInfo; otherwise null.
     */
    public RunningServiceInfo runningServiceInfo;

    /**
     * Create an uninitialized instance of {@link ApplicationErrorReport}.
     */
@@ -223,6 +234,9 @@ public class ApplicationErrorReport implements Parcelable {
            case TYPE_BATTERY:
                batteryInfo.writeToParcel(dest, flags);
                break;
            case TYPE_RUNNING_SERVICE:
                runningServiceInfo.writeToParcel(dest, flags);
                break;
        }
    }

@@ -239,16 +253,25 @@ public class ApplicationErrorReport implements Parcelable {
                crashInfo = new CrashInfo(in);
                anrInfo = null;
                batteryInfo = null;
                runningServiceInfo = null;
                break;
            case TYPE_ANR:
                anrInfo = new AnrInfo(in);
                crashInfo = null;
                batteryInfo = null;
                runningServiceInfo = null;
                break;
            case TYPE_BATTERY:
                batteryInfo = new BatteryInfo(in);
                anrInfo = null;
                crashInfo = null;
                runningServiceInfo = null;
                break;
            case TYPE_RUNNING_SERVICE:
                batteryInfo = null;
                anrInfo = null;
                crashInfo = null;
                runningServiceInfo = new RunningServiceInfo(in);
                break;
        }
    }
@@ -494,6 +517,51 @@ public class ApplicationErrorReport implements Parcelable {
        }
    }

    /**
     * Describes a running service report.
     */
    public static class RunningServiceInfo {
        /**
         * Duration in milliseconds that the service has been running.
         */
        public long durationMillis;

        /**
         * Dump of debug information about the service.
         */
        public String serviceDetails;

        /**
         * Create an uninitialized instance of RunningServiceInfo.
         */
        public RunningServiceInfo() {
        }

        /**
         * Create an instance of RunningServiceInfo initialized from a Parcel.
         */
        public RunningServiceInfo(Parcel in) {
            durationMillis = in.readLong();
            serviceDetails = in.readString();
        }

        /**
         * Save a RunningServiceInfo instance to a parcel.
         */
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeLong(durationMillis);
            dest.writeString(serviceDetails);
        }

        /**
         * Dump a BatteryInfo instance to a Printer.
         */
        public void dump(Printer pw, String prefix) {
            pw.println(prefix + "durationMillis: " + durationMillis);
            pw.println(prefix + "serviceDetails: " + serviceDetails);
        }
    }

    public static final Parcelable.Creator<ApplicationErrorReport> CREATOR
            = new Parcelable.Creator<ApplicationErrorReport>() {
        public ApplicationErrorReport createFromParcel(Parcel source) {
+25 −8
Original line number Diff line number Diff line
@@ -6752,7 +6752,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                }
                return;
            } else if ("service".equals(cmd)) {
                dumpService(fd, pw, args, opti, true);
                dumpService(fd, pw, args, opti, dumpAll);
                return;
            } else if ("services".equals(cmd) || "s".equals(cmd)) {
                synchronized (this) {
@@ -7058,29 +7058,45 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            componentNameString = args[opti];
            opti++;
            ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
            synchronized (this) {
                r = componentName != null ? mServices.get(componentName) : null;
            }
            newArgs = new String[args.length - opti];
            if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
        }

        if (r != null) {
            dumpService(fd, pw, r, newArgs);
            dumpService(fd, pw, r, newArgs, dumpAll);
        } else {
            ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
            synchronized (this) {
                for (ServiceRecord r1 : mServices.values()) {
                    if (componentNameString == null
                            || r1.name.flattenToString().contains(componentNameString)) {
                    dumpService(fd, pw, r1, newArgs);
                        services.add(r1);
                    }
                }
            }
            for (int i=0; i<services.size(); i++) {
                dumpService(fd, pw, services.get(i), newArgs, dumpAll);
            }
        }
    }

    /**
     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
     * there is a thread associated with the service.
     */
    private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args) {
    private void dumpService(FileDescriptor fd, PrintWriter pw, ServiceRecord r, String[] args,
            boolean dumpAll) {
        pw.println("  Service " + r.name.flattenToString());
        if (dumpAll) {
            synchronized (this) {
                pw.print("  * "); pw.println(r);
                r.dump(pw, "    ");
            }
            pw.println("");
        }
        if (r.app != null && r.app.thread != null) {
            try {
                // flush anything that is already in the PrintWriter since the thread is going
@@ -7088,6 +7104,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                pw.flush();
                r.app.thread.dumpService(fd, r, args);
                pw.print("\n");
                pw.flush();
            } catch (RemoteException e) {
                pw.println("got a RemoteException while dumping the service");
            }