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

Commit 4b34000a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add proto dump flag to services (2/2)"

parents 87d2ba36 e78b01ad
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -45,13 +45,13 @@ public interface IServiceManager extends IInterface
     * Place a new @a service called @a name into the service
     * manager.
     */
    void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
    void addService(String name, IBinder service, boolean allowIsolated, int dumpFlags)
            throws RemoteException;

    /**
     * Return a list of all currently running services.
     */
    String[] listServices(int dumpPriority) throws RemoteException;
    String[] listServices(int dumpFlags) throws RemoteException;

    /**
     * Assign a permission controller to the service manager.  After set, this
@@ -72,9 +72,13 @@ public interface IServiceManager extends IInterface
    /*
     * Must update values in IServiceManager.h
     */
    int DUMP_PRIORITY_CRITICAL = 1 << 0;
    int DUMP_PRIORITY_HIGH = 1 << 1;
    int DUMP_PRIORITY_NORMAL = 1 << 2;
    int DUMP_PRIORITY_ALL = DUMP_PRIORITY_CRITICAL | DUMP_PRIORITY_HIGH
            | DUMP_PRIORITY_NORMAL;
    /* Allows services to dump sections according to priorities. */
    int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0;
    int DUMP_FLAG_PRIORITY_HIGH = 1 << 1;
    int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2;
    int DUMP_FLAG_PRIORITY_ALL = DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH
            | DUMP_FLAG_PRIORITY_NORMAL;
    /* Allows services to dump sections in protobuf format. */
    int DUMP_FLAG_PROTO = 1 << 3;

}
+3 −3
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ public final class ServiceManager {
     * @param service the service object
     */
    public static void addService(String name, IBinder service) {
        addService(name, service, false, IServiceManager.DUMP_PRIORITY_NORMAL);
        addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_NORMAL);
    }

    /**
@@ -96,7 +96,7 @@ public final class ServiceManager {
     * to access this service
     */
    public static void addService(String name, IBinder service, boolean allowIsolated) {
        addService(name, service, allowIsolated, IServiceManager.DUMP_PRIORITY_NORMAL);
        addService(name, service, allowIsolated, IServiceManager.DUMP_FLAG_PRIORITY_NORMAL);
    }

    /**
@@ -143,7 +143,7 @@ public final class ServiceManager {
     */
    public static String[] listServices() {
        try {
            return getIServiceManager().listServices(IServiceManager.DUMP_PRIORITY_ALL);
            return getIServiceManager().listServices(IServiceManager.DUMP_FLAG_PRIORITY_ALL);
        } catch (RemoteException e) {
            Log.e(TAG, "error in listServices", e);
            return null;
+38 −30
Original line number Diff line number Diff line
@@ -53,9 +53,10 @@ import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
import static android.net.NetworkPolicyManager.isProcStateAllowedWhileIdleOrPowerSaveMode;
import static android.net.NetworkPolicyManager.isProcStateAllowedWhileOnRestrictBackground;
import static android.os.Build.VERSION_CODES.N;
import static android.os.IServiceManager.DUMP_PRIORITY_CRITICAL;
import static android.os.IServiceManager.DUMP_PRIORITY_HIGH;
import static android.os.IServiceManager.DUMP_PRIORITY_NORMAL;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
import static android.os.IServiceManager.DUMP_FLAG_PROTO;
import static android.os.Process.BLUETOOTH_UID;
import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.Process.FIRST_ISOLATED_UID;
@@ -722,30 +723,36 @@ public class ActivityManagerService extends IActivityManager.Stub
     */
    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
        @Override
        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) {
            doDump(fd, pw, new String[] {"activities"});
        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
                boolean asProto) {
            if (asProto) return;
            doDump(fd, pw, new String[]{"activities"}, asProto);
        }
        @Override
        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
            doDump(fd, pw, new String[] {"settings"});
            doDump(fd, pw, new String[] {"intents"});
            doDump(fd, pw, new String[] {"broadcasts"});
            doDump(fd, pw, new String[] {"providers"});
            doDump(fd, pw, new String[] {"permissions"});
            doDump(fd, pw, new String[] {"services"});
            doDump(fd, pw, new String[] {"recents"});
            doDump(fd, pw, new String[] {"lastanr"});
            doDump(fd, pw, new String[] {"starter"});
        public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
            if (asProto) {
                doDump(fd, pw, new String[0], asProto);
            } else {
                doDump(fd, pw, new String[]{"settings"}, asProto);
                doDump(fd, pw, new String[]{"intents"}, asProto);
                doDump(fd, pw, new String[]{"broadcasts"}, asProto);
                doDump(fd, pw, new String[]{"providers"}, asProto);
                doDump(fd, pw, new String[]{"permissions"}, asProto);
                doDump(fd, pw, new String[]{"services"}, asProto);
                doDump(fd, pw, new String[]{"recents"}, asProto);
                doDump(fd, pw, new String[]{"lastanr"}, asProto);
                doDump(fd, pw, new String[]{"starter"}, asProto);
                if (mAssociations.size() > 0) {
                doDump(fd, pw, new String[] {"associations"});
                    doDump(fd, pw, new String[]{"associations"}, asProto);
                }
                doDump(fd, pw, new String[]{"processes"}, asProto);
            }
            doDump(fd, pw, new String[] {"processes"});
        }
        @Override
        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            doDump(fd, pw, args);
        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
            doDump(fd, pw, args, asProto);
        }
    };
