Audio V4: Introduce 4.0 shim to HIDL

The difference between the 2.0 and the 4.0 is very small
by design and most of the modification have been made in a
retro compatible way
The intent is to be able to merge the two implementation
but it could not be done in this patch due to time constrains.

Bug: 38184704
Test: compile
Change-Id: I4738928313b7fd1f6332c0f22bb802d4fba41d82
Signed-off-by: Kevin Rocard <krocard@google.com>
diff --git a/media/libaudiohal/4.0/Android.bp b/media/libaudiohal/4.0/Android.bp
new file mode 100644
index 0000000..3d104ab
--- /dev/null
+++ b/media/libaudiohal/4.0/Android.bp
@@ -0,0 +1,57 @@
+cc_library_shared {
+    name: "libaudiohal@4.0",
+
+    srcs: [
+        "DeviceHalLocal.cpp",
+        "DevicesFactoryHalHybrid.cpp",
+        "DevicesFactoryHalLocal.cpp",
+        "StreamHalLocal.cpp",
+
+        "ConversionHelperHidl.cpp",
+        "DeviceHalHidl.cpp",
+        "DevicesFactoryHalHidl.cpp",
+        "EffectBufferHalHidl.cpp",
+        "EffectHalHidl.cpp",
+        "EffectsFactoryHalHidl.cpp",
+        "StreamHalHidl.cpp",
+    ],
+
+    export_include_dirs: ["include"],
+
+    cflags: [
+        "-Wall",
+        "-Wextra",
+        "-Werror",
+    ],
+    shared_libs: [
+        "libaudiohal_deathhandler",
+        "libaudioutils",
+        "libcutils",
+        "liblog",
+        "libutils",
+        "libhardware",
+        "libbase",
+        "libfmq",
+        "libhwbinder",
+        "libhidlbase",
+        "libhidlmemory",
+        "libhidltransport",
+        "android.hardware.audio@4.0",
+        "android.hardware.audio.common-util",
+        "android.hardware.audio.common@4.0",
+        "android.hardware.audio.common@4.0-util",
+        "android.hardware.audio.effect@4.0",
+        "android.hidl.allocator@1.0",
+        "android.hidl.memory@1.0",
+        "libmedia_helper",
+        "libmediautils",
+    ],
+    header_libs: [
+        "android.hardware.audio.common.util@all-versions",
+        "libaudiohal_headers"
+    ],
+
+    export_shared_lib_headers: [
+        "libfmq",
+    ],
+}
diff --git a/media/libaudiohal/4.0/DeviceHalHidl.cpp b/media/libaudiohal/4.0/DeviceHalHidl.cpp
index 24f2eeb..8da1051 100644
--- a/media/libaudiohal/4.0/DeviceHalHidl.cpp
+++ b/media/libaudiohal/4.0/DeviceHalHidl.cpp
@@ -24,9 +24,12 @@
 #include <hwbinder/IPCThreadState.h>
 #include <utils/Log.h>
 
+#include <common/all-versions/VersionUtils.h>
+
 #include "DeviceHalHidl.h"
 #include "HidlUtils.h"
 #include "StreamHalHidl.h"
+#include "VersionUtils.h"
 
 using ::android::hardware::audio::common::V4_0::AudioConfig;
 using ::android::hardware::audio::common::V4_0::AudioDevice;
@@ -38,10 +41,12 @@
 using ::android::hardware::audio::common::V4_0::AudioMode;
 using ::android::hardware::audio::common::V4_0::AudioSource;
 using ::android::hardware::audio::common::V4_0::HidlUtils;
+using ::android::hardware::audio::common::utils::mkEnumConverter;
 using ::android::hardware::audio::V4_0::DeviceAddress;
 using ::android::hardware::audio::V4_0::IPrimaryDevice;
 using ::android::hardware::audio::V4_0::ParameterValue;
 using ::android::hardware::audio::V4_0::Result;
+using ::android::hardware::audio::V4_0::SinkMetadata;
 using ::android::hardware::hidl_string;
 using ::android::hardware::hidl_vec;
 
@@ -194,7 +199,9 @@
     hidl_vec<ParameterValue> hidlParams;
     status_t status = parametersFromHal(kvPairs, &hidlParams);
     if (status != OK) return status;
