libaudioHAL: reduce version specific code am: 00538f18b8
am: ddfa210b93

Change-Id: I231a5f2a351157dce8884f5e1093fdef1671c5d0
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index 5e22322..5837fcf 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -13,12 +13,6 @@
     ],
 
     shared_libs: [
-        "android.hardware.audio.effect@2.0",
-        "android.hardware.audio.effect@4.0",
-        "android.hardware.audio.effect@5.0",
-        "android.hardware.audio@2.0",
-        "android.hardware.audio@4.0",
-        "android.hardware.audio@5.0",
         "libaudiohal@2.0",
         "libaudiohal@4.0",
         "libaudiohal@5.0",
@@ -26,7 +20,8 @@
     ],
 
     header_libs: [
-        "libaudiohal_headers"
+        "libaudiohal_headers",
+        "libbase_headers",
     ]
 }
 
diff --git a/media/libaudiohal/DevicesFactoryHalInterface.cpp b/media/libaudiohal/DevicesFactoryHalInterface.cpp
index 5068d23..d5336fa 100644
--- a/media/libaudiohal/DevicesFactoryHalInterface.cpp
+++ b/media/libaudiohal/DevicesFactoryHalInterface.cpp
@@ -22,10 +22,8 @@
 
 // static
 sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
-    return V5_0::createDevicesFactoryHal() ?:
-           V4_0::createDevicesFactoryHal() ?:
-           V2_0::createDevicesFactoryHal() ?:
-           nullptr;
+    return createPreferedImpl<DevicesFactoryHalInterface>();
 }
 
 } // namespace android
+
diff --git a/media/libaudiohal/EffectsFactoryHalInterface.cpp b/media/libaudiohal/EffectsFactoryHalInterface.cpp
index 1cbe5e6..d15b14e 100644
--- a/media/libaudiohal/EffectsFactoryHalInterface.cpp
+++ b/media/libaudiohal/EffectsFactoryHalInterface.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2017 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,20 +14,15 @@
  * limitations under the License.
  */
 
-#include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
-#include <android/hardware/audio/effect/4.0/IEffectsFactory.h>
-#include <android/hardware/audio/effect/5.0/IEffectsFactory.h>
-
 #include <libaudiohal/FactoryHalHidl.h>
 
+#include <media/audiohal/EffectsFactoryHalInterface.h>
+
 namespace android {
 
 // static
 sp<EffectsFactoryHalInterface> EffectsFactoryHalInterface::create() {
-    return effect::V5_0::createEffectsFactoryHal() ?:
-           effect::V4_0::createEffectsFactoryHal() ?:
-           effect::V2_0::createEffectsFactoryHal() ?:
-           nullptr;
+    return createPreferedImpl<EffectsFactoryHalInterface>();
 }
 
 // static
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
index 3f68d07..0e1f1bb 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.cpp
@@ -17,9 +17,10 @@
 #define LOG_TAG "DevicesFactoryHalHybrid"
 //#define LOG_NDEBUG 0
 
+#include "DevicesFactoryHalHidl.h"
 #include "DevicesFactoryHalHybrid.h"
 #include "DevicesFactoryHalLocal.h"
-#include "DevicesFactoryHalHidl.h"
+#include <libaudiohal/FactoryHalHidl.h>
 
 namespace android {
 namespace CPP_VERSION {
@@ -36,6 +37,12 @@
     }
     return mLocalFactory->openDevice(name, device);
 }
-
 } // namespace CPP_VERSION
+
+template <>
+sp<DevicesFactoryHalInterface> createFactoryHal<AudioHALVersion::CPP_VERSION>() {
+    auto service = hardware::audio::CPP_VERSION::IDevicesFactory::getService();
+    return service ? new CPP_VERSION::DevicesFactoryHalHybrid(service) : nullptr;
+}
+
 } // namespace android
