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 Original line Diff line number Diff line
@@ -56,10 +56,13 @@ static void usage() {
            "usage: dumpsys\n"
            "usage: dumpsys\n"
            "         To dump all services.\n"
            "         To dump all services.\n"
            "or:\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"
            "         --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"
            "         --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"
            "         --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
            "         SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\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 showListOnly = false;
    bool skipServices = false;
    bool skipServices = false;
    int timeoutArg = 10;
    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},
                                          {"skip", no_argument, 0, 0},
                                          {"help", 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
    // Must reset optind, otherwise subsequent calls will fail (wouldn't happen on main.cpp, but
    // happens on test cases).
    // happens on test cases).
@@ -106,6 +109,18 @@ int Dumpsys::main(int argc, char* const argv[]) {
            } 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")) {
                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;
            break;


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


  protected:
  protected:
    MOCK_METHOD0(onAsBinder, IBinder*());
    MOCK_METHOD0(onAsBinder, IBinder*());
@@ -131,7 +131,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()).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) {
    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) {
    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) {
        for (const std::string& service : services) {
            expected.append("  ").append(service).append("\n");
            expected.append("  ").append(service).append("\n");
        }
        }
@@ -236,6 +248,26 @@ TEST_F(DumpsysTest, ListRunningServices) {
    AssertNotDumped({"Valet"});
    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
// 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");
@@ -300,3 +332,65 @@ TEST_F(DumpsysTest, DumpWithSkip) {
    AssertNotDumped("dump3");
    AssertNotDumped("dump3");
    AssertNotDumped("dump5");
    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 Original line Diff line number Diff line
@@ -138,6 +138,7 @@ struct svcinfo
    uint32_t handle;
    uint32_t handle;
    struct binder_death death;
    struct binder_death death;
    int allow_isolated;
    int allow_isolated;
    uint32_t dumpsys_priority;
    size_t len;
    size_t len;
    uint16_t name[0];
    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;
    return si->handle;
}
}


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


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


    //ALOGI("target=%p code=%d pid=%d uid=%d\n",
    //ALOGI("target=%p code=%d pid=%d uid=%d\n",
    //      (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);
    //      (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);
        handle = bio_get_ref(msg);
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        if (do_add_service(bs, s, len, handle, txn->sender_euid,
        dumpsys_priority = bio_get_uint32(msg);
            allow_isolated, txn->sender_pid))
        if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,
                           txn->sender_pid))
            return -1;
            return -1;
        break;
        break;


    case SVC_MGR_LIST_SERVICES: {
    case SVC_MGR_LIST_SERVICES: {
        uint32_t n = bio_get_uint32(msg);
        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)) {
        if (!svc_can_list(txn->sender_pid, txn->sender_euid)) {
            ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
            ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
@@ -331,8 +333,15 @@ int svcmgr_handler(struct binder_state *bs,
            return -1;
            return -1;
        }
        }
        si = svclist;
        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;
            si = si->next;
        }
        if (si) {
        if (si) {
            bio_put_string16(reply, si->name);
            bio_put_string16(reply, si->name);
            return 0;
            return 0;
+4 −4
Original line number Original line Diff line number Diff line
@@ -161,19 +161,18 @@ 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)
                                bool allowIsolated, int dumpsysPriority) {
    {
        Parcel data, reply;
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        data.writeString16(name);
        data.writeStrongBinder(service);
        data.writeStrongBinder(service);
        data.writeInt32(allowIsolated ? 1 : 0);
        data.writeInt32(allowIsolated ? 1 : 0);
        data.writeInt32(dumpsysPriority);
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
        return err == NO_ERROR ? reply.readExceptionCode() : err;
        return err == NO_ERROR ? reply.readExceptionCode() : err;
    }
    }


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


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


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


Loading