Loading cmds/dumpsys/dumpsys.cpp +29 −13 Original line number Original line Diff line number Diff line Loading @@ -62,6 +62,8 @@ static void usage() { " --help: shows this help\n" " --help: shows this help\n" " -l: only list services, do not dump them\n" " -l: only list services, do not dump them\n" " -t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds\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" " --priority LEVEL: filter services based on specified priority\n" " LEVEL must be one of CRITICAL | HIGH | NORMAL\n" " LEVEL must be one of CRITICAL | HIGH | NORMAL\n" " --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n" " --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n" Loading @@ -77,17 +79,17 @@ static bool IsSkipped(const Vector<String16>& skipped, const String16& service) return false; return false; } } static bool ConvertPriorityTypeToBitmask(String16& type, int& bitmask) { static bool ConvertPriorityTypeToBitmask(const String16& type, int& bitmask) { if (type == PRIORITY_ARG_CRITICAL) { if (type == PriorityDumper::PRIORITY_ARG_CRITICAL) { bitmask = IServiceManager::DUMP_PRIORITY_CRITICAL; bitmask = IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL; return true; return true; } } if (type == PRIORITY_ARG_HIGH) { if (type == PriorityDumper::PRIORITY_ARG_HIGH) { bitmask = IServiceManager::DUMP_PRIORITY_HIGH; bitmask = IServiceManager::DUMP_FLAG_PRIORITY_HIGH; return true; return true; } } if (type == PRIORITY_ARG_NORMAL) { if (type == PriorityDumper::PRIORITY_ARG_NORMAL) { bitmask = IServiceManager::DUMP_PRIORITY_NORMAL; bitmask = IServiceManager::DUMP_FLAG_PRIORITY_NORMAL; return true; return true; } } return false; return false; Loading @@ -98,11 +100,14 @@ int Dumpsys::main(int argc, char* const argv[]) { Vector<String16> args; Vector<String16> args; String16 priorityType; String16 priorityType; Vector<String16> skippedServices; Vector<String16> skippedServices; Vector<String16> protoServices; bool showListOnly = false; bool showListOnly = false; bool skipServices = false; bool skipServices = false; bool filterByProto = false; int timeoutArg = 10; 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}, static struct option longOptions[] = {{"priority", required_argument, 0, 0}, {"proto", no_argument, 0, 0}, {"skip", no_argument, 0, 0}, {"skip", no_argument, 0, 0}, {"help", no_argument, 0, 0}, {"help", no_argument, 0, 0}, {0, 0, 0, 0}}; {0, 0, 0, 0}}; Loading @@ -124,12 +129,14 @@ int Dumpsys::main(int argc, char* const argv[]) { case 0: case 0: if (!strcmp(longOptions[optionIndex].name, "skip")) { if (!strcmp(longOptions[optionIndex].name, "skip")) { skipServices = true; skipServices = true; } else if (!strcmp(longOptions[optionIndex].name, "proto")) { filterByProto = true; } else if (!strcmp(longOptions[optionIndex].name, "help")) { } else if (!strcmp(longOptions[optionIndex].name, "help")) { usage(); usage(); return 0; return 0; } else if (!strcmp(longOptions[optionIndex].name, "priority")) { } else if (!strcmp(longOptions[optionIndex].name, "priority")) { priorityType = String16(String8(optarg)); priorityType = String16(String8(optarg)); if (!ConvertPriorityTypeToBitmask(priorityType, dumpPriority)) { if (!ConvertPriorityTypeToBitmask(priorityType, dumpPriorityFlags)) { fprintf(stderr, "\n"); fprintf(stderr, "\n"); usage(); usage(); return -1; return -1; Loading Loading @@ -179,10 +186,19 @@ int Dumpsys::main(int argc, char* const argv[]) { if (services.empty() || showListOnly) { if (services.empty() || showListOnly) { // gets all services // gets all services services = sm_->listServices(dumpPriority); services = sm_->listServices(dumpPriorityFlags); services.sort(sort_func); services.sort(sort_func); if (dumpPriority != IServiceManager::DUMP_PRIORITY_ALL) { if (filterByProto) { args.insertAt(String16(PRIORITY_ARG), 0); 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); args.insertAt(priorityType, 1); } else { } else { args.add(String16("-a")); args.add(String16("-a")); Loading Loading @@ -230,7 +246,7 @@ int Dumpsys::main(int argc, char* const argv[]) { if (N > 1) { if (N > 1) { aout << "------------------------------------------------------------" aout << "------------------------------------------------------------" "-------------------" << endl; "-------------------" << endl; if (dumpPriority == IServiceManager::DUMP_PRIORITY_ALL) { if (dumpPriorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_ALL) { aout << "DUMP OF SERVICE " << service_name << ":" << endl; aout << "DUMP OF SERVICE " << service_name << ":" << endl; } else { } else { aout << "DUMP OF SERVICE " << priorityType << " " << service_name << ":" << endl; aout << "DUMP OF SERVICE " << priorityType << " " << service_name << ":" << endl; Loading cmds/dumpsys/tests/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -15,6 +15,7 @@ cc_test { static_libs: [ static_libs: [ "libdumpsys", "libdumpsys", "libgmock", "libgmock", "libserviceutils", ], ], clang: true, clang: true, Loading cmds/dumpsys/tests/dumpsys_test.cpp +71 −17 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <gtest/gtest.h> #include <gtest/gtest.h> #include <android-base/file.h> #include <android-base/file.h> #include <serviceutils/PriorityDumper.h> #include <utils/String16.h> #include <utils/String16.h> #include <utils/String8.h> #include <utils/String8.h> #include <utils/Vector.h> #include <utils/Vector.h> Loading Loading @@ -131,16 +132,16 @@ class DumpsysTest : public Test { for (auto& service : services) { for (auto& service : services) { services16.add(String16(service.c_str())); 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)); .WillRepeatedly(Return(services16)); } } void ExpectListServicesWithPriority(std::vector<std::string> services, int dumpPriority) { void ExpectListServicesWithPriority(std::vector<std::string> services, int dumpFlags) { Vector<String16> services16; Vector<String16> services16; for (auto& service : services) { for (auto& service : services) { services16.add(String16(service.c_str())); 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) { sp<BinderMock> ExpectCheckService(const char* name, bool running = true) { Loading Loading @@ -210,6 +211,13 @@ class DumpsysTest : public Test { EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + service + ":\n" + dump)); 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) { void AssertNotDumped(const std::string& dump) { EXPECT_THAT(stdout_, Not(HasSubstr(dump))); EXPECT_THAT(stdout_, Not(HasSubstr(dump))); } } Loading Loading @@ -250,7 +258,7 @@ TEST_F(DumpsysTest, ListRunningServices) { // Tests 'dumpsys -l --priority HIGH' // Tests 'dumpsys -l --priority HIGH' TEST_F(DumpsysTest, ListAllServicesWithPriority) { TEST_F(DumpsysTest, ListAllServicesWithPriority) { ExpectListServicesWithPriority({"Locksmith", "Valet"}, IServiceManager::DUMP_PRIORITY_HIGH); ExpectListServicesWithPriority({"Locksmith", "Valet"}, IServiceManager::DUMP_FLAG_PRIORITY_HIGH); ExpectCheckService("Locksmith"); ExpectCheckService("Locksmith"); ExpectCheckService("Valet"); ExpectCheckService("Valet"); Loading @@ -261,13 +269,26 @@ TEST_F(DumpsysTest, ListAllServicesWithPriority) { // Tests 'dumpsys -l --priority HIGH' with and empty list // Tests 'dumpsys -l --priority HIGH' with and empty list TEST_F(DumpsysTest, ListEmptyServicesWithPriority) { TEST_F(DumpsysTest, ListEmptyServicesWithPriority) { ExpectListServicesWithPriority({}, IServiceManager::DUMP_PRIORITY_HIGH); ExpectListServicesWithPriority({}, IServiceManager::DUMP_FLAG_PRIORITY_HIGH); CallMain({"-l", "--priority", "HIGH"}); CallMain({"-l", "--priority", "HIGH"}); AssertRunningServices({}); 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 // Tests 'dumpsys service_name' on a service is running TEST_F(DumpsysTest, DumpRunningService) { TEST_F(DumpsysTest, DumpRunningService) { ExpectDump("Valet", "Here's your car"); ExpectDump("Valet", "Here's your car"); Loading Loading @@ -336,7 +357,7 @@ TEST_F(DumpsysTest, DumpWithSkip) { // Tests 'dumpsys --skip skipped3 skipped5 --priority CRITICAL', which should skip these services // Tests 'dumpsys --skip skipped3 skipped5 --priority CRITICAL', which should skip these services TEST_F(DumpsysTest, DumpWithSkipAndPriority) { TEST_F(DumpsysTest, DumpWithSkipAndPriority) { ExpectListServicesWithPriority({"running1", "stopped2", "skipped3", "running4", "skipped5"}, ExpectListServicesWithPriority({"running1", "stopped2", "skipped3", "running4", "skipped5"}, IServiceManager::DUMP_PRIORITY_CRITICAL); IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL); ExpectDump("running1", "dump1"); ExpectDump("running1", "dump1"); ExpectCheckService("stopped2", false); ExpectCheckService("stopped2", false); ExpectDump("skipped3", "dump3"); ExpectDump("skipped3", "dump3"); Loading @@ -346,8 +367,8 @@ TEST_F(DumpsysTest, DumpWithSkipAndPriority) { CallMain({"--priority", "CRITICAL", "--skip", "skipped3", "skipped5"}); CallMain({"--priority", "CRITICAL", "--skip", "skipped3", "skipped5"}); AssertRunningServices({"running1", "running4", "skipped3 (skipped)", "skipped5 (skipped)"}); AssertRunningServices({"running1", "running4", "skipped3 (skipped)", "skipped5 (skipped)"}); AssertDumped("running1", "dump1"); AssertDumpedWithPriority("running1", "dump1", PriorityDumper::PRIORITY_ARG_CRITICAL); AssertDumped("running4", "dump4"); AssertDumpedWithPriority("running4", "dump4", PriorityDumper::PRIORITY_ARG_CRITICAL); AssertStopped("stopped2"); AssertStopped("stopped2"); AssertNotDumped("dump3"); AssertNotDumped("dump3"); AssertNotDumped("dump5"); AssertNotDumped("dump5"); Loading @@ -356,41 +377,74 @@ TEST_F(DumpsysTest, DumpWithSkipAndPriority) { // Tests 'dumpsys --priority CRITICAL' // Tests 'dumpsys --priority CRITICAL' TEST_F(DumpsysTest, DumpWithPriorityCritical) { TEST_F(DumpsysTest, DumpWithPriorityCritical) { ExpectListServicesWithPriority({"runningcritical1", "runningcritical2"}, ExpectListServicesWithPriority({"runningcritical1", "runningcritical2"}, IServiceManager::DUMP_PRIORITY_CRITICAL); IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL); ExpectDump("runningcritical1", "dump1"); ExpectDump("runningcritical1", "dump1"); ExpectDump("runningcritical2", "dump2"); ExpectDump("runningcritical2", "dump2"); CallMain({"--priority", "CRITICAL"}); CallMain({"--priority", "CRITICAL"}); AssertRunningServices({"runningcritical1", "runningcritical2"}); AssertRunningServices({"runningcritical1", "runningcritical2"}); AssertDumped("runningcritical1", "dump1"); AssertDumpedWithPriority("runningcritical1", "dump1", PriorityDumper::PRIORITY_ARG_CRITICAL); AssertDumped("runningcritical2", "dump2"); AssertDumpedWithPriority("runningcritical2", "dump2", PriorityDumper::PRIORITY_ARG_CRITICAL); } } // Tests 'dumpsys --priority HIGH' // Tests 'dumpsys --priority HIGH' TEST_F(DumpsysTest, DumpWithPriorityHigh) { TEST_F(DumpsysTest, DumpWithPriorityHigh) { ExpectListServicesWithPriority({"runninghigh1", "runninghigh2"}, ExpectListServicesWithPriority({"runninghigh1", "runninghigh2"}, IServiceManager::DUMP_PRIORITY_HIGH); IServiceManager::DUMP_FLAG_PRIORITY_HIGH); ExpectDump("runninghigh1", "dump1"); ExpectDump("runninghigh1", "dump1"); ExpectDump("runninghigh2", "dump2"); ExpectDump("runninghigh2", "dump2"); CallMain({"--priority", "HIGH"}); CallMain({"--priority", "HIGH"}); AssertRunningServices({"runninghigh1", "runninghigh2"}); AssertRunningServices({"runninghigh1", "runninghigh2"}); AssertDumped("runninghigh1", "dump1"); AssertDumpedWithPriority("runninghigh1", "dump1", PriorityDumper::PRIORITY_ARG_HIGH); AssertDumped("runninghigh2", "dump2"); AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH); } } // Tests 'dumpsys --priority NORMAL' // Tests 'dumpsys --priority NORMAL' TEST_F(DumpsysTest, DumpWithPriorityNormal) { TEST_F(DumpsysTest, DumpWithPriorityNormal) { ExpectListServicesWithPriority({"runningnormal1", "runningnormal2"}, ExpectListServicesWithPriority({"runningnormal1", "runningnormal2"}, IServiceManager::DUMP_PRIORITY_NORMAL); IServiceManager::DUMP_FLAG_PRIORITY_NORMAL); ExpectDump("runningnormal1", "dump1"); ExpectDump("runningnormal1", "dump1"); ExpectDump("runningnormal2", "dump2"); ExpectDump("runningnormal2", "dump2"); CallMain({"--priority", "NORMAL"}); CallMain({"--priority", "NORMAL"}); AssertRunningServices({"runningnormal1", "runningnormal2"}); AssertRunningServices({"runningnormal1", "runningnormal2"}); AssertDumped("runningnormal1", "dump1"); AssertDumpedWithPriority("runningnormal1", "dump1", PriorityDumper::PRIORITY_ARG_NORMAL); AssertDumped("runningnormal2", "dump2"); 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); } } libs/binder/include/binder/BinderService.h +6 −5 Original line number Original line Diff line number Diff line Loading @@ -35,15 +35,16 @@ class BinderService { { public: public: static status_t publish(bool allowIsolated = false, static status_t publish(bool allowIsolated = false, int dumpPriority = IServiceManager::DUMP_PRIORITY_NORMAL) { int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_NORMAL) { sp<IServiceManager> sm(defaultServiceManager()); sp<IServiceManager> sm(defaultServiceManager()); return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated, return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated, dumpPriority); dumpFlags); } } static void publishAndJoinThreadPool(bool allowIsolated = false, static void publishAndJoinThreadPool( int dumpPriority = IServiceManager::DUMP_PRIORITY_NORMAL) { bool allowIsolated = false, publish(allowIsolated, dumpPriority); int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_NORMAL) { publish(allowIsolated, dumpFlags); joinThreadPool(); joinThreadPool(); } } Loading libs/binder/include/binder/IServiceManager.h +8 −7 Original line number Original line Diff line number Diff line Loading @@ -34,11 +34,12 @@ public: /* /* * Must match values in IServiceManager.java * Must match values in IServiceManager.java */ */ static const int DUMP_PRIORITY_CRITICAL = 1 << 0; static const int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0; static const int DUMP_PRIORITY_HIGH = 1 << 1; static const int DUMP_FLAG_PRIORITY_HIGH = 1 << 1; static const int DUMP_PRIORITY_NORMAL = 1 << 2; static const int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2; static const int DUMP_PRIORITY_ALL = static const int DUMP_FLAG_PRIORITY_ALL = DUMP_PRIORITY_CRITICAL | DUMP_PRIORITY_HIGH | DUMP_PRIORITY_NORMAL; 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 * Retrieve an existing service, blocking for a few seconds Loading @@ -56,12 +57,12 @@ public: */ */ virtual status_t addService(const String16& name, const sp<IBinder>& service, virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated = false, bool allowIsolated = false, int dumpsysPriority = DUMP_PRIORITY_NORMAL) = 0; int dumpsysFlags = DUMP_FLAG_PRIORITY_NORMAL) = 0; /** /** * Return list of all existing services. * 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 { enum { GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, Loading Loading
cmds/dumpsys/dumpsys.cpp +29 −13 Original line number Original line Diff line number Diff line Loading @@ -62,6 +62,8 @@ static void usage() { " --help: shows this help\n" " --help: shows this help\n" " -l: only list services, do not dump them\n" " -l: only list services, do not dump them\n" " -t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds\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" " --priority LEVEL: filter services based on specified priority\n" " LEVEL must be one of CRITICAL | HIGH | NORMAL\n" " LEVEL must be one of CRITICAL | HIGH | NORMAL\n" " --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n" " --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n" Loading @@ -77,17 +79,17 @@ static bool IsSkipped(const Vector<String16>& skipped, const String16& service) return false; return false; } } static bool ConvertPriorityTypeToBitmask(String16& type, int& bitmask) { static bool ConvertPriorityTypeToBitmask(const String16& type, int& bitmask) { if (type == PRIORITY_ARG_CRITICAL) { if (type == PriorityDumper::PRIORITY_ARG_CRITICAL) { bitmask = IServiceManager::DUMP_PRIORITY_CRITICAL; bitmask = IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL; return true; return true; } } if (type == PRIORITY_ARG_HIGH) { if (type == PriorityDumper::PRIORITY_ARG_HIGH) { bitmask = IServiceManager::DUMP_PRIORITY_HIGH; bitmask = IServiceManager::DUMP_FLAG_PRIORITY_HIGH; return true; return true; } } if (type == PRIORITY_ARG_NORMAL) { if (type == PriorityDumper::PRIORITY_ARG_NORMAL) { bitmask = IServiceManager::DUMP_PRIORITY_NORMAL; bitmask = IServiceManager::DUMP_FLAG_PRIORITY_NORMAL; return true; return true; } } return false; return false; Loading @@ -98,11 +100,14 @@ int Dumpsys::main(int argc, char* const argv[]) { Vector<String16> args; Vector<String16> args; String16 priorityType; String16 priorityType; Vector<String16> skippedServices; Vector<String16> skippedServices; Vector<String16> protoServices; bool showListOnly = false; bool showListOnly = false; bool skipServices = false; bool skipServices = false; bool filterByProto = false; int timeoutArg = 10; 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}, static struct option longOptions[] = {{"priority", required_argument, 0, 0}, {"proto", no_argument, 0, 0}, {"skip", no_argument, 0, 0}, {"skip", no_argument, 0, 0}, {"help", no_argument, 0, 0}, {"help", no_argument, 0, 0}, {0, 0, 0, 0}}; {0, 0, 0, 0}}; Loading @@ -124,12 +129,14 @@ int Dumpsys::main(int argc, char* const argv[]) { case 0: case 0: if (!strcmp(longOptions[optionIndex].name, "skip")) { if (!strcmp(longOptions[optionIndex].name, "skip")) { skipServices = true; skipServices = true; } else if (!strcmp(longOptions[optionIndex].name, "proto")) { filterByProto = true; } else if (!strcmp(longOptions[optionIndex].name, "help")) { } else if (!strcmp(longOptions[optionIndex].name, "help")) { usage(); usage(); return 0; return 0; } else if (!strcmp(longOptions[optionIndex].name, "priority")) { } else if (!strcmp(longOptions[optionIndex].name, "priority")) { priorityType = String16(String8(optarg)); priorityType = String16(String8(optarg)); if (!ConvertPriorityTypeToBitmask(priorityType, dumpPriority)) { if (!ConvertPriorityTypeToBitmask(priorityType, dumpPriorityFlags)) { fprintf(stderr, "\n"); fprintf(stderr, "\n"); usage(); usage(); return -1; return -1; Loading Loading @@ -179,10 +186,19 @@ int Dumpsys::main(int argc, char* const argv[]) { if (services.empty() || showListOnly) { if (services.empty() || showListOnly) { // gets all services // gets all services services = sm_->listServices(dumpPriority); services = sm_->listServices(dumpPriorityFlags); services.sort(sort_func); services.sort(sort_func); if (dumpPriority != IServiceManager::DUMP_PRIORITY_ALL) { if (filterByProto) { args.insertAt(String16(PRIORITY_ARG), 0); 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); args.insertAt(priorityType, 1); } else { } else { args.add(String16("-a")); args.add(String16("-a")); Loading Loading @@ -230,7 +246,7 @@ int Dumpsys::main(int argc, char* const argv[]) { if (N > 1) { if (N > 1) { aout << "------------------------------------------------------------" aout << "------------------------------------------------------------" "-------------------" << endl; "-------------------" << endl; if (dumpPriority == IServiceManager::DUMP_PRIORITY_ALL) { if (dumpPriorityFlags == IServiceManager::DUMP_FLAG_PRIORITY_ALL) { aout << "DUMP OF SERVICE " << service_name << ":" << endl; aout << "DUMP OF SERVICE " << service_name << ":" << endl; } else { } else { aout << "DUMP OF SERVICE " << priorityType << " " << service_name << ":" << endl; aout << "DUMP OF SERVICE " << priorityType << " " << service_name << ":" << endl; Loading
cmds/dumpsys/tests/Android.bp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -15,6 +15,7 @@ cc_test { static_libs: [ static_libs: [ "libdumpsys", "libdumpsys", "libgmock", "libgmock", "libserviceutils", ], ], clang: true, clang: true, Loading
cmds/dumpsys/tests/dumpsys_test.cpp +71 −17 Original line number Original line Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <gtest/gtest.h> #include <gtest/gtest.h> #include <android-base/file.h> #include <android-base/file.h> #include <serviceutils/PriorityDumper.h> #include <utils/String16.h> #include <utils/String16.h> #include <utils/String8.h> #include <utils/String8.h> #include <utils/Vector.h> #include <utils/Vector.h> Loading Loading @@ -131,16 +132,16 @@ class DumpsysTest : public Test { for (auto& service : services) { for (auto& service : services) { services16.add(String16(service.c_str())); 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)); .WillRepeatedly(Return(services16)); } } void ExpectListServicesWithPriority(std::vector<std::string> services, int dumpPriority) { void ExpectListServicesWithPriority(std::vector<std::string> services, int dumpFlags) { Vector<String16> services16; Vector<String16> services16; for (auto& service : services) { for (auto& service : services) { services16.add(String16(service.c_str())); 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) { sp<BinderMock> ExpectCheckService(const char* name, bool running = true) { Loading Loading @@ -210,6 +211,13 @@ class DumpsysTest : public Test { EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + service + ":\n" + dump)); 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) { void AssertNotDumped(const std::string& dump) { EXPECT_THAT(stdout_, Not(HasSubstr(dump))); EXPECT_THAT(stdout_, Not(HasSubstr(dump))); } } Loading Loading @@ -250,7 +258,7 @@ TEST_F(DumpsysTest, ListRunningServices) { // Tests 'dumpsys -l --priority HIGH' // Tests 'dumpsys -l --priority HIGH' TEST_F(DumpsysTest, ListAllServicesWithPriority) { TEST_F(DumpsysTest, ListAllServicesWithPriority) { ExpectListServicesWithPriority({"Locksmith", "Valet"}, IServiceManager::DUMP_PRIORITY_HIGH); ExpectListServicesWithPriority({"Locksmith", "Valet"}, IServiceManager::DUMP_FLAG_PRIORITY_HIGH); ExpectCheckService("Locksmith"); ExpectCheckService("Locksmith"); ExpectCheckService("Valet"); ExpectCheckService("Valet"); Loading @@ -261,13 +269,26 @@ TEST_F(DumpsysTest, ListAllServicesWithPriority) { // Tests 'dumpsys -l --priority HIGH' with and empty list // Tests 'dumpsys -l --priority HIGH' with and empty list TEST_F(DumpsysTest, ListEmptyServicesWithPriority) { TEST_F(DumpsysTest, ListEmptyServicesWithPriority) { ExpectListServicesWithPriority({}, IServiceManager::DUMP_PRIORITY_HIGH); ExpectListServicesWithPriority({}, IServiceManager::DUMP_FLAG_PRIORITY_HIGH); CallMain({"-l", "--priority", "HIGH"}); CallMain({"-l", "--priority", "HIGH"}); AssertRunningServices({}); 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 // Tests 'dumpsys service_name' on a service is running TEST_F(DumpsysTest, DumpRunningService) { TEST_F(DumpsysTest, DumpRunningService) { ExpectDump("Valet", "Here's your car"); ExpectDump("Valet", "Here's your car"); Loading Loading @@ -336,7 +357,7 @@ TEST_F(DumpsysTest, DumpWithSkip) { // Tests 'dumpsys --skip skipped3 skipped5 --priority CRITICAL', which should skip these services // Tests 'dumpsys --skip skipped3 skipped5 --priority CRITICAL', which should skip these services TEST_F(DumpsysTest, DumpWithSkipAndPriority) { TEST_F(DumpsysTest, DumpWithSkipAndPriority) { ExpectListServicesWithPriority({"running1", "stopped2", "skipped3", "running4", "skipped5"}, ExpectListServicesWithPriority({"running1", "stopped2", "skipped3", "running4", "skipped5"}, IServiceManager::DUMP_PRIORITY_CRITICAL); IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL); ExpectDump("running1", "dump1"); ExpectDump("running1", "dump1"); ExpectCheckService("stopped2", false); ExpectCheckService("stopped2", false); ExpectDump("skipped3", "dump3"); ExpectDump("skipped3", "dump3"); Loading @@ -346,8 +367,8 @@ TEST_F(DumpsysTest, DumpWithSkipAndPriority) { CallMain({"--priority", "CRITICAL", "--skip", "skipped3", "skipped5"}); CallMain({"--priority", "CRITICAL", "--skip", "skipped3", "skipped5"}); AssertRunningServices({"running1", "running4", "skipped3 (skipped)", "skipped5 (skipped)"}); AssertRunningServices({"running1", "running4", "skipped3 (skipped)", "skipped5 (skipped)"}); AssertDumped("running1", "dump1"); AssertDumpedWithPriority("running1", "dump1", PriorityDumper::PRIORITY_ARG_CRITICAL); AssertDumped("running4", "dump4"); AssertDumpedWithPriority("running4", "dump4", PriorityDumper::PRIORITY_ARG_CRITICAL); AssertStopped("stopped2"); AssertStopped("stopped2"); AssertNotDumped("dump3"); AssertNotDumped("dump3"); AssertNotDumped("dump5"); AssertNotDumped("dump5"); Loading @@ -356,41 +377,74 @@ TEST_F(DumpsysTest, DumpWithSkipAndPriority) { // Tests 'dumpsys --priority CRITICAL' // Tests 'dumpsys --priority CRITICAL' TEST_F(DumpsysTest, DumpWithPriorityCritical) { TEST_F(DumpsysTest, DumpWithPriorityCritical) { ExpectListServicesWithPriority({"runningcritical1", "runningcritical2"}, ExpectListServicesWithPriority({"runningcritical1", "runningcritical2"}, IServiceManager::DUMP_PRIORITY_CRITICAL); IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL); ExpectDump("runningcritical1", "dump1"); ExpectDump("runningcritical1", "dump1"); ExpectDump("runningcritical2", "dump2"); ExpectDump("runningcritical2", "dump2"); CallMain({"--priority", "CRITICAL"}); CallMain({"--priority", "CRITICAL"}); AssertRunningServices({"runningcritical1", "runningcritical2"}); AssertRunningServices({"runningcritical1", "runningcritical2"}); AssertDumped("runningcritical1", "dump1"); AssertDumpedWithPriority("runningcritical1", "dump1", PriorityDumper::PRIORITY_ARG_CRITICAL); AssertDumped("runningcritical2", "dump2"); AssertDumpedWithPriority("runningcritical2", "dump2", PriorityDumper::PRIORITY_ARG_CRITICAL); } } // Tests 'dumpsys --priority HIGH' // Tests 'dumpsys --priority HIGH' TEST_F(DumpsysTest, DumpWithPriorityHigh) { TEST_F(DumpsysTest, DumpWithPriorityHigh) { ExpectListServicesWithPriority({"runninghigh1", "runninghigh2"}, ExpectListServicesWithPriority({"runninghigh1", "runninghigh2"}, IServiceManager::DUMP_PRIORITY_HIGH); IServiceManager::DUMP_FLAG_PRIORITY_HIGH); ExpectDump("runninghigh1", "dump1"); ExpectDump("runninghigh1", "dump1"); ExpectDump("runninghigh2", "dump2"); ExpectDump("runninghigh2", "dump2"); CallMain({"--priority", "HIGH"}); CallMain({"--priority", "HIGH"}); AssertRunningServices({"runninghigh1", "runninghigh2"}); AssertRunningServices({"runninghigh1", "runninghigh2"}); AssertDumped("runninghigh1", "dump1"); AssertDumpedWithPriority("runninghigh1", "dump1", PriorityDumper::PRIORITY_ARG_HIGH); AssertDumped("runninghigh2", "dump2"); AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH); } } // Tests 'dumpsys --priority NORMAL' // Tests 'dumpsys --priority NORMAL' TEST_F(DumpsysTest, DumpWithPriorityNormal) { TEST_F(DumpsysTest, DumpWithPriorityNormal) { ExpectListServicesWithPriority({"runningnormal1", "runningnormal2"}, ExpectListServicesWithPriority({"runningnormal1", "runningnormal2"}, IServiceManager::DUMP_PRIORITY_NORMAL); IServiceManager::DUMP_FLAG_PRIORITY_NORMAL); ExpectDump("runningnormal1", "dump1"); ExpectDump("runningnormal1", "dump1"); ExpectDump("runningnormal2", "dump2"); ExpectDump("runningnormal2", "dump2"); CallMain({"--priority", "NORMAL"}); CallMain({"--priority", "NORMAL"}); AssertRunningServices({"runningnormal1", "runningnormal2"}); AssertRunningServices({"runningnormal1", "runningnormal2"}); AssertDumped("runningnormal1", "dump1"); AssertDumpedWithPriority("runningnormal1", "dump1", PriorityDumper::PRIORITY_ARG_NORMAL); AssertDumped("runningnormal2", "dump2"); 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); } }
libs/binder/include/binder/BinderService.h +6 −5 Original line number Original line Diff line number Diff line Loading @@ -35,15 +35,16 @@ class BinderService { { public: public: static status_t publish(bool allowIsolated = false, static status_t publish(bool allowIsolated = false, int dumpPriority = IServiceManager::DUMP_PRIORITY_NORMAL) { int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_NORMAL) { sp<IServiceManager> sm(defaultServiceManager()); sp<IServiceManager> sm(defaultServiceManager()); return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated, return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated, dumpPriority); dumpFlags); } } static void publishAndJoinThreadPool(bool allowIsolated = false, static void publishAndJoinThreadPool( int dumpPriority = IServiceManager::DUMP_PRIORITY_NORMAL) { bool allowIsolated = false, publish(allowIsolated, dumpPriority); int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_NORMAL) { publish(allowIsolated, dumpFlags); joinThreadPool(); joinThreadPool(); } } Loading
libs/binder/include/binder/IServiceManager.h +8 −7 Original line number Original line Diff line number Diff line Loading @@ -34,11 +34,12 @@ public: /* /* * Must match values in IServiceManager.java * Must match values in IServiceManager.java */ */ static const int DUMP_PRIORITY_CRITICAL = 1 << 0; static const int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0; static const int DUMP_PRIORITY_HIGH = 1 << 1; static const int DUMP_FLAG_PRIORITY_HIGH = 1 << 1; static const int DUMP_PRIORITY_NORMAL = 1 << 2; static const int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2; static const int DUMP_PRIORITY_ALL = static const int DUMP_FLAG_PRIORITY_ALL = DUMP_PRIORITY_CRITICAL | DUMP_PRIORITY_HIGH | DUMP_PRIORITY_NORMAL; 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 * Retrieve an existing service, blocking for a few seconds Loading @@ -56,12 +57,12 @@ public: */ */ virtual status_t addService(const String16& name, const sp<IBinder>& service, virtual status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated = false, bool allowIsolated = false, int dumpsysPriority = DUMP_PRIORITY_NORMAL) = 0; int dumpsysFlags = DUMP_FLAG_PRIORITY_NORMAL) = 0; /** /** * Return list of all existing services. * 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 { enum { GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION, Loading