Abstract away access to audio devices HAL

In this CL all direct access to audio_hw_device_t and its functions is
encapsulated within the new class DeviceHalLocal. Loading of hardware
modules is encapsulated withing DevicesFactoryHalLocal.  AudioFlinger
uses interface classes DevicesFactoryHalInterface and DeviceHalInterface
to access these functions.

Bug: 30222631
Change-Id: Ic88b20c55813a24b898f4a832e082c17d81935b7
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index ae0d38f..414cce8 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -27,6 +27,8 @@
     AudioHwDevice.cpp           \
     AudioStreamOut.cpp          \
     SpdifStreamOut.cpp          \
+    DeviceHalLocal.cpp          \
+    DevicesFactoryHalLocal.cpp	\
     EffectHalLocal.cpp          \
     EffectsFactoryHalLocal.cpp	\
     Effects.cpp                 \
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 9ec97d1..b5ab782 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -44,8 +44,12 @@
 
 #include "AudioMixer.h"
 #include "AudioFlinger.h"
+#include "DeviceHalInterface.h"
+#include "DevicesFactoryHalInterface.h"
 #include "EffectsFactoryHalInterface.h"
 #include "ServiceUtilities.h"
+// FIXME: Remove after streams HAL is componentized
+#include "DeviceHalLocal.h"
 
 #include <media/AudioResamplerPublic.h>
 
@@ -142,35 +146,6 @@
     return "unknown";
 }
 
-static int load_audio_interface(const char *if_name, audio_hw_device_t **dev)
-{
-    const hw_module_t *mod;
-    int rc;
-
-    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
-    ALOGE_IF(rc, "%s couldn't load audio hw module %s.%s (%s)", __func__,
-                 AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
-    if (rc) {
-        goto out;
-    }
-    rc = audio_hw_device_open(mod, dev);
-    ALOGE_IF(rc, "%s couldn't open audio hw device in %s.%s (%s)", __func__,
-                 AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
-    if (rc) {
-        goto out;
-    }
-    if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
-        ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
-        rc = BAD_VALUE;
-        goto out;
-    }
-    return 0;
-
-out:
-    *dev = NULL;
-    return rc;
-}
-
 // ----------------------------------------------------------------------------
 
 AudioFlinger::AudioFlinger()
@@ -206,6 +181,7 @@
     // in bad state, reset the state upon service start.
     BatteryNotifier::getInstance().noteResetAudio();
 
+    mDevicesFactoryHal = DevicesFactoryHalInterface::create();
     mEffectsFactoryHal = EffectsFactoryHalInterface::create();
 
 #ifdef TEE_SINK
@@ -266,7 +242,6 @@
 
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
         // no mHardwareLock needed, as there are no other references to this
-        audio_hw_device_close(mAudioHwDevs.valueAt(i)->hwDevice());
         delete mAudioHwDevs.valueAt(i);
     }
 
@@ -305,10 +280,12 @@
         // then try to find a module supporting the requested device.
         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
             AudioHwDevice *audioHwDevice = mAudioHwDevs.valueAt(i);
-            audio_hw_device_t *dev = audioHwDevice->hwDevice();
-            if ((dev->get_supported_devices != NULL) &&
-                    (dev->get_supported_devices(dev) & devices) == devices)
+            sp<DeviceHalInterface> dev = audioHwDevice->hwDevice();
+            uint32_t supportedDevices;
+            if (dev->getSupportedDevices(&supportedDevices) == OK &&
+                    (supportedDevices & devices) == devices) {
                 return audioHwDevice;
+            }
         }
     } else {
         // check a match for the requested module handle
@@ -455,8 +432,8 @@
         }
         // dump all hardware devs
         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
-            audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
-            dev->dump(dev, fd);
+            sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
+            dev->dump(fd);
         }
 
 #ifdef TEE_SINK
@@ -818,7 +795,7 @@
 
         mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
         if (dev->canSetMasterVolume()) {
-            dev->hwDevice()->set_master_volume(dev->hwDevice(), value);
+            dev->hwDevice()->setMasterVolume(value);
         }
         mHardwareStatus = AUDIO_HW_IDLE;
     }
@@ -855,9 +832,9 @@
 
     { // scope for the lock
         AutoMutex lock(mHardwareLock);
-        audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
+        sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
         mHardwareStatus = AUDIO_HW_SET_MODE;
-        ret = dev->set_mode(dev, mode);
+        ret = dev->setMode(mode);
         mHardwareStatus = AUDIO_HW_IDLE;
     }
 
@@ -886,8 +863,8 @@
     AutoMutex lock(mHardwareLock);
     mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
-        audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
-        status_t result = dev->set_mic_mute(dev, state);
+        sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
+        status_t result = dev->setMicMute(state);
         if (result != NO_ERROR) {
             ret = result;
         }
@@ -907,8 +884,8 @@
     AutoMutex lock(mHardwareLock);
     mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
     for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
-        audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
-        status_t result = dev->get_mic_mute(dev, &state);
+        sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
+        status_t result = dev->getMicMute(&state);
         if (result == NO_ERROR) {
             mute = mute && state;
         }
@@ -940,7 +917,7 @@
 
         mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
         if (dev->canSetMasterMute()) {
-            dev->hwDevice()->set_master_mute(dev->hwDevice(), muted);
+            dev->hwDevice()->setMasterMute(muted);
         }
         mHardwareStatus = AUDIO_HW_IDLE;
     }
@@ -1118,8 +1095,8 @@
             AutoMutex lock(mHardwareLock);
             mHardwareStatus = AUDIO_HW_SET_PARAMETER;
             for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
