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

Commit c59411b1 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Rework activity manager debug dumps.

Change how we do debug dumps from the activity manager to make
everything go through the activity manager interface (no more
secondary interfaces), and use the command line arguments to
control what gets dumped.

The output from dumpsys without args still dumps everything.

When just dumping the activity service, we now dump a subset
of all of the am state that is interesting without being
overwhelming.

You can use "dumpsys activity -h" to get help with other things
that can be dumped.
parent ee0511d7
Loading
Loading
Loading
Loading
+14 −10
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ int main(int argc, char* const argv[])

    const size_t N = services.size();

    if (N > 1) {
        // first print a list of the current services
        aout << "Currently running services:" << endl;
    
@@ -60,13 +61,16 @@ int main(int argc, char* const argv[])
                aout << "  " << services[i] << endl;
            }
        }
    }

    for (size_t i=0; i<N; i++) {
        sp<IBinder> service = sm->checkService(services[i]);
        if (service != NULL) {
            if (N > 1) {
                aout << "------------------------------------------------------------"
                        "-------------------" << endl;
                aout << "DUMP OF SERVICE " << services[i] << ":" << endl;
            }
            int err = service->dump(STDOUT_FILENO, args);
            if (err != 0) {
                aerr << "Error dumping service info: (" << strerror(err)
+432 −369
Original line number Diff line number Diff line
@@ -1210,10 +1210,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(m));
            }
            ServiceManager.addService("activity.broadcasts", new BroadcastsBinder(m));
            ServiceManager.addService("activity.services", new ServicesBinder(m));
            ServiceManager.addService("activity.senders", new SendersBinder(m));
            ServiceManager.addService("activity.providers", new ProvidersBinder(m));
            ServiceManager.addService("permission", new PermissionController(m));
            ApplicationInfo info =
@@ -1321,54 +1317,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        }
    }
    static class BroadcastsBinder extends Binder {
        ActivityManagerService mActivityManagerService;
        BroadcastsBinder(ActivityManagerService activityManagerService) {
            mActivityManagerService = activityManagerService;
        }
        @Override
        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            mActivityManagerService.dumpBroadcasts(pw);
        }
    }
    static class ServicesBinder extends Binder {
        ActivityManagerService mActivityManagerService;
        ServicesBinder(ActivityManagerService activityManagerService) {
            mActivityManagerService = activityManagerService;
        }
        @Override
        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            mActivityManagerService.dumpServices(pw);
        }
    }
    static class SendersBinder extends Binder {
        ActivityManagerService mActivityManagerService;
        SendersBinder(ActivityManagerService activityManagerService) {
            mActivityManagerService = activityManagerService;
        }
        @Override
        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            mActivityManagerService.dumpSenders(pw);
        }
    }
    static class ProvidersBinder extends Binder {
        ActivityManagerService mActivityManagerService;
        ProvidersBinder(ActivityManagerService activityManagerService) {
            mActivityManagerService = activityManagerService;
        }
        @Override
        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            mActivityManagerService.dumpProviders(pw);
        }
    }
    static class MemBinder extends Binder {
        ActivityManagerService mActivityManagerService;
        MemBinder(ActivityManagerService activityManagerService) {
@@ -9151,7 +9099,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        synchronized (this) {
        if (checkCallingPermission(android.Manifest.permission.DUMP)
                != PackageManager.PERMISSION_GRANTED) {
            pw.println("Permission Denial: can't dump ActivityManager from from pid="
@@ -9161,11 +9108,130 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                    + android.Manifest.permission.DUMP);
            return;
        }
            if (args.length != 0 && "service".equals(args[0])) {
                dumpService(fd, pw, args);
        
        boolean dumpAll = false;
        
        int opti = 0;
        while (opti < args.length) {
            String opt = args[opti];
            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
                break;
            }
            opti++;
            if ("-a".equals(opt)) {
                dumpAll = true;
            } else if ("-h".equals(opt)) {
                pw.println("Activity manager dump options:");
                pw.println("  [-a] [h- [cmd] ...");
                pw.println("  cmd may be one of:");
                pw.println("    activities: activity stack state");
                pw.println("    broadcasts: broadcast state");
                pw.println("    intents: pending intent state");
                pw.println("    processes: process state");
                pw.println("    providers: content provider state");
                pw.println("    services: service state");
                pw.println("    service [name]: service client-side state");
                return;
            } else {
                pw.println("Unknown argument: " + opt + "; use -h for help");
            }
        }
        
        // Is the caller requesting to dump a particular piece of data?
        if (opti < args.length) {
            String cmd = args[opti];
            opti++;
            if ("activities".equals(cmd) || "a".equals(cmd)) {
                synchronized (this) {
                    dumpActivitiesLocked(fd, pw, args, opti, true, true);
                }
                return;
            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
                synchronized (this) {
                    dumpBroadcastsLocked(fd, pw, args, opti, true);
                }
                return;
            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
                synchronized (this) {
                    dumpPendingIntentsLocked(fd, pw, args, opti, true);
                }
                return;
            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
                synchronized (this) {
                    dumpProcessesLocked(fd, pw, args, opti, true);
                }
                return;
            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
                synchronized (this) {
                    dumpProvidersLocked(fd, pw, args, opti, true);
                }
                return;
            } else if ("service".equals(cmd)) {
                dumpService(fd, pw, args, opti, true);
                return;
            } else if ("services".equals(cmd) || "s".equals(cmd)) {
                synchronized (this) {
                    dumpServicesLocked(fd, pw, args, opti, true);
                }
                return;
            }
        }
        
        // No piece of data specified, dump everything.
        synchronized (this) {
            boolean needSep;
            if (dumpAll) {
                pw.println("Providers in Current Activity Manager State:");
            }
            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
            if (needSep) {
                pw.println(" ");
            }
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
                pw.println("Broadcasts in Current Activity Manager State:");
            }
            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
            if (needSep) {
                pw.println(" ");
            }
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
                pw.println("Services in Current Activity Manager State:");
            }
            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll);
            if (needSep) {
                pw.println(" ");
            }
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
                pw.println("PendingIntents in Current Activity Manager State:");
            }
            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
            if (needSep) {
                pw.println(" ");
            }
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
                pw.println("Activities in Current Activity Manager State:");
            }
            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, !dumpAll);
            if (needSep) {
                pw.println(" ");
            }
            if (dumpAll) {
                pw.println("-------------------------------------------------------------------------------");
                pw.println("Processes in Current Activity Manager State:");
            }
            dumpProcessesLocked(fd, pw, args, opti, dumpAll);
        }
    }
    
    boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
            int opti, boolean dumpAll, boolean needHeader) {
        if (needHeader) {
            pw.println("  Activity stack:");
        }
        dumpHistoryList(pw, mHistory, "  ", "Hist", true);
        pw.println(" ");
        pw.println("  Running activities (most recent first):");
@@ -9192,7 +9258,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        pw.println("  mFocusedActivity: " + mFocusedActivity);
        pw.println("  mLastPausedActivity: " + mLastPausedActivity);
            if (mRecentTasks.size() > 0) {
        if (dumpAll && mRecentTasks.size() > 0) {
            pw.println(" ");
            pw.println("Recent tasks in Current Activity Manager State:");
@@ -9208,12 +9274,15 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        pw.println(" ");
        pw.println("  mCurTask: " + mCurTask);
        
            pw.println(" ");
            pw.println("Processes in Current Activity Manager State:");
        return true;
    }
        
    boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
            int opti, boolean dumpAll) {
        boolean needSep = false;
        int numPers = 0;
        if (dumpAll) {
            for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
                final int NA = procs.size();
                for (int ia=0; ia<NA; ia++) {
@@ -9231,6 +9300,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                    }
                }
            }
        }
        
        if (mLruProcesses.size() > 0) {
            if (needSep) pw.println(" ");
@@ -9350,23 +9420,31 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        }
        pw.println(" ");
            pw.println("  Total persistent processes: " + numPers);
        pw.println("  mHomeProcess: " + mHomeProcess);
        pw.println("  mConfiguration: " + mConfiguration);
        pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
                || mOrigWaitForDebugger) {
            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
                    + " mDebugTransient=" + mDebugTransient
                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
        }
        if (mAlwaysFinishActivities || mController != null) {
            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
                    + " mController=" + mController);
        }
        if (dumpAll) {
            pw.println("  Total persistent processes: " + numPers);
            pw.println("  mStartRunning=" + mStartRunning
                    + " mSystemReady=" + mSystemReady
                    + " mBooting=" + mBooting
                    + " mBooted=" + mBooted
                    + " mFactoryTest=" + mFactoryTest);
            pw.println("  mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
            pw.println("  mGoingToSleep=" + mGoingToSleep);
            pw.println("  mLaunchingActivity=" + mLaunchingActivity);
            pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
                    + " mDebugTransient=" + mDebugTransient
                    + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
            pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
                    + " mController=" + mController);
        }
        
        return true;
    }
    /**
@@ -9377,20 +9455,22 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
     *  - the first arg isn't the flattened component name of an existing service:
     *    dump all services whose component contains the first arg as a substring
     */
    protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args) {
    protected void dumpService(FileDescriptor fd, PrintWriter pw, String[] args,
            int opti, boolean dumpAll) {
        String[] newArgs;
        String componentNameString;
        ServiceRecord r;
        if (args.length == 1) {
        if (opti <= args.length) {
            componentNameString = null;
            newArgs = EMPTY_STRING_ARRAY;
            r = null;
        } else {
            componentNameString = args[1];
            componentNameString = args[opti];
            opti++;
            ComponentName componentName = ComponentName.unflattenFromString(componentNameString);
            r = componentName != null ? mServices.get(componentName) : null;
            newArgs = new String[args.length - 2];
            if (args.length > 2) System.arraycopy(args, 2, newArgs, 0, args.length - 2);
            newArgs = new String[args.length - opti];
            if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
        }
        if (r != null) {
@@ -9424,19 +9504,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
        }
    }
    void dumpBroadcasts(PrintWriter pw) {
        synchronized (this) {
            if (checkCallingPermission(android.Manifest.permission.DUMP)
                    != PackageManager.PERMISSION_GRANTED) {
                pw.println("Permission Denial: can't dump ActivityManager from from pid="
                        + Binder.getCallingPid()
                        + ", uid=" + Binder.getCallingUid()
                        + " without permission "
                        + android.Manifest.permission.DUMP);
                return;
            }
            pw.println("Broadcasts in Current Activity Manager State:");
    boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
            int opti, boolean dumpAll) {
        boolean needSep = false;
        
        if (dumpAll) {
            if (mRegisteredReceivers.size() > 0) {
                pw.println(" ");
                pw.println("  Registered Receivers:");
@@ -9451,6 +9523,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            pw.println(" ");
            pw.println("Receiver Resolver Table:");
            mReceiverResolver.dump(pw, "  ");
            needSep = true;
        }
        
        if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
                || mPendingBroadcast != null) {
@@ -9477,8 +9551,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            } else {
                pw.println("    (null)");
            }
            needSep = true;
        }
        if (dumpAll) {
            pw.println(" ");
            pw.println("  Historical broadcasts:");
            for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
@@ -9489,9 +9565,9 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                pw.println("  Historical Broadcast #" + i + ":");
                r.dump(pw, "    ");
            }
            needSep = true;
        }
        
            pw.println(" ");
            pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
        if (mStickyBroadcasts != null) {
            pw.println(" ");
            pw.println("  Sticky broadcasts:");
@@ -9514,29 +9590,25 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                    }
                }
            }
            needSep = true;
        }
        
        if (dumpAll) {
            pw.println(" ");
            pw.println("  mBroadcastsScheduled=" + mBroadcastsScheduled);
            pw.println("  mHandler:");
            mHandler.dump(new PrintWriterPrinter(pw), "    ");
        }
            needSep = true;
        }
        
    void dumpServices(PrintWriter pw) {
        synchronized (this) {
            if (checkCallingPermission(android.Manifest.permission.DUMP)
                    != PackageManager.PERMISSION_GRANTED) {
                pw.println("Permission Denial: can't dump ActivityManager from from pid="
                        + Binder.getCallingPid()
                        + ", uid=" + Binder.getCallingUid()
                        + " without permission "
                        + android.Manifest.permission.DUMP);
                return;
        return needSep;
    }
            pw.println("Services in Current Activity Manager State:");
    boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
            int opti, boolean dumpAll) {
        boolean needSep = false;
        if (dumpAll) {
            if (mServices.size() > 0) {
                pw.println("  Active services:");
                Iterator<ServiceRecord> it = mServices.values().iterator();
@@ -9547,6 +9619,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                }
                needSep = true;
            }
        }
        if (mPendingServices.size() > 0) {
            if (needSep) pw.println(" ");
@@ -9581,6 +9654,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
            needSep = true;
        }
        if (dumpAll) {
            if (mServiceConnections.size() > 0) {
                if (needSep) pw.println(" ");
                pw.println("  Connection bindings to services:");
@@ -9591,26 +9665,18 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                    pw.print("  * "); pw.println(r);
                    r.dump(pw, "    ");
                }
            }
                needSep = true;
            }
        }
        
    void dumpProviders(PrintWriter pw) {
        synchronized (this) {
            if (checkCallingPermission(android.Manifest.permission.DUMP)
                    != PackageManager.PERMISSION_GRANTED) {
                pw.println("Permission Denial: can't dump ActivityManager from from pid="
                        + Binder.getCallingPid()
                        + ", uid=" + Binder.getCallingUid()
                        + " without permission "
                        + android.Manifest.permission.DUMP);
                return;
        return needSep;
    }
            pw.println("Content Providers in Current Activity Manager State:");
    boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
            int opti, boolean dumpAll) {
        boolean needSep = false;
        if (dumpAll) {
            if (mProvidersByClass.size() > 0) {
                if (needSep) pw.println(" ");
                pw.println("  Published content providers (by class):");
@@ -9636,6 +9702,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                }
                needSep = true;
            }
        }
        if (mLaunchingProviders.size() > 0) {
            if (needSep) pw.println(" ");
@@ -9661,30 +9728,24 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                    perm.dump(pw, "      ");
                }
            }
            }
        }
            needSep = true;
        }
        
    void dumpSenders(PrintWriter pw) {
        synchronized (this) {
            if (checkCallingPermission(android.Manifest.permission.DUMP)
                    != PackageManager.PERMISSION_GRANTED) {
                pw.println("Permission Denial: can't dump ActivityManager from from pid="
                        + Binder.getCallingPid()
                        + ", uid=" + Binder.getCallingUid()
                        + " without permission "
                        + android.Manifest.permission.DUMP);
                return;
        return needSep;
    }
            pw.println("Pending Intents in Current Activity Manager State:");
    boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
            int opti, boolean dumpAll) {
        boolean needSep = false;
        
        if (dumpAll) {
            if (this.mIntentSenderRecords.size() > 0) {
                Iterator<WeakReference<PendingIntentRecord>> it
                        = mIntentSenderRecords.values().iterator();
                while (it.hasNext()) {
                    WeakReference<PendingIntentRecord> ref = it.next();
                    PendingIntentRecord rec = ref != null ? ref.get(): null;
                    needSep = true;
                    if (rec != null) {
                        pw.print("  * "); pw.println(rec);
                        rec.dump(pw, "    ");
@@ -9694,6 +9755,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
                }
            }
        }
        
        return needSep;
    }
    private static final void dumpHistoryList(PrintWriter pw, List list,