Skip to content

Commit a3867c7

Browse files
Add listServices/isDeclared/getDeclaredInstances for Accessors
We associate specific accessors with instance names, so we can get more information about what is available through the existing service manager APIs. Test: atest binderRpcTest Bug: 358427181 Change-Id: I337430a222b537643351bfc70178ccd1dc06d73b
1 parent 3c93111 commit a3867c7

4 files changed

Lines changed: 164 additions & 9 deletions

File tree

libs/binder/BackendUnifiedServiceManager.cpp

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
#include "BackendUnifiedServiceManager.h"
1717

18+
#include <android-base/strings.h>
1819
#include <android/os/IAccessor.h>
1920
#include <android/os/IServiceManager.h>
2021
#include <binder/RpcSession.h>
@@ -339,11 +340,15 @@ Status BackendUnifiedServiceManager::addService(const ::std::string& name,
339340
}
340341
Status BackendUnifiedServiceManager::listServices(int32_t dumpPriority,
341342
::std::vector<::std::string>* _aidl_return) {
343+
Status status = Status::ok();
342344
if (mTheRealServiceManager) {
343-
return mTheRealServiceManager->listServices(dumpPriority, _aidl_return);
345+
status = mTheRealServiceManager->listServices(dumpPriority, _aidl_return);
344346
}
345-
return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
346-
kUnsupportedOpNoServiceManager);
347+
if (!status.isOk()) return status;
348+
349+
appendInjectedAccessorServices(_aidl_return);
350+
351+
return status;
347352
}
348353
Status BackendUnifiedServiceManager::registerForNotifications(
349354
const ::std::string& name, const sp<os::IServiceCallback>& callback) {
@@ -362,19 +367,43 @@ Status BackendUnifiedServiceManager::unregisterForNotifications(
362367
kUnsupportedOpNoServiceManager);
363368
}
364369
Status BackendUnifiedServiceManager::isDeclared(const ::std::string& name, bool* _aidl_return) {
370+
Status status = Status::ok();
365371
if (mTheRealServiceManager) {
366-
return mTheRealServiceManager->isDeclared(name, _aidl_return);
372+
status = mTheRealServiceManager->isDeclared(name, _aidl_return);
367373
}
368-
return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
369-
kUnsupportedOpNoServiceManager);
374+
if (!status.isOk()) return status;
375+
376+
if (!*_aidl_return) {
377+
forEachInjectedAccessorService([&](const std::string& instance) {
378+
if (name == instance) {
379+
*_aidl_return = true;
380+
}
381+
});
382+
}
383+
384+
return status;
370385
}
371386
Status BackendUnifiedServiceManager::getDeclaredInstances(
372387
const ::std::string& iface, ::std::vector<::std::string>* _aidl_return) {
388+
Status status = Status::ok();
373389
if (mTheRealServiceManager) {
374-
return mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return);
390+
status = mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return);
375391
}
376-
return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION,
377-
kUnsupportedOpNoServiceManager);
392+
if (!status.isOk()) return status;
393+
394+
forEachInjectedAccessorService([&](const std::string& instance) {
395+
// Declared instances have the format
396+
// <interface>/instance like foo.bar.ISomething/instance
397+
// If it does not have that format, consider the instance to be ""
398+
std::string_view name(instance);
399+
if (base::ConsumePrefix(&name, iface + "/")) {
400+
_aidl_return->emplace_back(name);
401+
} else if (iface == instance) {
402+
_aidl_return->push_back("");
403+
}
404+
});
405+
406+
return status;
378407
}
379408
Status BackendUnifiedServiceManager::updatableViaApex(
380409
const ::std::string& name, ::std::optional<::std::string>* _aidl_return) {

libs/binder/BackendUnifiedServiceManager.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,5 +167,9 @@ class BackendUnifiedServiceManager : public android::os::BnServiceManager {
167167
sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager();
168168

169169
android::binder::Status getInjectedAccessor(const std::string& name, android::os::Service* service);
170+
void appendInjectedAccessorServices(std::vector<std::string>* list);
171+
// Do not call any other service manager APIs that might take the accessor
172+
// mutex because this will be holding it!
173+
void forEachInjectedAccessorService(const std::function<void(const std::string&)>& f);
170174

171175
} // namespace android

libs/binder/IServiceManager.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,25 @@ android::binder::Status getInjectedAccessor(const std::string& name,
304304
return android::binder::Status::ok();
305305
}
306306

307+
void appendInjectedAccessorServices(std::vector<std::string>* list) {
308+
LOG_ALWAYS_FATAL_IF(list == nullptr,
309+
"Attempted to get list of services from Accessors with nullptr");
310+
std::lock_guard<std::mutex> lock(gAccessorProvidersMutex);
311+
for (const auto& entry : gAccessorProviders) {
312+
list->insert(list->end(), entry.mProvider->instances().begin(),
313+
entry.mProvider->instances().end());
314+
}
315+
}
316+
317+
void forEachInjectedAccessorService(const std::function<void(const std::string&)>& f) {
318+
std::lock_guard<std::mutex> lock(gAccessorProvidersMutex);
319+
for (const auto& entry : gAccessorProviders) {
320+
for (const auto& instance : entry.mProvider->instances()) {
321+
f(instance);
322+
}
323+
}
324+
}
325+
307326
sp<IServiceManager> defaultServiceManager()
308327
{
309328
std::call_once(gSmOnce, []() {

libs/binder/tests/binderRpcTest.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,6 +1328,109 @@ TEST_P(BinderRpcAccessor, InjectNoSockaddrProvided) {
13281328
EXPECT_EQ(status, OK);
13291329
}
13301330

1331+
class BinderRpcAccessorNoConnection : public ::testing::Test {};
1332+
1333+
TEST_F(BinderRpcAccessorNoConnection, listServices) {
1334+
const String16 kInstanceName("super.cool.service/better_than_default");
1335+
const String16 kInstanceName2("super.cool.service/better_than_default2");
1336+
1337+
auto receipt =
1338+
addAccessorProvider({String8(kInstanceName).c_str(), String8(kInstanceName2).c_str()},
1339+
[&](const String16&) -> sp<IBinder> { return nullptr; });
1340+
EXPECT_FALSE(receipt.expired());
1341+
Vector<String16> list =
1342+
defaultServiceManager()->listServices(IServiceManager::DUMP_FLAG_PRIORITY_ALL);
1343+
bool name1 = false;
1344+
bool name2 = false;
1345+
for (auto name : list) {
1346+
if (name == kInstanceName) name1 = true;
1347+
if (name == kInstanceName2) name2 = true;
1348+
}
1349+
EXPECT_TRUE(name1);
1350+
EXPECT_TRUE(name2);
1351+
status_t status = removeAccessorProvider(receipt);
1352+
EXPECT_EQ(status, OK);
1353+
}
1354+
1355+
TEST_F(BinderRpcAccessorNoConnection, isDeclared) {
1356+
const String16 kInstanceName("super.cool.service/default");
1357+
const String16 kInstanceName2("still_counts_as_declared");
1358+
1359+
auto receipt =
1360+
addAccessorProvider({String8(kInstanceName).c_str(), String8(kInstanceName2).c_str()},
1361+
[&](const String16&) -> sp<IBinder> { return nullptr; });
1362+
EXPECT_FALSE(receipt.expired());
1363+
EXPECT_TRUE(defaultServiceManager()->isDeclared(kInstanceName));
1364+
EXPECT_TRUE(defaultServiceManager()->isDeclared(kInstanceName2));
1365+
EXPECT_FALSE(defaultServiceManager()->isDeclared(String16("doesnt_exist")));
1366+
status_t status = removeAccessorProvider(receipt);
1367+
EXPECT_EQ(status, OK);
1368+
}
1369+
1370+
TEST_F(BinderRpcAccessorNoConnection, getDeclaredInstances) {
1371+
const String16 kInstanceName("super.cool.service.IFoo/default");
1372+
const String16 kInstanceName2("super.cool.service.IFoo/extra/default");
1373+
const String16 kInstanceName3("super.cool.service.IFoo");
1374+
1375+
auto receipt =
1376+
addAccessorProvider({String8(kInstanceName).c_str(), String8(kInstanceName2).c_str(),
1377+
String8(kInstanceName3).c_str()},
1378+
[&](const String16&) -> sp<IBinder> { return nullptr; });
1379+
EXPECT_FALSE(receipt.expired());
1380+
Vector<String16> list =
1381+
defaultServiceManager()->getDeclaredInstances(String16("super.cool.service.IFoo"));
1382+
// We would prefer ASSERT_EQ here, but we must call removeAccessorProvider
1383+
EXPECT_EQ(list.size(), 3u);
1384+
if (list.size() == 3) {
1385+
bool name1 = false;
1386+
bool name2 = false;
1387+
bool name3 = false;
1388+
for (auto name : list) {
1389+
if (name == String16("default")) name1 = true;
1390+
if (name == String16("extra/default")) name2 = true;
1391+
if (name == String16()) name3 = true;
1392+
}
1393+
EXPECT_TRUE(name1) << String8(list[0]);
1394+
EXPECT_TRUE(name2) << String8(list[1]);
1395+
EXPECT_TRUE(name3) << String8(list[2]);
1396+
}
1397+
1398+
status_t status = removeAccessorProvider(receipt);
1399+
EXPECT_EQ(status, OK);
1400+
}
1401+
1402+
TEST_F(BinderRpcAccessorNoConnection, getDeclaredWrongInstances) {
1403+
const String16 kInstanceName("super.cool.service.IFoo");
1404+
1405+
auto receipt = addAccessorProvider({String8(kInstanceName).c_str()},
1406+
[&](const String16&) -> sp<IBinder> { return nullptr; });
1407+
EXPECT_FALSE(receipt.expired());
1408+
Vector<String16> list = defaultServiceManager()->getDeclaredInstances(String16("unknown"));
1409+
EXPECT_TRUE(list.empty());
1410+
1411+
status_t status = removeAccessorProvider(receipt);
1412+
EXPECT_EQ(status, OK);
1413+
}
1414+
1415+
TEST_F(BinderRpcAccessorNoConnection, getDeclaredInstancesSlash) {
1416+
// This is treated as if there were no '/' and the declared instance is ""
1417+
const String16 kInstanceName("super.cool.service.IFoo/");
1418+
1419+
auto receipt = addAccessorProvider({String8(kInstanceName).c_str()},
1420+
[&](const String16&) -> sp<IBinder> { return nullptr; });
1421+
EXPECT_FALSE(receipt.expired());
1422+
Vector<String16> list =
1423+
defaultServiceManager()->getDeclaredInstances(String16("super.cool.service.IFoo"));
1424+
bool name1 = false;
1425+
for (auto name : list) {
1426+
if (name == String16("")) name1 = true;
1427+
}
1428+
EXPECT_TRUE(name1);
1429+
1430+
status_t status = removeAccessorProvider(receipt);
1431+
EXPECT_EQ(status, OK);
1432+
}
1433+
13311434
constexpr const char* kARpcInstance = "some.instance.name.IFoo/default";
13321435
const char* kARpcSupportedServices[] = {
13331436
kARpcInstance,

0 commit comments

Comments
 (0)