-                audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
-                status_t result = dev->set_parameters(dev, keyValuePairs.string());
+                sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
+                status_t result = dev->setParameters(keyValuePairs);
                 // return success if at least one audio device accepts the parameters as not all
                 // HALs are requested to support all parameters. If no audio device supports the
                 // requested parameters, the last error is reported.
@@ -1200,16 +1177,16 @@
         String8 out_s8;
 
         for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
-            char *s;
+            String8 s;
+            status_t result;
             {
             AutoMutex lock(mHardwareLock);
             mHardwareStatus = AUDIO_HW_GET_PARAMETER;
-            audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
-            s = dev->get_parameters(dev, keys.string());
+            sp<DeviceHalInterface> dev = mAudioHwDevs.valueAt(i)->hwDevice();
+            result = dev->getParameters(keys, &s);
             mHardwareStatus = AUDIO_HW_IDLE;
             }
-            out_s8 += String8(s ? s : "");
-            free(s);
+            if (result == OK) out_s8 += s;
         }
         return out_s8;
     }
@@ -1246,14 +1223,14 @@
     proposed.channel_mask = channelMask;
     proposed.format = format;
 
-    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
+    sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
     size_t frames;
     for (;;) {
         // Note: config is currently a const parameter for get_input_buffer_size()
         // but we use a copy from proposed in case config changes from the call.
         config = proposed;
-        frames = dev->get_input_buffer_size(dev, &config);
-        if (frames != 0) {
+        status_t result = dev->getInputBufferSize(&config, &frames);
+        if (result == OK && frames != 0) {
             break; // hal success, config is the result
         }
         // change one parameter of the configuration each iteration to a more "common" value
@@ -1300,9 +1277,9 @@
     }
 
     AutoMutex lock(mHardwareLock);
-    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
+    sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
     mHardwareStatus = AUDIO_HW_SET_VOICE_VOLUME;
-    ret = dev->set_voice_volume(dev, value);
+    ret = dev->setVoiceVolume(value);
     mHardwareStatus = AUDIO_HW_IDLE;
 
     return ret;
@@ -1640,16 +1617,16 @@
         }
     }
 
-    audio_hw_device_t *dev;
+    sp<DeviceHalInterface> dev;
 
-    int rc = load_audio_interface(name, &dev);
+    int rc = mDevicesFactoryHal->openDevice(name, &dev);
     if (rc) {
         ALOGE("loadHwModule() error %d loading module %s", rc, name);
         return AUDIO_MODULE_HANDLE_NONE;
     }
 
     mHardwareStatus = AUDIO_HW_INIT;
