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

Commit 6a40853e authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Add proto dump flag to services (1/2)

Adds new PROTO flag which requests services to dump sections
in proto format. Modifies dumpsys to take in proto argument
and pass on proto flags to services which support proto
dumps. Modify PriorityDumper helper class to parse proto
arguments and set asProto flags.

Bug: 67716082

Test: mmm -j56 frameworks/native/cmds/dumpsys && \
      mmm -j56 frameworks/native/services/utils && \
      adb sync data && \
      adb shell /data/nativetest/dumpsys_test/dumpsys_test && \
      adb shell /data/nativetest64/dumpsys_test/dumpsys_test && \
      adb shell /data/nativetest/prioritydumper_test/prioritydumper_test && \
      adb shell /data/nativetest64/prioritydumper_test/prioritydumper_test && \
      printf "\n\n#### ALL TESTS PASSED ####\n"

Change-Id: I42c2a6a8876efbf9a7d792d68572499b16985147
parent fabd2f5c
Loading
Loading
Loading
Loading
+29 −13
Original line number Diff line number Diff line
@@ -62,6 +62,8 @@ static void usage() {
            "         --help: shows this help\n"
            "         -l: only list services, do not dump them\n"
            "         -t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds\n"
            "         --proto: filter services that support dumping data in proto format. Dumps"
            "               will be in proto format.\n"
            "         --priority LEVEL: filter services based on specified priority\n"
            "               LEVEL must be one of CRITICAL | HIGH | NORMAL\n"
            "         --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
@@ -77,17 +79,17 @@ static bool IsSkipped(const Vector<String16>& skipped, const String16& service)
    return false;
}