-    return processReturn("setParameters", mDevice->setParameters(hidlParams));
+    // TODO: change the API so that context and kvPairs are separated
+    return processReturn("setParameters",
+                         utils::setParameters(mDevice, {} /* context */, hidlParams));
 }
 
 status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
@@ -204,7 +211,8 @@
     status_t status = keysFromHal(keys, &hidlKeys);
     if (status != OK) return status;
     Result retval;
-    Return<void> ret = mDevice->getParameters(
+    Return<void> ret = utils::getParameters(mDevice,
+            {} /* context */,
             hidlKeys,
             [&](Result r, const hidl_vec<ParameterValue>& parameters) {
                 retval = r;
@@ -250,7 +258,8 @@
             handle,
             hidlDevice,
             hidlConfig,
-            AudioOutputFlag(flags),
+            mkEnumConverter<AudioOutputFlag>(flags),
+            {} /* metadata */,
             [&](Result r, const sp<IStreamOut>& result, const AudioConfig& suggestedConfig) {
                 retval = r;
                 if (retval == Result::OK) {
@@ -276,12 +285,15 @@
     AudioConfig hidlConfig;
     HidlUtils::audioConfigFromHal(*config, &hidlConfig);
     Result retval = Result::NOT_INITIALIZED;
+    // TODO: correctly propagate the tracks sources and volume
+    //       for now, only send the main source at 1dbfs
+    SinkMetadata metadata = {{{AudioSource(source), 1}}};
     Return<void> ret = mDevice->openInputStream(
             handle,
             hidlDevice,
             hidlConfig,
-            AudioInputFlag(flags),
-            AudioSource(source),
+            flags,
+            metadata,
             [&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
                 retval = r;
                 if (retval == Result::OK) {
@@ -351,7 +363,7 @@
     if (mDevice == 0) return NO_INIT;
     native_handle_t* hidlHandle = native_handle_create(1, 0);
     hidlHandle->data[0] = fd;
-    Return<void> ret = mDevice->debugDump(hidlHandle);
+    Return<void> ret = mDevice->debug(hidlHandle, {} /* options */);
     native_handle_delete(hidlHandle);
     return processReturn("dump", ret);
 }
diff --git a/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp b/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp
index 5feed09..c83194e 100644
--- a/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/4.0/DevicesFactoryHalHidl.cpp
@@ -52,36 +52,11 @@
 DevicesFactoryHalHidl::~DevicesFactoryHalHidl() {
 }
 
-// static
-status_t DevicesFactoryHalHidl::nameFromHal(const char *name, IDevicesFactory::Device *device) {
-    if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_PRIMARY) == 0) {
-        *device = IDevicesFactory::Device::PRIMARY;
-        return OK;
-    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_A2DP) == 0) {
-        *device = IDevicesFactory::Device::A2DP;
-        return OK;
-    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_USB) == 0) {
-        *device = IDevicesFactory::Device::USB;
-        return OK;
-    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX) == 0) {
-        *device = IDevicesFactory::Device::R_SUBMIX;
-        return OK;
-    } else if(strcmp(name, AUDIO_HARDWARE_MODULE_ID_STUB) == 0) {
-        *device = IDevicesFactory::Device::STUB;
-        return OK;
-    }
-    ALOGE("Invalid device name %s", name);
-    return BAD_VALUE;
-}
-
 status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
     if (mDevicesFactory == 0) return NO_INIT;
-    IDevicesFactory::Device hidlDevice;
-    status_t status = nameFromHal(name, &hidlDevice);
-    if (status != OK) return status;
     Result retval = Result::NOT_INITIALIZED;
     Return<void> ret = mDevicesFactory->openDevice(
-            hidlDevice,
+            name,
             [&](Result r, const sp<IDevice>& result) {
                 retval = r;
                 if (retval == Result::OK) {
diff --git a/media/libaudiohal/4.0/DevicesFactoryHalHidl.h b/media/libaudiohal/4.0/DevicesFactoryHalHidl.h
index 51a74a8..114889b 100644
--- a/media/libaudiohal/4.0/DevicesFactoryHalHidl.h
+++ b/media/libaudiohal/4.0/DevicesFactoryHalHidl.h
@@ -42,8 +42,6 @@
     sp<IDevicesFactory> mDevicesFactory;
     sp<IDevicesFactory> mDevicesFactoryMsd;
 
-    static status_t nameFromHal(const char *name, IDevicesFactory::Device *device);
-
     // Can not be constructed directly by clients.
     DevicesFactoryHalHidl();
 
diff --git a/media/libaudiohal/4.0/DevicesFactoryHalHybrid.cpp b/media/libaudiohal/4.0/DevicesFactoryHalHybrid.cpp
index 722b95a..c43509c 100644
--- a/media/libaudiohal/4.0/DevicesFactoryHalHybrid.cpp
+++ b/media/libaudiohal/4.0/DevicesFactoryHalHybrid.cpp
@@ -17,7 +17,7 @@
 #define LOG_TAG "DevicesFactoryHalHybrid"
 //#define LOG_NDEBUG 0
 
-#include "DevicesFactoryHalHybrid.h"
+#include <libaudiohal/4.0/DevicesFactoryHalHybrid.h>
 #include "DevicesFactoryHalLocal.h"
 #include "DevicesFactoryHalHidl.h"
 
diff --git a/media/libaudiohal/4.0/EffectHalHidl.cpp b/media/libaudiohal/4.0/EffectHalHidl.cpp
index 32d5cea..c99c4c8 100644
--- a/media/libaudiohal/4.0/EffectHalHidl.cpp
+++ b/media/libaudiohal/4.0/EffectHalHidl.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "EffectHalHidl"
 //#define LOG_NDEBUG 0
 
+#include <common/all-versions/VersionUtils.h>
 #include <hwbinder/IPCThreadState.h>
 #include <media/EffectsFactoryApi.h>
 #include <utils/Log.h>
@@ -34,6 +35,7 @@
 using ::android::hardware::audio::common::V4_0::HidlUtils;
 using ::android::hardware::audio::common::V4_0::AudioChannelMask;
 using ::android::hardware::audio::common::V4_0::AudioFormat;
+using ::android::hardware::audio::common::utils::mkEnumConverter;
 using ::android::hardware::hidl_vec;
 using ::android::hardware::MQDescriptorSync;
 using ::android::hardware::Return;
@@ -76,10 +78,10 @@
 void EffectHalHidl::effectBufferConfigFromHal(
         const buffer_config_t& halConfig, EffectBufferConfig* config) {
     config->samplingRateHz = halConfig.samplingRate;
-    config->channels = AudioChannelMask(halConfig.channels);
+    config->channels = mkEnumConverter<AudioChannelMask>(halConfig.channels);
     config->format = AudioFormat(halConfig.format);
     config->accessMode = EffectBufferAccess(halConfig.accessMode);
-    config->mask = EffectConfigParameters(halConfig.mask);
+    config->mask = mkEnumConverter<EffectConfigParameters>(halConfig.mask);
 }
 
 // static
diff --git a/media/libaudiohal/4.0/EffectsFactoryHalHidl.cpp b/media/libaudiohal/4.0/EffectsFactoryHalHidl.cpp
index 301175e..dfed784 100644
--- a/media/libaudiohal/4.0/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/4.0/EffectsFactoryHalHidl.cpp
@@ -18,11 +18,11 @@
 //#define LOG_NDEBUG 0
 
 #include <cutils/native_handle.h>
+#include <libaudiohal/4.0/EffectsFactoryHalHidl.h>
 
 #include "ConversionHelperHidl.h"
 #include "EffectBufferHalHidl.h"
 #include "EffectHalHidl.h"
-#include "EffectsFactoryHalHidl.h"
 #include "HidlUtils.h"
 
 using ::android::hardware::audio::common::V4_0::HidlUtils;
@@ -133,7 +133,7 @@
     if (mEffectsFactory == 0) return NO_INIT;
     native_handle_t* hidlHandle = native_handle_create(1, 0);
     hidlHandle->data[0] = fd;
-    Return<void> ret = mEffectsFactory->debugDump(hidlHandle);
+    Return<void> ret = mEffectsFactory->debug(hidlHandle, {} /* options */);
     native_handle_delete(hidlHandle);
     return processReturn(__FUNCTION__, ret);
 }
diff --git a/media/libaudiohal/4.0/StreamHalHidl.cpp b/media/libaudiohal/4.0/StreamHalHidl.cpp
index 9ba3b694..de16e98 100644
--- a/media/libaudiohal/4.0/StreamHalHidl.cpp
+++ b/media/libaudiohal/4.0/StreamHalHidl.cpp
@@ -25,6 +25,7 @@
 #include "DeviceHalHidl.h"
 #include "EffectHalHidl.h"
 #include "StreamHalHidl.h"
+#include "VersionUtils.h"
 
 using ::android::hardware::audio::common::V4_0::AudioChannelMask;
 using ::android::hardware::audio::common::V4_0::AudioFormat;
@@ -56,7 +57,7 @@
     if (mStream != nullptr && mStreamPowerLog.isUserDebugOrEngBuild()) {
         // Obtain audio properties (see StreamHalHidl::getAudioProperties() below).
         Return<void> ret = mStream->getAudioProperties(
-                [&](uint32_t sr, AudioChannelMask m, AudioFormat f) {
+                [&](auto sr, auto m, auto f) {
                 mStreamPowerLog.init(sr,
                         static_cast<audio_channel_mask_t>(m),
                         static_cast<audio_format_t>(f));
@@ -96,7 +97,7 @@
         uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format) {
     if (!mStream) return NO_INIT;
     Return<void> ret = mStream->getAudioProperties(
-            [&](uint32_t sr, AudioChannelMask m, AudioFormat f) {
+            [&](uint32_t sr, auto m, auto f) {
                 *sampleRate = sr;
                 *mask = static_cast<audio_channel_mask_t>(m);
                 *format = static_cast<audio_format_t>(f);
@@ -109,7 +110,8 @@
     hidl_vec<ParameterValue> hidlParams;
     status_t status = parametersFromHal(kvPairs, &hidlParams);
     if (status != OK) return status;
-    return processReturn("setParameters", mStream->setParameters(hidlParams));
+    return processReturn("setParameters",
+                         utils::setParameters(mStream, hidlParams, {} /* options */));
 }
 
 status_t StreamHalHidl::getParameters(const String8& keys, String8 *values) {
@@ -119,7 +121,9 @@
     status_t status = keysFromHal(keys, &hidlKeys);
     if (status != OK) return status;
     Result retval;
-    Return<void> ret = mStream->getParameters(
+    Return<void> ret = utils::getParameters(
+            mStream,
+            {} /* context */,
             hidlKeys,
             [&](Result r, const hidl_vec<ParameterValue>& parameters) {
                 retval = r;
@@ -151,7 +155,7 @@
     if (!mStream) return NO_INIT;
     native_handle_t* hidlHandle = native_handle_create(1, 0);
     hidlHandle->data[0] = fd;
-    Return<void> ret = mStream->debugDump(hidlHandle);
+    Return<void> ret = mStream->debug(hidlHandle, {} /* options */);
     native_handle_delete(hidlHandle);
     mStreamPowerLog.dump(fd);
     return processReturn("dump", ret);
diff --git a/media/libaudiohal/4.0/StreamHalLocal.cpp b/media/libaudiohal/4.0/StreamHalLocal.cpp
index fc6e047..592a931 100644
--- a/media/libaudiohal/4.0/StreamHalLocal.cpp
+++ b/media/libaudiohal/4.0/StreamHalLocal.cpp
@@ -22,6 +22,7 @@
 
 #include "DeviceHalLocal.h"
 #include "StreamHalLocal.h"
+#include "VersionUtils.h"
 
 namespace android {
 namespace V4_0 {
diff --git a/media/libaudiohal/4.0/VersionUtils.h b/media/libaudiohal/4.0/VersionUtils.h
new file mode 100644
index 0000000..1246c2e
--- /dev/null
+++ b/media/libaudiohal/4.0/VersionUtils.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2018 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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_VERSION_UTILS_4_0_H
+#define ANDROID_HARDWARE_VERSION_UTILS_4_0_H
+
+#include <android/hardware/audio/4.0/types.h>
+#include <hidl/HidlSupport.h>
+
+using ::android::hardware::audio::V4_0::ParameterValue;
+using ::android::hardware::audio::V4_0::Result;
+using ::android::hardware::Return;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+
+namespace android {
+namespace V4_0 {
+namespace utils {
+
+template <class T, class Callback>
+Return<void> getParameters(T& object, hidl_vec<ParameterValue> context,
+                           hidl_vec<hidl_string> keys, Callback callback) {
+    return object->getParameters(context, keys, callback);
+}
+
+template <class T>
+Return<Result> setParameters(T& object, hidl_vec<ParameterValue> context,
+                             hidl_vec<ParameterValue> keys) {
+    return object->setParameters(context, keys);
+}
+
+} // namespace utils
+} // namespace V4_0
+} // namespace android
+
+#endif // ANDROID_HARDWARE_VERSION_UTILS_4_0_H
diff --git a/media/libaudiohal/4.0/DevicesFactoryHalHybrid.h b/media/libaudiohal/4.0/include/libaudiohal/4.0/DevicesFactoryHalHybrid.h
similarity index 100%
rename from media/libaudiohal/4.0/DevicesFactoryHalHybrid.h
rename to media/libaudiohal/4.0/include/libaudiohal/4.0/DevicesFactoryHalHybrid.h
diff --git a/media/libaudiohal/4.0/EffectsFactoryHalHidl.h b/media/libaudiohal/4.0/include/libaudiohal/4.0/EffectsFactoryHalHidl.h
similarity index 100%
rename from media/libaudiohal/4.0/EffectsFactoryHalHidl.h
rename to media/libaudiohal/4.0/include/libaudiohal/4.0/EffectsFactoryHalHidl.h
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index 7ecb9d8..3a5df27 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -12,9 +12,12 @@
     ],
 
     shared_libs: [
-        "android.hardware.audio@2.0",
         "android.hardware.audio.effect@2.0",
+        "android.hardware.audio.effect@4.0",
+        "android.hardware.audio@2.0",
+        "android.hardware.audio@4.0",
         "libaudiohal@2.0",
+        "libaudiohal@4.0",
         "libutils",
     ],
 
diff --git a/media/libaudiohal/DevicesFactoryHalInterface.cpp b/media/libaudiohal/DevicesFactoryHalInterface.cpp
index cfec3d6..4c8eaf6 100644
--- a/media/libaudiohal/DevicesFactoryHalInterface.cpp
+++ b/media/libaudiohal/DevicesFactoryHalInterface.cpp
@@ -14,16 +14,20 @@
  * limitations under the License.
  */
 
-#include "DevicesFactoryHalHybrid.h"
 #include <android/hardware/audio/2.0/IDevicesFactory.h>
+#include <android/hardware/audio/4.0/IDevicesFactory.h>
 
-using namespace ::android::hardware::audio;
+#include <DevicesFactoryHalHybrid.h>
+#include <libaudiohal/4.0/DevicesFactoryHalHybrid.h>
 
 namespace android {
 
 // static
 sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
-    if (V2_0::IDevicesFactory::getService() != nullptr) {
+    if (hardware::audio::V4_0::IDevicesFactory::getService() != nullptr) {
+        return new V4_0::DevicesFactoryHalHybrid();
+    }
+    if (hardware::audio::V2_0::IDevicesFactory::getService() != nullptr) {
         return new DevicesFactoryHalHybrid();
     }
     return nullptr;
diff --git a/media/libaudiohal/EffectsFactoryHalInterface.cpp b/media/libaudiohal/EffectsFactoryHalInterface.cpp
index 01a171e..ead1fa2 100644
--- a/media/libaudiohal/EffectsFactoryHalInterface.cpp
+++ b/media/libaudiohal/EffectsFactoryHalInterface.cpp
@@ -14,21 +14,21 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "EffectsFactoryHalHidl"
-//#define LOG_NDEBUG 0
+#include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
+#include <android/hardware/audio/effect/4.0/IEffectsFactory.h>
 
-#include "EffectHalHidl.h"
-#include "EffectsFactoryHalHidl.h"
+#include <EffectsFactoryHalHidl.h>
+#include <libaudiohal/4.0/EffectsFactoryHalHidl.h>
 
-using ::android::hardware::Return;
-
-using namespace ::android::hardware::audio::effect;
 
 namespace android {
 
 // static
 sp<EffectsFactoryHalInterface> EffectsFactoryHalInterface::create() {
-    if (V2_0::IEffectsFactory::getService() != nullptr) {
+    if (hardware::audio::effect::V4_0::IEffectsFactory::getService() != nullptr) {
+        return new V4_0::EffectsFactoryHalHidl();
+    }
+    if (hardware::audio::effect::V2_0::IEffectsFactory::getService() != nullptr) {
         return new EffectsFactoryHalHidl();
     }
     return nullptr;