Merge "Add waitForHwService." am: 3b41bfec5d am: 3f9a9fce4a
am: 9ba3dfebe1
Change-Id: I73344aab7a85ff0ec810c193adb48b152805dfae
diff --git a/transport/ServiceManagement.cpp b/transport/ServiceManagement.cpp
index 1734935..9a6a3b5 100644
--- a/transport/ServiceManagement.cpp
+++ b/transport/ServiceManagement.cpp
@@ -22,12 +22,14 @@
#include <hidl/Status.h>
#include <android-base/logging.h>
+#include <condition_variable>
#include <dlfcn.h>
#include <dirent.h>
#include <hidl-util/FQName.h>
#include <hidl-util/StringHelper.h>
#include <hwbinder/IPCThreadState.h>
#include <hwbinder/Parcel.h>
+#include <mutex>
#include <unistd.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
@@ -175,5 +177,65 @@
return manager;
}
+namespace details {
+
+struct Waiter : IServiceNotification {
+ Return<void> onRegistration(const hidl_string& /* fqName */,
+ const hidl_string& /* name */,
+ bool /* preexisting */) override {
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (mRegistered) {
+ return Void();
+ }
+ mRegistered = true;
+ lock.unlock();
+
+ mCondition.notify_one();
+ return Void();
+ }
+
+ void wait() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mCondition.wait(lock, [this]{
+ return mRegistered;
+ });
+ }
+
+private:
+ std::mutex mMutex;
+ std::condition_variable mCondition;
+ bool mRegistered = false;
+};
+
+void waitForHwService(
+ const std::string &interface, const std::string &instanceName) {
+ const sp<IServiceManager> manager = defaultServiceManager();
+
+ if (manager == nullptr) {
+ LOG(ERROR) << "Could not get default service manager.";
+ return;
+ }
+
+ sp<Waiter> waiter = new Waiter();
+ Return<bool> ret = manager->registerForNotifications(interface, instanceName, waiter);
+
+ if (!ret.isOk()) {
+ LOG(ERROR) << "Transport error, " << ret.description()
+ << ", during notification registration for "
+ << interface << "/" << instanceName << ".";
+ return;
+ }
+
+ if (!ret) {
+ LOG(ERROR) << "Could not register for notifications for "
+ << interface << "/" << instanceName << ".";
+ return;
+ }
+
+ waiter->wait();
+}
+
+}; // namespace details
+
}; // namespace hardware
}; // namespace android
diff --git a/transport/include/hidl/ServiceManagement.h b/transport/include/hidl/ServiceManagement.h
index d4552a7..2035fb7 100644
--- a/transport/include/hidl/ServiceManagement.h
+++ b/transport/include/hidl/ServiceManagement.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_HARDWARE_ISERVICE_MANAGER_H
#define ANDROID_HARDWARE_ISERVICE_MANAGER_H
+#include <string>
#include <utils/StrongPointer.h>
namespace android {
@@ -37,6 +38,10 @@
sp<::android::hidl::manager::V1_0::IServiceManager> defaultServiceManager();
sp<::android::hidl::manager::V1_0::IServiceManager> getPassthroughServiceManager();
+namespace details {
+void waitForHwService(const std::string &interface, const std::string &instanceName);
+};
+
}; // namespace hardware
}; // namespace android