Allow defaultPassthroughServiceImplementation for higher minor am: 7852e276fa
am: b32c85511f

Change-Id: I3c071556e51c930fb3e8a58373d6a91dce4fc7c9
diff --git a/transport/include/hidl/LegacySupport.h b/transport/include/hidl/LegacySupport.h
index fdc5a48..0f37ae0 100644
--- a/transport/include/hidl/LegacySupport.h
+++ b/transport/include/hidl/LegacySupport.h
@@ -26,9 +26,12 @@
 namespace android {
 namespace hardware {
 namespace details {
-template <class Interface, typename Func>
+template <typename Interface>
+using RegisterServiceCb = std::function<status_t(const sp<Interface>&, const std::string&)>;
+
+template <class Interface, class ExpectInterface = Interface>
 __attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
-    Func registerServiceCb, const std::string& name = "default") {
+        RegisterServiceCb<Interface> registerServiceCb, const std::string& name = "default") {
     sp<Interface> service = Interface::getService(name, true /* getStub */);
 
     if (service == nullptr) {
@@ -39,6 +42,9 @@
 
     LOG_FATAL_IF(service->isRemote(), "Implementation of %s/%s is remote!",
             Interface::descriptor, name.c_str());
+    LOG_FATAL_IF(ExpectInterface::castFrom(service) == nullptr,
+                 "Implementation of %s/%s is not a %s!", Interface::descriptor, name.c_str(),
+                 ExpectInterface::descriptor);
 
     status_t status = registerServiceCb(service, name);
 
@@ -57,14 +63,14 @@
 /**
  * Registers passthrough service implementation.
  */
-template <class Interface>
+template <class Interface, class ExpectInterface = Interface>
 __attribute__((warn_unused_result)) status_t registerPassthroughServiceImplementation(
-    const std::string& name = "default") {
-    return details::registerPassthroughServiceImplementation<Interface>(
-        [](const sp<Interface>& service, const std::string& name) {
-            return service->registerAsService(name);
-        },
-        name);
+        const std::string& name = "default") {
+    return details::registerPassthroughServiceImplementation<Interface, ExpectInterface>(
+            [](const sp<Interface>& service, const std::string& name) {
+                return service->registerAsService(name);
+            },
+            name);
 }
 
 /**
@@ -72,11 +78,11 @@
  *
  * Return value is exit status.
  */
-template <class Interface>
+template <class Interface, class ExpectInterface = Interface>
 __attribute__((warn_unused_result)) status_t defaultPassthroughServiceImplementation(
-    const std::string& name, size_t maxThreads = 1) {
+        const std::string& name, size_t maxThreads = 1) {
     configureRpcThreadpool(maxThreads, true);
-    status_t result = registerPassthroughServiceImplementation<Interface>(name);
+    status_t result = registerPassthroughServiceImplementation<Interface, ExpectInterface>(name);
 
     if (result != OK) {
         return result;
@@ -85,10 +91,11 @@
     joinRpcThreadpool();
     return UNKNOWN_ERROR;
 }
-template<class Interface>
-__attribute__((warn_unused_result))
-status_t defaultPassthroughServiceImplementation(size_t maxThreads = 1) {
-    return defaultPassthroughServiceImplementation<Interface>("default", maxThreads);
+template <class Interface, class ExpectInterface = Interface>
+__attribute__((warn_unused_result)) status_t defaultPassthroughServiceImplementation(
+        size_t maxThreads = 1) {
+    return defaultPassthroughServiceImplementation<Interface, ExpectInterface>("default",
+                                                                               maxThreads);
 }
 
 /**
@@ -99,10 +106,10 @@
  * through registerPassthroughServiceImplementation, so if that function is used in conjunction with
  * this one, the process may exit while a client is still using the HAL.
  */
-template <class Interface>
+template <class Interface, class ExpectInterface = Interface>
 __attribute__((warn_unused_result)) status_t registerLazyPassthroughServiceImplementation(
-    const std::string& name = "default") {
-    return details::registerPassthroughServiceImplementation<Interface>(
+        const std::string& name = "default") {
+    return details::registerPassthroughServiceImplementation<Interface, ExpectInterface>(
             [](const sp<Interface>& service, const std::string& name) {
                 using android::hardware::LazyServiceRegistrar;
                 return LazyServiceRegistrar::getInstance().registerService(service, name);
@@ -116,11 +123,12 @@
  *
  * Return value is exit status.
  */
-template <class Interface>
+template <class Interface, class ExpectInterface = Interface>
 __attribute__((warn_unused_result)) status_t defaultLazyPassthroughServiceImplementation(
-    const std::string& name, size_t maxThreads = 1) {
+        const std::string& name, size_t maxThreads = 1) {
     configureRpcThreadpool(maxThreads, true);
-    status_t result = registerLazyPassthroughServiceImplementation<Interface>(name);
+    status_t result =
+            registerLazyPassthroughServiceImplementation<Interface, ExpectInterface>(name);
 
     if (result != OK) {
         return result;
@@ -129,10 +137,11 @@
     joinRpcThreadpool();
     return UNKNOWN_ERROR;
 }
-template <class Interface>
+template <class Interface, class ExpectInterface = Interface>
 __attribute__((warn_unused_result)) status_t defaultLazyPassthroughServiceImplementation(
-    size_t maxThreads = 1) {
-    return defaultLazyPassthroughServiceImplementation<Interface>("default", maxThreads);
+        size_t maxThreads = 1) {
+    return defaultLazyPassthroughServiceImplementation<Interface, ExpectInterface>("default",
+                                                                                   maxThreads);
 }
 
 }  // namespace hardware