@@ -2493,15 +2500,15 @@ public class ActivityManagerService extends IActivityManager.Stub
    public void setSystemProcess() {
        try {
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, /* allowIsolated= */ true,
                    DUMP_PRIORITY_CRITICAL | DUMP_PRIORITY_NORMAL);
                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
            ServiceManager.addService("meminfo", new MemBinder(this), /* allowIsolated= */ false,
                    DUMP_PRIORITY_HIGH | DUMP_PRIORITY_NORMAL);
                    DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
            ServiceManager.addService("dbinfo", new DbBinder(this));
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(this),
                        /* allowIsolated= */ false, DUMP_PRIORITY_CRITICAL);
                        /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
            }
            ServiceManager.addService("permission", new PermissionController(this));
            ServiceManager.addService("processinfo", new ProcessInfoService(this));
@@ -2554,7 +2561,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        private final PriorityDump.PriorityDumper mPriorityDumper =
                new PriorityDump.PriorityDumper() {
            @Override
            public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
            public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args,
                    boolean asProto) {
                if (asProto) return;
                mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
            }
        };
@@ -2604,7 +2613,9 @@ public class ActivityManagerService extends IActivityManager.Stub
        private final PriorityDump.PriorityDumper mPriorityDumper =
                new PriorityDump.PriorityDumper() {
            @Override
            public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) {
            public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
                    boolean asProto) {
                if (asProto) return;
                if (!DumpUtils.checkDumpAndUsageStatsPermission(mActivityManagerService.mContext,
                        "cpuinfo", pw)) return;
                synchronized (mActivityManagerService.mProcessCpuTracker) {
@@ -14847,7 +14858,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    /**
     * Wrapper function to print out debug data filtered by specified arguments.
    */
    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args) {
    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
        boolean dumpAll = false;
@@ -14856,7 +14867,6 @@ public class ActivityManagerService extends IActivityManager.Stub
        boolean dumpCheckinFormat = false;
        boolean dumpVisibleStacksOnly = false;
        boolean dumpFocusedStackOnly = false;
        boolean useProto = false;
        String dumpPackage = null;
        int opti = 0;
@@ -14890,8 +14900,6 @@ public class ActivityManagerService extends IActivityManager.Stub
            } else if ("-h".equals(opt)) {
                ActivityManagerShellCommand.dumpHelp(pw, true);
                return;
            } else if ("--proto".equals(opt)) {
                useProto = true;
            } else {
                pw.println("Unknown argument: " + opt + "; use -h for help");
            }
+113 −40
Original line number Diff line number Diff line
@@ -16,12 +16,19 @@

package com.android.server.utils;

import android.annotation.IntDef;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;

/**
 * Helper for {@link android.os.Binder#dump(java.io.FileDescriptor, String[])} that supports the
 * {@link #PRIORITY_ARG} argument.
 * {@link #PRIORITY_ARG} and {@link #PROTO_ARG} arguments.
 * <p>
 * Typical usage:
 *
@@ -31,14 +38,26 @@ public class SpringfieldNuclearPowerPlant extends Binder {
 private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {

     @Override
     public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) {
     public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
       if (asProto) {
         ProtoOutputStream proto = new ProtoOutputStream(fd);
         proto.write(SpringfieldProto.DONUTS, 1);
         proto.flush();
       } else {
         pw.println("Donuts in the box: 1");
       }
     }

     @Override
     public void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (asProto) {
          ProtoOutputStream proto = new ProtoOutputStream(fd);
          proto.write(SpringfieldProto.REACTOR_STATUS, DANGER_MELTDOWN_IMMINENT);
          proto.flush();
        } else {
          pw.println("Nuclear reactor status: DANGER - MELTDOWN IMMINENT");
        }
     }
  };

  @Override
@@ -65,6 +84,9 @@ public class SpringfieldNuclearPowerPlant extends Binder {
    $ adb shell dumpsys snpp --dump-priority NORMAL
    Nuclear reactor status: DANGER - MELTDOWN IMMINENT

    $ adb shell dumpsys snpp --dump-priority CRITICAL --proto
    //binary output

 * </code></pre>
 *
 *
@@ -85,95 +107,146 @@ public class SpringfieldNuclearPowerPlant extends Binder {
public final class PriorityDump {

    public static final String PRIORITY_ARG = "--dump-priority";
    public static final String PROTO_ARG = "--proto";

    private PriorityDump() {
        throw new UnsupportedOperationException();
    }

    /** Enum to switch through supported priority types */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({PRIORITY_TYPE_INVALID, PRIORITY_TYPE_CRITICAL, PRIORITY_TYPE_HIGH,
            PRIORITY_TYPE_NORMAL})
    private @interface PriorityType { }
    private static final int PRIORITY_TYPE_INVALID = 0;
    private static final int PRIORITY_TYPE_CRITICAL = 1;
    private static final int PRIORITY_TYPE_HIGH = 2;
    private static final int PRIORITY_TYPE_NORMAL = 3;

    /**
     * Parses {@code} and call the proper {@link PriorityDumper} method when the first argument is
     * {@code --dump-priority}, stripping the priority and its type.
     * Parses {@code args} matching {@code --dump-priority} and/or {@code --proto}. The matching
     * arguments are stripped.
     * <p>
     * If priority args are passed as an argument, it will call the appropriate method and if proto
     * args are passed then the {@code asProto} flag is set.
     * <p>
     * For example, if called as {@code --dump-priority HIGH arg1 arg2 arg3}, it will call
     * <code>dumper.dumpHigh(fd, pw, {"arg1", "arg2", "arg3"}) </code>
     * <code>dumper.dumpHigh(fd, pw, {"arg1", "arg2", "arg3"}, false) </code>
     * <p>
     * If the {@code --dump-priority} is not set, it calls
     * {@link PriorityDumper#dump(FileDescriptor, PrintWriter, String[])} passing the whole
     * {@link PriorityDumper#dump(FileDescriptor, PrintWriter, String[], boolean)} passing the whole
     * {@code args} instead.
     */
    public static void dump(PriorityDumper dumper, FileDescriptor fd, PrintWriter pw,
            String[] args) {
        if (args != null && args.length >= 2 && args[0].equals(PRIORITY_ARG)) {
            final String priority = args[1];
        boolean asProto = false;
        @PriorityType int priority = PRIORITY_TYPE_INVALID;

        if (args == null) {
            dumper.dump(fd, pw, args, asProto);
            return;
        }

        String[] strippedArgs = new String[args.length];
        int strippedCount = 0;
        for (int argIndex = 0; argIndex < args.length; argIndex++) {
            if (args[argIndex].equals(PROTO_ARG)) {
                asProto = true;
            } else if (args[argIndex].equals(PRIORITY_ARG)) {
                if (argIndex + 1 < args.length) {
                    argIndex++;
                    priority = getPriorityType(args[argIndex]);
                }
            } else {
                strippedArgs[strippedCount++] = args[argIndex];
            }
        }

        if (strippedCount < args.length) {
            strippedArgs = Arrays.copyOf(strippedArgs, strippedCount);
        }

        switch (priority) {
                case "CRITICAL": {
                    dumper.dumpCritical(fd, pw, getStrippedArgs(args));
            case PRIORITY_TYPE_CRITICAL: {
                dumper.dumpCritical(fd, pw, strippedArgs, asProto);
                return;
            }
                case "HIGH": {
                    dumper.dumpHigh(fd, pw, getStrippedArgs(args));
            case PRIORITY_TYPE_HIGH: {
                dumper.dumpHigh(fd, pw, strippedArgs, asProto);
                return;
            }
                case "NORMAL": {
                    dumper.dumpNormal(fd, pw, getStrippedArgs(args));
            case PRIORITY_TYPE_NORMAL: {
                dumper.dumpNormal(fd, pw, strippedArgs, asProto);
                return;
            }
            default: {
                dumper.dump(fd, pw, strippedArgs, asProto);
                return;
            }
        }
        dumper.dump(fd, pw, args);
    }

    /**
     * Gets an array without the {@code --dump-priority PRIORITY} prefix.
     * Converts priority argument type to enum.
     */
    private static String[] getStrippedArgs(String[] args) {
        final String[] stripped = new String[args.length - 2];
        System.arraycopy(args, 2, stripped, 0, stripped.length);
        return stripped;
    private static @PriorityType int getPriorityType(String arg) {
        switch (arg) {
            case "CRITICAL": {
                return PRIORITY_TYPE_CRITICAL;
            }
            case "HIGH": {
                return PRIORITY_TYPE_HIGH;
            }
            case "NORMAL": {
                return PRIORITY_TYPE_NORMAL;
            }
        }
        return PRIORITY_TYPE_INVALID;
    }

    /**
     * Helper for {@link android.os.Binder#dump(java.io.FileDescriptor, String[])} that supports the
     * {@link #PRIORITY_ARG} argument.
     * {@link #PRIORITY_ARG} and {@link #PROTO_ARG} arguments.
     *
     * @hide
     */
    public static interface PriorityDumper {
    public interface PriorityDumper {

        /**
         * Dumps only the critical section.
         */
        @SuppressWarnings("unused")
        default void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) {
        default void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
                boolean asProto) {
        }

        /**
         * Dumps only the high-priority section.
         */
        @SuppressWarnings("unused")
        default void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args) {
        default void dumpHigh(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
        }

        /**
         * Dumps only the normal section.
         */
        @SuppressWarnings("unused")
        default void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args) {
        default void dumpNormal(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
        }

        /**
         * Dumps all sections.
         * <p>
         * This method is called when
         * {@link PriorityDump#dump(PriorityDumper, FileDescriptor, PrintWriter, String[])} is
         * called without priority arguments. By default, it calls the 3 {@code dumpTYPE} methods,
         * so sub-classes just need to implement the priority types they support.
         * {@link PriorityDump#dump(PriorityDumper, FileDescriptor, PrintWriter, String[], boolean)}
         * is called without priority arguments. By default, it calls the 3 {@code dumpTYPE}
         * methods, so sub-classes just need to implement the priority types they support.
         */
        @SuppressWarnings("unused")
        default void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            dumpCritical(fd, pw, args);
            dumpHigh(fd, pw, args);
            dumpNormal(fd, pw, args);
        default void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
            dumpCritical(fd, pw, args, asProto);
            dumpHigh(fd, pw, args, asProto);
            dumpNormal(fd, pw, args, asProto);
        }
    }
}
+6 −8
Original line number Diff line number Diff line
@@ -392,13 +392,14 @@ public class WindowManagerService extends IWindowManager.Stub

    private final PriorityDump.PriorityDumper mPriorityDumper = new PriorityDump.PriorityDumper() {
        @Override
        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args) {
            doDump(fd, pw, new String[] {"-a"});
        public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
                boolean asProto) {
            doDump(fd, pw, new String[] {"-a"}, asProto);
        }

        @Override
        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            doDump(fd, pw, args);
        public void dump(FileDescriptor fd, PrintWriter pw, String[] args, boolean asProto) {
            doDump(fd, pw, args, asProto);
        }
    };

@@ -6730,10 +6731,9 @@ public class WindowManagerService extends IWindowManager.Stub
        PriorityDump.dump(mPriorityDumper, fd, pw, args);
    }

    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args) {
    private void doDump(FileDescriptor fd, PrintWriter pw, String[] args, boolean useProto) {
        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
        boolean dumpAll = false;
        boolean useProto = false;

        int opti = 0;
        while (opti < args.length) {
@@ -6744,8 +6744,6 @@ public class WindowManagerService extends IWindowManager.Stub
            opti++;
            if ("-a".equals(opt)) {
                dumpAll = true;
            } else if ("--proto".equals(opt)) {
                useProto = true;
            } else if ("-h".equals(opt)) {
                pw.println("Window manager dump options:");
                pw.println("  [-a] [-h] [cmd] ...");
Loading