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

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

Merge "Pass dumpsys priority to IServiceManager"

parents 6679f368 f56042d6
Loading
Loading
Loading
Loading
+23 −8
Original line number Diff line number Diff line
@@ -56,10 +56,13 @@ static void usage() {
            "usage: dumpsys\n"
            "         To dump all services.\n"
            "or:\n"
            "       dumpsys [-t TIMEOUT] [--help | -l | --skip SERVICES | SERVICE [ARGS]]\n"
            "       dumpsys [-t TIMEOUT] [--priority LEVEL] [--help | -l | --skip SERVICES | "
            "SERVICE [ARGS]]\n"
            "         --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"
            "         --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"
            "         SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n");
}
@@ -80,11 +83,11 @@ int Dumpsys::main(int argc, char* const argv[]) {
    bool showListOnly = false;
    bool skipServices = false;
    int timeoutArg = 10;
    static struct option longOptions[] = {
    int dumpPriority = IServiceManager::DUMP_PRIORITY_ALL;
    static struct option longOptions[] = {{"priority", required_argument, 0, 0},
                                          {"skip", no_argument, 0, 0},
                                          {"help", no_argument, 0, 0},
        {     0,           0, 0,  0 }
    };
                                          {0, 0, 0, 0}};

    // Must reset optind, otherwise subsequent calls will fail (wouldn't happen on main.cpp, but
    // happens on test cases).
@@ -106,6 +109,18 @@ int Dumpsys::main(int argc, char* const argv[]) {
            } else if (!strcmp(longOptions[optionIndex].name, "help")) {
                usage();
                return 0;
            } else if (!strcmp(longOptions[optionIndex].name, "priority")) {
                if (!strcmp(optarg, "CRITICAL")) {
                    dumpPriority = IServiceManager::DUMP_PRIORITY_CRITICAL;
                } else if (!strcmp(optarg, "HIGH")) {
                    dumpPriority = IServiceManager::DUMP_PRIORITY_HIGH;
                } else if (!strcmp(optarg, "NORMAL")) {
                    dumpPriority = IServiceManager::DUMP_PRIORITY_NORMAL;
                } else {
                    fprintf(stderr, "\n");
                    usage();
                    return -1;
                }
            }
            break;

@@ -151,7 +166,7 @@ int Dumpsys::main(int argc, char* const argv[]) {

    if (services.empty() || showListOnly) {
        // gets all services
        services = sm_->listServices();
        services = sm_->listServices(dumpPriority);
        services.sort(sort_func);
        args.add(String16("-a"));
    }
+98 −4
Original line number Diff line number Diff line
@@ -50,8 +50,8 @@ class ServiceManagerMock : public IServiceManager {
  public:
    MOCK_CONST_METHOD1(getService, sp<IBinder>(const String16&));
    MOCK_CONST_METHOD1(checkService, sp<IBinder>(const String16&));
    MOCK_METHOD3(addService, status_t(const String16&, const sp<IBinder>&, bool));
    MOCK_METHOD0(listServices, Vector<String16>());
    MOCK_METHOD4(addService, status_t(const String16&, const sp<IBinder>&, bool, int));
    MOCK_METHOD1(listServices, Vector<String16>(int));

  protected:
    MOCK_METHOD0(onAsBinder, IBinder*());
@@ -131,7 +131,16 @@ class DumpsysTest : public Test {
        for (auto& service : services) {
            services16.add(String16(service.c_str()));
        }
        EXPECT_CALL(sm_, listServices()).WillRepeatedly(Return(services16));
        EXPECT_CALL(sm_, listServices(IServiceManager::DUMP_PRIORITY_ALL))
            .WillRepeatedly(Return(services16));
    }

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

    sp<BinderMock> ExpectCheckService(const char* name, bool running = true) {
@@ -179,7 +188,10 @@ class DumpsysTest : public Test {
    }

    void AssertRunningServices(const std::vector<std::string>& services) {
        std::string expected("Currently running services:\n");
        std::string expected;
        if (services.size() > 1) {
            expected.append("Currently running services:\n");
        }
        for (const std::string& service : services) {
            expected.append("  ").append(service).append("\n");
        }
@@ -236,6 +248,26 @@ TEST_F(DumpsysTest, ListRunningServices) {
    AssertNotDumped({"Valet"});
}

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

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

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

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

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

    AssertRunningServices({});
}

// Tests 'dumpsys service_name' on a service is running
TEST_F(DumpsysTest, DumpRunningService) {
    ExpectDump("Valet", "Here's your car");
@@ -300,3 +332,65 @@ TEST_F(DumpsysTest, DumpWithSkip) {
    AssertNotDumped("dump3");
    AssertNotDumped("dump5");
}

// 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);
    ExpectDump("running1", "dump1");
    ExpectCheckService("stopped2", false);
    ExpectDump("skipped3", "dump3");
    ExpectDump("running4", "dump4");
    ExpectDump("skipped5", "dump5");

    CallMain({"--priority", "CRITICAL", "--skip", "skipped3", "skipped5"});

    AssertRunningServices({"running1", "running4", "skipped3 (skipped)", "skipped5 (skipped)"});
    AssertDumped("running1", "dump1");
    AssertDumped("running4", "dump4");
    AssertStopped("stopped2");
    AssertNotDumped("dump3");
    AssertNotDumped("dump5");
}

// Tests 'dumpsys --priority CRITICAL'
TEST_F(DumpsysTest, DumpWithPriorityCritical) {
    ExpectListServicesWithPriority({"runningcritical1", "runningcritical2"},
                                   IServiceManager::DUMP_PRIORITY_CRITICAL);
    ExpectDump("runningcritical1", "dump1");
    ExpectDump("runningcritical2", "dump2");

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

    AssertRunningServices({"runningcritical1", "runningcritical2"});
    AssertDumped("runningcritical1", "dump1");
    AssertDumped("runningcritical2", "dump2");
}

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

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

    AssertRunningServices({"runninghigh1", "runninghigh2"});
    AssertDumped("runninghigh1", "dump1");
    AssertDumped("runninghigh2", "dump2");
}

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

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

    AssertRunningServices({"runningnormal1", "runningnormal2"});
    AssertDumped("runningnormal1", "dump1");
    AssertDumped("runningnormal2", "dump2");
}
+17 −8
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ struct svcinfo
    uint32_t handle;
    struct binder_death death;
    int allow_isolated;
    uint32_t dumpsys_priority;
    size_t len;
    uint16_t name[0];
};
@@ -198,11 +199,8 @@ uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid)
    return si->handle;
}

