Merge "Add hidl-module-defaults to libhidltransport."
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..3631423
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1,5 @@
+smoreland@google.com
+elsk@google.com
+maco@google.com
+hridya@google.com
+malchev@google.com
diff --git a/libhidlmemory/include/hidlmemory/mapping.h b/libhidlmemory/include/hidlmemory/mapping.h
index 8ed0d54..5e1dab3 100644
--- a/libhidlmemory/include/hidlmemory/mapping.h
+++ b/libhidlmemory/include/hidlmemory/mapping.h
@@ -19,7 +19,11 @@
namespace android {
namespace hardware {
+/**
+ * Returns the IMemory instance corresponding to a hidl_memory object.
+ * If the shared memory cannot be fetched, this returns nullptr.
+ */
sp<android::hidl::memory::V1_0::IMemory> mapMemory(const hidl_memory &memory);
} // namespace hardware
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/libhidlmemory/mapping.cpp b/libhidlmemory/mapping.cpp
index 3761f99..f4bb21e 100644
--- a/libhidlmemory/mapping.cpp
+++ b/libhidlmemory/mapping.cpp
@@ -33,17 +33,20 @@
sp<IMapper> mapper = IMapper::getService(memory.name(), true /* getStub */);
if (mapper == nullptr) {
- LOG(FATAL) << "Could not fetch mapper for " << memory.name() << " shared memory";
+ LOG(ERROR) << "Could not fetch mapper for " << memory.name() << " shared memory";
+ return nullptr;
}
if (mapper->isRemote()) {
- LOG(FATAL) << "IMapper must be a passthrough service.";
+ LOG(ERROR) << "IMapper must be a passthrough service.";
+ return nullptr;
}
Return<sp<IMemory>> ret = mapper->mapMemory(memory);
if (!ret.isOk()) {
- LOG(FATAL) << "hidl_memory map returned transport error.";
+ LOG(ERROR) << "hidl_memory map returned transport error.";
+ return nullptr;
}
return ret;
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index 8121911..0b7ec34 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -25,6 +25,7 @@
#include <mutex>
#include <regex>
+#include <set>
#include <hidl/HidlBinderSupport.h>
#include <hidl/ServiceManagement.h>
@@ -179,10 +180,11 @@
return results;
}
-bool matchPackageName(const std::string &lib, std::string *matchedName) {
+bool matchPackageName(const std::string& lib, std::string* matchedName, std::string* implName) {
std::smatch match;
if (std::regex_match(lib, match, gLibraryFileNamePattern)) {
*matchedName = match.str(1) + "::I*";
+ *implName = match.str(2);
return true;
}
return false;
@@ -207,6 +209,44 @@
<< interfaceName << "/" << instanceName;
}
+using InstanceDebugInfo = hidl::manager::V1_0::IServiceManager::InstanceDebugInfo;
+static inline void fetchPidsForPassthroughLibraries(
+ std::map<std::string, InstanceDebugInfo>* infos) {
+ static const std::string proc = "/proc/";
+
+ std::map<std::string, std::set<pid_t>> pids;
+ std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(proc.c_str()), closedir);
+ if (!dir) return;
+ dirent* dp;
+ while ((dp = readdir(dir.get())) != nullptr) {
+ pid_t pid = strtoll(dp->d_name, NULL, 0);
+ if (pid == 0) continue;
+ std::string mapsPath = proc + dp->d_name + "/maps";
+ std::ifstream ifs{mapsPath};
+ if (!ifs.is_open()) continue;
+
+ for (std::string line; std::getline(ifs, line);) {
+ // The last token of line should look like
+ // vendor/lib64/hw/android.hardware.foo@1.0-impl-extra.so
+ // Use some simple filters to ignore bad lines before extracting libFileName
+ // and checking the key in info to make parsing faster.
+ if (line.back() != 'o') continue;
+ if (line.rfind('@') == std::string::npos) continue;
+
+ auto spacePos = line.rfind(' ');
+ if (spacePos == std::string::npos) continue;
+ auto libFileName = line.substr(spacePos + 1);
+ auto it = infos->find(libFileName);
+ if (it == infos->end()) continue;
+ pids[libFileName].insert(pid);
+ }
+ }
+ for (auto& pair : *infos) {
+ pair.second.clientPids =
+ std::vector<pid_t>{pids[pair.first].begin(), pids[pair.first].end()};
+ }
+}
+
struct PassthroughServiceManager : IServiceManager {
Return<sp<IBase>> get(const hidl_string& fqName,
const hidl_string& name) override {
@@ -311,6 +351,7 @@
Return<void> debugDump(debugDump_cb _hidl_cb) override {
using Arch = ::android::hidl::base::V1_0::DebugInfo::Architecture;
+ using std::literals::string_literals::operator""s;
static std::vector<std::pair<Arch, std::vector<const char *>>> sAllPaths{
{Arch::IS_64BIT, {HAL_LIBRARY_PATH_ODM_64BIT,
HAL_LIBRARY_PATH_VENDOR_64BIT,
@@ -319,24 +360,32 @@
HAL_LIBRARY_PATH_VENDOR_32BIT,
HAL_LIBRARY_PATH_SYSTEM_32BIT}}
};
- std::vector<InstanceDebugInfo> vec;
+ std::map<std::string, InstanceDebugInfo> map;
for (const auto &pair : sAllPaths) {
Arch arch = pair.first;
for (const auto &path : pair.second) {
std::vector<std::string> libs = search(path, "", ".so");
for (const std::string &lib : libs) {
std::string matchedName;
- if (matchPackageName(lib, &matchedName)) {
- vec.push_back({
- .interfaceName = matchedName,
- .instanceName = "*",
- .clientPids = {},
- .arch = arch
- });
+ std::string implName;
+ if (matchPackageName(lib, &matchedName, &implName)) {
+ std::string instanceName{"* ("s + path + ")"s};
+ if (!implName.empty()) instanceName += " ("s + implName + ")"s;
+ map.emplace(path + lib, InstanceDebugInfo{.interfaceName = matchedName,
+ .instanceName = instanceName,
+ .clientPids = {},
+ .arch = arch});
}
}
}
}
+ fetchPidsForPassthroughLibraries(&map);
+ hidl_vec<InstanceDebugInfo> vec;
+ vec.resize(map.size());
+ size_t idx = 0;
+ for (auto&& pair : map) {
+ vec[idx++] = std::move(pair.second);
+ }
_hidl_cb(vec);
return Void();
}