diff --git a/media/libaudiohal/impl/DevicesFactoryHalHybrid.h b/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
index 8b335a3..545bb70 100644
--- a/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
+++ b/media/libaudiohal/impl/DevicesFactoryHalHybrid.h
@@ -41,11 +41,6 @@
     sp<DevicesFactoryHalInterface> mHidlFactory;
 };
 
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal() {
-    auto service = IDevicesFactory::getService();
-    return service ? new DevicesFactoryHalHybrid(service) : nullptr;
-}
-
 } // namespace CPP_VERSION
 } // namespace android
 
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
index 42280a3..ba7b195 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
@@ -19,11 +19,12 @@
 
 #include <cutils/native_handle.h>
 
-#include "EffectsFactoryHalHidl.h"
 #include "ConversionHelperHidl.h"
 #include "EffectBufferHalHidl.h"
 #include "EffectHalHidl.h"
+#include "EffectsFactoryHalHidl.h"
 #include "HidlUtils.h"
+#include <libaudiohal/FactoryHalHidl.h>
 
 using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
 using ::android::hardware::Return;
@@ -145,4 +146,11 @@
 
 } // namespace CPP_VERSION
 } // namespace effect
+
+template<>
+sp<EffectsFactoryHalInterface> createFactoryHal<AudioHALVersion::CPP_VERSION>() {
+    auto service = hardware::audio::effect::CPP_VERSION::IEffectsFactory::getService();
+    return service ? new effect::CPP_VERSION::EffectsFactoryHalHidl(service) : nullptr;
+}
+
 } // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.h b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
index bed4f7e..2828513 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
@@ -65,11 +65,6 @@
     status_t queryAllDescriptors();
 };
 
-sp<EffectsFactoryHalInterface> createEffectsFactoryHal() {
-    auto service = IEffectsFactory::getService();
-    return service ? new EffectsFactoryHalHidl(service) : nullptr;
-}
-
 } // namespace CPP_VERSION
 } // namespace effect
 } // namespace android
diff --git a/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h b/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
index c7319d0..829f99c 100644
--- a/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
+++ b/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
@@ -23,33 +23,42 @@
 #include <media/audiohal/EffectsFactoryHalInterface.h>
 #include <utils/StrongPointer.h>
 
+#include <array>
+#include <utility>
+
 namespace android {
 
-namespace effect {
-namespace V2_0 {
-sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
-} // namespace V2_0
+/** Supported HAL versions, in order of preference.
+ * Implementation should use specialize the `create*FactoryHal` for their version.
+ * Client should use `createPreferedImpl<*FactoryHal>()` to instantiate
+ * the preferred available impl.
+ */
+enum class AudioHALVersion {
+    V5_0,
+    V4_0,
+    V2_0,
+    end, // used for iterating over supported versions
+};
 
-namespace V4_0 {
-sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
-} // namespace V4_0
+/** Template function to fully specialized for each version and each Interface. */
+template <AudioHALVersion, class Interface>
+sp<Interface> createFactoryHal();
 
-namespace V5_0 {
-sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
-} // namespace V5_0
-} // namespace effect
+/** @Return the preferred available implementation or nullptr if none are available. */
+template <class Interface, AudioHALVersion version = AudioHALVersion{}>
+static sp<Interface> createPreferedImpl() {
+    if constexpr (version == AudioHALVersion::end) {
+        return nullptr; // tried all version, all returned nullptr
+    } else {
+        if (auto created = createFactoryHal<version, Interface>(); created != nullptr) {
+           return created;
+        }
 
-namespace V2_0 {
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
-} // namespace V2_0
+        using Raw = std::underlying_type_t<AudioHALVersion>; // cast as enum class do not support ++
+        return createPreferedImpl<Interface, AudioHALVersion(Raw(version) + 1)>();
+    }
+}
 
-namespace V4_0 {
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
-} // namespace V4_0
-
-namespace V5_0 {
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
-} // namespace V5_0
 
 } // namespace android