-    rc = dev->init_check(dev);
+    rc = dev->initCheck();
     mHardwareStatus = AUDIO_HW_IDLE;
     if (rc) {
         ALOGE("loadHwModule() init check error %d for module %s", rc, name);
@@ -1667,32 +1644,26 @@
 
         if (0 == mAudioHwDevs.size()) {
             mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
-            if (NULL != dev->get_master_volume) {
-                float mv;
-                if (OK == dev->get_master_volume(dev, &mv)) {
-                    mMasterVolume = mv;
-                }
+            float mv;
+            if (OK == dev->getMasterVolume(&mv)) {
+                mMasterVolume = mv;
             }
 
             mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
-            if (NULL != dev->get_master_mute) {
-                bool mm;
-                if (OK == dev->get_master_mute(dev, &mm)) {
-                    mMasterMute = mm;
-                }
+            bool mm;
+            if (OK == dev->getMasterMute(&mm)) {
+                mMasterMute = mm;
             }
         }
 
         mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
-        if ((NULL != dev->set_master_volume) &&
-            (OK == dev->set_master_volume(dev, mMasterVolume))) {
+        if (OK == dev->setMasterVolume(mMasterVolume)) {
             flags = static_cast<AudioHwDevice::Flags>(flags |
                     AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME);
         }
 
         mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
-        if ((NULL != dev->set_master_mute) &&
-            (OK == dev->set_master_mute(dev, mMasterMute))) {
+        if (OK == dev->setMasterMute(mMasterMute)) {
             flags = static_cast<AudioHwDevice::Flags>(flags |
                     AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE);
         }
@@ -1703,8 +1674,7 @@
     audio_module_handle_t handle = (audio_module_handle_t) nextUniqueId(AUDIO_UNIQUE_ID_USE_MODULE);
     mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
 
-    ALOGI("loadHwModule() Loaded %s audio interface from %s (%s) handle %d",
-          name, dev->common.module->name, dev->common.module->id, handle);
+    ALOGI("loadHwModule() Loaded %s audio interface, handle %d", name, handle);
 
     return handle;
 
@@ -1754,13 +1724,15 @@
         return mHwAvSyncIds.valueAt(index);
     }
 
-    audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
+    sp<DeviceHalInterface> dev = mPrimaryHardwareDev->hwDevice();
     if (dev == NULL) {
         return AUDIO_HW_SYNC_INVALID;
     }
-    char *reply = dev->get_parameters(dev, AUDIO_PARAMETER_HW_AV_SYNC);
-    AudioParameter param = AudioParameter(String8(reply));
-    free(reply);
+    String8 reply;
+    AudioParameter param;
+    if (dev->getParameters(String8(AUDIO_PARAMETER_HW_AV_SYNC), &reply) == OK) {
+        param = AudioParameter(reply);
+    }
 
     int value;
     if (param.getInt(String8(AUDIO_PARAMETER_HW_AV_SYNC), value) != NO_ERROR) {
@@ -1945,7 +1917,7 @@
 
             AutoMutex lock(mHardwareLock);
             mHardwareStatus = AUDIO_HW_SET_MODE;
-            mPrimaryHardwareDev->hwDevice()->set_mode(mPrimaryHardwareDev->hwDevice(), mMode);
+            mPrimaryHardwareDev->hwDevice()->setMode(mMode);
             mHardwareStatus = AUDIO_HW_IDLE;
         }
         return NO_ERROR;
@@ -2041,7 +2013,7 @@
     AudioStreamOut *out = thread->clearOutput();
     ALOG_ASSERT(out != NULL, "out shouldn't be NULL");
     // from now on thread->mOutput is NULL
-    out->hwDev()->close_output_stream(out->hwDev(), out->stream);
+    static_cast<DeviceHalLocal*>(out->hwDev().get())->closeOutputStream(out->stream);
     delete out;
 }
 
@@ -2136,10 +2108,10 @@
     }
 
     audio_config_t halconfig = *config;
-    audio_hw_device_t *inHwHal = inHwDev->hwDevice();
+    sp<DeviceHalInterface> inHwHal = inHwDev->hwDevice();
     audio_stream_in_t *inStream = NULL;
-    status_t status = inHwHal->open_input_stream(inHwHal, *input, devices, &halconfig,
-                                        &inStream, flags, address.string(), source);
+    status_t status = static_cast<DeviceHalLocal*>(inHwHal.get())->openInputStream(
+            *input, devices, &halconfig, flags, address.string(), source, &inStream);
     ALOGV("openInput_l() openInputStream returned input %p, SamplingRate %d"
            ", Format %#x, Channels %x, flags %#x, status %d addr %s",
             inStream,
@@ -2160,8 +2132,8 @@
         // FIXME describe the change proposed by HAL (save old values so we can log them here)
         ALOGV("openInput_l() reopening with proposed sampling rate and channel mask");
         inStream = NULL;
-        status = inHwHal->open_input_stream(inHwHal, *input, devices, &halconfig,
-                                            &inStream, flags, address.string(), source);
+        status = static_cast<DeviceHalLocal*>(inHwHal.get())->openInputStream(
+                *input, devices, &halconfig, flags, address.string(), source, &inStream);
         // FIXME log this new status; HAL should not propose any further changes
     }
 
@@ -2312,7 +2284,7 @@
     AudioStreamIn *in = thread->clearInput();
     ALOG_ASSERT(in != NULL, "in shouldn't be NULL");
     // from now on thread->mInput is NULL
-    in->hwDev()->close_input_stream(in->hwDev(), in->stream);
+    static_cast<DeviceHalLocal*>(in->hwDev().get())->closeInputStream(in->stream);
     delete in;
 }
 
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index cbd9a08..1890c94 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -71,6 +71,8 @@
 class AudioMixer;
 class AudioBuffer;
 class AudioResampler;
+class DeviceHalInterface;
+class DevicesFactoryHalInterface;
 class EffectsFactoryHalInterface;
 class FastMixer;
 class PassthruBufferProvider;
@@ -616,7 +618,7 @@
         audio_stream_in_t* const stream;
         audio_input_flags_t flags;
 
-        audio_hw_device_t* hwDev() const { return audioHwDev->hwDevice(); }
+        sp<DeviceHalInterface> hwDev() const { return audioHwDev->hwDevice(); }
 
         AudioStreamIn(AudioHwDevice *dev, audio_stream_in_t *in, audio_input_flags_t flags) :
             audioHwDev(dev), stream(in), flags(flags) {}
@@ -647,6 +649,8 @@
                 AudioHwDevice*                      mPrimaryHardwareDev; // mAudioHwDevs[0] or NULL
                 DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>  mAudioHwDevs;
 
+                sp<DevicesFactoryHalInterface> mDevicesFactoryHal;
+
     // for dump, indicates which hardware operation is currently in progress (but not stream ops)
     enum hardware_call_state {
         AUDIO_HW_IDLE = 0,              // no operation in progress
diff --git a/services/audioflinger/AudioHwDevice.cpp b/services/audioflinger/AudioHwDevice.cpp
index 7494930..ee10f8d 100644
--- a/services/audioflinger/AudioHwDevice.cpp
+++ b/services/audioflinger/AudioHwDevice.cpp
@@ -93,5 +93,10 @@
     return status;
 }
 
+uint32_t AudioHwDevice::version() const
+{
+    uint32_t result;
+    return mHwDevice->getVersion(&result) == OK ? result : 0;
+}
 
 }; // namespace android
diff --git a/services/audioflinger/AudioHwDevice.h b/services/audioflinger/AudioHwDevice.h
index b9f65c1..54e1d59 100644
--- a/services/audioflinger/AudioHwDevice.h
+++ b/services/audioflinger/AudioHwDevice.h
@@ -26,6 +26,7 @@
 #include <utils/Errors.h>
 #include <system/audio.h>
 