int do_add_service(struct binder_state *bs,
                   const uint16_t *s, size_t len,
                   uint32_t handle, uid_t uid, int allow_isolated,
                   pid_t spid)
{
int do_add_service(struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle,
                   uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid) {
    struct svcinfo *si;

    //ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle,
@@ -239,6 +237,7 @@ int do_add_service(struct binder_state *bs,
        si->death.func = (void*) svcinfo_death;
        si->death.ptr = si;
        si->allow_isolated = allow_isolated;
        si->dumpsys_priority = dumpsys_priority;
        si->next = svclist;
        svclist = si;
    }
@@ -259,6 +258,7 @@ int svcmgr_handler(struct binder_state *bs,
    uint32_t handle;
    uint32_t strict_policy;
    int allow_isolated;
    uint32_t dumpsys_priority;

    //ALOGI("target=%p code=%d pid=%d uid=%d\n",
    //      (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);
@@ -317,13 +317,15 @@ int svcmgr_handler(struct binder_state *bs,
        }
        handle = bio_get_ref(msg);
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        if (do_add_service(bs, s, len, handle, txn->sender_euid,
            allow_isolated, txn->sender_pid))
        dumpsys_priority = bio_get_uint32(msg);
        if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,
                           txn->sender_pid))
            return -1;
        break;

    case SVC_MGR_LIST_SERVICES: {
        uint32_t n = bio_get_uint32(msg);
        uint32_t req_dumpsys_priority = bio_get_uint32(msg);

        if (!svc_can_list(txn->sender_pid, txn->sender_euid)) {
            ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
@@ -331,8 +333,15 @@ int svcmgr_handler(struct binder_state *bs,
            return -1;
        }
        si = svclist;
        while ((n-- > 0) && si)
        // walk through the list of services n times skipping services that
        // do not support the requested priority
        while (si) {
            if (si->dumpsys_priority & req_dumpsys_priority) {
                if (n == 0) break;
                n--;
            }
            si = si->next;
        }
        if (si) {
            bio_put_string16(reply, si->name);
            return 0;
+4 −4
Original line number Diff line number Diff line
@@ -161,19 +161,18 @@ public:
    }

    virtual status_t addService(const String16& name, const sp<IBinder>& service,
            bool allowIsolated)
    {
                                bool allowIsolated, int dumpsysPriority) {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        data.writeStrongBinder(service);
        data.writeInt32(allowIsolated ? 1 : 0);
        data.writeInt32(dumpsysPriority);
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
        return err == NO_ERROR ? reply.readExceptionCode() : err;
    }

    virtual Vector<String16> listServices()
    {
    virtual Vector<String16> listServices(int dumpsysPriority) {
        Vector<String16> res;
        int n = 0;

@@ -181,6 +180,7 @@ public:
            Parcel data, reply;
            data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
            data.writeInt32(n++);
            data.writeInt32(dumpsysPriority);
            status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply);
            if (err != NO_ERROR)
                break;
+7 −6
Original line number Diff line number Diff line
@@ -34,15 +34,16 @@ template<typename SERVICE>
class BinderService
{
public:
    static status_t publish(bool allowIsolated = false) {
    static status_t publish(bool allowIsolated = false,
                            int dumpPriority = IServiceManager::DUMP_PRIORITY_NORMAL) {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(
                String16(SERVICE::getServiceName()),
                new SERVICE(), allowIsolated);
        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,
                              dumpPriority);
    }

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

Loading