static bool ConvertPriorityTypeToBitmask(String16& type, int& bitmask) {
    if (type == PRIORITY_ARG_CRITICAL) {
        bitmask = IServiceManager::DUMP_PRIORITY_CRITICAL;
static bool ConvertPriorityTypeToBitmask(const String16& type, int& bitmask) {
    if (type == PriorityDumper::PRIORITY_ARG_CRITICAL) {
        bitmask = IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL;
        return true;
    }
    if (type == PRIORITY_ARG_HIGH) {
        bitmask = IServiceManager::DUMP_PRIORITY_HIGH;
    if (type == PriorityDumper::PRIORITY_ARG_HIGH) {
        bitmask = IServiceManager::DUMP_FLAG_PRIORITY_HIGH;
        return true;
    }
    if (type == PRIORITY_ARG_NORMAL) {
        bitmask = IServiceManager::DUMP_PRIORITY_NORMAL;
    if (type == PriorityDumper::PRIORITY_ARG_NORMAL) {
        bitmask = IServiceManager::DUMP_FLAG_PRIORITY_NORMAL;
        return true;
    }
    return false;
@@ -98,11 +100,14 @@ int Dumpsys::main(int argc, char* const argv[]) {
    Vector<String16> args;
    String16 priorityType;
    Vector<String16> skippedServices;
    Vector<String16> protoServices;
    bool showListOnly = false;
    bool skipServices = false;
    bool filterByProto = false;
    int timeoutArg = 10;
    int dumpPriority = IServiceManager::DUMP_PRIORITY_ALL;
    int dumpPriorityFlags = IServiceManager::DUMP_FLAG_PRIORITY_ALL;
    static struct option longOptions[] = {{"priority", required_argument, 0, 0},
                                          {"proto", no_argument, 0, 0},
                                          {"skip", no_argument, 0, 0},
                                          {"help", no_argument, 0, 0},
                                          {0, 0, 0, 0}};
@@ -124,12 +129,14 @@ int Dumpsys::main(int argc, char* const argv[]) {
        case 0:
            if (!strcmp(longOptions[optionIndex].name, "skip")) {
                skipServices = true;
            } else if (!strcmp(longOptions[optionIndex].name, "proto")) {
                filterByProto = true;
            } else if (!strcmp(longOptions[optionIndex].name, "help")) {
                usage();
                return 0;
            } else if (!strcmp(longOptions[optionIndex].name, "priority")) {
                priorityType = String16(String8(optarg));
                if (!ConvertPriorityTypeToBitmask(priorityType, dumpPriority)) {
                if (!ConvertPriorityTypeToBitmask(priorityType, dumpPriorityFlags)) {
                    fprintf(stderr, "\n");
                    usage();
                    return -1;
@@ -179,10 +186,19 @@ int Dumpsys::main(int argc, char* const argv[]) {

    if (services.empty() || showListOnly) {
        // gets all services
        services = sm_->listServices(dumpPriority);
        services = sm_->listServices(dumpPriorityFlags);
        services.sort(sort_func);
        if (dumpPriority != IServiceManager::DUMP_PRIORITY_ALL) {
            args.insertAt(String16(PRIORITY_ARG), 0);
        if (filterByProto) {
            protoServices = sm_->listServices(IServiceManager::DUMP_FLAG_PROTO);
            protoServices.sort(sort_func);
            Vector<String16> intersection;
            std::set_intersection(services.begin(), services.end(), protoServices.begin(),
                                  protoServices.end(), std::back_inserter(intersection));
            services = std::move(intersection);
            args.insertAt(String16(PriorityDumper::PROTO_ARG), 0);
        }
        if (dumpPriorityFlags != IServiceManager::DUMP_FLAG_PRIORITY_ALL) {
            args.insertAt(String16(PriorityDumper::PRIORITY_ARG), 0);
            args.insertAt(priorityType, 1);
        } else {
            args.add(String16("-a"));
@@ -230,7 +246,7 @@ int Dumpsys::main(int argc, char* const argv[]) {
            if (N > 1) {
                aout << "------------------------------------------------------------"
                        "-------------------" << endl;
                if (dumpPriority == IServiceManager::DUMP_PRIORITY_ALL) {
                if (dumpPriorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_ALL) {
                    aout << "DUMP OF SERVICE " << service_name << ":" << endl;
                } else {
                    aout << "DUMP OF SERVICE " << priorityType << " " << service_name << ":" << endl;
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ cc_test {
    static_libs: [
        "libdumpsys",
        "libgmock",
        "libserviceutils",
    ],

    clang: true,
+71 −17
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <gtest/gtest.h>

#include <android-base/file.h>
#include <serviceutils/PriorityDumper.h>
#include <utils/String16.h>
#include <utils/String8.h>
#include <utils/Vector.h>
@@ -131,16 +132,16 @@ class DumpsysTest : public Test {
        for (auto& service : services) {
            services16.add(String16(service.c_str()));
        }
        EXPECT_CALL(sm_, listServices(IServiceManager::DUMP_PRIORITY_ALL))
        EXPECT_CALL(sm_, listServices(IServiceManager::DUMP_FLAG_PRIORITY_ALL))
            .WillRepeatedly(Return(services16));
    }

    void ExpectListServicesWithPriority(std::vector<std::string> services, int dumpPriority) {
    void ExpectListServicesWithPriority(std::vector<std::string> services, int dumpFlags) {
        Vector<String16> services16;
        for (auto& service : services) {
            services16.add(String16(service.c_str()));
        }
        EXPECT_CALL(sm_, listServices(dumpPriority)).WillRepeatedly(Return(services16));
        EXPECT_CALL(sm_, listServices(dumpFlags)).WillRepeatedly(Return(services16));
    }

    sp<BinderMock> ExpectCheckService(const char* name, bool running = true) {
@@ -210,6 +211,13 @@ class DumpsysTest : public Test {
        EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + service + ":\n" + dump));
    }

    void AssertDumpedWithPriority(const std::string& service, const std::string& dump,
                                  const char16_t* priorityType) {
        std::string priority = String8(priorityType).c_str();
        EXPECT_THAT(stdout_,
                    HasSubstr("DUMP OF SERVICE " + priority + " " + service + ":\n" + dump));
    }

    void AssertNotDumped(const std::string& dump) {
        EXPECT_THAT(stdout_, Not(HasSubstr(dump)));
    }
@@ -250,7 +258,7 @@ TEST_F(DumpsysTest, ListRunningServices) {

// Tests 'dumpsys -l --priority HIGH'
TEST_F(DumpsysTest, ListAllServicesWithPriority) {
    ExpectListServicesWithPriority({"Locksmith", "Valet"}, IServiceManager::DUMP_PRIORITY_HIGH);
    ExpectListServicesWithPriority({"Locksmith", "Valet"}, IServiceManager::DUMP_FLAG_PRIORITY_HIGH);
    ExpectCheckService("Locksmith");
    ExpectCheckService("Valet");

@@ -261,13 +269,26 @@ TEST_F(DumpsysTest, ListAllServicesWithPriority) {

// Tests 'dumpsys -l --priority HIGH' with and empty list
TEST_F(DumpsysTest, ListEmptyServicesWithPriority) {
    ExpectListServicesWithPriority({}, IServiceManager::DUMP_PRIORITY_HIGH);
    ExpectListServicesWithPriority({}, IServiceManager::DUMP_FLAG_PRIORITY_HIGH);

    CallMain({"-l", "--priority", "HIGH"});

    AssertRunningServices({});
}

// Tests 'dumpsys -l --proto'
TEST_F(DumpsysTest, ListAllServicesWithProto) {
    ExpectListServicesWithPriority({"Locksmith", "Valet", "Car"},
                                   IServiceManager::DUMP_FLAG_PRIORITY_ALL);
    ExpectListServicesWithPriority({"Valet", "Car"}, IServiceManager::DUMP_FLAG_PROTO);
    ExpectCheckService("Car");
    ExpectCheckService("Valet");

    CallMain({"-l", "--proto"});

    AssertRunningServices({"Car", "Valet"});
}

// Tests 'dumpsys service_name' on a service is running
TEST_F(DumpsysTest, DumpRunningService) {
    ExpectDump("Valet", "Here's your car");
@@ -336,7 +357,7 @@ TEST_F(DumpsysTest, DumpWithSkip) {
// Tests 'dumpsys --skip skipped3 skipped5 --priority CRITICAL', which should skip these services
TEST_F(DumpsysTest, DumpWithSkipAndPriority) {
    ExpectListServicesWithPriority({"running1", "stopped2", "skipped3", "running4", "skipped5"},
                                   IServiceManager::DUMP_PRIORITY_CRITICAL);
                                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
    ExpectDump("running1", "dump1");
    ExpectCheckService("stopped2", false);
    ExpectDump("skipped3", "dump3");
@@ -346,8 +367,8 @@ TEST_F(DumpsysTest, DumpWithSkipAndPriority) {
    CallMain({"--priority", "CRITICAL", "--skip", "skipped3", "skipped5"});

    AssertRunningServices({"running1", "running4", "skipped3 (skipped)", "skipped5 (skipped)"});
    AssertDumped("running1", "dump1");
    AssertDumped("running4", "dump4");
    AssertDumpedWithPriority("running1", "dump1", PriorityDumper::PRIORITY_ARG_CRITICAL);
    AssertDumpedWithPriority("running4", "dump4", PriorityDumper::PRIORITY_ARG_CRITICAL);
    AssertStopped("stopped2");
    AssertNotDumped("dump3");
    AssertNotDumped("dump5");
@@ -356,41 +377,74 @@ TEST_F(DumpsysTest, DumpWithSkipAndPriority) {
// Tests 'dumpsys --priority CRITICAL'
TEST_F(DumpsysTest, DumpWithPriorityCritical) {
    ExpectListServicesWithPriority({"runningcritical1", "runningcritical2"},
                                   IServiceManager::DUMP_PRIORITY_CRITICAL);
                                   IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL);
    ExpectDump("runningcritical1", "dump1");
    ExpectDump("runningcritical2", "dump2");

    CallMain({"--priority", "CRITICAL"});

    AssertRunningServices({"runningcritical1", "runningcritical2"});
    AssertDumped("runningcritical1", "dump1");
    AssertDumped("runningcritical2", "dump2");
    AssertDumpedWithPriority("runningcritical1", "dump1", PriorityDumper::PRIORITY_ARG_CRITICAL);
    AssertDumpedWithPriority("runningcritical2", "dump2", PriorityDumper::PRIORITY_ARG_CRITICAL);
}

// Tests 'dumpsys --priority HIGH'
TEST_F(DumpsysTest, DumpWithPriorityHigh) {
    ExpectListServicesWithPriority({"runninghigh1", "runninghigh2"},
                                   IServiceManager::DUMP_PRIORITY_HIGH);
                                   IServiceManager::DUMP_FLAG_PRIORITY_HIGH);
    ExpectDump("runninghigh1", "dump1");
    ExpectDump("runninghigh2", "dump2");

    CallMain({"--priority", "HIGH"});

    AssertRunningServices({"runninghigh1", "runninghigh2"});
    AssertDumped("runninghigh1", "dump1");
    AssertDumped("runninghigh2", "dump2");
    AssertDumpedWithPriority("runninghigh1", "dump1", PriorityDumper::PRIORITY_ARG_HIGH);
    AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH);
}

// Tests 'dumpsys --priority NORMAL'
TEST_F(DumpsysTest, DumpWithPriorityNormal) {
    ExpectListServicesWithPriority({"runningnormal1", "runningnormal2"},
                                   IServiceManager::DUMP_PRIORITY_NORMAL);
                                   IServiceManager::DUMP_FLAG_PRIORITY_NORMAL);
    ExpectDump("runningnormal1", "dump1");
    ExpectDump("runningnormal2", "dump2");

    CallMain({"--priority", "NORMAL"});

    AssertRunningServices({"runningnormal1", "runningnormal2"});
    AssertDumped("runningnormal1", "dump1");
    AssertDumped("runningnormal2", "dump2");
    AssertDumpedWithPriority("runningnormal1", "dump1", PriorityDumper::PRIORITY_ARG_NORMAL);
    AssertDumpedWithPriority("runningnormal2", "dump2", PriorityDumper::PRIORITY_ARG_NORMAL);
}

// Tests 'dumpsys --proto'
TEST_F(DumpsysTest, DumpWithProto) {
    ExpectListServicesWithPriority({"run8", "run1", "run2", "run5"},
                                   IServiceManager::DUMP_FLAG_PRIORITY_ALL);
    ExpectListServicesWithPriority({"run3", "run2", "run4", "run8"},
                                   IServiceManager::DUMP_FLAG_PROTO);
    ExpectDump("run2", "dump1");
    ExpectDump("run8", "dump2");

    CallMain({"--proto"});

    AssertRunningServices({"run2", "run8"});
    AssertDumped("run2", "dump1");
    AssertDumped("run8", "dump2");
}

// Tests 'dumpsys --priority HIGH --proto'
TEST_F(DumpsysTest, DumpWithPriorityHighAndProto) {
    ExpectListServicesWithPriority({"runninghigh1", "runninghigh2"},
                                   IServiceManager::DUMP_FLAG_PRIORITY_HIGH);
    ExpectListServicesWithPriority({"runninghigh1", "runninghigh2", "runninghigh3"},
                                   IServiceManager::DUMP_FLAG_PROTO);

    ExpectDump("runninghigh1", "dump1");
    ExpectDump("runninghigh2", "dump2");

    CallMain({"--priority", "HIGH", "--proto"});

    AssertRunningServices({"runninghigh1", "runninghigh2"});
    AssertDumpedWithPriority("runninghigh1", "dump1", PriorityDumper::PRIORITY_ARG_HIGH);
    AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH);
}
+6 −5
Original line number Diff line number Diff line
@@ -35,15 +35,16 @@ class BinderService
{
public:
    static status_t publish(bool allowIsolated = false,
                            int dumpPriority = IServiceManager::DUMP_PRIORITY_NORMAL) {
                            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_NORMAL) {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
                              dumpPriority);
                              dumpFlags);
    }

    static void publishAndJoinThreadPool(bool allowIsolated = false,
                                         int dumpPriority = IServiceManager::DUMP_PRIORITY_NORMAL) {
        publish(allowIsolated, dumpPriority);
    static void publishAndJoinThreadPool(
            bool allowIsolated = false,
            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_NORMAL) {
        publish(allowIsolated, dumpFlags);
        joinThreadPool();
    }

+8 −7
Original line number Diff line number Diff line
@@ -34,11 +34,12 @@ public:
    /*
     * Must match values in IServiceManager.java
     */
    static const int DUMP_PRIORITY_CRITICAL = 1 << 0;
    static const int DUMP_PRIORITY_HIGH = 1 << 1;
    static const int DUMP_PRIORITY_NORMAL = 1 << 2;
    static const int DUMP_PRIORITY_ALL =
            DUMP_PRIORITY_CRITICAL | DUMP_PRIORITY_HIGH | DUMP_PRIORITY_NORMAL;
    static const int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0;
    static const int DUMP_FLAG_PRIORITY_HIGH = 1 << 1;
    static const int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2;
    static const int DUMP_FLAG_PRIORITY_ALL =
            DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL;
    static const int DUMP_FLAG_PROTO = 1 << 3;

    /**
     * Retrieve an existing service, blocking for a few seconds
@@ -56,12 +57,12 @@ public:
     */
    virtual status_t addService(const String16& name, const sp<IBinder>& service,
                                bool allowIsolated = false,
                                int dumpsysPriority = DUMP_PRIORITY_NORMAL) = 0;
                                int dumpsysFlags = DUMP_FLAG_PRIORITY_NORMAL) = 0;

    /**
     * Return list of all existing services.
     */
    virtual Vector<String16> listServices(int dumpsysPriority = DUMP_PRIORITY_ALL) = 0;
    virtual Vector<String16> listServices(int dumpsysFlags = DUMP_FLAG_PRIORITY_ALL) = 0;

    enum {
        GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
Loading