Deal with split between IFoo and IHwFoo.
Add two macros that allow us to:
- Retrieve an interface instance with
a specific name and version. The implementation
of this will try to retrieve the interface from
the hwservicemanager. If that fails, in the future
it can try to retrieve a pass-through version.
- Register an interface implementation. The implementation
of this automatically wraps it in a hwbinder object if
necessary.
Also changed IServiceManager to work correctly with the new
macros in libhwbinder.
TODO (b/30584126): the versions should not need to be passed in,
but instead be retrieved from the generated interfaces directly.
Bug: 30588200
Change-Id: I0567b6a0d3c34b6c8ee54445bea0a42f41a9fcc4
diff --git a/IServiceManager.cpp b/IServiceManager.cpp
index ccbe28d..477d1dd 100644
--- a/IServiceManager.cpp
+++ b/IServiceManager.cpp
@@ -38,7 +38,7 @@
{
AutoMutex _l(gDefaultServiceManagerLock);
while (gDefaultServiceManager == NULL) {
- gDefaultServiceManager = interface_cast<IServiceManager>(
+ gDefaultServiceManager = interface_cast<IHwServiceManager>(
ProcessState::self()->getContextObject(NULL));
if (gDefaultServiceManager == NULL)
sleep(1);
@@ -50,11 +50,11 @@
// ----------------------------------------------------------------------
-class BpServiceManager : public BpInterface<IServiceManager>
+class BpServiceManager : public BpInterface<IHwServiceManager>
{
public:
explicit BpServiceManager(const sp<IBinder>& impl)
- : BpInterface<IServiceManager>(impl)
+ : BpInterface<IHwServiceManager>(impl)
{
}
@@ -73,7 +73,7 @@
virtual sp<IBinder> checkService( const String16& name, const hidl_version& version) const
{
Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+ data.writeInterfaceToken(getInterfaceDescriptor());
data.writeString16(name);
version.writeToParcel(data);
remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
@@ -85,7 +85,7 @@
bool allowIsolated)
{
Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+ data.writeInterfaceToken(getInterfaceDescriptor());
data.writeString16(name);
data.writeStrongBinder(service);
version.writeToParcel(data);
@@ -101,7 +101,7 @@
for (;;) {
Parcel data, reply;
- data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
+ data.writeInterfaceToken(getInterfaceDescriptor());
data.writeInt32(n++);
status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply);
if (err != NO_ERROR)
diff --git a/include/hidl/HidlSupport.h b/include/hidl/HidlSupport.h
index 2689ab4..4b0e369 100644
--- a/include/hidl/HidlSupport.h
+++ b/include/hidl/HidlSupport.h
@@ -194,6 +194,7 @@
bool operator==(const hidl_version& other) {
return (mMajor == other.get_major() && mMinor == other.get_minor());
}
+
uint16_t get_major() const { return mMajor; }
uint16_t get_minor() const { return mMinor; }
@@ -220,8 +221,40 @@
return hidl_version(major,minor);
}
+#define DECLARE_REGISTER_AND_GET_SERVICE(INTERFACE) \
+ static ::android::sp<I##INTERFACE> getService( \
+ const ::android::String16 &serviceName, \
+ const hidl_version &version); \
+ status_t registerAsService( \
+ const ::android::String16& serviceName, \
+ const hidl_version &version);
+
+#define IMPLEMENT_REGISTER_AND_GET_SERVICE(INTERFACE) \
+ ::android::sp<I##INTERFACE> I##INTERFACE::getService( \
+ const ::android::String16 &serviceName, \
+ const hidl_version &version /* TODO get version from IFoo directly */) \
+ { \
+ sp<I##INTERFACE> iface; \
+ const sp<IServiceManager> sm = defaultServiceManager(); \
+ if (sm != nullptr) { \
+ sp<IBinder> binderIface = sm->getService(serviceName, version); \
+ iface = IHw##INTERFACE::asInterface(binderIface); \
+ } \
+ /* TODO: if we don't have a binder interface, try to instantiate default */ \
+ return iface; \
+ } \
+ status_t I##INTERFACE::registerAsService( \
+ const ::android::String16& serviceName, \
+ const hidl_version &version) \
+ { \
+ sp<Bn##INTERFACE> binderIface = new Bn##INTERFACE(this); \
+ const sp<IServiceManager> sm = defaultServiceManager(); \
+ return sm->addService(serviceName, binderIface, version); \
+ }
+
} // namespace hardware
} // namespace android
+
#endif // ANDROID_HIDL_SUPPORT_H
diff --git a/include/hidl/IServiceManager.h b/include/hidl/IServiceManager.h
index 5d6155a..758384c 100644
--- a/include/hidl/IServiceManager.h
+++ b/include/hidl/IServiceManager.h
@@ -26,11 +26,9 @@
namespace android {
namespace hardware {
-class IServiceManager : public IInterface
+class IServiceManager : virtual public RefBase
{
public:
- DECLARE_HWBINDER_META_INTERFACE(ServiceManager);
-
/**
* Retrieve an existing service, blocking for a few seconds
* if it doesn't yet exist.
@@ -54,7 +52,12 @@
const android::hardware::hidl_version& version,
bool allowIsolated = false) = 0;
- enum {
+};
+
+struct IHwServiceManager : public IServiceManager, public IInterface {
+ DECLARE_HWBINDER_META_INTERFACE(ServiceManager);
+
+ enum Call {
GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
CHECK_SERVICE_TRANSACTION,
ADD_SERVICE_TRANSACTION,