Loading cmds/lshal/ListCommand.cpp +41 −34 Original line number Diff line number Diff line Loading @@ -523,17 +523,18 @@ Status ListCommand::fetchAllLibraries(const sp<IServiceManager> &manager) { using namespace ::android::hardware; using namespace ::android::hidl::manager::V1_0; using namespace ::android::hidl::base::V1_0; using std::literals::chrono_literals::operator""s; // The lambda function may be executed asynchrounously because it is passed to timeoutIPC, // even though the interface function call is synchronous. // However, there's no need to lock because if ret.isOk(), the background thread has // already ended, so it is safe to dereference entries. auto entries = std::make_shared<std::map<std::string, TableEntry>>(); auto ret = timeoutIPC(10s, manager, &IServiceManager::debugDump, [entries](const auto& infos) { auto ret = timeoutIPC(mLshal.getDebugDumpWait(), manager, &IServiceManager::debugDump, [entries](const auto& infos) { for (const auto& info : infos) { std::string interfaceName = std::string{info.interfaceName.c_str()} + "/" + std::string{info.instanceName.c_str()}; std::string interfaceName = std::string{info.interfaceName.c_str()} + "/" + std::string{info.instanceName.c_str()}; entries->emplace(interfaceName, TableEntry{ .interfaceName = interfaceName, Loading Loading @@ -567,17 +568,22 @@ Status ListCommand::fetchPassthrough(const sp<IServiceManager> &manager) { // However, there's no need to lock because if ret.isOk(), the background thread has // already ended, so it is safe to dereference entries. auto entries = std::make_shared<std::vector<TableEntry>>(); auto ret = timeoutIPC(manager, &IServiceManager::debugDump, [entries](const auto& infos) { auto ret = timeoutIPC(mLshal.getIpcCallWait(), manager, &IServiceManager::debugDump, [entries](const auto& infos) { for (const auto& info : infos) { if (info.clientPids.size() <= 0) { continue; } entries->emplace_back( TableEntry{.interfaceName = std::string{info.interfaceName.c_str()} + "/" + TableEntry{.interfaceName = std::string{info.interfaceName.c_str()} + "/" + std::string{info.instanceName.c_str()}, .transport = vintf::Transport::PASSTHROUGH, .serverPid = info.clientPids.size() == 1 ? info.clientPids[0] : NO_PID, .serverPid = info.clientPids.size() == 1 ? info.clientPids[0] : NO_PID, .clientPids = info.clientPids, .arch = fromBaseArchitecture(info.arch)}); } Loading Loading @@ -605,7 +611,7 @@ Status ListCommand::fetchBinderized(const sp<IServiceManager> &manager) { // However, there's no need to lock because if listRet.isOk(), the background thread has // already ended, so it is safe to dereference fqInstanceNames. auto fqInstanceNames = std::make_shared<hidl_vec<hidl_string>>(); auto listRet = timeoutIPC(manager, &IServiceManager::list, auto listRet = timeoutIPC(mLshal.getIpcCallWait(), manager, &IServiceManager::list, [fqInstanceNames](const auto& names) { *fqInstanceNames = names; }); if (!listRet.isOk()) { err() << "Error: Failed to list services for " << mode << ": " Loading Loading @@ -642,7 +648,8 @@ Status ListCommand::fetchBinderizedEntry(const sp<IServiceManager> &manager, const auto pair = splitFirst(entry->interfaceName, '/'); const auto &serviceName = pair.first; const auto &instanceName = pair.second; auto getRet = timeoutIPC(manager, &IServiceManager::get, serviceName, instanceName); auto getRet = timeoutIPC(mLshal.getIpcCallWait(), manager, &IServiceManager::get, serviceName, instanceName); if (!getRet.isOk()) { handleError(TRANSACTION_ERROR, "cannot be fetched from service manager:" + getRet.description()); Loading @@ -661,7 +668,7 @@ Status ListCommand::fetchBinderizedEntry(const sp<IServiceManager> &manager, // However, there's no need to lock because if debugRet.isOk(), the background thread has // already ended, so it is safe to dereference debugInfo. auto debugInfo = std::make_shared<DebugInfo>(); auto debugRet = timeoutIPC(service, &IBase::getDebugInfo, auto debugRet = timeoutIPC(mLshal.getIpcCallWait(), service, &IBase::getDebugInfo, [debugInfo](const auto& received) { *debugInfo = received; }); if (!debugRet.isOk()) { handleError(TRANSACTION_ERROR, Loading Loading @@ -697,7 +704,7 @@ Status ListCommand::fetchBinderizedEntry(const sp<IServiceManager> &manager, // The lambda function may be executed asynchrounously because it is passed to timeoutIPC, // even though the interface function call is synchronous. auto hashIndexStore = std::make_shared<ssize_t>(-1); auto ifaceChainRet = timeoutIPC(service, &IBase::interfaceChain, auto ifaceChainRet = timeoutIPC(mLshal.getIpcCallWait(), service, &IBase::interfaceChain, [hashIndexStore, serviceName](const auto& c) { for (size_t i = 0; i < c.size(); ++i) { if (serviceName == c[i]) { Loading @@ -720,7 +727,7 @@ Status ListCommand::fetchBinderizedEntry(const sp<IServiceManager> &manager, } // See comments about hashIndex above. auto hashChain = std::make_shared<hidl_vec<hidl_array<uint8_t, 32>>>(); auto hashRet = timeoutIPC(service, &IBase::getHashChain, auto hashRet = timeoutIPC(mLshal.getIpcCallWait(), service, &IBase::getHashChain, [hashChain](const auto& ret) { *hashChain = std::move(ret); }); if (!hashRet.isOk()) { handleError(TRANSACTION_ERROR, "getHashChain failed: " + hashRet.description()); Loading cmds/lshal/Lshal.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -250,5 +250,17 @@ const sp<IServiceManager> &Lshal::passthroughManager() const { return mPassthroughManager; } void Lshal::setWaitTimeForTest(std::chrono::milliseconds ipcCallWait, std::chrono::milliseconds debugDumpWait) { mIpcCallWait = ipcCallWait; mDebugDumpWait = debugDumpWait; } std::chrono::milliseconds Lshal::getIpcCallWait() const { return mIpcCallWait; } std::chrono::milliseconds Lshal::getDebugDumpWait() const { return mDebugDumpWait; } } // namespace lshal } // namespace android cmds/lshal/Lshal.h +9 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <chrono> #include <iostream> #include <string> Loading Loading @@ -58,6 +59,11 @@ public: void forEachCommand(const std::function<void(const Command* c)>& f) const; void setWaitTimeForTest(std::chrono::milliseconds ipcCallWait, std::chrono::milliseconds debugDumpWait); std::chrono::milliseconds getIpcCallWait() const; std::chrono::milliseconds getDebugDumpWait() const; private: Status parseArgs(const Arg &arg); Loading @@ -70,6 +76,9 @@ private: std::vector<std::unique_ptr<Command>> mRegisteredCommands; std::chrono::milliseconds mIpcCallWait{500}; std::chrono::milliseconds mDebugDumpWait{10000}; DISALLOW_COPY_AND_ASSIGN(Lshal); }; Loading cmds/lshal/Timeout.h +0 −9 Original line number Diff line number Diff line Loading @@ -27,8 +27,6 @@ namespace android { namespace lshal { static constexpr std::chrono::milliseconds IPC_CALL_WAIT{500}; class BackgroundTaskState { public: explicit BackgroundTaskState(std::function<void(void)> &&func) Loading Loading @@ -96,12 +94,5 @@ timeoutIPC(std::chrono::duration<R, P> wait, const sp<I> &interfaceObject, Funct return ret; } template<class Function, class I, class... Args> typename std::result_of<Function(I *, Args...)>::type timeoutIPC(const sp<I> &interfaceObject, Function &&func, Args &&... args) { return timeoutIPC(IPC_CALL_WAIT, interfaceObject, func, args...); } } // namespace lshal } // namespace android Loading
cmds/lshal/ListCommand.cpp +41 −34 Original line number Diff line number Diff line Loading @@ -523,17 +523,18 @@ Status ListCommand::fetchAllLibraries(const sp<IServiceManager> &manager) { using namespace ::android::hardware; using namespace ::android::hidl::manager::V1_0; using namespace ::android::hidl::base::V1_0; using std::literals::chrono_literals::operator""s; // The lambda function may be executed asynchrounously because it is passed to timeoutIPC, // even though the interface function call is synchronous. // However, there's no need to lock because if ret.isOk(), the background thread has // already ended, so it is safe to dereference entries. auto entries = std::make_shared<std::map<std::string, TableEntry>>(); auto ret = timeoutIPC(10s, manager, &IServiceManager::debugDump, [entries](const auto& infos) { auto ret = timeoutIPC(mLshal.getDebugDumpWait(), manager, &IServiceManager::debugDump, [entries](const auto& infos) { for (const auto& info : infos) { std::string interfaceName = std::string{info.interfaceName.c_str()} + "/" + std::string{info.instanceName.c_str()}; std::string interfaceName = std::string{info.interfaceName.c_str()} + "/" + std::string{info.instanceName.c_str()}; entries->emplace(interfaceName, TableEntry{ .interfaceName = interfaceName, Loading Loading @@ -567,17 +568,22 @@ Status ListCommand::fetchPassthrough(const sp<IServiceManager> &manager) { // However, there's no need to lock because if ret.isOk(), the background thread has // already ended, so it is safe to dereference entries. auto entries = std::make_shared<std::vector<TableEntry>>(); auto ret = timeoutIPC(manager, &IServiceManager::debugDump, [entries](const auto& infos) { auto ret = timeoutIPC(mLshal.getIpcCallWait(), manager, &IServiceManager::debugDump, [entries](const auto& infos) { for (const auto& info : infos) { if (info.clientPids.size() <= 0) { continue; } entries->emplace_back( TableEntry{.interfaceName = std::string{info.interfaceName.c_str()} + "/" + TableEntry{.interfaceName = std::string{info.interfaceName.c_str()} + "/" + std::string{info.instanceName.c_str()}, .transport = vintf::Transport::PASSTHROUGH, .serverPid = info.clientPids.size() == 1 ? info.clientPids[0] : NO_PID, .serverPid = info.clientPids.size() == 1 ? info.clientPids[0] : NO_PID, .clientPids = info.clientPids, .arch = fromBaseArchitecture(info.arch)}); } Loading Loading @@ -605,7 +611,7 @@ Status ListCommand::fetchBinderized(const sp<IServiceManager> &manager) { // However, there's no need to lock because if listRet.isOk(), the background thread has // already ended, so it is safe to dereference fqInstanceNames. auto fqInstanceNames = std::make_shared<hidl_vec<hidl_string>>(); auto listRet = timeoutIPC(manager, &IServiceManager::list, auto listRet = timeoutIPC(mLshal.getIpcCallWait(), manager, &IServiceManager::list, [fqInstanceNames](const auto& names) { *fqInstanceNames = names; }); if (!listRet.isOk()) { err() << "Error: Failed to list services for " << mode << ": " Loading Loading @@ -642,7 +648,8 @@ Status ListCommand::fetchBinderizedEntry(const sp<IServiceManager> &manager, const auto pair = splitFirst(entry->interfaceName, '/'); const auto &serviceName = pair.first; const auto &instanceName = pair.second; auto getRet = timeoutIPC(manager, &IServiceManager::get, serviceName, instanceName); auto getRet = timeoutIPC(mLshal.getIpcCallWait(), manager, &IServiceManager::get, serviceName, instanceName); if (!getRet.isOk()) { handleError(TRANSACTION_ERROR, "cannot be fetched from service manager:" + getRet.description()); Loading @@ -661,7 +668,7 @@ Status ListCommand::fetchBinderizedEntry(const sp<IServiceManager> &manager, // However, there's no need to lock because if debugRet.isOk(), the background thread has // already ended, so it is safe to dereference debugInfo. auto debugInfo = std::make_shared<DebugInfo>(); auto debugRet = timeoutIPC(service, &IBase::getDebugInfo, auto debugRet = timeoutIPC(mLshal.getIpcCallWait(), service, &IBase::getDebugInfo, [debugInfo](const auto& received) { *debugInfo = received; }); if (!debugRet.isOk()) { handleError(TRANSACTION_ERROR, Loading Loading @@ -697,7 +704,7 @@ Status ListCommand::fetchBinderizedEntry(const sp<IServiceManager> &manager, // The lambda function may be executed asynchrounously because it is passed to timeoutIPC, // even though the interface function call is synchronous. auto hashIndexStore = std::make_shared<ssize_t>(-1); auto ifaceChainRet = timeoutIPC(service, &IBase::interfaceChain, auto ifaceChainRet = timeoutIPC(mLshal.getIpcCallWait(), service, &IBase::interfaceChain, [hashIndexStore, serviceName](const auto& c) { for (size_t i = 0; i < c.size(); ++i) { if (serviceName == c[i]) { Loading @@ -720,7 +727,7 @@ Status ListCommand::fetchBinderizedEntry(const sp<IServiceManager> &manager, } // See comments about hashIndex above. auto hashChain = std::make_shared<hidl_vec<hidl_array<uint8_t, 32>>>(); auto hashRet = timeoutIPC(service, &IBase::getHashChain, auto hashRet = timeoutIPC(mLshal.getIpcCallWait(), service, &IBase::getHashChain, [hashChain](const auto& ret) { *hashChain = std::move(ret); }); if (!hashRet.isOk()) { handleError(TRANSACTION_ERROR, "getHashChain failed: " + hashRet.description()); Loading
cmds/lshal/Lshal.cpp +12 −0 Original line number Diff line number Diff line Loading @@ -250,5 +250,17 @@ const sp<IServiceManager> &Lshal::passthroughManager() const { return mPassthroughManager; } void Lshal::setWaitTimeForTest(std::chrono::milliseconds ipcCallWait, std::chrono::milliseconds debugDumpWait) { mIpcCallWait = ipcCallWait; mDebugDumpWait = debugDumpWait; } std::chrono::milliseconds Lshal::getIpcCallWait() const { return mIpcCallWait; } std::chrono::milliseconds Lshal::getDebugDumpWait() const { return mDebugDumpWait; } } // namespace lshal } // namespace android
cmds/lshal/Lshal.h +9 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <chrono> #include <iostream> #include <string> Loading Loading @@ -58,6 +59,11 @@ public: void forEachCommand(const std::function<void(const Command* c)>& f) const; void setWaitTimeForTest(std::chrono::milliseconds ipcCallWait, std::chrono::milliseconds debugDumpWait); std::chrono::milliseconds getIpcCallWait() const; std::chrono::milliseconds getDebugDumpWait() const; private: Status parseArgs(const Arg &arg); Loading @@ -70,6 +76,9 @@ private: std::vector<std::unique_ptr<Command>> mRegisteredCommands; std::chrono::milliseconds mIpcCallWait{500}; std::chrono::milliseconds mDebugDumpWait{10000}; DISALLOW_COPY_AND_ASSIGN(Lshal); }; Loading
cmds/lshal/Timeout.h +0 −9 Original line number Diff line number Diff line Loading @@ -27,8 +27,6 @@ namespace android { namespace lshal { static constexpr std::chrono::milliseconds IPC_CALL_WAIT{500}; class BackgroundTaskState { public: explicit BackgroundTaskState(std::function<void(void)> &&func) Loading Loading @@ -96,12 +94,5 @@ timeoutIPC(std::chrono::duration<R, P> wait, const sp<I> &interfaceObject, Funct return ret; } template<class Function, class I, class... Args> typename std::result_of<Function(I *, Args...)>::type timeoutIPC(const sp<I> &interfaceObject, Function &&func, Args &&... args) { return timeoutIPC(IPC_CALL_WAIT, interfaceObject, func, args...); } } // namespace lshal } // namespace android