servicedispatcher: allow to use getService.
If the client wants to call getService() instead
of checkService(), allow them to do that.
Test: manual
Bug: 190233850
Change-Id: I53da0d942870261897cb65f7f474eb13422d3afd
diff --git a/libs/binder/servicedispatcher.cpp b/libs/binder/servicedispatcher.cpp
index 9aa60e6..76cf210 100644
--- a/libs/binder/servicedispatcher.cpp
+++ b/libs/binder/servicedispatcher.cpp
@@ -44,15 +44,20 @@
using std::string_view_literals::operator""sv;
namespace {
+
+using ServiceRetriever = decltype(&android::IServiceManager::checkService);
+
int Usage(const char* program) {
auto basename = Basename(program);
auto format = R"(dispatch calls to RPC service.
Usage:
- %s <service_name>
+ %s [-g] <service_name>
<service_name>: the service to connect to.
- %s manager
+ %s [-g] manager
Runs an RPC-friendly service that redirects calls to servicemanager.
+ -g: use getService() instead of checkService().
+
If successful, writes port number and a new line character to stdout, and
blocks until killed.
Otherwise, writes error message to stderr and exits with non-zero code.
@@ -61,13 +66,13 @@
return EX_USAGE;
}
-int Dispatch(const char* name) {
+int Dispatch(const char* name, const ServiceRetriever& serviceRetriever) {
auto sm = defaultServiceManager();
if (nullptr == sm) {
LOG(ERROR) << "No servicemanager";
return EX_SOFTWARE;
}
- auto binder = sm->checkService(String16(name));
+ auto binder = std::invoke(serviceRetriever, defaultServiceManager(), String16(name));
if (nullptr == binder) {
LOG(ERROR) << "No service \"" << name << "\"";
return EX_SOFTWARE;
@@ -162,13 +167,13 @@
// Workaround for b/191059588.
// TODO(b/191059588): Once we can run RpcServer on single-threaded services,
// `servicedispatcher manager` should call Dispatch("manager") directly.
-int wrapServiceManager() {
+int wrapServiceManager(const ServiceRetriever& serviceRetriever) {
auto sm = defaultServiceManager();
if (nullptr == sm) {
LOG(ERROR) << "No servicemanager";
return EX_SOFTWARE;
}
- auto service = sm->checkService(String16("manager"));
+ auto service = std::invoke(serviceRetriever, defaultServiceManager(), String16("manager"));
if (nullptr == service) {
LOG(ERROR) << "No service called `manager`";
return EX_SOFTWARE;
@@ -227,8 +232,12 @@
LOG(WARNING) << "WARNING: servicedispatcher is debug only. Use with caution.";
int opt;
- while (-1 != (opt = getopt(argc, argv, ""))) {
+ ServiceRetriever serviceRetriever = &android::IServiceManager::checkService;
+ while (-1 != (opt = getopt(argc, argv, "g"))) {
switch (opt) {
+ case 'g': {
+ serviceRetriever = &android::IServiceManager::getService;
+ } break;
default: {
return Usage(argv[0]);
}
@@ -239,7 +248,7 @@
auto name = argv[optind];
if (name == "manager"sv) {
- return wrapServiceManager();
+ return wrapServiceManager(serviceRetriever);
}
- return Dispatch(name);
+ return Dispatch(name, serviceRetriever);
}