+#include "DeviceHalInterface.h"
 
 namespace android {
 
@@ -40,7 +41,7 @@
 
     AudioHwDevice(audio_module_handle_t handle,
                   const char *moduleName,
-                  audio_hw_device_t *hwDevice,
+                  sp<DeviceHalInterface> hwDevice,
                   Flags flags)
         : mHandle(handle)
         , mModuleName(strdup(moduleName))
@@ -58,8 +59,8 @@
 
     audio_module_handle_t handle() const { return mHandle; }
     const char *moduleName() const { return mModuleName; }
-    audio_hw_device_t *hwDevice() const { return mHwDevice; }
-    uint32_t version() const { return mHwDevice->common.version; }
+    sp<DeviceHalInterface> hwDevice() const { return mHwDevice; }
+    uint32_t version() const;
 
     /** This method creates and opens the audio hardware output stream.
      * The "address" parameter qualifies the "devices" audio device type if needed.
@@ -79,7 +80,7 @@
 private:
     const audio_module_handle_t mHandle;
     const char * const          mModuleName;
-    audio_hw_device_t * const   mHwDevice;
+    sp<DeviceHalInterface>      mHwDevice;
     const Flags                 mFlags;
 };
 
diff --git a/services/audioflinger/AudioStreamOut.cpp b/services/audioflinger/AudioStreamOut.cpp
index 6026bbb..4839480 100644
--- a/services/audioflinger/AudioStreamOut.cpp
+++ b/services/audioflinger/AudioStreamOut.cpp
@@ -23,6 +23,10 @@
 
 #include "AudioHwDevice.h"
 #include "AudioStreamOut.h"
+#include "DeviceHalInterface.h"
+
+// FIXME: Remove after streams HAL is componentized
+#include "DeviceHalLocal.h"
 
 namespace android {
 
@@ -40,7 +44,7 @@
 {
 }
 
-audio_hw_device_t *AudioStreamOut::hwDev() const
+sp<DeviceHalInterface> AudioStreamOut::hwDev() const
 {
     return audioHwDev->hwDevice();
 }
@@ -121,14 +125,13 @@
                 ? (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO)
                 : flags;
 
-    int status = hwDev()->open_output_stream(
-            hwDev(),
+    int status = static_cast<DeviceHalLocal*>(hwDev().get())->openOutputStream(
             handle,
             devices,
             customFlags,
             config,
-            &outStream,
-            address);
+            address,
+            &outStream);
     ALOGV("AudioStreamOut::open(), HAL returned "
             " stream %p, sampleRate %d, Format %#x, "
             "channelMask %#x, status %d",
@@ -144,14 +147,13 @@
         struct audio_config customConfig = *config;
         customConfig.format = AUDIO_FORMAT_PCM_16_BIT;
 
-        status = hwDev()->open_output_stream(
-                hwDev(),
+        status = static_cast<DeviceHalLocal*>(hwDev().get())->openOutputStream(
                 handle,
                 devices,
                 customFlags,
                 &customConfig,
-                &outStream,
-                address);
+                address,
+                &outStream);
         ALOGV("AudioStreamOut::open(), treat IEC61937 as PCM, status = %d", status);
     }
 
diff --git a/services/audioflinger/AudioStreamOut.h b/services/audioflinger/AudioStreamOut.h
index 1e31b6a..d132f6f 100644
--- a/services/audioflinger/AudioStreamOut.h
+++ b/services/audioflinger/AudioStreamOut.h
@@ -26,6 +26,7 @@
 namespace android {
 
 class AudioHwDevice;
+class DeviceHalInterface;
 
 /**
  * Managed access to a HAL output stream.
@@ -39,7 +40,7 @@
     audio_stream_out_t *stream;
     const audio_output_flags_t flags;
 
-    audio_hw_device_t *hwDev() const;
+    sp<DeviceHalInterface> hwDev() const;
 
     AudioStreamOut(AudioHwDevice *dev, audio_output_flags_t flags);
 
diff --git a/services/audioflinger/DeviceHalInterface.h b/services/audioflinger/DeviceHalInterface.h
new file mode 100644
index 0000000..ea682f0
--- /dev/null
+++ b/services/audioflinger/DeviceHalInterface.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2016 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_DEVICE_HAL_INTERFACE_H
+#define ANDROID_HARDWARE_DEVICE_HAL_INTERFACE_H
+
+#include <hardware/audio.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class DeviceHalInterface : public RefBase
+{
+  public:
+    // The destructor automatically closes the device.
+    virtual ~DeviceHalInterface() {}
+
+    // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
+    virtual status_t getSupportedDevices(uint32_t *devices) = 0;
+
+    // Get the hardware module version.
+    virtual status_t getVersion(uint32_t *version) = 0;
+
+    // Check to see if the audio hardware interface has been initialized.
+    virtual status_t initCheck() = 0;
+
+    // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
+    virtual status_t setVoiceVolume(float volume) = 0;
+
+    // Set the audio volume for all audio activities other than voice call.
+    virtual status_t setMasterVolume(float volume) = 0;
+
+    // Get the current master volume value for the HAL.
+    virtual status_t getMasterVolume(float *volume) = 0;
+
+    // Called when the audio mode changes.
+    virtual status_t setMode(audio_mode_t mode) = 0;
+
+    // Muting control.
+    virtual status_t setMicMute(bool state) = 0;
+    virtual status_t getMicMute(bool *state) = 0;
+    virtual status_t setMasterMute(bool state) = 0;
+    virtual status_t getMasterMute(bool *state) = 0;
+
+    // Set global audio parameters.
+    virtual status_t setParameters(const String8& kvPairs) = 0;
+
+    // Get global audio parameters.
+    virtual status_t getParameters(const String8& keys, String8 *values) = 0;
+
+    // Returns audio input buffer size according to parameters passed.
+    virtual status_t getInputBufferSize(const struct audio_config *config,
+            size_t *size) = 0;
+
+    // Creates and opens the audio hardware output stream. The stream is closed
+    // by releasing all references to the returned object.
+    // FIXME: Enable when StreamOutHalInterface is introduced.
+    // virtual status_t openOutputStream(
+    //         audio_io_handle_t handle,
+    //         audio_devices_t devices,
+    //         audio_output_flags_t flags,
+    //         struct audio_config *config,
+    //         const char *address,
+    //         sp<StreamOutHalInterface> *outStream) = 0;
+
+    // Creates and opens the audio hardware input stream. The stream is closed
+    // by releasing all references to the returned object.
+    // FIXME: Enable when StreamInHalInterface is introduced.
+    // virtual status_t openInputStream(
+    //         audio_io_handle_t handle,
+    //         audio_devices_t devices,
+    //         struct audio_config *config,
+    //         audio_input_flags_t flags,
+    //         const char *address,
+    //         audio_source_t source,
+    //         sp<StreamInHalInterface> *inStream) = 0;
+
+    // Creates an audio patch between several source and sink ports.
+    virtual status_t createAudioPatch(
+            unsigned int num_sources,
+            const struct audio_port_config *sources,
+            unsigned int num_sinks,
+            const struct audio_port_config *sinks,
+            audio_patch_handle_t *patch) = 0;
+
+    // Releases an audio patch.
+    virtual status_t releaseAudioPatch(audio_patch_handle_t patch) = 0;
+
+    // Fills the list of supported attributes for a given audio port.
+    virtual status_t getAudioPort(struct audio_port *port) = 0;
+
+    // Set audio port configuration.
+    virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
+
+    virtual status_t dump(int fd) = 0;
+
+  protected:
+    // Subclasses can not be constructed directly by clients.
+    DeviceHalInterface() {}
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DEVICE_HAL_INTERFACE_H
diff --git a/services/audioflinger/DeviceHalLocal.cpp b/services/audioflinger/DeviceHalLocal.cpp
new file mode 100644
index 0000000..b602f16
--- /dev/null
+++ b/services/audioflinger/DeviceHalLocal.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#define LOG_TAG "AudioFlinger::DeviceHalLocal"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+
+#include "DeviceHalLocal.h"
+
+namespace android {
+
+DeviceHalLocal::DeviceHalLocal(audio_hw_device_t *dev)
+        : mDev(dev) {
+}
+
+DeviceHalLocal::~DeviceHalLocal() {
+    int status = audio_hw_device_close(mDev);
+    ALOGW_IF(status, "Error closing audio hw device %p: %s", mDev, strerror(-status));
+    mDev = 0;
+}
+
+status_t DeviceHalLocal::getSupportedDevices(uint32_t *devices) {
+    if (mDev->get_supported_devices == NULL) return INVALID_OPERATION;
+    *devices = mDev->get_supported_devices(mDev);
+    return OK;
+}
+
+status_t DeviceHalLocal::getVersion(uint32_t *version) {
+    *version = mDev->common.version;
+    return OK;
+}
+
+status_t DeviceHalLocal::initCheck() {
+    return mDev->init_check(mDev);
+}
+
+status_t DeviceHalLocal::setVoiceVolume(float volume) {
+    return mDev->set_voice_volume(mDev, volume);
+}
+
+status_t DeviceHalLocal::setMasterVolume(float volume) {
+    if (mDev->set_master_volume == NULL) return INVALID_OPERATION;
+    return mDev->set_master_volume(mDev, volume);
+}
+
+status_t DeviceHalLocal::getMasterVolume(float *volume) {
+    if (mDev->get_master_volume == NULL) return INVALID_OPERATION;
+    return mDev->get_master_volume(mDev, volume);
+}
+
+status_t DeviceHalLocal::setMode(audio_mode_t mode) {
+    return mDev->set_mode(mDev, mode);
+}
+
+status_t DeviceHalLocal::setMicMute(bool state) {
+    return mDev->set_mic_mute(mDev, state);
+}
+
+status_t DeviceHalLocal::getMicMute(bool *state) {
+    return mDev->get_mic_mute(mDev, state);
+}
+
+status_t DeviceHalLocal::setMasterMute(bool state) {
+    if (mDev->set_master_mute == NULL) return INVALID_OPERATION;
+    return mDev->set_master_mute(mDev, state);
+}
+
+status_t DeviceHalLocal::getMasterMute(bool *state) {
+    if (mDev->get_master_mute == NULL) return INVALID_OPERATION;
+    return mDev->get_master_mute(mDev, state);
+}
+
+status_t DeviceHalLocal::setParameters(const String8& kvPairs) {
+    return mDev->set_parameters(mDev, kvPairs.string());
+}
+
+status_t DeviceHalLocal::getParameters(const String8& keys, String8 *values) {
+    char *c_values = mDev->get_parameters(mDev, keys.string());
+    if (c_values != NULL) {
+        values->setTo(c_values);
+        free(c_values);
+    } else {
+        values->clear();
+    }
+    return OK;
+}
+
+status_t DeviceHalLocal::getInputBufferSize(
+        const struct audio_config *config, size_t *size) {
+    *size = mDev->get_input_buffer_size(mDev, config);
+    return OK;
+}
+
+status_t DeviceHalLocal::createAudioPatch(
+        unsigned int num_sources,
+        const struct audio_port_config *sources,
+        unsigned int num_sinks,
+        const struct audio_port_config *sinks,
+        audio_patch_handle_t *patch) {
+    return mDev->create_audio_patch(mDev, num_sources, sources, num_sinks, sinks, patch);
+}
+
+status_t DeviceHalLocal::releaseAudioPatch(audio_patch_handle_t patch) {
+    return mDev->release_audio_patch(mDev, patch);
+}
+
+status_t DeviceHalLocal::getAudioPort(struct audio_port *port) {
+    return mDev->get_audio_port(mDev, port);
+}
+
+status_t DeviceHalLocal::setAudioPortConfig(const struct audio_port_config *config) {
+    return mDev->set_audio_port_config(mDev, config);
+}
+
+status_t DeviceHalLocal::dump(int fd) {
+    return mDev->dump(mDev, fd);
+}
+
+status_t DeviceHalLocal::openOutputStream(
+        audio_io_handle_t handle,
+        audio_devices_t devices,
+        audio_output_flags_t flags,
+        struct audio_config *config,
+        const char *address,
+        struct audio_stream_out **stream_out) {
+    return mDev->open_output_stream(mDev, handle, devices, flags, config, stream_out, address);
+}
+
+status_t DeviceHalLocal::closeOutputStream(struct audio_stream_out *stream_out) {
+    mDev->close_output_stream(mDev, stream_out);
+    return OK;
+}
+
+status_t DeviceHalLocal::openInputStream(
+        audio_io_handle_t handle,
+        audio_devices_t devices,
+        struct audio_config *config,
+        audio_input_flags_t flags,
+        const char *address,
+        audio_source_t source,
+        struct audio_stream_in **stream_in) {
+    return mDev->open_input_stream(
+            mDev, handle, devices, config, stream_in, flags, address, source);
+}
+
+status_t DeviceHalLocal::closeInputStream(struct audio_stream_in *stream_in) {
+    mDev->close_input_stream(mDev, stream_in);
+    return OK;
+}
+
+} // namespace android
diff --git a/services/audioflinger/DeviceHalLocal.h b/services/audioflinger/DeviceHalLocal.h
new file mode 100644
index 0000000..cc53e9c
--- /dev/null
+++ b/services/audioflinger/DeviceHalLocal.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2016 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_DEVICE_HAL_LOCAL_H
+#define ANDROID_HARDWARE_DEVICE_HAL_LOCAL_H
+
+#include "DeviceHalInterface.h"
+
+namespace android {
+
+class DeviceHalLocal : public DeviceHalInterface
+{
+  public:
+    // The destructor automatically closes the device.
+    virtual ~DeviceHalLocal();
+
+    // Sets the value of 'devices' to a bitmask of 1 or more values of audio_devices_t.
+    virtual status_t getSupportedDevices(uint32_t *devices);
+
+    // Get the hardware module version.
+    virtual status_t getVersion(uint32_t *version);
+
+    // Check to see if the audio hardware interface has been initialized.
+    virtual status_t initCheck();
+
+    // Set the audio volume of a voice call. Range is between 0.0 and 1.0.
+    virtual status_t setVoiceVolume(float volume);
+
+    // Set the audio volume for all audio activities other than voice call.
+    virtual status_t setMasterVolume(float volume);
+
+    // Get the current master volume value for the HAL.
+    virtual status_t getMasterVolume(float *volume);
+
+    // Called when the audio mode changes.
+    virtual status_t setMode(audio_mode_t mode);
+
+    // Muting control.
+    virtual status_t setMicMute(bool state);
+    virtual status_t getMicMute(bool *state);
+    virtual status_t setMasterMute(bool state);
+    virtual status_t getMasterMute(bool *state);
+
+    // Set global audio parameters.
+    virtual status_t setParameters(const String8& kvPairs);
+
+    // Get global audio parameters.
+    virtual status_t getParameters(const String8& keys, String8 *values);
+
+    // Returns audio input buffer size according to parameters passed.
+    virtual status_t getInputBufferSize(const struct audio_config *config,
+            size_t *size);
+
+    // Creates and opens the audio hardware output stream. The stream is closed
+    // by releasing all references to the returned object.
+    // FIXME: Enable when StreamOutHalInterface is introduced.
+    // virtual status_t openOutputStream(
+    //         audio_io_handle_t handle,
+    //         audio_devices_t devices,
+    //         audio_output_flags_t flags,
+    //         struct audio_config *config,
+    //         const char *address,
+    //         sp<StreamOutHalInterface> *outStream);
+
+    // Creates and opens the audio hardware input stream. The stream is closed
+    // by releasing all references to the returned object.
+    // FIXME: Enable when StreamInHalInterface is introduced.
+    // virtual status_t openInputStream(
+    //         audio_io_handle_t handle,
+    //         audio_devices_t devices,
+    //         struct audio_config *config,
+    //         audio_input_flags_t flags,
+    //         const char *address,
+    //         audio_source_t source,
+    //         sp<StreamInHalInterface> *inStream);
+
+    // Creates an audio patch between several source and sink ports.
+    virtual status_t createAudioPatch(
+            unsigned int num_sources,
+            const struct audio_port_config *sources,
+            unsigned int num_sinks,
+            const struct audio_port_config *sinks,
+            audio_patch_handle_t *patch);
+
+    // Releases an audio patch.
+    virtual status_t releaseAudioPatch(audio_patch_handle_t patch);
+
+    // Fills the list of supported attributes for a given audio port.
+    virtual status_t getAudioPort(struct audio_port *port);
+
+    // Set audio port configuration.
+    virtual status_t setAudioPortConfig(const struct audio_port_config *config);
+
+    virtual status_t dump(int fd);
+
+    // FIXME: Remove when StreamOutHalInterface is introduced.
+    status_t openOutputStream(
+            audio_io_handle_t handle,
+            audio_devices_t devices,
+            audio_output_flags_t flags,
+            struct audio_config *config,
+            const char *address,
+            struct audio_stream_out **stream_out);
+
+    // FIXME: Remove when StreamOutHalInterface is introduced.
+    status_t closeOutputStream(struct audio_stream_out *stream_out);
+
+    // FIXME: Remove when StreamInHalInterface is introduced.
+    status_t openInputStream(
+            audio_io_handle_t handle,
+            audio_devices_t devices,
+            struct audio_config *config,
+            audio_input_flags_t flags,
+            const char *address,
+            audio_source_t source,
+            struct audio_stream_in **stream_in);
+
+    // FIXME: Remove when StreamInHalInterface is introduced.
+    status_t closeInputStream(struct audio_stream_in *stream_in);
+
+  private:
+    audio_hw_device_t *mDev;
+
+    friend class DevicesFactoryHalLocal;
+
+    // Can not be constructed directly by clients.
+    explicit DeviceHalLocal(audio_hw_device_t *dev);
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DEVICE_HAL_LOCAL_H
diff --git a/services/audioflinger/DevicesFactoryHalInterface.h b/services/audioflinger/DevicesFactoryHalInterface.h
new file mode 100644
index 0000000..70c8260
--- /dev/null
+++ b/services/audioflinger/DevicesFactoryHalInterface.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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_DEVICES_FACTORY_HAL_INTERFACE_H
+#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_INTERFACE_H
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include "DeviceHalInterface.h"
+
+namespace android {
+
+class DevicesFactoryHalInterface : public RefBase
+{
+  public:
+    virtual ~DevicesFactoryHalInterface() {}
+
+    // Opens a device with the specified name. To close the device, it is
+    // necessary to release references to the returned object.
+    virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device) = 0;
+
+    static sp<DevicesFactoryHalInterface> create();
+
+  protected:
+    // Subclasses can not be constructed directly by clients.
+    DevicesFactoryHalInterface() {}
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_INTERFACE_H
diff --git a/services/audioflinger/DevicesFactoryHalLocal.cpp b/services/audioflinger/DevicesFactoryHalLocal.cpp
new file mode 100644
index 0000000..437be25
--- /dev/null
+++ b/services/audioflinger/DevicesFactoryHalLocal.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#define LOG_TAG "AudioFlinger::DevicesFactoryHalLocal"
+//#define LOG_NDEBUG 0
+
+#include <string.h>
+
+#include <hardware/audio.h>
+#include <utils/Log.h>
+
+#include "DeviceHalLocal.h"
+#include "DevicesFactoryHalLocal.h"
+
+namespace android {
+
+// static
+sp<DevicesFactoryHalInterface> DevicesFactoryHalInterface::create() {
+    return new DevicesFactoryHalLocal();
+}
+
+static status_t load_audio_interface(const char *if_name, audio_hw_device_t **dev)
+{
+    const hw_module_t *mod;
+    int rc;
+
+    rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
+    if (rc) {
+        ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__,
+                AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
+        goto out;
+    }
+    rc = audio_hw_device_open(mod, dev);
+    if (rc) {
+        ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__,
+                AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
+        goto out;
+    }
+    if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
+        ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
+        rc = BAD_VALUE;
+        audio_hw_device_close(*dev);
+        goto out;
+    }
+    return OK;
+
+out:
+    *dev = NULL;
+    return rc;
+}
+
+status_t DevicesFactoryHalLocal::openDevice(const char *name, sp<DeviceHalInterface> *device) {
+    audio_hw_device_t *dev;
+    status_t rc = load_audio_interface(name, &dev);
+    if (rc == OK) {
+        *device = new DeviceHalLocal(dev);
+    }
+    return rc;
+}
+
+} // namespace android
diff --git a/services/audioflinger/DevicesFactoryHalLocal.h b/services/audioflinger/DevicesFactoryHalLocal.h
new file mode 100644
index 0000000..55d422c
--- /dev/null
+++ b/services/audioflinger/DevicesFactoryHalLocal.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 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_DEVICES_FACTORY_HAL_LOCAL_H
+#define ANDROID_HARDWARE_DEVICES_FACTORY_HAL_LOCAL_H
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include "DeviceHalLocal.h"
+#include "DevicesFactoryHalInterface.h"
+
+namespace android {
+
+class DevicesFactoryHalLocal : public DevicesFactoryHalInterface
+{
+  public:
+    virtual ~DevicesFactoryHalLocal() {}
+
+    // Opens a device with the specified name. To close the device, it is
+    // necessary to release references to the returned object.
+    virtual status_t openDevice(const char *name, sp<DeviceHalInterface> *device);
+
+  private:
+    friend class DevicesFactoryHalInterface;
+
+    // Can not be constructed directly by clients.
+    DevicesFactoryHalLocal() {}
+};
+
+} // namespace android
+
+#endif // ANDROID_HARDWARE_DEVICES_FACTORY_HAL_LOCAL_H
diff --git a/services/audioflinger/EffectHalInterface.h b/services/audioflinger/EffectHalInterface.h
index 8f93723..e774520 100644
--- a/services/audioflinger/EffectHalInterface.h
+++ b/services/audioflinger/EffectHalInterface.h
@@ -23,7 +23,7 @@
 
 namespace android {
 
-class EffectHalInterface : public virtual RefBase
+class EffectHalInterface : public RefBase
 {
   public:
     // The destructor automatically releases the effect.
diff --git a/services/audioflinger/EffectHalLocal.cpp b/services/audioflinger/EffectHalLocal.cpp
index 11fdc30..aae1921 100644
--- a/services/audioflinger/EffectHalLocal.cpp
+++ b/services/audioflinger/EffectHalLocal.cpp
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "AudioFlinger::EffectHalLocal"
+//#define LOG_NDEBUG 0
+
 #include <media/EffectsFactoryApi.h>
 #include <utils/Log.h>
 
@@ -27,9 +30,8 @@
 
 EffectHalLocal::~EffectHalLocal() {
     int status = EffectRelease(mHandle);
-    if (status != 0) {
-        ALOGW("Error releasing effect %p: %s", mHandle, strerror(-status));
-    }
+    ALOGW_IF(status, "Error releasing effect %p: %s", mHandle, strerror(-status));
+    mHandle = 0;
 }
 
 status_t EffectHalLocal::process(audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) {
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 984bde0..42b5e98 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -467,7 +467,7 @@
             audio_stream_t *stream = thread->stream();
             if (stream != NULL) {
                 stream->add_audio_effect(stream,
-                        reinterpret_cast<EffectHalLocal*>(mEffectInterface.get())->handle());
+                        static_cast<EffectHalLocal*>(mEffectInterface.get())->handle());
             }
         }
     }
@@ -554,7 +554,7 @@
             audio_stream_t *stream = thread->stream();
             if (stream != NULL) {
                 stream->remove_audio_effect(stream,
-                        reinterpret_cast<EffectHalLocal*>(mEffectInterface.get())->handle());
+                        static_cast<EffectHalLocal*>(mEffectInterface.get())->handle());
             }
         }
     }
diff --git a/services/audioflinger/EffectsFactoryHalInterface.h b/services/audioflinger/EffectsFactoryHalInterface.h
index 2805560..a865dd1 100644
--- a/services/audioflinger/EffectsFactoryHalInterface.h
+++ b/services/audioflinger/EffectsFactoryHalInterface.h
@@ -25,7 +25,7 @@
 
 namespace android {
 
-class EffectsFactoryHalInterface : public virtual RefBase
+class EffectsFactoryHalInterface : public RefBase
 {
   public:
     virtual ~EffectsFactoryHalInterface() {}
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index bee17fd..c94ea45 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -202,9 +202,9 @@
                     if (hwModule != AUDIO_MODULE_HANDLE_NONE) {
                         ssize_t index = audioflinger->mAudioHwDevs.indexOfKey(hwModule);
                         if (index >= 0) {
-                            audio_hw_device_t *hwDevice =
+                            sp<DeviceHalInterface> hwDevice =
                                     audioflinger->mAudioHwDevs.valueAt(index)->hwDevice();
-                            hwDevice->release_audio_patch(hwDevice, halHandle);
+                            hwDevice->releaseAudioPatch(halHandle);
                         }
                     }
                 }
@@ -344,13 +344,12 @@
                         goto exit;
                     }
 
-                    audio_hw_device_t *hwDevice = audioHwDevice->hwDevice();
-                    status = hwDevice->create_audio_patch(hwDevice,
-                                                           patch->num_sources,
-                                                           patch->sources,
-                                                           patch->num_sinks,
-                                                           patch->sinks,
-                                                           &halHandle);
+                    sp<DeviceHalInterface> hwDevice = audioHwDevice->hwDevice();
+                    status = hwDevice->createAudioPatch(patch->num_sources,
+                                                        patch->sources,
+                                                        patch->num_sinks,
+                                                        patch->sinks,
+                                                        &halHandle);
                 }
             }
         } break;
@@ -623,8 +622,8 @@
                     status = INVALID_OPERATION;
                     break;
                 }
-                audio_hw_device_t *hwDevice = audioHwDevice->hwDevice();
-                status = hwDevice->release_audio_patch(hwDevice, removedPatch->mHalHandle);
+                sp<DeviceHalInterface> hwDevice = audioHwDevice->hwDevice();
+                status = hwDevice->releaseAudioPatch(removedPatch->mHalHandle);
             }
         } break;
         case AUDIO_PORT_TYPE_MIX: {
@@ -688,8 +687,8 @@
 
     AudioHwDevice *audioHwDevice = audioflinger->mAudioHwDevs.valueAt(index);
     if (audioHwDevice->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
-        audio_hw_device_t *hwDevice = audioHwDevice->hwDevice();
-        return hwDevice->set_audio_port_config(hwDevice, config);
+        sp<DeviceHalInterface> hwDevice = audioHwDevice->hwDevice();
+        return hwDevice->setAudioPortConfig(config);
     } else {
         return INVALID_OPERATION;
     }
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 546cb86..6b5651d 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3504,13 +3504,12 @@
     mPatch = *patch;
 
     if (mOutput->audioHwDev->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
-        audio_hw_device_t *hwDevice = mOutput->audioHwDev->hwDevice();
-        status = hwDevice->create_audio_patch(hwDevice,
-                                               patch->num_sources,
-                                               patch->sources,
-                                               patch->num_sinks,
-                                               patch->sinks,
-                                               handle);
+        sp<DeviceHalInterface> hwDevice = mOutput->audioHwDev->hwDevice();
+        status = hwDevice->createAudioPatch(patch->num_sources,
+                                            patch->sources,
+                                            patch->num_sinks,
+                                            patch->sinks,
+                                            handle);
     } else {
         char *address;
         if (strcmp(patch->sinks[0].ext.device.address, "") != 0) {
@@ -3556,8 +3555,8 @@
     mOutDevice = AUDIO_DEVICE_NONE;
 
     if (mOutput->audioHwDev->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
-        audio_hw_device_t *hwDevice = mOutput->audioHwDev->hwDevice();
-        status = hwDevice->release_audio_patch(hwDevice, handle);
+        sp<DeviceHalInterface> hwDevice = mOutput->audioHwDev->hwDevice();
+        status = hwDevice->releaseAudioPatch(handle);
     } else {
         AudioParameter param;
         param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0);
@@ -7588,13 +7587,12 @@
     }
 
     if (mInput->audioHwDev->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
-        audio_hw_device_t *hwDevice = mInput->audioHwDev->hwDevice();
-        status = hwDevice->create_audio_patch(hwDevice,
-                                               patch->num_sources,
-                                               patch->sources,
-                                               patch->num_sinks,
-                                               patch->sinks,
-                                               handle);
+        sp<DeviceHalInterface> hwDevice = mInput->audioHwDev->hwDevice();
+        status = hwDevice->createAudioPatch(patch->num_sources,
+                                            patch->sources,
+                                            patch->num_sinks,
+                                            patch->sinks,
+                                            handle);
     } else {
         char *address;
         if (strcmp(patch->sources[0].ext.device.address, "") != 0) {
@@ -7630,8 +7628,8 @@
     mInDevice = AUDIO_DEVICE_NONE;
 
     if (mInput->audioHwDev->version() >= AUDIO_DEVICE_API_VERSION_3_0) {
-        audio_hw_device_t *hwDevice = mInput->audioHwDev->hwDevice();
-        status = hwDevice->release_audio_patch(hwDevice, handle);
+        sp<DeviceHalInterface> hwDevice = mInput->audioHwDev->hwDevice();
+        status = hwDevice->releaseAudioPatch(handle);
     } else {
         AudioParameter param;
         param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0);