diff --git a/policy_hal/Android.mk b/policy_hal/Android.mk
index b6c01a4..7d365d6 100644
--- a/policy_hal/Android.mk
+++ b/policy_hal/Android.mk
@@ -1,26 +1,49 @@
-ifneq ($(USE_LEGACY_AUDIO_POLICY), 1)
-ifeq ($(USE_CUSTOM_AUDIO_POLICY), 1)
+ifeq ($(strip $(BOARD_USES_EXTN_AUDIO_POLICY_MANAGER)),true)
 
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
-    AudioPolicyManager.cpp
+LOCAL_SRC_FILES := AudioPolicyManager.cpp
 
 LOCAL_SHARED_LIBRARIES := \
     libcutils \
     libutils \
     liblog
 
-LOCAL_C_INCLUDES := \
-    $(TOPDIR)frameworks/av/services/audiopolicy \
-
 LOCAL_STATIC_LIBRARIES := \
     libmedia_helper
 
-LOCAL_MODULE:= libaudiopolicymanager
+LOCAL_WHOLE_STATIC_LIBRARIES := \
+    libaudiopolicy_legacy
+
+LOCAL_MODULE := audio_policy.$(TARGET_BOARD_PLATFORM)
+LOCAL_MODULE_RELATIVE_PATH := hw
+LOCAL_MODULE_TAGS := optional
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FM)),true)
+LOCAL_CFLAGS += -DAUDIO_EXTN_FM_ENABLED
+endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_PROXY_DEVICE)),true)
+LOCAL_CFLAGS += -DAUDIO_EXTN_AFE_PROXY_ENABLED
+endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_INCALL_MUSIC)),true)
+LOCAL_CFLAGS += -DAUDIO_EXTN_INCALL_MUSIC_ENABLED
+endif
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_HDMI_SPK)),true)
+LOCAL_CFLAGS += -DAUDIO_EXTN_HDMI_SPK_ENABLED
+endif
+
+
+ifeq ($(strip $(TARGET_BOARD_PLATFORM)),msm8916)
+LOCAL_CFLAGS += -DVOICE_CONCURRENCY
+LOCAL_CFLAGS += -DWFD_CONCURRENCY
+endif
+
+ifeq ($(strip $(AUDIO_FEATURE_ENABLED_MULTIPLE_TUNNEL)), true)
+LOCAL_CFLAGS += -DMULTIPLE_OFFLOAD_ENABLED
+endif
+
 
 include $(BUILD_SHARED_LIBRARY)
 
 endif
-endif
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 019161b..2309730 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2009 The Android Open Source Project
@@ -27,180 +27,57 @@
 #define ALOGVV(a...) do { } while(0)
 #endif
 
-// A device mask for all audio input devices that are considered "virtual" when evaluating
-// active inputs in getActiveInput()
-#define APM_AUDIO_IN_DEVICE_VIRTUAL_ALL  AUDIO_DEVICE_IN_REMOTE_SUBMIX
 // A device mask for all audio output devices that are considered "remote" when evaluating
 // active output devices in isStreamActiveRemotely()
 #define APM_AUDIO_OUT_DEVICE_REMOTE_ALL  AUDIO_DEVICE_OUT_REMOTE_SUBMIX
 
-#include <inttypes.h>
-#include <math.h>
-
-#include <cutils/properties.h>
 #include <utils/Log.h>
-#include <hardware/audio.h>
-#include <hardware/audio_effect.h>
-#include <media/AudioParameter.h>
 #include "AudioPolicyManager.h"
-#include "audio_policy_conf.h"
+#include <hardware/audio_effect.h>
+#include <hardware/audio.h>
+#include <math.h>
+#include <hardware_legacy/audio_policy_conf.h>
+#include <cutils/properties.h>
 
-namespace android {
-
-// ----------------------------------------------------------------------------
-// Definitions for audio_policy.conf file parsing
-// ----------------------------------------------------------------------------
-
-struct StringToEnum {
-    const char *name;
-    uint32_t value;
-};
-
-#define STRING_TO_ENUM(string) { #string, string }
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
-const StringToEnum sDeviceNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_EARPIECE),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPEAKER),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_SCO),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_ALL_USB),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_TELEPHONY_TX),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_LINE),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI_ARC),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPDIF),
-    STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_HDMI),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_FM_TUNER),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_TV_TUNER),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_LINE),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_SPDIF),
-    STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
-};
-
-const StringToEnum sFlagNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DIRECT),
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY),
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_FAST),
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
-    STRING_TO_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
-};
-
-const StringToEnum sFormatNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_FORMAT_PCM_16_BIT),
-    STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_BIT),
-    STRING_TO_ENUM(AUDIO_FORMAT_PCM_32_BIT),
-    STRING_TO_ENUM(AUDIO_FORMAT_PCM_8_24_BIT),
-    STRING_TO_ENUM(AUDIO_FORMAT_PCM_FLOAT),
-    STRING_TO_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED),
-    STRING_TO_ENUM(AUDIO_FORMAT_MP3),
-    STRING_TO_ENUM(AUDIO_FORMAT_AAC),
-    STRING_TO_ENUM(AUDIO_FORMAT_VORBIS),
-};
-
-const StringToEnum sOutChannelsNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_MONO),
-    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_STEREO),
-    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
-    STRING_TO_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
-};
-
-const StringToEnum sInChannelsNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_CHANNEL_IN_MONO),
-    STRING_TO_ENUM(AUDIO_CHANNEL_IN_STEREO),
-    STRING_TO_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK),
-};
-
-const StringToEnum sGainModeNameToEnumTable[] = {
-    STRING_TO_ENUM(AUDIO_GAIN_MODE_JOINT),
-    STRING_TO_ENUM(AUDIO_GAIN_MODE_CHANNELS),
-    STRING_TO_ENUM(AUDIO_GAIN_MODE_RAMP),
-};
-
-
-uint32_t AudioPolicyManager::stringToEnum(const struct StringToEnum *table,
-                                              size_t size,
-                                              const char *name)
-{
-    for (size_t i = 0; i < size; i++) {
-        if (strcmp(table[i].name, name) == 0) {
-            ALOGV("stringToEnum() found %s", table[i].name);
-            return table[i].value;
-        }
-    }
-    return 0;
-}
-
-const char *AudioPolicyManager::enumToString(const struct StringToEnum *table,
-                                              size_t size,
-                                              uint32_t value)
-{
-    for (size_t i = 0; i < size; i++) {
-        if (table[i].value == value) {
-            return table[i].name;
-        }
-    }
-    return "";
-}
-
-bool AudioPolicyManager::stringToBool(const char *value)
-{
-    return ((strcasecmp("true", value) == 0) || (strcmp("1", value) == 0));
-}
-
+namespace android_audio_legacy {
 
 // ----------------------------------------------------------------------------
 // AudioPolicyInterface implementation
 // ----------------------------------------------------------------------------
-
+const char* AudioPolicyManager::HDMI_SPKR_STR = "hdmi_spkr";
+int AudioPolicyManager::mvoice_call_state = 0;
 
 status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
-                                                          audio_policy_dev_state_t state,
-                                                  const char *device_address)
+                                                      AudioSystem::device_connection_state state,
+                                                      const char *device_address)
 {
-    String8 address = String8(device_address);
+    SortedVector <audio_io_handle_t> outputs;
 
-    ALOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address);
+    ALOGD("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address);
 
     // connect/disconnect only 1 device at a time
     if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
 
+    if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) {
+        ALOGE("setDeviceConnectionState() invalid address: %s", device_address);
+        return BAD_VALUE;
+    }
+
     // handle output devices
     if (audio_is_output_device(device)) {
-        SortedVector <audio_io_handle_t> outputs;
 
-        sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device);
-        devDesc->mAddress = address;
-        ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
+        if (!mHasA2dp && audio_is_a2dp_device(device)) {
+            ALOGE("setDeviceConnectionState() invalid A2DP device: %x", device);
+            return BAD_VALUE;
+        }
+        if (!mHasUsb && audio_is_usb_device(device)) {
+            ALOGE("setDeviceConnectionState() invalid USB audio device: %x", device);
+            return BAD_VALUE;
+        }
+        if (!mHasRemoteSubmix && audio_is_remote_submix_device((audio_devices_t)device)) {
+            ALOGE("setDeviceConnectionState() invalid remote submix audio device: %x", device);
+            return BAD_VALUE;
+        }
 
         // save a copy of the opened output descriptors before any output is opened or closed
         // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
@@ -208,46 +85,109 @@
         switch (state)
         {
         // handle output device connection
-        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE:
-            if (index >= 0) {
+        case AudioSystem::DEVICE_STATE_AVAILABLE:
+            if (mAvailableOutputDevices & device) {
+#ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
+                if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+                   if (!strncmp(device_address, HDMI_SPKR_STR, MAX_DEVICE_ADDRESS_LEN)) {
+                        mHdmiAudioDisabled = false;
+                    } else {
+                        mHdmiAudioEvent = true;
+                    }
+                }
+#endif
                 ALOGW("setDeviceConnectionState() device already connected: %x", device);
                 return INVALID_OPERATION;
             }
             ALOGV("setDeviceConnectionState() connecting device %x", device);
 
-            if (checkOutputsForDevice(device, state, outputs, address) != NO_ERROR) {
+            if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) {
                 return INVALID_OPERATION;
             }
-            // outputs should never be empty here
-            ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
-                    "checkOutputsForDevice() returned no outputs but status OK");
-            ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
+            ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %d outputs",
                   outputs.size());
             // register new device as available
-            index = mAvailableOutputDevices.add(devDesc);
-            if (index >= 0) {
-                mAvailableOutputDevices[index]->mId = nextUniqueId();
-                HwModule *module = getModuleForDevice(device);
-                ALOG_ASSERT(module != NULL, "setDeviceConnectionState():"
-                        "could not find HW module for device %08x", device);
-                mAvailableOutputDevices[index]->mModule = module;
-            } else {
-                return NO_MEMORY;
-            }
+            mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices | device);
 
+#ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
+            if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+                if (!strncmp(device_address, HDMI_SPKR_STR, MAX_DEVICE_ADDRESS_LEN)) {
+                    mHdmiAudioDisabled = false;
+                } else {
+                    mHdmiAudioEvent = true;
+                }
+                if (mHdmiAudioDisabled || !mHdmiAudioEvent) {
+                    mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device);
+                }
+            }
+#endif
+            if (!outputs.isEmpty()) {
+                String8 paramStr;
+                if (mHasA2dp && audio_is_a2dp_device(device)) {
+                    // handle A2DP device connection
+                    AudioParameter param;
+                    param.add(String8(AUDIO_PARAMETER_A2DP_SINK_ADDRESS), String8(device_address));
+                    paramStr = param.toString();
+                    mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
+                    mA2dpSuspended = false;
+                } else if (audio_is_bluetooth_sco_device(device)) {
+                    // handle SCO device connection
+                    mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
+                } else if (mHasUsb && audio_is_usb_device(device)) {
+                    // handle USB device connection
+                    mUsbCardAndDevice = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
+                    paramStr = mUsbCardAndDevice;
+                }
+                // not currently handling multiple simultaneous submixes: ignoring remote submix
+                //   case and address
+                if (!paramStr.isEmpty()) {
+                    for (size_t i = 0; i < outputs.size(); i++) {
+                        mpClientInterface->setParameters(outputs[i], paramStr);
+                    }
+                }
+            }
             break;
         // handle output device disconnection
-        case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
-            if (index < 0) {
+        case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
+            if (!(mAvailableOutputDevices & device)) {
+#ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
+                if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+                    if (!strncmp(device_address, HDMI_SPKR_STR, MAX_DEVICE_ADDRESS_LEN)) {
+                        mHdmiAudioDisabled = true;
+                    } else {
+                        mHdmiAudioEvent = false;
+                    }
+                }
+#endif
                 ALOGW("setDeviceConnectionState() device not connected: %x", device);
                 return INVALID_OPERATION;
             }
 
             ALOGV("setDeviceConnectionState() disconnecting device %x", device);
             // remove device from available output devices
-            mAvailableOutputDevices.remove(devDesc);
+            mAvailableOutputDevices = (audio_devices_t)(mAvailableOutputDevices & ~device);
 
-            checkOutputsForDevice(device, state, outputs, address);
+#ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
+            if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+                if (!strncmp(device_address, HDMI_SPKR_STR, MAX_DEVICE_ADDRESS_LEN)) {
+                    mHdmiAudioDisabled = true;
+                } else {
+                    mHdmiAudioEvent = false;
+                }
+            }
+#endif
+            checkOutputsForDevice(device, state, outputs);
+            if (mHasA2dp && audio_is_a2dp_device(device)) {
+                // handle A2DP device disconnection
+                mA2dpDeviceAddress = "";
+                mA2dpSuspended = false;
+            } else if (audio_is_bluetooth_sco_device(device)) {
+                // handle SCO device disconnection
+                mScoDeviceAddress = "";
+            } else if (mHasUsb && audio_is_usb_device(device)) {
+                // handle USB device disconnection
+                mUsbCardAndDevice = "";
+            }
             // not currently handling multiple simultaneous submixes: ignoring remote submix
             //   case and address
             } break;
@@ -257,8 +197,6 @@
             return BAD_VALUE;
         }
 
-        // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
-        // output is suspended before any tracks are moved to it
         checkA2dpSuspend();
         checkOutputForAllStrategies();
         // outputs must be closed after checkOutputForAllStrategies() is executed
@@ -267,122 +205,1180 @@
                 AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]);
                 // close unused outputs after device disconnection or direct outputs that have been
                 // opened by checkOutputsForDevice() to query dynamic parameters
-                if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
+                if ((state == AudioSystem::DEVICE_STATE_UNAVAILABLE) ||
                         (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
                          (desc->mDirectOpenCount == 0))) {
                     closeOutput(outputs[i]);
                 }
             }
-            // check again after closing A2DP output to reset mA2dpSuspended if needed
-            checkA2dpSuspend();
         }
 
         updateDevicesAndOutputs();
+        audio_devices_t newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/);
+#ifdef AUDIO_EXTN_FM_ENABLED
+        if(device == AUDIO_DEVICE_OUT_FM) {
+            if (state == AudioSystem::DEVICE_STATE_AVAILABLE) {
+                mOutputs.valueFor(mPrimaryOutput)->changeRefCount(AudioSystem::MUSIC, 1);
+                newDevice = (audio_devices_t)(getNewDevice(mPrimaryOutput, false) | AUDIO_DEVICE_OUT_FM);
+            } else {
+                mOutputs.valueFor(mPrimaryOutput)->changeRefCount(AudioSystem::MUSIC, -1);
+            }
+
+            AudioParameter param = AudioParameter();
+            param.addInt(String8("handle_fm"), (int)newDevice);
+            ALOGV("setDeviceConnectionState() setParameters handle_fm");
+            mpClientInterface->setParameters(mPrimaryOutput, param.toString());
+        }
+#endif
         for (size_t i = 0; i < mOutputs.size(); i++) {
             // do not force device change on duplicated output because if device is 0, it will
             // also force a device 0 for the two outputs it is duplicated to which may override
             // a valid device selection on those outputs.
+            audio_devices_t cachedDevice = getNewDevice(mOutputs.keyAt(i), true /*fromCache*/);
+            AudioOutputDescriptor *desc = mOutputs.valueFor(mOutputs.keyAt(i));
+            if (cachedDevice == AUDIO_DEVICE_OUT_SPEAKER &&
+                device == AUDIO_DEVICE_OUT_PROXY &&
+                (desc->mFlags & AUDIO_OUTPUT_FLAG_FAST)) {
+                    ALOGI("Avoid routing touch tone to spkr as proxy is being disconnected");
+                    break;
+            }
             setOutputDevice(mOutputs.keyAt(i),
-                            getNewOutputDevice(mOutputs.keyAt(i), true /*fromCache*/),
+                            cachedDevice,
                             !mOutputs.valueAt(i)->isDuplicated(),
                             0);
         }
 
-        mpClientInterface->onAudioPortListUpdate();
-        return NO_ERROR;
-    }  // end if is output device
-
+        if (device == AUDIO_DEVICE_OUT_WIRED_HEADSET) {
+            device = AUDIO_DEVICE_IN_WIRED_HEADSET;
+        } else if (device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO ||
+                   device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
+                   device == AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
+            device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+        } else if(device == AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET){
+            device = AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
+        } else {
+            return NO_ERROR;
+        }
+    }
     // handle input devices
     if (audio_is_input_device(device)) {
-        SortedVector <audio_io_handle_t> inputs;
 
-        sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device);
-        devDesc->mAddress = address;
-        ssize_t index = mAvailableInputDevices.indexOf(devDesc);
         switch (state)
         {
         // handle input device connection
-        case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
-            if (index >= 0) {
+        case AudioSystem::DEVICE_STATE_AVAILABLE: {
+            if (mAvailableInputDevices & device) {
                 ALOGW("setDeviceConnectionState() device already connected: %d", device);
                 return INVALID_OPERATION;
             }
-            HwModule *module = getModuleForDevice(device);
-            if (module == NULL) {
-                ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
-                      device);
-                return INVALID_OPERATION;
+            mAvailableInputDevices = mAvailableInputDevices | (device & ~AUDIO_DEVICE_BIT_IN);
             }
-            if (checkInputsForDevice(device, state, inputs, address) != NO_ERROR) {
-                return INVALID_OPERATION;
-            }
-
-            index = mAvailableInputDevices.add(devDesc);
-            if (index >= 0) {
-                mAvailableInputDevices[index]->mId = nextUniqueId();
-                mAvailableInputDevices[index]->mModule = module;
-            } else {
-                return NO_MEMORY;
-            }
-        } break;
+            break;
 
         // handle input device disconnection
-        case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
-            if (index < 0) {
+        case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
+            if (!(mAvailableInputDevices & device)) {
                 ALOGW("setDeviceConnectionState() device not connected: %d", device);
                 return INVALID_OPERATION;
             }
-            checkInputsForDevice(device, state, inputs, address);
-            mAvailableInputDevices.remove(devDesc);
-        } break;
+            mAvailableInputDevices = (audio_devices_t) (mAvailableInputDevices & ~device);
+            } break;
 
         default:
             ALOGE("setDeviceConnectionState() invalid state: %x", state);
             return BAD_VALUE;
         }
 
-        closeAllInputs();
+        audio_io_handle_t activeInput = getActiveInput();
+        if (activeInput != 0) {
+            AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
+            audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource);
+            if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) {
+                ALOGV("setDeviceConnectionState() changing device from %x to %x for input %d",
+                        inputDesc->mDevice, newDevice, activeInput);
+                inputDesc->mDevice = newDevice;
+                AudioParameter param = AudioParameter();
+                param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
+                mpClientInterface->setParameters(activeInput, param.toString());
+            }
+        }
 
-        mpClientInterface->onAudioPortListUpdate();
         return NO_ERROR;
-    } // end if is input device
+    }
 
     ALOGW("setDeviceConnectionState() invalid device: %x", device);
     return BAD_VALUE;
 }
 
-audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devices_t device,
-                                                  const char *device_address)
+void AudioPolicyManager::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
 {
-    audio_policy_dev_state_t state = AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
-    String8 address = String8(device_address);
-    sp<DeviceDescriptor> devDesc = new DeviceDescriptor(String8(""), device);
-    devDesc->mAddress = String8(device_address);
-    ssize_t index;
-    DeviceVector *deviceVector;
+    ALOGD("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
 
-    if (audio_is_output_device(device)) {
-        deviceVector = &mAvailableOutputDevices;
-    } else if (audio_is_input_device(device)) {
-        deviceVector = &mAvailableInputDevices;
-    } else {
-        ALOGW("getDeviceConnectionState() invalid device type %08x", device);
-        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
+    bool forceVolumeReeval = false;
+    switch(usage) {
+    case AudioSystem::FOR_COMMUNICATION:
+        if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO &&
+            config != AudioSystem::FORCE_NONE) {
+            ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
+            return;
+        }
+        forceVolumeReeval = true;
+        mForceUse[usage] = config;
+        break;
+    case AudioSystem::FOR_MEDIA:
+        if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP &&
+#ifdef AUDIO_EXTN_FM_ENABLED
+            config != AudioSystem::FORCE_SPEAKER &&
+#endif
+            config != AudioSystem::FORCE_WIRED_ACCESSORY &&
+            config != AudioSystem::FORCE_ANALOG_DOCK &&
+            config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE &&
+            config != AudioSystem::FORCE_NO_BT_A2DP) {
+            ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
+            return;
+        }
+        mForceUse[usage] = config;
+        break;
+    case AudioSystem::FOR_RECORD:
+        if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY &&
+            config != AudioSystem::FORCE_NONE) {
+            ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
+            return;
+        }
+        mForceUse[usage] = config;
+        break;
+    case AudioSystem::FOR_DOCK:
+        if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK &&
+            config != AudioSystem::FORCE_BT_DESK_DOCK &&
+            config != AudioSystem::FORCE_WIRED_ACCESSORY &&
+            config != AudioSystem::FORCE_ANALOG_DOCK &&
+            config != AudioSystem::FORCE_DIGITAL_DOCK) {
+            ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
+        }
+        forceVolumeReeval = true;
+        mForceUse[usage] = config;
+        break;
+    case AudioSystem::FOR_SYSTEM:
+        if (config != AudioSystem::FORCE_NONE &&
+            config != AudioSystem::FORCE_SYSTEM_ENFORCED) {
+            ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
+        }
+        forceVolumeReeval = true;
+        mForceUse[usage] = config;
+        break;
+    default:
+        ALOGW("setForceUse() invalid usage %d", usage);
+        break;
     }
 
-    index = deviceVector->indexOf(devDesc);
-    if (index >= 0) {
-        return AUDIO_POLICY_DEVICE_STATE_AVAILABLE;
-    } else {
-        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
+    // check for device and output changes triggered by new force usage
+    checkA2dpSuspend();
+    checkOutputForAllStrategies();
+    updateDevicesAndOutputs();
+    for (int i = mOutputs.size() -1; i >= 0; i--) {
+        audio_io_handle_t output = mOutputs.keyAt(i);
+        audio_devices_t newDevice = getNewDevice(output, true /*fromCache*/);
+        setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE));
+        if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
+            applyStreamVolumes(output, newDevice, 0, true);
+        }
+    }
+
+    audio_io_handle_t activeInput = getActiveInput();
+    if (activeInput != 0) {
+        AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
+        audio_devices_t newDevice = getDeviceForInputSource(inputDesc->mInputSource);
+        if ((newDevice != AUDIO_DEVICE_NONE) && (newDevice != inputDesc->mDevice)) {
+            ALOGV("setForceUse() changing device from %x to %x for input %d",
+                    inputDesc->mDevice, newDevice, activeInput);
+            inputDesc->mDevice = newDevice;
+            AudioParameter param = AudioParameter();
+            param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
+            mpClientInterface->setParameters(activeInput, param.toString());
+        }
+    }
+
+}
+
+audio_io_handle_t AudioPolicyManager::getInput(int inputSource,
+                                    uint32_t samplingRate,
+                                    uint32_t format,
+                                    uint32_t channelMask,
+                                    AudioSystem::audio_in_acoustics acoustics)
+{
+    audio_io_handle_t input = 0;
+    audio_devices_t device = getDeviceForInputSource(inputSource);
+
+    ALOGD("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x",
+          inputSource, samplingRate, format, channelMask, acoustics);
+
+    if (device == AUDIO_DEVICE_NONE) {
+        ALOGW("getInput() could not find device for inputSource %d", inputSource);
+        return 0;
+    }
+
+#ifdef VOICE_CONCURRENCY
+
+    char propValue[PROPERTY_VALUE_MAX];
+    bool prop_rec_enabled=false, prop_voip_enabled = false;
+
+    if(property_get("voice.record.conc.disabled", propValue, NULL)) {
+        prop_rec_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+    }
+
+    if(property_get("voice.voip.conc.disabled", propValue, NULL)) {
+        prop_voip_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+    }
+
+    if (prop_rec_enabled && mvoice_call_state) {
+         //check if voice call is active  / running in background
+         //some of VoIP apps(like SIP2SIP call) supports resume of VoIP call when call in progress
+         //Need to block input request
+        if((AudioSystem::MODE_IN_CALL == mPhoneState) ||
+           ((AudioSystem::MODE_IN_CALL == mPrevPhoneState) &&
+             (AudioSystem::MODE_IN_COMMUNICATION == mPhoneState)))
+        {
+            switch(inputSource) {
+                case AUDIO_SOURCE_VOICE_UPLINK:
+                case AUDIO_SOURCE_VOICE_DOWNLINK:
+                case AUDIO_SOURCE_VOICE_CALL:
+                    ALOGD("Creating input during incall mode for inputSource: %d ",inputSource);
+                break;
+
+                case AUDIO_SOURCE_VOICE_COMMUNICATION:
+                    if(prop_voip_enabled) {
+                       ALOGD("BLOCKING VoIP request during incall mode for inputSource: %d ",inputSource);
+                       return 0;
+                    }
+                break;
+                default:
+                    ALOGD("BLOCKING input during incall mode for inputSource: %d ",inputSource);
+                return 0;
+            }
+        }
+    }//check for VoIP flag
+    else if(prop_voip_enabled && mvoice_call_state) {
+         //check if voice call is active  / running in background
+         //some of VoIP apps(like SIP2SIP call) supports resume of VoIP call when call in progress
+         //Need to block input request
+        if((AudioSystem::MODE_IN_CALL == mPhoneState) ||
+           ((AudioSystem::MODE_IN_CALL == mPrevPhoneState) &&
+             (AudioSystem::MODE_IN_COMMUNICATION == mPhoneState)))
+        {
+            if(inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION) {
+                ALOGD("BLOCKING VoIP request during incall mode for inputSource: %d ",inputSource);
+                return 0;
+            }
+        }
+    }
+
+#endif
+    IOProfile *profile = getInputProfile(device,
+                                         samplingRate,
+                                         format,
+                                         channelMask);
+    if (profile == NULL) {
+        ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d,"
+                "channelMask %04x",
+                device, samplingRate, format, channelMask);
+        return 0;
+    }
+
+    if (profile->mModule->mHandle == 0) {
+        ALOGE("getInput(): HW module %s not opened", profile->mModule->mName);
+        return 0;
+    }
+
+    AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile);
+
+    inputDesc->mInputSource = inputSource;
+    inputDesc->mDevice = device;
+    inputDesc->mSamplingRate = samplingRate;
+    inputDesc->mFormat = (audio_format_t)format;
+    inputDesc->mChannelMask = (audio_channel_mask_t)channelMask;
+    inputDesc->mRefCount = 0;
+    input = mpClientInterface->openInput(profile->mModule->mHandle,
+                                    &inputDesc->mDevice,
+                                    &inputDesc->mSamplingRate,
+                                    &inputDesc->mFormat,
+                                    &inputDesc->mChannelMask);
+
+    // only accept input with the exact requested set of parameters
+    if (input == 0 ||
+        (samplingRate != inputDesc->mSamplingRate) ||
+        (format != inputDesc->mFormat) ||
+        (channelMask != inputDesc->mChannelMask)) {
+        ALOGV("getInput() failed opening input: samplingRate %d, format %d, channelMask %d",
+                samplingRate, format, channelMask);
+        if (input != 0) {
+            mpClientInterface->closeInput(input);
+        }
+        delete inputDesc;
+        return 0;
+    }
+    mInputs.add(input, inputDesc);
+    ALOGD("getInput() returns input %d", input);
+
+    return input;
+}
+
+AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(AudioSystem::stream_type stream)
+{
+       // stream to strategy mapping
+        switch (stream) {
+        case AudioSystem::VOICE_CALL:
+        case AudioSystem::BLUETOOTH_SCO:
+            return STRATEGY_PHONE;
+        case AudioSystem::RING:
+        case AudioSystem::ALARM:
+            return STRATEGY_SONIFICATION;
+        case AudioSystem::NOTIFICATION:
+            return STRATEGY_SONIFICATION_RESPECTFUL;
+        case AudioSystem::DTMF:
+            return STRATEGY_DTMF;
+        default:
+            ALOGE("unknown stream type");
+        case AudioSystem::SYSTEM:
+            // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
+            // while key clicks are played produces a poor result
+        case AudioSystem::TTS:
+        case AudioSystem::MUSIC:
+#ifdef AUDIO_EXTN_INCALL_MUSIC_ENABLED
+        case AudioSystem::INCALL_MUSIC:
+#endif
+#ifdef QCOM_INCALL_MUSIC_ENABLED
+        case AudioSystem::INCALL_MUSIC:
+#endif
+             return STRATEGY_MEDIA;
+        case AudioSystem::ENFORCED_AUDIBLE:
+            return STRATEGY_ENFORCED_AUDIBLE;
+    }
+
+}
+
+audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
+                                                             bool fromCache)
+{
+    uint32_t device = AUDIO_DEVICE_NONE;
+
+    if (fromCache) {
+        ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
+              strategy, mDeviceForStrategy[strategy]);
+        return mDeviceForStrategy[strategy];
+    }
+
+    switch (strategy) {
+
+    case STRATEGY_SONIFICATION_RESPECTFUL:
+        if (isInCall()) {
+            device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
+        } else if (isStreamActiveRemotely(AudioSystem::MUSIC,
+                SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
+            // while media is playing on a remote device, use the the sonification behavior.
+            // Note that we test this usecase before testing if media is playing because
+            //   the isStreamActive() method only informs about the activity of a stream, not
+            //   if it's for local playback. Note also that we use the same delay between both tests
+            device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
+        } else if (isStreamActive(AudioSystem::MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
+            // while media is playing (or has recently played), use the same device
+            device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
+        } else {
+            // when media is not playing anymore, fall back on the sonification behavior
+            device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
+        }
+
+        break;
+
+    case STRATEGY_DTMF:
+        if (!isInCall()) {
+            // when off call, DTMF strategy follows the same rules as MEDIA strategy
+            device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
+            break;
+        }
+        // when in call, DTMF and PHONE strategies follow the same rules
+        // FALL THROUGH
+
+    case STRATEGY_PHONE:
+        // for phone strategy, we first consider the forced use and then the available devices by order
+        // of priority
+        switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
+        case AudioSystem::FORCE_BT_SCO:
+            if (!isInCall() || strategy != STRATEGY_DTMF) {
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+                if (device) break;
+            }
+            device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+            if (device) break;
+            device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
+            if (device) break;
+            // if SCO device is requested but no SCO device is available, fall back to default case
+            // FALL THROUGH
+
+        default:    // FORCE_NONE
+            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
+            if (mHasA2dp && !isInCall() &&
+                    (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
+                    (getA2dpOutput() != 0) && !mA2dpSuspended) {
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
+                if (device) break;
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
+                if (device) break;
+            }
+            device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
+            if (device) break;
+            device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET;
+            if (device) break;
+            if (mPhoneState != AudioSystem::MODE_IN_CALL) {
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY;
+                if (device) break;
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE;
+                if (device) break;
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
+                if (device) break;
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
+                if (device) break;
+            }
+
+            // Allow voice call on USB ANLG DOCK headset
+            device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
+            if (device) break;
+
+            device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_EARPIECE;
+            if (device) break;
+            device = mDefaultOutputDevice;
+            if (device == AUDIO_DEVICE_NONE) {
+                ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
+            }
+            break;
+
+        case AudioSystem::FORCE_SPEAKER:
+            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
+            // A2DP speaker when forcing to speaker output
+            if (mHasA2dp && !isInCall() &&
+                    (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
+                    (getA2dpOutput() != 0) && !mA2dpSuspended) {
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
+                if (device) break;
+            }
+            if (mPhoneState != AudioSystem::MODE_IN_CALL) {
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY;
+                if (device) break;
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE;
+                if (device) break;
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
+                if (device) break;
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
+                if (device) break;
+                device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
+                if (device) break;
+            }
+            device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
+            if (device) break;
+            device = mDefaultOutputDevice;
+            if (device == AUDIO_DEVICE_NONE) {
+                ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
+            }
+            break;
+        }
+                // FIXME: Why do need to replace with speaker? If voice call is active
+                // We should use device from STRATEGY_PHONE
+#ifdef AUDIO_EXTN_FM_ENABLED
+        if (mAvailableOutputDevices & AUDIO_DEVICE_OUT_FM) {
+            if (mForceUse[AudioSystem::FOR_MEDIA] == AudioSystem::FORCE_SPEAKER) {
+                device = AUDIO_DEVICE_OUT_SPEAKER;
+            }
+        }
+#endif
+    break;
+
+    case STRATEGY_SONIFICATION:
+
+        // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
+        // handleIncallSonification().
+        if (isInCall()) {
+            device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
+            break;
+        }
+        // FALL THROUGH
+
+    case STRATEGY_ENFORCED_AUDIBLE:
+        // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
+        // except:
+        //   - when in call where it doesn't default to STRATEGY_PHONE behavior
+        //   - in countries where not enforced in which case it follows STRATEGY_MEDIA
+
+        if ((strategy == STRATEGY_SONIFICATION) ||
+                (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED)) {
+            device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
+            if (device == AUDIO_DEVICE_NONE) {
+                ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
+            }
+        }
+        // The second device used for sonification is the same as the device used by media strategy
+        // FALL THROUGH
+
+    case STRATEGY_MEDIA: {
+        uint32_t device2 = AUDIO_DEVICE_NONE;
+
+        if (isInCall() && (device == AUDIO_DEVICE_NONE)) {
+            // when in call, get the device for Phone strategy
+            device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
+            break;
+        }
+#ifdef AUDIO_EXTN_FM_ENABLED
+        if (mForceUse[AudioSystem::FOR_MEDIA] == AudioSystem::FORCE_SPEAKER) {
+            device = AUDIO_DEVICE_OUT_SPEAKER;
+            break;
+        }
+#endif
+
+        if (strategy != STRATEGY_SONIFICATION) {
+            // no sonification on remote submix (e.g. WFD)
+            device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+        }
+        if ((device2 == AUDIO_DEVICE_NONE) &&
+                mHasA2dp && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) &&
+                (getA2dpOutput() != 0) && !mA2dpSuspended) {
+            device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
+            if (device2 == AUDIO_DEVICE_NONE) {
+                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
+            }
+            if (device2 == AUDIO_DEVICE_NONE) {
+                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
+            }
+        }
+        if (device2 == AUDIO_DEVICE_NONE) {
+            device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
+        }
+        if (device2 == AUDIO_DEVICE_NONE) {
+            device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET;
+        }
+        if (device2 == AUDIO_DEVICE_NONE) {
+            device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY;
+        }
+        if (device2 == AUDIO_DEVICE_NONE) {
+            device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE;
+        }
+        if (device2 == AUDIO_DEVICE_NONE) {
+            device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
+        }
+        if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
+             && (device2 == AUDIO_DEVICE_NONE)) {
+            // no sonification on aux digital (e.g. HDMI)
+            device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL;
+        }
+        if ((device2 == AUDIO_DEVICE_NONE) &&
+                (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_ANALOG_DOCK)
+                && (strategy != STRATEGY_SONIFICATION)) {
+            device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
+        }
+#ifdef AUDIO_EXTN_FM_ENABLED
+            if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
+                 && (device2 == AUDIO_DEVICE_NONE)) {
+                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_FM_TX;
+            }
+#endif
+#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
+            if ((strategy != STRATEGY_SONIFICATION) && (device == AUDIO_DEVICE_NONE)
+                 && (device2 == AUDIO_DEVICE_NONE)) {
+                // no sonification on WFD sink
+                device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_PROXY;
+            }
+#endif
+        if (device2 == AUDIO_DEVICE_NONE) {
+            device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER;
+        }
+
+        // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
+        // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
+        device |= device2;
+        if (device) break;
+        device = mDefaultOutputDevice;
+        if (device == AUDIO_DEVICE_NONE) {
+            ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
+        }
+        } break;
+
+    default:
+        ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
+        break;
+    }
+
+    ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
+    return device;
+}
+
+audio_devices_t AudioPolicyManager::getDeviceForInputSource(int inputSource)
+{
+    uint32_t device = AUDIO_DEVICE_NONE;
+
+    switch (inputSource) {
+    case AUDIO_SOURCE_VOICE_UPLINK:
+      if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) {
+          device = AUDIO_DEVICE_IN_VOICE_CALL;
+          break;
+      }
+      // FALL THROUGH
+
+    case AUDIO_SOURCE_DEFAULT:
+    case AUDIO_SOURCE_MIC:
+    case AUDIO_SOURCE_VOICE_RECOGNITION:
+    case AUDIO_SOURCE_HOTWORD:
+    case AUDIO_SOURCE_VOICE_COMMUNICATION:
+        if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO &&
+            mAvailableInputDevices & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
+            device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+        } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_WIRED_HEADSET) {
+            device = AUDIO_DEVICE_IN_WIRED_HEADSET;
+        } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET) {
+            device = AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET;
+        } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
+        }
+        break;
+    case AUDIO_SOURCE_CAMCORDER:
+        if (mAvailableInputDevices & AUDIO_DEVICE_IN_BACK_MIC) {
+            device = AUDIO_DEVICE_IN_BACK_MIC;
+        } else if (mAvailableInputDevices & AUDIO_DEVICE_IN_BUILTIN_MIC) {
+            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
+        }
+        break;
+    case AUDIO_SOURCE_VOICE_DOWNLINK:
+    case AUDIO_SOURCE_VOICE_CALL:
+        if (mAvailableInputDevices & AUDIO_DEVICE_IN_VOICE_CALL) {
+            device = AUDIO_DEVICE_IN_VOICE_CALL;
+        }
+        break;
+    case AUDIO_SOURCE_REMOTE_SUBMIX:
+        if (mAvailableInputDevices & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
+            device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
+        }
+        break;
+#ifdef AUDIO_EXTN_FM_ENABLED
+    case AUDIO_SOURCE_FM_RX:
+        device = AUDIO_DEVICE_IN_FM_RX;
+        break;
+    case AUDIO_SOURCE_FM_RX_A2DP:
+        device = AUDIO_DEVICE_IN_FM_RX_A2DP;
+        break;
+#endif
+    default:
+        ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
+        break;
+    }
+    ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
+    return device;
+}
+
+AudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device)
+{
+    switch(getDeviceForVolume(device)) {
+        case AUDIO_DEVICE_OUT_EARPIECE:
+            return DEVICE_CATEGORY_EARPIECE;
+        case AUDIO_DEVICE_OUT_WIRED_HEADSET:
+        case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
+        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
+        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
+        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
+        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
+#ifdef AUDIO_EXTN_FM_ENABLED
+        case AUDIO_DEVICE_OUT_FM:
+#endif
+            return DEVICE_CATEGORY_HEADSET;
+        case AUDIO_DEVICE_OUT_SPEAKER:
+        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
+        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
+        case AUDIO_DEVICE_OUT_AUX_DIGITAL:
+        case AUDIO_DEVICE_OUT_USB_ACCESSORY:
+        case AUDIO_DEVICE_OUT_USB_DEVICE:
+        case AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
+#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
+        case AUDIO_DEVICE_OUT_PROXY:
+#endif
+        default:
+            return DEVICE_CATEGORY_SPEAKER;
     }
 }
 
-void AudioPolicyManager::setPhoneState(audio_mode_t state)
+status_t AudioPolicyManager::checkAndSetVolume(int stream,
+                                               int index,
+                                               audio_io_handle_t output,
+                                               audio_devices_t device,
+                                               int delayMs,
+                                               bool force)
 {
-    ALOGV("setPhoneState() state %d", state);
+    ALOGV("checkAndSetVolume: index %d output %d device %x", index, output, device);
+    // do not change actual stream volume if the stream is muted
+    if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
+        ALOGVV("checkAndSetVolume() stream %d muted count %d",
+              stream, mOutputs.valueFor(output)->mMuteCount[stream]);
+        return NO_ERROR;
+    }
+
+    // do not change in call volume if bluetooth is connected and vice versa
+    if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
+        (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {
+        ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
+             stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);
+        return INVALID_OPERATION;
+    }
+
+    float volume = computeVolume(stream, index, output, device);
+    // We actually change the volume if:
+    // - the float value returned by computeVolume() changed
+    // - the force flag is set
+    if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
+            force) {
+        mOutputs.valueFor(output)->mCurVolume[stream] = volume;
+        ALOGV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
+        // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
+        // enabled
+        if (stream == AudioSystem::BLUETOOTH_SCO) {
+            mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs);
+#ifdef AUDIO_EXTN_FM_ENABLED
+        } else if (stream == AudioSystem::MUSIC &&
+                   output == mPrimaryOutput) {
+            float fmVolume = -1.0;
+            fmVolume = computeVolume(stream, index, output, device);
+            if (fmVolume >= 0) {
+                    AudioParameter param = AudioParameter();
+                    param.addFloat(String8("fm_volume"), fmVolume);
+                    ALOGV("checkAndSetVolume setParameters fm_volume, volume=:%f delay=:%d",fmVolume,delayMs*2);
+                    //Double delayMs to avoid sound burst while device switch.
+                    mpClientInterface->setParameters(mPrimaryOutput, param.toString(), delayMs*2);
+            }
+#endif
+        }
+        mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
+    }
+
+    if (stream == AudioSystem::VOICE_CALL ||
+        stream == AudioSystem::BLUETOOTH_SCO) {
+        float voiceVolume;
+        // Force voice volume to max for bluetooth SCO as volume is managed by the headset
+        if (stream == AudioSystem::VOICE_CALL) {
+            voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
+        } else {
+            voiceVolume = 1.0;
+        }
+
+        if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) {
+            mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
+            mLastVoiceVolume = voiceVolume;
+        }
+    }
+
+    return NO_ERROR;
+}
+
+
+float AudioPolicyManager::computeVolume(int stream,
+                                        int index,
+                                        audio_io_handle_t output,
+                                        audio_devices_t device)
+{
+    float volume = 1.0;
+    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
+
+    if (device == AUDIO_DEVICE_NONE) {
+        device = outputDesc->device();
+    }
+
+    // if volume is not 0 (not muted), force media volume to max on digital output
+    if (stream == AudioSystem::MUSIC &&
+        index != mStreams[stream].mIndexMin &&
+        (device == AUDIO_DEVICE_OUT_AUX_DIGITAL ||
+         device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET ||
+         device == AUDIO_DEVICE_OUT_USB_ACCESSORY ||
+#ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
+         device == AUDIO_DEVICE_OUT_PROXY ||
+#endif
+         device == AUDIO_DEVICE_OUT_USB_DEVICE )) {
+        return 1.0;
+    }
+#ifdef AUDIO_EXTN_INCALL_MUSIC_ENABLED
+    if (stream == AudioSystem::INCALL_MUSIC) {
+        return 1.0;
+    }
+#endif
+    return AudioPolicyManagerBase::computeVolume(stream, index, output, device);
+}
+
+
+audio_io_handle_t AudioPolicyManager::getOutput(AudioSystem::stream_type stream,
+                                    uint32_t samplingRate,
+                                    uint32_t format,
+                                    uint32_t channelMask,
+                                    AudioSystem::output_flags flags,
+                                    const audio_offload_info_t *offloadInfo)
+{
+    audio_io_handle_t output = 0;
+    uint32_t latency = 0;
+    routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
+    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
+    IOProfile *profile = NULL;
+
+#ifdef VOICE_CONCURRENCY
+    char propValue[PROPERTY_VALUE_MAX];
+    bool prop_play_enabled=false, prop_voip_enabled = false;
+
+    if(property_get("voice.playback.conc.disabled", propValue, NULL)) {
+       prop_play_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+    }
+
+    if(property_get("voice.voip.conc.disabled", propValue, NULL)) {
+       prop_voip_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+    }
+
+    if (prop_play_enabled && mvoice_call_state) {
+        //check if voice call is active  / running in background
+        if((AudioSystem::MODE_IN_CALL == mPhoneState) ||
+             ((AudioSystem::MODE_IN_CALL == mPrevPhoneState)
+                && (AudioSystem::MODE_IN_COMMUNICATION == mPhoneState)))
+        {
+            if(AUDIO_OUTPUT_FLAG_VOIP_RX  & flags) {
+                if(prop_voip_enabled) {
+                    ALOGD(" IN call mode returing no output .. for VoIP usecase flags: %x ", flags );
+                   // flags = (AudioSystem::output_flags)AUDIO_OUTPUT_FLAG_FAST;
+                   return 0;
+                }
+            }
+            else {
+                ALOGD(" IN call mode adding ULL flags .. flags: %x ", flags );
+                flags = (AudioSystem::output_flags)AUDIO_OUTPUT_FLAG_FAST;
+            }
+        }
+    } else if (prop_voip_enabled && mvoice_call_state) {
+        //check if voice call is active  / running in background
+        //some of VoIP apps(like SIP2SIP call) supports resume of VoIP call when call in progress
+        //return only ULL ouput
+        if((AudioSystem::MODE_IN_CALL == mPhoneState) ||
+             ((AudioSystem::MODE_IN_CALL == mPrevPhoneState)
+                && (AudioSystem::MODE_IN_COMMUNICATION == mPhoneState)))
+        {
+            if(AUDIO_OUTPUT_FLAG_VOIP_RX  & flags) {
+                ALOGD(" IN call mode returing no output .. for VoIP usecase flags: %x ", flags );
+               // flags = (AudioSystem::output_flags)AUDIO_OUTPUT_FLAG_FAST;
+               return 0;
+            }
+        }
+    }
+#endif
+
+#ifdef WFD_CONCURRENCY
+    if ((mAvailableOutputDevices & AUDIO_DEVICE_OUT_PROXY)
+          && (stream != AudioSystem::MUSIC)) {
+        ALOGV(" WFD mode adding ULL flags for non music stream.. flags: %x ", flags );
+        //For voip paths
+        if(flags & AudioSystem::OUTPUT_FLAG_DIRECT)
+            flags = AudioSystem::OUTPUT_FLAG_DIRECT;
+        else //route every thing else to ULL path
+            flags = (AudioSystem::output_flags)AUDIO_OUTPUT_FLAG_FAST;
+    }
+#endif
+
+    ALOGD(" getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x ",
+          device, stream, samplingRate, format, channelMask, flags);
+
+
+
+#ifdef AUDIO_POLICY_TEST
+    if (mCurOutput != 0) {
+        ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
+                mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
+
+        if (mTestOutputs[mCurOutput] == 0) {
+            ALOGV("getOutput() opening test output");
+            AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
+            outputDesc->mDevice = mTestDevice;
+            outputDesc->mSamplingRate = mTestSamplingRate;
+            outputDesc->mFormat = mTestFormat;
+            outputDesc->mChannelMask = mTestChannels;
+            outputDesc->mLatency = mTestLatencyMs;
+            outputDesc->mFlags = (audio_output_flags_t)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0);
+            outputDesc->mRefCount[stream] = 0;
+            mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice,
+                                            &outputDesc->mSamplingRate,
+                                            &outputDesc->mFormat,
+                                            &outputDesc->mChannelMask,
+                                            &outputDesc->mLatency,
+                                            outputDesc->mFlags,
+                                            offloadInfo);
+            if (mTestOutputs[mCurOutput]) {
+                AudioParameter outputCmd = AudioParameter();
+                outputCmd.addInt(String8("set_id"),mCurOutput);
+                mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
+                addOutput(mTestOutputs[mCurOutput], outputDesc);
+            }
+        }
+        return mTestOutputs[mCurOutput];
+    }
+#endif //AUDIO_POLICY_TEST
+
+    // open a direct output if required by specified parameters
+    //force direct flag if offload flag is set: offloading implies a direct output stream
+    // and all common behaviors are driven by checking only the direct flag
+    // this should normally be set appropriately in the policy configuration file
+    if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
+        flags = (AudioSystem::output_flags)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
+    }
+
+    if ((format == AudioSystem::PCM_16_BIT) &&(AudioSystem::popCount(channelMask) > 2)) {
+        ALOGV("owerwrite flag(%x) for PCM16 multi-channel(CM:%x) playback", flags ,channelMask);
+        flags = (AudioSystem::output_flags)AUDIO_OUTPUT_FLAG_DIRECT;
+    }
+
+    // Do not allow offloading if one non offloadable effect is enabled. This prevents from
+    // creating an offloaded track and tearing it down immediately after start when audioflinger
+    // detects there is an active non offloadable effect.
+    // FIXME: We should check the audio session here but we do not have it in this context.
+    // This may prevent offloading in rare situations where effects are left active by apps
+    // in the background.
+    if ((((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
+            !isNonOffloadableEffectEnabled()) &&
+            flags & AUDIO_OUTPUT_FLAG_DIRECT) {
+        profile = getProfileForDirectOutput(device,
+                                           samplingRate,
+                                           format,
+                                           channelMask,
+                                           (audio_output_flags_t)flags);
+    }
+
+    if (profile != NULL) {
+        AudioOutputDescriptor *outputDesc = NULL;
+
+#ifdef MULTIPLE_OFFLOAD_ENABLED
+        bool multiOffloadEnabled = false;
+        char value[PROPERTY_VALUE_MAX] = {0};
+        property_get("audio.offload.multiple.enabled", value, NULL);
+        if (atoi(value) || !strncmp("true", value, 4))
+            multiOffloadEnabled = true;
+        // if multiple concurrent offload decode is supported
+        // do no check for reuse and also don't close previous output if its offload
+        // previous output will be closed during track destruction
+        if (multiOffloadEnabled)
+            goto get_output__new_output_desc;
+#endif
+        for (size_t i = 0; i < mOutputs.size(); i++) {
+            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
+            if (!desc->isDuplicated() && (profile == desc->mProfile)) {
+                outputDesc = desc;
+                // reuse direct output if currently open and configured with same parameters
+                if ((samplingRate == outputDesc->mSamplingRate) &&
+                        (format == outputDesc->mFormat) &&
+                        (channelMask == outputDesc->mChannelMask)) {
+                    outputDesc->mDirectOpenCount++;
+                    ALOGD("getOutput() reusing direct output %d", mOutputs.keyAt(i));
+                    return mOutputs.keyAt(i);
+                }
+            }
+        }
+        // close direct output if currently open and configured with different parameters
+        if (outputDesc != NULL) {
+            closeOutput(outputDesc->mId);
+        }
+get_output__new_output_desc:
+        outputDesc = new AudioOutputDescriptor(profile);
+        outputDesc->mDevice = device;
+        outputDesc->mSamplingRate = samplingRate;
+        outputDesc->mFormat = (audio_format_t)format;
+        outputDesc->mChannelMask = (audio_channel_mask_t)channelMask;
+        outputDesc->mLatency = 0;
+        outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags);
+        outputDesc->mRefCount[stream] = 0;
+        outputDesc->mStopTime[stream] = 0;
+        outputDesc->mDirectOpenCount = 1;
+        output = mpClientInterface->openOutput(profile->mModule->mHandle,
+                                        &outputDesc->mDevice,
+                                        &outputDesc->mSamplingRate,
+                                        &outputDesc->mFormat,
+                                        &outputDesc->mChannelMask,
+                                        &outputDesc->mLatency,
+                                        outputDesc->mFlags,
+                                        offloadInfo);
+
+        // only accept an output with the requested parameters
+        if (output == 0 ||
+            (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
+            (format != 0 && format != outputDesc->mFormat) ||
+            (channelMask != 0 && channelMask != outputDesc->mChannelMask)) {
+            ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
+                    "format %d %d, channelMask %04x %04x", output, samplingRate,
+                    outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
+                    outputDesc->mChannelMask);
+            if (output != 0) {
+                mpClientInterface->closeOutput(output);
+            }
+            delete outputDesc;
+            return 0;
+        }
+        audio_io_handle_t srcOutput = getOutputForEffect();
+        addOutput(output, outputDesc);
+        audio_io_handle_t dstOutput = getOutputForEffect();
+        if (dstOutput == output) {
+            mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
+        }
+        mPreviousOutputs = mOutputs;
+        ALOGV("getOutput() returns new direct output %d", output);
+        return output;
+    }
+
+    // ignoring channel mask due to downmix capability in mixer
+
+    // open a non direct output
+
+    // for non direct outputs, only PCM is supported
+    if (audio_is_linear_pcm((audio_format_t)format)) {
+        // get which output is suitable for the specified stream. The actual
+        // routing change will happen when startOutput() will be called
+        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
+
+        output = selectOutput(outputs, flags);
+    }
+    ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
+            "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
+
+    ALOGD("getOutput() returns output %d", output);
+
+    return output;
+}
+
+
+// This function checks for the parameters which can be offloaded.
+// This can be enhanced depending on the capability of the DSP and policy
+// of the system.
+bool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo)
+{
+    ALOGD("copl: isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
+     " BitRate=%u, duration=%lld us, has_video=%d",
+     offloadInfo.sample_rate, offloadInfo.channel_mask,
+     offloadInfo.format,
+     offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
+     offloadInfo.has_video);
+
+#ifdef VOICE_CONCURRENCY
+    char concpropValue[PROPERTY_VALUE_MAX];
+    if(property_get("voice.playback.conc.disabled", concpropValue, NULL)) {
+         bool propenabled = atoi(concpropValue) || !strncmp("true", concpropValue, 4);
+         if (propenabled) {
+            if(isInCall())
+            {
+                ALOGD("\n copl: blocking  compress offload on call mode\n");
+                return false;
+            }
+         }
+    }
+
+#endif
+    // Check if stream type is music, then only allow offload as of now.
+    if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
+    {
+        ALOGD("copl: isOffloadSupported: stream_type != MUSIC, returning false");
+        return false;
+    }
+
+    char propValue[PROPERTY_VALUE_MAX];
+    bool pcmOffload = false;
+    if (audio_is_offload_pcm(offloadInfo.format)) {
+        if(property_get("audio.offload.pcm.enable", propValue, NULL)) {
+            bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+            if (prop_enabled) {
+                ALOGW("PCM offload property is enabled");
+                pcmOffload = true;
+            }
+        }
+        if (!pcmOffload) {
+            ALOGD("copl: PCM offload disabled by property audio.offload.pcm.enable");
+            return false;
+        }
+    }
+
+    if (!pcmOffload) {
+        // Check if offload has been disabled
+        if (property_get("audio.offload.disable", propValue, "0")) {
+            if (atoi(propValue) != 0) {
+                ALOGD("copl: offload disabled by audio.offload.disable=%s", propValue );
+                return false;
+            }
+        }
+
+        //check if it's multi-channel AAC format
+        if (AudioSystem::popCount(offloadInfo.channel_mask) > 2
+              && offloadInfo.format == AUDIO_FORMAT_AAC) {
+            ALOGD("copl: offload disabled for multi-channel AAC format");
+            return false;
+        }
+
+        if (offloadInfo.has_video)
+        {
+            if(property_get("av.offload.enable", propValue, NULL)) {
+                bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+                if (!prop_enabled) {
+                    ALOGW("offload disabled by av.offload.enable = %s ", propValue );
+                    return false;
+                }
+            } else {
+                return false;
+            }
+
+            if(offloadInfo.is_streaming) {
+                if (property_get("av.streaming.offload.enable", propValue, NULL)) {
+                    bool prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+                    if (!prop_enabled) {
+                       ALOGW("offload disabled by av.streaming.offload.enable = %s ", propValue );
+                       return false;
+                    }
+                } else {
+                    //Do not offload AV streamnig if the property is not defined
+                    return false;
+                }
+            }
+            ALOGD("copl: isOffloadSupported: has_video == true, property\
+                    set to enable offload");
+        }
+    }
+
+    //If duration is less than minimum value defined in property, return false
+    if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
+        if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
+            ALOGD("copl: Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
+            return false;
+        }
+    } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
+        ALOGD("copl: Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
+        //duration checks only valid for MP3/AAC formats,
+        //do not check duration for other audio formats, e.g. dolby AAC/AC3 and amrwb+ formats
+        if (offloadInfo.format == AUDIO_FORMAT_MP3 || offloadInfo.format == AUDIO_FORMAT_AAC || pcmOffload)
+            return false;
+    }
+
+    // Do not allow offloading if one non offloadable effect is enabled. This prevents from
+    // creating an offloaded track and tearing it down immediately after start when audioflinger
+    // detects there is an active non offloadable effect.
+    // FIXME: We should check the audio session here but we do not have it in this context.
+    // This may prevent offloading in rare situations where effects are left active by apps
+    // in the background.
+    if (isNonOffloadableEffectEnabled()) {
+        return false;
+    }
+
+    // See if there is a profile to support this.
+    // AUDIO_DEVICE_NONE
+    IOProfile *profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
+                                            offloadInfo.sample_rate,
+                                            offloadInfo.format,
+                                            offloadInfo.channel_mask,
+                                            AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
+    ALOGD("copl: isOffloadSupported() profile %sfound", profile != NULL ? "" : "NOT ");
+    return (profile != NULL);
+}
+
+void AudioPolicyManager::setPhoneState(int state)
+
+{
+    ALOGD("setPhoneState() state %d", state);
     audio_devices_t newDevice = AUDIO_DEVICE_NONE;
-    if (state < 0 || state >= AUDIO_MODE_CNT) {
+    if (state < 0 || state >= AudioSystem::NUM_MODES) {
         ALOGW("setPhoneState() invalid state %d", state);
         return;
     }
@@ -396,8 +1392,8 @@
     // pertaining to sonification strategy see handleIncallSonification()
     if (isInCall()) {
         ALOGV("setPhoneState() in call state management: new state is %d", state);
-        for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
-            handleIncallSonification((audio_stream_type_t)stream, false, true);
+        for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
+            handleIncallSonification(stream, false, true);
         }
     }
 
@@ -405,6 +1401,7 @@
     int oldState = mPhoneState;
     mPhoneState = state;
     bool force = false;
+    int voice_call_state = 0;
 
     // are we entering or starting a call
     if (!isStateInCall(oldState) && isStateInCall(state)) {
@@ -433,7 +1430,7 @@
     }
 
     // check for device and output changes triggered by new phone state
-    newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
+    newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/);
     checkA2dpSuspend();
     checkOutputForAllStrategies();
     updateDevicesAndOutputs();
@@ -445,6 +1442,135 @@
     if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) {
         newDevice = hwOutputDesc->device();
     }
+#ifdef VOICE_CONCURRENCY
+    char propValue[PROPERTY_VALUE_MAX];
+    bool prop_playback_enabled = false, prop_rec_enabled=false, prop_voip_enabled = false;
+
+    if(property_get("voice.playback.conc.disabled", propValue, NULL)) {
+        prop_playback_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+    }
+
+    if(property_get("voice.record.conc.disabled", propValue, NULL)) {
+        prop_rec_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+    }
+
+    if(property_get("voice.voip.conc.disabled", propValue, NULL)) {
+        prop_voip_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
+    }
+
+    bool mode_in_call = (AudioSystem::MODE_IN_CALL != oldState) && (AudioSystem::MODE_IN_CALL == state);
+    //query if it is a actual voice call initiated by telephony
+    if (mode_in_call) {
+        String8 valueStr = mpClientInterface->getParameters((audio_io_handle_t)0, String8("in_call"));
+        AudioParameter result = AudioParameter(valueStr);
+        if (result.getInt(String8("in_call"), voice_call_state) == NO_ERROR)
+            ALOGD("SetPhoneState: Voice call state = %d", voice_call_state);
+    }
+
+    if (mode_in_call && voice_call_state) {
+        ALOGD("Entering to call mode oldState :: %d state::%d ",oldState, state);
+        mvoice_call_state = voice_call_state;
+        if (prop_playback_enabled) {
+            //Call invalidate to reset all opened non ULL audio tracks
+            // Move tracks associated to this strategy from previous output to new output
+            for (int i = AudioSystem::SYSTEM; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
+                ALOGV(" Invalidate on call mode for stream :: %d ", i);
+                //FIXME see fixme on name change
+                mpClientInterface->setStreamOutput((AudioSystem::stream_type)i,
+                                                  0 /* ignored */);
+            }
+        }
+
+        if (prop_rec_enabled) {
+            //Close all active inputs
+            audio_io_handle_t activeInput = getActiveInput();
+            if (activeInput != 0) {
+               AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput);
+               switch(activeDesc->mInputSource) {
+                   case AUDIO_SOURCE_VOICE_UPLINK:
+                   case AUDIO_SOURCE_VOICE_DOWNLINK:
+                   case AUDIO_SOURCE_VOICE_CALL:
+                       ALOGD("FOUND active input during call active: %d",activeDesc->mInputSource);
+                   break;
+
+                   case  AUDIO_SOURCE_VOICE_COMMUNICATION:
+                        if(prop_voip_enabled) {
+                            ALOGD("CLOSING VoIP input source on call setup :%d ",activeDesc->mInputSource);
+                            stopInput(activeInput);
+                            releaseInput(activeInput);
+                        }
+                   break;
+
+                   default:
+                       ALOGD("CLOSING input on call setup  for inputSource: %d",activeDesc->mInputSource);
+                       stopInput(activeInput);
+                       releaseInput(activeInput);
+                   break;
+               }
+           }
+        } else if (prop_voip_enabled) {
+            audio_io_handle_t activeInput = getActiveInput();
+            if (activeInput != 0) {
+               AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput);
+                if (AUDIO_SOURCE_VOICE_COMMUNICATION == activeDesc->mInputSource) {
+                    ALOGD("CLOSING VoIP on call setup : %d",activeDesc->mInputSource);
+                    stopInput(activeInput);
+                    releaseInput(activeInput);
+                }
+            }
+        }
+
+        //suspend  PCM (deep-buffer) output & close  compress & direct tracks
+        for (size_t i = 0; i < mOutputs.size(); i++) {
+            AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
+            if (!outputDesc || !outputDesc->mProfile) {
+               ALOGD("ouput desc / profile is NULL");
+               continue;
+            }
+            if (((!outputDesc->isDuplicated() &&outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY))
+                        && prop_playback_enabled) {
+                ALOGD(" calling suspendOutput on call mode for primary output");
+                mpClientInterface->suspendOutput(mOutputs.keyAt(i));
+            } //Close compress all sessions
+            else if ((outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
+                            &&  prop_playback_enabled) {
+                ALOGD(" calling closeOutput on call mode for COMPRESS output");
+                closeOutput(mOutputs.keyAt(i));
+            }
+            else if ((outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_VOIP_RX)
+                            && prop_voip_enabled) {
+                ALOGD(" calling closeOutput on call mode for DIRECT  output");
+                closeOutput(mOutputs.keyAt(i));
+            }
+        }
+   }
+
+   if ((AudioSystem::MODE_IN_CALL == oldState) && (AudioSystem::MODE_IN_CALL != state)
+        && prop_playback_enabled && mvoice_call_state) {
+        ALOGD("EXITING from call mode oldState :: %d state::%d \n",oldState, state);
+        mvoice_call_state = 0;
+        //restore PCM (deep-buffer) output after call termination
+        for (size_t i = 0; i < mOutputs.size(); i++) {
+            AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
+            if (!outputDesc || !outputDesc->mProfile) {
+               ALOGD("ouput desc / profile is NULL");
+               continue;
+            }
+            if (!outputDesc->isDuplicated() &&outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
+                ALOGD("calling restoreOutput after call mode for primary output");
+                mpClientInterface->restoreOutput(mOutputs.keyAt(i));
+            }
+       }
+       //call invalidate tracks so that any open streams can fall back to deep buffer/compress path from ULL
+       for (int i = AudioSystem::SYSTEM; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
+           ALOGD("Invalidate on call mode for stream :: %d ", i);
+           //FIXME see fixme on name change
+           mpClientInterface->setStreamOutput((AudioSystem::stream_type)i,
+                                                  0 /* ignored */);
+       }
+    }
+#endif
+    mPrevPhoneState = oldState;
 
     int delayMs = 0;
     if (isStateInCall(state)) {
@@ -479,5279 +1605,35 @@
     // pertaining to sonification strategy see handleIncallSonification()
     if (isStateInCall(state)) {
         ALOGV("setPhoneState() in call state management: new state is %d", state);
-        for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
-            handleIncallSonification((audio_stream_type_t)stream, true, true);
+        for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
+            handleIncallSonification(stream, true, true);
         }
     }
 
     // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
-    if (state == AUDIO_MODE_RINGTONE &&
-        isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
+    if (state == AudioSystem::MODE_RINGTONE &&
+        isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
         mLimitRingtoneVolume = true;
     } else {
         mLimitRingtoneVolume = false;
     }
+    ALOGD(" End of setPhoneState ... mPhoneState: %d ",mPhoneState);
 }
 
-void AudioPolicyManager::setForceUse(audio_policy_force_use_t usage,
-                                         audio_policy_forced_cfg_t config)
+bool AudioPolicyManager::isStateInCall(int state)
 {
-    ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
-
-    bool forceVolumeReeval = false;
-    switch(usage) {
-    case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
-        if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
-            config != AUDIO_POLICY_FORCE_NONE) {
-            ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
-            return;
-        }
-        forceVolumeReeval = true;
-        mForceUse[usage] = config;
-        break;
-    case AUDIO_POLICY_FORCE_FOR_MEDIA:
-        if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
-            config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
-            config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
-            config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
-            config != AUDIO_POLICY_FORCE_NO_BT_A2DP) {
-            ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
-            return;
-        }
-        mForceUse[usage] = config;
-        break;
-    case AUDIO_POLICY_FORCE_FOR_RECORD:
-        if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
-            config != AUDIO_POLICY_FORCE_NONE) {
-            ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
-            return;
-        }
-        mForceUse[usage] = config;
-        break;
-    case AUDIO_POLICY_FORCE_FOR_DOCK:
-        if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
-            config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
-            config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
-            config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
-            config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
-            ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
-        }
-        forceVolumeReeval = true;
-        mForceUse[usage] = config;
-        break;
-    case AUDIO_POLICY_FORCE_FOR_SYSTEM:
-        if (config != AUDIO_POLICY_FORCE_NONE &&
-            config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
-            ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
-        }
-        forceVolumeReeval = true;
-        mForceUse[usage] = config;
-        break;
-    default:
-        ALOGW("setForceUse() invalid usage %d", usage);
-        break;
-    }
-
-    // check for device and output changes triggered by new force usage
-    checkA2dpSuspend();
-    checkOutputForAllStrategies();
-    updateDevicesAndOutputs();
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        audio_io_handle_t output = mOutputs.keyAt(i);
-        audio_devices_t newDevice = getNewOutputDevice(output, true /*fromCache*/);
-        setOutputDevice(output, newDevice, (newDevice != AUDIO_DEVICE_NONE));
-        if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
-            applyStreamVolumes(output, newDevice, 0, true);
-        }
-    }
-
-    audio_io_handle_t activeInput = getActiveInput();
-    if (activeInput != 0) {
-        setInputDevice(activeInput, getNewInputDevice(activeInput));
-    }
-
+    return ((state == AudioSystem::MODE_IN_CALL) || (state == AudioSystem::MODE_IN_COMMUNICATION) ||
+       ((state == AudioSystem::MODE_RINGTONE) && (mPrevPhoneState == AudioSystem::MODE_IN_CALL)));
 }
 
-audio_policy_forced_cfg_t AudioPolicyManager::getForceUse(audio_policy_force_use_t usage)
+extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
 {
-    return mForceUse[usage];
+    return new AudioPolicyManager(clientInterface);
 }
 
-void AudioPolicyManager::setSystemProperty(const char* property, const char* value)
+extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
 {
-    ALOGV("setSystemProperty() property %s, value %s", property, value);
-}
-
-// Find a direct output profile compatible with the parameters passed, even if the input flags do
-// not explicitly request a direct output
-sp<AudioPolicyManager::IOProfile> AudioPolicyManager::getProfileForDirectOutput(
-                                                               audio_devices_t device,
-                                                               uint32_t samplingRate,
-                                                               audio_format_t format,
-                                                               audio_channel_mask_t channelMask,
-                                                               audio_output_flags_t flags)
-{
-    for (size_t i = 0; i < mHwModules.size(); i++) {
-        if (mHwModules[i]->mHandle == 0) {
-            continue;
-        }
-        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++) {
-            sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
-            bool found = false;
-            if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
-                if (profile->isCompatibleProfile(device, samplingRate, format,
-                                           channelMask,
-                                           AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) {
-                    found = true;
-                }
-            } else {
-                if (profile->isCompatibleProfile(device, samplingRate, format,
-                                           channelMask,
-                                           AUDIO_OUTPUT_FLAG_DIRECT)) {
-                    found = true;
-                }
-            }
-            if (found && (mAvailableOutputDevices.types() & profile->mSupportedDevices.types())) {
-                return profile;
-            }
-        }
-    }
-    return 0;
-}
-
-audio_io_handle_t AudioPolicyManager::getOutput(audio_stream_type_t stream,
-                                    uint32_t samplingRate,
-                                    audio_format_t format,
-                                    audio_channel_mask_t channelMask,
-                                    audio_output_flags_t flags,
-                                    const audio_offload_info_t *offloadInfo)
-{
-    audio_io_handle_t output = 0;
-    uint32_t latency = 0;
-    routing_strategy strategy = getStrategy(stream);
-    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
-    ALOGV("getOutput() device %d, stream %d, samplingRate %d, format %x, channelMask %x, flags %x",
-          device, stream, samplingRate, format, channelMask, flags);
-
-#ifdef AUDIO_POLICY_TEST
-    if (mCurOutput != 0) {
-        ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
-                mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
-
-        if (mTestOutputs[mCurOutput] == 0) {
-            ALOGV("getOutput() opening test output");
-            AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
-            outputDesc->mDevice = mTestDevice;
-            outputDesc->mSamplingRate = mTestSamplingRate;
-            outputDesc->mFormat = mTestFormat;
-            outputDesc->mChannelMask = mTestChannels;
-            outputDesc->mLatency = mTestLatencyMs;
-            outputDesc->mFlags =
-                    (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
-            outputDesc->mRefCount[stream] = 0;
-            mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice,
-                                            &outputDesc->mSamplingRate,
-                                            &outputDesc->mFormat,
-                                            &outputDesc->mChannelMask,
-                                            &outputDesc->mLatency,
-                                            outputDesc->mFlags,
-                                            offloadInfo);
-            if (mTestOutputs[mCurOutput]) {
-                AudioParameter outputCmd = AudioParameter();
-                outputCmd.addInt(String8("set_id"),mCurOutput);
-                mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
-                addOutput(mTestOutputs[mCurOutput], outputDesc);
-            }
-        }
-        return mTestOutputs[mCurOutput];
-    }
-#endif //AUDIO_POLICY_TEST
-
-    // open a direct output if required by specified parameters
-    //force direct flag if offload flag is set: offloading implies a direct output stream
-    // and all common behaviors are driven by checking only the direct flag
-    // this should normally be set appropriately in the policy configuration file
-    if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
-        flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
-    }
-
-    // Do not allow offloading if one non offloadable effect is enabled. This prevents from
-    // creating an offloaded track and tearing it down immediately after start when audioflinger
-    // detects there is an active non offloadable effect.
-    // FIXME: We should check the audio session here but we do not have it in this context.
-    // This may prevent offloading in rare situations where effects are left active by apps
-    // in the background.
-    sp<IOProfile> profile;
-    if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
-            !isNonOffloadableEffectEnabled()) {
-        profile = getProfileForDirectOutput(device,
-                                           samplingRate,
-                                           format,
-                                           channelMask,
-                                           (audio_output_flags_t)flags);
-    }
-
-    if (profile != 0) {
-        AudioOutputDescriptor *outputDesc = NULL;
-
-        for (size_t i = 0; i < mOutputs.size(); i++) {
-            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
-            if (!desc->isDuplicated() && (profile == desc->mProfile)) {
-                outputDesc = desc;
-                // reuse direct output if currently open and configured with same parameters
-                if ((samplingRate == outputDesc->mSamplingRate) &&
-                        (format == outputDesc->mFormat) &&
-                        (channelMask == outputDesc->mChannelMask)) {
-                    outputDesc->mDirectOpenCount++;
-                    ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
-                    return mOutputs.keyAt(i);
-                }
-            }
-        }
-        // close direct output if currently open and configured with different parameters
-        if (outputDesc != NULL) {
-            closeOutput(outputDesc->mIoHandle);
-        }
-        outputDesc = new AudioOutputDescriptor(profile);
-        outputDesc->mDevice = device;
-        outputDesc->mSamplingRate = samplingRate;
-        outputDesc->mFormat = format;
-        outputDesc->mChannelMask = channelMask;
-        outputDesc->mLatency = 0;
-        outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags);
-        outputDesc->mRefCount[stream] = 0;
-        outputDesc->mStopTime[stream] = 0;
-        outputDesc->mDirectOpenCount = 1;
-        output = mpClientInterface->openOutput(profile->mModule->mHandle,
-                                        &outputDesc->mDevice,
-                                        &outputDesc->mSamplingRate,
-                                        &outputDesc->mFormat,
-                                        &outputDesc->mChannelMask,
-                                        &outputDesc->mLatency,
-                                        outputDesc->mFlags,
-                                        offloadInfo);
-
-        // only accept an output with the requested parameters
-        if (output == 0 ||
-            (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
-            (format != AUDIO_FORMAT_DEFAULT && format != outputDesc->mFormat) ||
-            (channelMask != 0 && channelMask != outputDesc->mChannelMask)) {
-            ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
-                    "format %d %d, channelMask %04x %04x", output, samplingRate,
-                    outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
-                    outputDesc->mChannelMask);
-            if (output != 0) {
-                mpClientInterface->closeOutput(output);
-            }
-            delete outputDesc;
-            return 0;
-        }
-        audio_io_handle_t srcOutput = getOutputForEffect();
-        addOutput(output, outputDesc);
-        audio_io_handle_t dstOutput = getOutputForEffect();
-        if (dstOutput == output) {
-            mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
-        }
-        mPreviousOutputs = mOutputs;
-        ALOGV("getOutput() returns new direct output %d", output);
-        mpClientInterface->onAudioPortListUpdate();
-        return output;
-    }
-
-    // ignoring channel mask due to downmix capability in mixer
-
-    // open a non direct output
-
-    // for non direct outputs, only PCM is supported
-    if (audio_is_linear_pcm(format)) {
-        // get which output is suitable for the specified stream. The actual
-        // routing change will happen when startOutput() will be called
-        SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
-
-        output = selectOutput(outputs, flags);
-    }
-    ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
-            "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
-
-    ALOGV("getOutput() returns output %d", output);
-
-    return output;
-}
-
-audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_handle_t>& outputs,
-                                                       audio_output_flags_t flags)
-{
-    // select one output among several that provide a path to a particular device or set of
-    // devices (the list was previously build by getOutputsForDevice()).
-    // The priority is as follows:
-    // 1: the output with the highest number of requested policy flags
-    // 2: the primary output
-    // 3: the first output in the list
-
-    if (outputs.size() == 0) {
-        return 0;
-    }
-    if (outputs.size() == 1) {
-        return outputs[0];
-    }
-
-    int maxCommonFlags = 0;
-    audio_io_handle_t outputFlags = 0;
-    audio_io_handle_t outputPrimary = 0;
-
-    for (size_t i = 0; i < outputs.size(); i++) {
-        AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]);
-        if (!outputDesc->isDuplicated()) {
-            int commonFlags = popcount(outputDesc->mProfile->mFlags & flags);
-            if (commonFlags > maxCommonFlags) {
-                outputFlags = outputs[i];
-                maxCommonFlags = commonFlags;
-                ALOGV("selectOutput() commonFlags for output %d, %04x", outputs[i], commonFlags);
-            }
-            if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
-                outputPrimary = outputs[i];
-            }
-        }
-    }
-
-    if (outputFlags != 0) {
-        return outputFlags;
-    }
-    if (outputPrimary != 0) {
-        return outputPrimary;
-    }
-
-    return outputs[0];
-}
-
-status_t AudioPolicyManager::startOutput(audio_io_handle_t output,
-                                             audio_stream_type_t stream,
-                                             int session)
-{
-    ALOGV("startOutput() output %d, stream %d, session %d", output, stream, session);
-    ssize_t index = mOutputs.indexOfKey(output);
-    if (index < 0) {
-        ALOGW("startOutput() unknown output %d", output);
-        return BAD_VALUE;
-    }
-
-    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
-
-    // increment usage count for this stream on the requested output:
-    // NOTE that the usage count is the same for duplicated output and hardware output which is
-    // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
-    outputDesc->changeRefCount(stream, 1);
-
-    if (outputDesc->mRefCount[stream] == 1) {
-        audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/);
-        routing_strategy strategy = getStrategy(stream);
-        bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
-                            (strategy == STRATEGY_SONIFICATION_RESPECTFUL);
-        uint32_t waitMs = 0;
-        bool force = false;
-        for (size_t i = 0; i < mOutputs.size(); i++) {
-            AudioOutputDescriptor *desc = mOutputs.valueAt(i);
-            if (desc != outputDesc) {
-                // force a device change if any other output is managed by the same hw
-                // module and has a current device selection that differs from selected device.
-                // In this case, the audio HAL must receive the new device selection so that it can
-                // change the device currently selected by the other active output.
-                if (outputDesc->sharesHwModuleWith(desc) &&
-                    desc->device() != newDevice) {
-                    force = true;
-                }
-                // wait for audio on other active outputs to be presented when starting
-                // a notification so that audio focus effect can propagate.
-                uint32_t latency = desc->latency();
-                if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
-                    waitMs = latency;
-                }
-            }
-        }
-        uint32_t muteWaitMs = setOutputDevice(output, newDevice, force);
-
-        // handle special case for sonification while in call
-        if (isInCall()) {
-            handleIncallSonification(stream, true, false);
-        }
-
-        // apply volume rules for current stream and device if necessary
-        checkAndSetVolume(stream,
-                          mStreams[stream].getVolumeIndex(newDevice),
-                          output,
-                          newDevice);
-
-        // update the outputs if starting an output with a stream that can affect notification
-        // routing
-        handleNotificationRoutingForStream(stream);
-        if (waitMs > muteWaitMs) {
-            usleep((waitMs - muteWaitMs) * 2 * 1000);
-        }
-    }
-    return NO_ERROR;
-}
-
-
-status_t AudioPolicyManager::stopOutput(audio_io_handle_t output,
-                                            audio_stream_type_t stream,
-                                            int session)
-{
-    ALOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
-    ssize_t index = mOutputs.indexOfKey(output);
-    if (index < 0) {
-        ALOGW("stopOutput() unknown output %d", output);
-        return BAD_VALUE;
-    }
-
-    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
-
-    // handle special case for sonification while in call
-    if (isInCall()) {
-        handleIncallSonification(stream, false, false);
-    }
-
-    if (outputDesc->mRefCount[stream] > 0) {
-        // decrement usage count of this stream on the output
-        outputDesc->changeRefCount(stream, -1);
-        // store time at which the stream was stopped - see isStreamActive()
-        if (outputDesc->mRefCount[stream] == 0) {
-            outputDesc->mStopTime[stream] = systemTime();
-            audio_devices_t newDevice = getNewOutputDevice(output, false /*fromCache*/);
-            // delay the device switch by twice the latency because stopOutput() is executed when
-            // the track stop() command is received and at that time the audio track buffer can
-            // still contain data that needs to be drained. The latency only covers the audio HAL
-            // and kernel buffers. Also the latency does not always include additional delay in the
-            // audio path (audio DSP, CODEC ...)
-            setOutputDevice(output, newDevice, false, outputDesc->mLatency*2);
-
-            // force restoring the device selection on other active outputs if it differs from the
-            // one being selected for this output
-            for (size_t i = 0; i < mOutputs.size(); i++) {
-                audio_io_handle_t curOutput = mOutputs.keyAt(i);
-                AudioOutputDescriptor *desc = mOutputs.valueAt(i);
-                if (curOutput != output &&
-                        desc->isActive() &&
-                        outputDesc->sharesHwModuleWith(desc) &&
-                        (newDevice != desc->device())) {
-                    setOutputDevice(curOutput,
-                                    getNewOutputDevice(curOutput, false /*fromCache*/),
-                                    true,
-                                    outputDesc->mLatency*2);
-                }
-            }
-            // update the outputs if stopping one with a stream that can affect notification routing
-            handleNotificationRoutingForStream(stream);
-        }
-        return NO_ERROR;
-    } else {
-        ALOGW("stopOutput() refcount is already 0 for output %d", output);
-        return INVALID_OPERATION;
-    }
-}
-
-void AudioPolicyManager::releaseOutput(audio_io_handle_t output)
-{
-    ALOGV("releaseOutput() %d", output);
-    ssize_t index = mOutputs.indexOfKey(output);
-    if (index < 0) {
-        ALOGW("releaseOutput() releasing unknown output %d", output);
-        return;
-    }
-
-#ifdef AUDIO_POLICY_TEST
-    int testIndex = testOutputIndex(output);
-    if (testIndex != 0) {
-        AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
-        if (outputDesc->isActive()) {
-            mpClientInterface->closeOutput(output);
-            delete mOutputs.valueAt(index);
-            mOutputs.removeItem(output);
-            mTestOutputs[testIndex] = 0;
-        }
-        return;
-    }
-#endif //AUDIO_POLICY_TEST
-
-    AudioOutputDescriptor *desc = mOutputs.valueAt(index);
-    if (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) {
-        if (desc->mDirectOpenCount <= 0) {
-            ALOGW("releaseOutput() invalid open count %d for output %d",
-                                                              desc->mDirectOpenCount, output);
-            return;
-        }
-        if (--desc->mDirectOpenCount == 0) {
-            closeOutput(output);
-            // If effects where present on the output, audioflinger moved them to the primary
-            // output by default: move them back to the appropriate output.
-            audio_io_handle_t dstOutput = getOutputForEffect();
-            if (dstOutput != mPrimaryOutput) {
-                mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, mPrimaryOutput, dstOutput);
-            }
-            mpClientInterface->onAudioPortListUpdate();
-        }
-    }
-}
-
-
-audio_io_handle_t AudioPolicyManager::getInput(audio_source_t inputSource,
-                                    uint32_t samplingRate,
-                                    audio_format_t format,
-                                    audio_channel_mask_t channelMask,
-                                    audio_in_acoustics_t acoustics)
-{
-    audio_io_handle_t input = 0;
-    audio_devices_t device = getDeviceForInputSource(inputSource);
-
-    ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x",
-          inputSource, samplingRate, format, channelMask, acoustics);
-
-    if (device == AUDIO_DEVICE_NONE) {
-        ALOGW("getInput() could not find device for inputSource %d", inputSource);
-        return 0;
-    }
-
-    // adapt channel selection to input source
-    switch(inputSource) {
-    case AUDIO_SOURCE_VOICE_UPLINK:
-        channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK;
-        break;
-    case AUDIO_SOURCE_VOICE_DOWNLINK:
-        channelMask = AUDIO_CHANNEL_IN_VOICE_DNLINK;
-        break;
-    case AUDIO_SOURCE_VOICE_CALL:
-        channelMask = AUDIO_CHANNEL_IN_VOICE_UPLINK | AUDIO_CHANNEL_IN_VOICE_DNLINK;
-        break;
-    default:
-        break;
-    }
-
-    sp<IOProfile> profile = getInputProfile(device,
-                                         samplingRate,
-                                         format,
-                                         channelMask);
-    if (profile == 0) {
-        ALOGW("getInput() could not find profile for device %04x, samplingRate %d, format %d, "
-                "channelMask %04x",
-                device, samplingRate, format, channelMask);
-        return 0;
-    }
-
-    if (profile->mModule->mHandle == 0) {
-        ALOGE("getInput(): HW module %s not opened", profile->mModule->mName);
-        return 0;
-    }
-
-    AudioInputDescriptor *inputDesc = new AudioInputDescriptor(profile);
-
-    inputDesc->mInputSource = inputSource;
-    inputDesc->mDevice = device;
-    inputDesc->mSamplingRate = samplingRate;
-    inputDesc->mFormat = format;
-    inputDesc->mChannelMask = channelMask;
-    inputDesc->mRefCount = 0;
-    input = mpClientInterface->openInput(profile->mModule->mHandle,
-                                    &inputDesc->mDevice,
-                                    &inputDesc->mSamplingRate,
-                                    &inputDesc->mFormat,
-                                    &inputDesc->mChannelMask);
-
-    // only accept input with the exact requested set of parameters
-    if (input == 0 ||
-        (samplingRate != inputDesc->mSamplingRate) ||
-        (format != inputDesc->mFormat) ||
-        (channelMask != inputDesc->mChannelMask)) {
-        ALOGI("getInput() failed opening input: samplingRate %d, format %d, channelMask %x",
-                samplingRate, format, channelMask);
-        if (input != 0) {
-            mpClientInterface->closeInput(input);
-        }
-        delete inputDesc;
-        return 0;
-    }
-    addInput(input, inputDesc);
-    mpClientInterface->onAudioPortListUpdate();
-    return input;
-}
-
-status_t AudioPolicyManager::startInput(audio_io_handle_t input)
-{
-    ALOGV("startInput() input %d", input);
-    ssize_t index = mInputs.indexOfKey(input);
-    if (index < 0) {
-        ALOGW("startInput() unknown input %d", input);
-        return BAD_VALUE;
-    }
-    AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
-
-#ifdef AUDIO_POLICY_TEST
-    if (mTestInput == 0)
-#endif //AUDIO_POLICY_TEST
-    {
-        // refuse 2 active AudioRecord clients at the same time except if the active input
-        // uses AUDIO_SOURCE_HOTWORD in which case it is closed.
-        audio_io_handle_t activeInput = getActiveInput();
-        if (!isVirtualInputDevice(inputDesc->mDevice) && activeInput != 0) {
-            AudioInputDescriptor *activeDesc = mInputs.valueFor(activeInput);
-            if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) {
-                ALOGW("startInput() preempting already started low-priority input %d", activeInput);
-                stopInput(activeInput);
-                releaseInput(activeInput);
-            } else {
-                ALOGW("startInput() input %d failed: other input already started", input);
-                return INVALID_OPERATION;
-            }
-        }
-    }
-
-    setInputDevice(input, getNewInputDevice(input), true /* force */);
-
-    // automatically enable the remote submix output when input is started
-    if (audio_is_remote_submix_device(inputDesc->mDevice)) {
-        setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                AUDIO_POLICY_DEVICE_STATE_AVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS);
-    }
-
-    ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource);
-
-    inputDesc->mRefCount = 1;
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::stopInput(audio_io_handle_t input)
-{
-    ALOGV("stopInput() input %d", input);
-    ssize_t index = mInputs.indexOfKey(input);
-    if (index < 0) {
-        ALOGW("stopInput() unknown input %d", input);
-        return BAD_VALUE;
-    }
-    AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
-
-    if (inputDesc->mRefCount == 0) {
-        ALOGW("stopInput() input %d already stopped", input);
-        return INVALID_OPERATION;
-    } else {
-        // automatically disable the remote submix output when input is stopped
-        if (audio_is_remote_submix_device(inputDesc->mDevice)) {
-            setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
-                    AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS);
-        }
-
-        resetInputDevice(input);
-        inputDesc->mRefCount = 0;
-        return NO_ERROR;
-    }
-}
-
-void AudioPolicyManager::releaseInput(audio_io_handle_t input)
-{
-    ALOGV("releaseInput() %d", input);
-    ssize_t index = mInputs.indexOfKey(input);
-    if (index < 0) {
-        ALOGW("releaseInput() releasing unknown input %d", input);
-        return;
-    }
-    mpClientInterface->closeInput(input);
-    delete mInputs.valueAt(index);
-    mInputs.removeItem(input);
-    nextAudioPortGeneration();
-    mpClientInterface->onAudioPortListUpdate();
-    ALOGV("releaseInput() exit");
-}
-
-void AudioPolicyManager::closeAllInputs() {
-    for(size_t input_index = 0; input_index < mInputs.size(); input_index++) {
-        mpClientInterface->closeInput(mInputs.keyAt(input_index));
-    }
-    mInputs.clear();
-    nextAudioPortGeneration();
-}
-
-void AudioPolicyManager::initStreamVolume(audio_stream_type_t stream,
-                                            int indexMin,
-                                            int indexMax)
-{
-    ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
-    if (indexMin < 0 || indexMin >= indexMax) {
-        ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax);
-        return;
-    }
-    mStreams[stream].mIndexMin = indexMin;
-    mStreams[stream].mIndexMax = indexMax;
-}
-
-status_t AudioPolicyManager::setStreamVolumeIndex(audio_stream_type_t stream,
-                                                      int index,
-                                                      audio_devices_t device)
-{
-
-    if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
-        return BAD_VALUE;
-    }
-    if (!audio_is_output_device(device)) {
-        return BAD_VALUE;
-    }
-
-    // Force max volume if stream cannot be muted
-    if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
-
-    ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",
-          stream, device, index);
-
-    // if device is AUDIO_DEVICE_OUT_DEFAULT set default value and
-    // clear all device specific values
-    if (device == AUDIO_DEVICE_OUT_DEFAULT) {
-        mStreams[stream].mIndexCur.clear();
-    }
-    mStreams[stream].mIndexCur.add(device, index);
-
-    // compute and apply stream volume on all outputs according to connected device
-    status_t status = NO_ERROR;
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        audio_devices_t curDevice =
-                getDeviceForVolume(mOutputs.valueAt(i)->device());
-        if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) {
-            status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);
-            if (volStatus != NO_ERROR) {
-                status = volStatus;
-            }
-        }
-    }
-    return status;
-}
-
-status_t AudioPolicyManager::getStreamVolumeIndex(audio_stream_type_t stream,
-                                                      int *index,
-                                                      audio_devices_t device)
-{
-    if (index == NULL) {
-        return BAD_VALUE;
-    }
-    if (!audio_is_output_device(device)) {
-        return BAD_VALUE;
-    }
-    // if device is AUDIO_DEVICE_OUT_DEFAULT, return volume for device corresponding to
-    // the strategy the stream belongs to.
-    if (device == AUDIO_DEVICE_OUT_DEFAULT) {
-        device = getDeviceForStrategy(getStrategy(stream), true /*fromCache*/);
-    }
-    device = getDeviceForVolume(device);
-
-    *index =  mStreams[stream].getVolumeIndex(device);
-    ALOGV("getStreamVolumeIndex() stream %d device %08x index %d", stream, device, *index);
-    return NO_ERROR;
-}
-
-audio_io_handle_t AudioPolicyManager::selectOutputForEffects(
-                                            const SortedVector<audio_io_handle_t>& outputs)
-{
-    // select one output among several suitable for global effects.
-    // The priority is as follows:
-    // 1: An offloaded output. If the effect ends up not being offloadable,
-    //    AudioFlinger will invalidate the track and the offloaded output
-    //    will be closed causing the effect to be moved to a PCM output.
-    // 2: A deep buffer output
-    // 3: the first output in the list
-
-    if (outputs.size() == 0) {
-        return 0;
-    }
-
-    audio_io_handle_t outputOffloaded = 0;
-    audio_io_handle_t outputDeepBuffer = 0;
-
-    for (size_t i = 0; i < outputs.size(); i++) {
-        AudioOutputDescriptor *desc = mOutputs.valueFor(outputs[i]);
-        ALOGV("selectOutputForEffects outputs[%zu] flags %x", i, desc->mFlags);
-        if ((desc->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
-            outputOffloaded = outputs[i];
-        }
-        if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
-            outputDeepBuffer = outputs[i];
-        }
-    }
-
-    ALOGV("selectOutputForEffects outputOffloaded %d outputDeepBuffer %d",
-          outputOffloaded, outputDeepBuffer);
-    if (outputOffloaded != 0) {
-        return outputOffloaded;
-    }
-    if (outputDeepBuffer != 0) {
-        return outputDeepBuffer;
-    }
-
-    return outputs[0];
-}
-
-audio_io_handle_t AudioPolicyManager::getOutputForEffect(const effect_descriptor_t *desc)
-{
-    // apply simple rule where global effects are attached to the same output as MUSIC streams
-
-    routing_strategy strategy = getStrategy(AUDIO_STREAM_MUSIC);
-    audio_devices_t device = getDeviceForStrategy(strategy, false /*fromCache*/);
-    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(device, mOutputs);
-
-    audio_io_handle_t output = selectOutputForEffects(dstOutputs);
-    ALOGV("getOutputForEffect() got output %d for fx %s flags %x",
-          output, (desc == NULL) ? "unspecified" : desc->name,  (desc == NULL) ? 0 : desc->flags);
-
-    return output;
-}
-
-status_t AudioPolicyManager::registerEffect(const effect_descriptor_t *desc,
-                                audio_io_handle_t io,
-                                uint32_t strategy,
-                                int session,
-                                int id)
-{
-    ssize_t index = mOutputs.indexOfKey(io);
-    if (index < 0) {
-        index = mInputs.indexOfKey(io);
-        if (index < 0) {
-            ALOGW("registerEffect() unknown io %d", io);
-            return INVALID_OPERATION;
-        }
-    }
-
-    if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) {
-        ALOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB",
-                desc->name, desc->memoryUsage);
-        return INVALID_OPERATION;
-    }
-    mTotalEffectsMemory += desc->memoryUsage;
-    ALOGV("registerEffect() effect %s, io %d, strategy %d session %d id %d",
-            desc->name, io, strategy, session, id);
-    ALOGV("registerEffect() memory %d, total memory %d", desc->memoryUsage, mTotalEffectsMemory);
-
-    EffectDescriptor *pDesc = new EffectDescriptor();
-    memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t));
-    pDesc->mIo = io;
-    pDesc->mStrategy = (routing_strategy)strategy;
-    pDesc->mSession = session;
-    pDesc->mEnabled = false;
-
-    mEffects.add(id, pDesc);
-
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::unregisterEffect(int id)
-{
-    ssize_t index = mEffects.indexOfKey(id);
-    if (index < 0) {
-        ALOGW("unregisterEffect() unknown effect ID %d", id);
-        return INVALID_OPERATION;
-    }
-
-    EffectDescriptor *pDesc = mEffects.valueAt(index);
-
-    setEffectEnabled(pDesc, false);
-
-    if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) {
-        ALOGW("unregisterEffect() memory %d too big for total %d",
-                pDesc->mDesc.memoryUsage, mTotalEffectsMemory);
-        pDesc->mDesc.memoryUsage = mTotalEffectsMemory;
-    }
-    mTotalEffectsMemory -= pDesc->mDesc.memoryUsage;
-    ALOGV("unregisterEffect() effect %s, ID %d, memory %d total memory %d",
-            pDesc->mDesc.name, id, pDesc->mDesc.memoryUsage, mTotalEffectsMemory);
-
-    mEffects.removeItem(id);
-    delete pDesc;
-
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::setEffectEnabled(int id, bool enabled)
-{
-    ssize_t index = mEffects.indexOfKey(id);
-    if (index < 0) {
-        ALOGW("unregisterEffect() unknown effect ID %d", id);
-        return INVALID_OPERATION;
-    }
-
-    return setEffectEnabled(mEffects.valueAt(index), enabled);
-}
-
-status_t AudioPolicyManager::setEffectEnabled(EffectDescriptor *pDesc, bool enabled)
-{
-    if (enabled == pDesc->mEnabled) {
-        ALOGV("setEffectEnabled(%s) effect already %s",
-             enabled?"true":"false", enabled?"enabled":"disabled");
-        return INVALID_OPERATION;
-    }
-
-    if (enabled) {
-        if (mTotalEffectsCpuLoad + pDesc->mDesc.cpuLoad > getMaxEffectsCpuLoad()) {
-            ALOGW("setEffectEnabled(true) CPU Load limit exceeded for Fx %s, CPU %f MIPS",
-                 pDesc->mDesc.name, (float)pDesc->mDesc.cpuLoad/10);
-            return INVALID_OPERATION;
-        }
-        mTotalEffectsCpuLoad += pDesc->mDesc.cpuLoad;
-        ALOGV("setEffectEnabled(true) total CPU %d", mTotalEffectsCpuLoad);
-    } else {
-        if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) {
-            ALOGW("setEffectEnabled(false) CPU load %d too high for total %d",
-                    pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad);
-            pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad;
-        }
-        mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad;
-        ALOGV("setEffectEnabled(false) total CPU %d", mTotalEffectsCpuLoad);
-    }
-    pDesc->mEnabled = enabled;
-    return NO_ERROR;
-}
-
-bool AudioPolicyManager::isNonOffloadableEffectEnabled()
-{
-    for (size_t i = 0; i < mEffects.size(); i++) {
-        const EffectDescriptor * const pDesc = mEffects.valueAt(i);
-        if (pDesc->mEnabled && (pDesc->mStrategy == STRATEGY_MEDIA) &&
-                ((pDesc->mDesc.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) == 0)) {
-            ALOGV("isNonOffloadableEffectEnabled() non offloadable effect %s enabled on session %d",
-                  pDesc->mDesc.name, pDesc->mSession);
-            return true;
-        }
-    }
-    return false;
-}
-
-bool AudioPolicyManager::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
-{
-    nsecs_t sysTime = systemTime();
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
-        if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool AudioPolicyManager::isStreamActiveRemotely(audio_stream_type_t stream,
-                                                    uint32_t inPastMs) const
-{
-    nsecs_t sysTime = systemTime();
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        const AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
-        if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
-                outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool AudioPolicyManager::isSourceActive(audio_source_t source) const
-{
-    for (size_t i = 0; i < mInputs.size(); i++) {
-        const AudioInputDescriptor * inputDescriptor = mInputs.valueAt(i);
-        if ((inputDescriptor->mInputSource == (int)source ||
-                (source == AUDIO_SOURCE_VOICE_RECOGNITION &&
-                 inputDescriptor->mInputSource == AUDIO_SOURCE_HOTWORD))
-             && (inputDescriptor->mRefCount > 0)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-
-status_t AudioPolicyManager::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
-    result.append(buffer);
-
-    snprintf(buffer, SIZE, " Primary Output: %d\n", mPrimaryOutput);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for communications %d\n",
-             mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA]);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD]);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK]);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for system %d\n", mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM]);
-    result.append(buffer);
-
-    snprintf(buffer, SIZE, " Available output devices:\n");
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-    for (size_t i = 0; i < mAvailableOutputDevices.size(); i++) {
-        mAvailableOutputDevices[i]->dump(fd, 2, i);
-    }
-    snprintf(buffer, SIZE, "\n Available input devices:\n");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
-        mAvailableInputDevices[i]->dump(fd, 2, i);
-    }
-
-    snprintf(buffer, SIZE, "\nHW Modules dump:\n");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < mHwModules.size(); i++) {
-        snprintf(buffer, SIZE, "- HW Module %zu:\n", i + 1);
-        write(fd, buffer, strlen(buffer));
-        mHwModules[i]->dump(fd);
-    }
-
-    snprintf(buffer, SIZE, "\nOutputs dump:\n");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        mOutputs.valueAt(i)->dump(fd);
-    }
-
-    snprintf(buffer, SIZE, "\nInputs dump:\n");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < mInputs.size(); i++) {
-        snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        mInputs.valueAt(i)->dump(fd);
-    }
-
-    snprintf(buffer, SIZE, "\nStreams dump:\n");
-    write(fd, buffer, strlen(buffer));
-    snprintf(buffer, SIZE,
-             " Stream  Can be muted  Index Min  Index Max  Index Cur [device : index]...\n");
-    write(fd, buffer, strlen(buffer));
-    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
-        snprintf(buffer, SIZE, " %02zu      ", i);
-        write(fd, buffer, strlen(buffer));
-        mStreams[i].dump(fd);
-    }
-
-    snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n",
-            (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory);
-    write(fd, buffer, strlen(buffer));
-
-    snprintf(buffer, SIZE, "Registered effects:\n");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < mEffects.size(); i++) {
-        snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        mEffects.valueAt(i)->dump(fd);
-    }
-
-
-    return NO_ERROR;
-}
-
-// This function checks for the parameters which can be offloaded.
-// This can be enhanced depending on the capability of the DSP and policy
-// of the system.
-bool AudioPolicyManager::isOffloadSupported(const audio_offload_info_t& offloadInfo)
-{
-    ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
-     " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
-     offloadInfo.sample_rate, offloadInfo.channel_mask,
-     offloadInfo.format,
-     offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
-     offloadInfo.has_video);
-
-    // Check if offload has been disabled
-    char propValue[PROPERTY_VALUE_MAX];
-    if (property_get("audio.offload.disable", propValue, "0")) {
-        if (atoi(propValue) != 0) {
-            ALOGV("offload disabled by audio.offload.disable=%s", propValue );
-            return false;
-        }
-    }
-
-    // Check if stream type is music, then only allow offload as of now.
-    if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
-    {
-        ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
-        return false;
-    }
-
-    //TODO: enable audio offloading with video when ready
-    if (offloadInfo.has_video)
-    {
-        ALOGV("isOffloadSupported: has_video == true, returning false");
-        return false;
-    }
-
-    //If duration is less than minimum value defined in property, return false
-    if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
-        if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
-            ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
-            return false;
-        }
-    } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
-        ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
-        return false;
-    }
-
-    // Do not allow offloading if one non offloadable effect is enabled. This prevents from
-    // creating an offloaded track and tearing it down immediately after start when audioflinger
-    // detects there is an active non offloadable effect.
-    // FIXME: We should check the audio session here but we do not have it in this context.
-    // This may prevent offloading in rare situations where effects are left active by apps
-    // in the background.
-    if (isNonOffloadableEffectEnabled()) {
-        return false;
-    }
-
-    // See if there is a profile to support this.
-    // AUDIO_DEVICE_NONE
-    sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
-                                            offloadInfo.sample_rate,
-                                            offloadInfo.format,
-                                            offloadInfo.channel_mask,
-                                            AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
-    ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
-    return (profile != 0);
-}
-
-status_t AudioPolicyManager::listAudioPorts(audio_port_role_t role,
-                                            audio_port_type_t type,
-                                            unsigned int *num_ports,
-                                            struct audio_port *ports,
-                                            unsigned int *generation)
-{
-    if (num_ports == NULL || (*num_ports != 0 && ports == NULL) ||
-            generation == NULL) {
-        return BAD_VALUE;
-    }
-    ALOGV("listAudioPorts() role %d type %d num_ports %d ports %p", role, type, *num_ports, ports);
-    if (ports == NULL) {
-        *num_ports = 0;
-    }
-
-    size_t portsWritten = 0;
-    size_t portsMax = *num_ports;
-    *num_ports = 0;
-    if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_DEVICE) {
-        if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
-            for (size_t i = 0;
-                    i  < mAvailableOutputDevices.size() && portsWritten < portsMax; i++) {
-                mAvailableOutputDevices[i]->toAudioPort(&ports[portsWritten++]);
-            }
-            *num_ports += mAvailableOutputDevices.size();
-        }
-        if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
-            for (size_t i = 0;
-                    i  < mAvailableInputDevices.size() && portsWritten < portsMax; i++) {
-                mAvailableInputDevices[i]->toAudioPort(&ports[portsWritten++]);
-            }
-            *num_ports += mAvailableInputDevices.size();
-        }
-    }
-    if (type == AUDIO_PORT_TYPE_NONE || type == AUDIO_PORT_TYPE_MIX) {
-        if (role == AUDIO_PORT_ROLE_SINK || role == AUDIO_PORT_ROLE_NONE) {
-            for (size_t i = 0; i < mInputs.size() && portsWritten < portsMax; i++) {
-                mInputs[i]->toAudioPort(&ports[portsWritten++]);
-            }
-            *num_ports += mInputs.size();
-        }
-        if (role == AUDIO_PORT_ROLE_SOURCE || role == AUDIO_PORT_ROLE_NONE) {
-            for (size_t i = 0; i < mOutputs.size() && portsWritten < portsMax; i++) {
-                mOutputs[i]->toAudioPort(&ports[portsWritten++]);
-            }
-            *num_ports += mOutputs.size();
-        }
-    }
-    *generation = curAudioPortGeneration();
-    ALOGV("listAudioPorts() got %d ports needed %d", portsWritten, *num_ports);
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::getAudioPort(struct audio_port *port __unused)
-{
-    return NO_ERROR;
-}
-
-AudioPolicyManager::AudioOutputDescriptor *AudioPolicyManager::getOutputFromId(
-                                                                    audio_port_handle_t id) const
-{
-    AudioOutputDescriptor *outputDesc = NULL;
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        outputDesc = mOutputs.valueAt(i);
-        if (outputDesc->mId == id) {
-            break;
-        }
-    }
-    return outputDesc;
-}
-
-AudioPolicyManager::AudioInputDescriptor *AudioPolicyManager::getInputFromId(
-                                                                    audio_port_handle_t id) const
-{
-    AudioInputDescriptor *inputDesc = NULL;
-    for (size_t i = 0; i < mInputs.size(); i++) {
-        inputDesc = mInputs.valueAt(i);
-        if (inputDesc->mId == id) {
-            break;
-        }
-    }
-    return inputDesc;
-}
-
-AudioPolicyManager::HwModule *AudioPolicyManager::getModuleForDevice(audio_devices_t device) const
-{
-    for (size_t i = 0; i < mHwModules.size(); i++) {
-        if (mHwModules[i]->mHandle == 0) {
-            continue;
-        }
-        if (audio_is_output_device(device)) {
-            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
-            {
-                if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) {
-                    return mHwModules[i];
-                }
-            }
-        } else {
-            for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++) {
-                if (mHwModules[i]->mInputProfiles[j]->mSupportedDevices.types() &
-                        device & ~AUDIO_DEVICE_BIT_IN) {
-                    return mHwModules[i];
-                }
-            }
-        }
-    }
-    return NULL;
-}
-
-AudioPolicyManager::HwModule *AudioPolicyManager::getModuleFromName(const char *name) const
-{
-    for (size_t i = 0; i < mHwModules.size(); i++)
-    {
-        if (strcmp(mHwModules[i]->mName, name) == 0) {
-            return mHwModules[i];
-        }
-    }
-    return NULL;
-}
-
-
-status_t AudioPolicyManager::createAudioPatch(const struct audio_patch *patch,
-                                               audio_patch_handle_t *handle,
-                                               uid_t uid)
-{
-    ALOGV("createAudioPatch()");
-
-    if (handle == NULL || patch == NULL) {
-        return BAD_VALUE;
-    }
-    ALOGV("createAudioPatch() num sources %d num sinks %d", patch->num_sources, patch->num_sinks);
-
-    if (patch->num_sources > 1 || patch->num_sinks > 1) {
-        return INVALID_OPERATION;
-    }
-    if (patch->sources[0].role != AUDIO_PORT_ROLE_SOURCE ||
-            patch->sinks[0].role != AUDIO_PORT_ROLE_SINK) {
-        return INVALID_OPERATION;
-    }
-
-    sp<AudioPatch> patchDesc;
-    ssize_t index = mAudioPatches.indexOfKey(*handle);
-
-    ALOGV("createAudioPatch sink id %d role %d type %d", patch->sinks[0].id, patch->sinks[0].role,
-                                                         patch->sinks[0].type);
-    ALOGV("createAudioPatch source id %d role %d type %d", patch->sources[0].id,
-                                                           patch->sources[0].role,
-                                                           patch->sources[0].type);
-
-    if (index >= 0) {
-        patchDesc = mAudioPatches.valueAt(index);
-        ALOGV("createAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
-                                                                  mUidCached, patchDesc->mUid, uid);
-        if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
-            return INVALID_OPERATION;
-        }
-    } else {
-        *handle = 0;
-    }
-
-    if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
-        // TODO add support for mix to mix connection
-        if (patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE) {
-            ALOGV("createAudioPatch() source mix sink not device");
-            return BAD_VALUE;
-        }
-        // output mix to output device connection
-        AudioOutputDescriptor *outputDesc = getOutputFromId(patch->sources[0].id);
-        if (outputDesc == NULL) {
-            ALOGV("createAudioPatch() output not found for id %d", patch->sources[0].id);
-            return BAD_VALUE;
-        }
-        if (patchDesc != 0) {
-            if (patchDesc->mPatch.sources[0].id != patch->sources[0].id) {
-                ALOGV("createAudioPatch() source id differs for patch current id %d new id %d",
-                                          patchDesc->mPatch.sources[0].id, patch->sources[0].id);
-                return BAD_VALUE;
-            }
-        }
-        sp<DeviceDescriptor> devDesc =
-                mAvailableOutputDevices.getDeviceFromId(patch->sinks[0].id);
-        if (devDesc == 0) {
-            ALOGV("createAudioPatch() out device not found for id %d", patch->sinks[0].id);
-            return BAD_VALUE;
-        }
-
-        if (!outputDesc->mProfile->isCompatibleProfile(devDesc->mType,
-                                                       patch->sources[0].sample_rate,
-                                                     patch->sources[0].format,
-                                                     patch->sources[0].channel_mask,
-                                                     AUDIO_OUTPUT_FLAG_NONE)) {
-            return INVALID_OPERATION;
-        }
-        // TODO: reconfigure output format and channels here
-        ALOGV("createAudioPatch() setting device %08x on output %d",
-                                              devDesc->mType, outputDesc->mIoHandle);
-        setOutputDevice(outputDesc->mIoHandle,
-                        devDesc->mType,
-                       true,
-                       0,
-                       handle);
-        index = mAudioPatches.indexOfKey(*handle);
-        if (index >= 0) {
-            if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
-                ALOGW("createAudioPatch() setOutputDevice() did not reuse the patch provided");
-            }
-            patchDesc = mAudioPatches.valueAt(index);
-            patchDesc->mUid = uid;
-            ALOGV("createAudioPatch() success");
-        } else {
-            ALOGW("createAudioPatch() setOutputDevice() failed to create a patch");
-            return INVALID_OPERATION;
-        }
-    } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
-        if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
-            // input device to input mix connection
-            AudioInputDescriptor *inputDesc = getInputFromId(patch->sinks[0].id);
-            if (inputDesc == NULL) {
-                return BAD_VALUE;
-            }
-            if (patchDesc != 0) {
-                if (patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) {
-                    return BAD_VALUE;
-                }
-            }
-            sp<DeviceDescriptor> devDesc =
-                    mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
-            if (devDesc == 0) {
-                return BAD_VALUE;
-            }
-
-            if (!inputDesc->mProfile->isCompatibleProfile(devDesc->mType,
-                                                           patch->sinks[0].sample_rate,
-                                                         patch->sinks[0].format,
-                                                         patch->sinks[0].channel_mask,
-                                                         AUDIO_OUTPUT_FLAG_NONE)) {
-                return INVALID_OPERATION;
-            }
-            // TODO: reconfigure output format and channels here
-            ALOGV("createAudioPatch() setting device %08x on output %d",
-                                                  devDesc->mType, inputDesc->mIoHandle);
-            setInputDevice(inputDesc->mIoHandle,
-                           devDesc->mType,
-                           true,
-                           handle);
-            index = mAudioPatches.indexOfKey(*handle);
-            if (index >= 0) {
-                if (patchDesc != 0 && patchDesc != mAudioPatches.valueAt(index)) {
-                    ALOGW("createAudioPatch() setInputDevice() did not reuse the patch provided");
-                }
-                patchDesc = mAudioPatches.valueAt(index);
-                patchDesc->mUid = uid;
-                ALOGV("createAudioPatch() success");
-            } else {
-                ALOGW("createAudioPatch() setInputDevice() failed to create a patch");
-                return INVALID_OPERATION;
-            }
-        } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
-            // device to device connection
-            if (patchDesc != 0) {
-                if (patchDesc->mPatch.sources[0].id != patch->sources[0].id &&
-                    patchDesc->mPatch.sinks[0].id != patch->sinks[0].id) {
-                    return BAD_VALUE;
-                }
-            }
-
-            sp<DeviceDescriptor> srcDeviceDesc =
-                    mAvailableInputDevices.getDeviceFromId(patch->sources[0].id);
-            sp<DeviceDescriptor> sinkDeviceDesc =
-                    mAvailableOutputDevices.getDeviceFromId(patch->sinks[0].id);
-            if (srcDeviceDesc == 0 || sinkDeviceDesc == 0) {
-                return BAD_VALUE;
-            }
-            //update source and sink with our own data as the data passed in the patch may
-            // be incomplete.
-            struct audio_patch newPatch = *patch;
-            srcDeviceDesc->toAudioPortConfig(&newPatch.sources[0], &patch->sources[0]);
-            sinkDeviceDesc->toAudioPortConfig(&newPatch.sinks[0], &patch->sinks[0]);
-
-            // TODO: add support for devices on different HW modules
-            if (srcDeviceDesc->mModule != sinkDeviceDesc->mModule) {
-                return INVALID_OPERATION;
-            }
-            // TODO: check from routing capabilities in config file and other conflicting patches
-
-            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
-            if (index >= 0) {
-                afPatchHandle = patchDesc->mAfPatchHandle;
-            }
-
-            status_t status = mpClientInterface->createAudioPatch(&newPatch,
-                                                                  &afPatchHandle,
-                                                                  0);
-            ALOGV("createAudioPatch() patch panel returned %d patchHandle %d",
-                                                                  status, afPatchHandle);
-            if (status == NO_ERROR) {
-                if (index < 0) {
-                    patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(),
-                                               &newPatch, uid);
-                    addAudioPatch(patchDesc->mHandle, patchDesc);
-                } else {
-                    patchDesc->mPatch = newPatch;
-                }
-                patchDesc->mAfPatchHandle = afPatchHandle;
-                *handle = patchDesc->mHandle;
-                nextAudioPortGeneration();
-                mpClientInterface->onAudioPatchListUpdate();
-            } else {
-                ALOGW("createAudioPatch() patch panel could not connect device patch, error %d",
-                status);
-                return INVALID_OPERATION;
-            }
-        } else {
-            return BAD_VALUE;
-        }
-    } else {
-        return BAD_VALUE;
-    }
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::releaseAudioPatch(audio_patch_handle_t handle,
-                                                  uid_t uid)
-{
-    ALOGV("releaseAudioPatch() patch %d", handle);
-
-    ssize_t index = mAudioPatches.indexOfKey(handle);
-
-    if (index < 0) {
-        return BAD_VALUE;
-    }
-    sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
-    ALOGV("releaseAudioPatch() mUidCached %d patchDesc->mUid %d uid %d",
-          mUidCached, patchDesc->mUid, uid);
-    if (patchDesc->mUid != mUidCached && uid != patchDesc->mUid) {
-        return INVALID_OPERATION;
-    }
-
-    struct audio_patch *patch = &patchDesc->mPatch;
-    patchDesc->mUid = mUidCached;
-    if (patch->sources[0].type == AUDIO_PORT_TYPE_MIX) {
-        AudioOutputDescriptor *outputDesc = getOutputFromId(patch->sources[0].id);
-        if (outputDesc == NULL) {
-            ALOGV("releaseAudioPatch() output not found for id %d", patch->sources[0].id);
-            return BAD_VALUE;
-        }
-
-        setOutputDevice(outputDesc->mIoHandle,
-                        getNewOutputDevice(outputDesc->mIoHandle, true /*fromCache*/),
-                       true,
-                       0,
-                       NULL);
-    } else if (patch->sources[0].type == AUDIO_PORT_TYPE_DEVICE) {
-        if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
-            AudioInputDescriptor *inputDesc = getInputFromId(patch->sinks[0].id);
-            if (inputDesc == NULL) {
-                ALOGV("releaseAudioPatch() input not found for id %d", patch->sinks[0].id);
-                return BAD_VALUE;
-            }
-            setInputDevice(inputDesc->mIoHandle,
-                           getNewInputDevice(inputDesc->mIoHandle),
-                           true,
-                           NULL);
-        } else if (patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) {
-            audio_patch_handle_t afPatchHandle = patchDesc->mAfPatchHandle;
-            status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
-            ALOGV("releaseAudioPatch() patch panel returned %d patchHandle %d",
-                                                              status, patchDesc->mAfPatchHandle);
-            removeAudioPatch(patchDesc->mHandle);
-            nextAudioPortGeneration();
-            mpClientInterface->onAudioPatchListUpdate();
-        } else {
-            return BAD_VALUE;
-        }
-    } else {
-        return BAD_VALUE;
-    }
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::listAudioPatches(unsigned int *num_patches,
-                                              struct audio_patch *patches,
-                                              unsigned int *generation)
-{
-    if (num_patches == NULL || (*num_patches != 0 && patches == NULL) ||
-            generation == NULL) {
-        return BAD_VALUE;
-    }
-    ALOGV("listAudioPatches() num_patches %d patches %p available patches %d",
-          *num_patches, patches, mAudioPatches.size());
-    if (patches == NULL) {
-        *num_patches = 0;
-    }
-
-    size_t patchesWritten = 0;
-    size_t patchesMax = *num_patches;
-    for (size_t i = 0;
-            i  < mAudioPatches.size() && patchesWritten < patchesMax; i++) {
-        patches[patchesWritten] = mAudioPatches[i]->mPatch;
-        patches[patchesWritten++].id = mAudioPatches[i]->mHandle;
-        ALOGV("listAudioPatches() patch %d num_sources %d num_sinks %d",
-              i, mAudioPatches[i]->mPatch.num_sources, mAudioPatches[i]->mPatch.num_sinks);
-    }
-    *num_patches = mAudioPatches.size();
-
-    *generation = curAudioPortGeneration();
-    ALOGV("listAudioPatches() got %d patches needed %d", patchesWritten, *num_patches);
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::setAudioPortConfig(const struct audio_port_config *config)
-{
-    ALOGV("setAudioPortConfig()");
-
-    if (config == NULL) {
-        return BAD_VALUE;
-    }
-    ALOGV("setAudioPortConfig() on port handle %d", config->id);
-    // Only support gain configuration for now
-    if (config->config_mask != AUDIO_PORT_CONFIG_GAIN || config->gain.index < 0) {
-        return BAD_VALUE;
-    }
-
-    sp<AudioPort> portDesc;
-    struct audio_port_config portConfig;
-    if (config->type == AUDIO_PORT_TYPE_MIX) {
-        if (config->role == AUDIO_PORT_ROLE_SOURCE) {
-            AudioOutputDescriptor *outputDesc = getOutputFromId(config->id);
-            if (outputDesc == NULL) {
-                return BAD_VALUE;
-            }
-            portDesc = outputDesc->mProfile;
-            outputDesc->toAudioPortConfig(&portConfig);
-        } else if (config->role == AUDIO_PORT_ROLE_SINK) {
-            AudioInputDescriptor *inputDesc = getInputFromId(config->id);
-            if (inputDesc == NULL) {
-                return BAD_VALUE;
-            }
-            portDesc = inputDesc->mProfile;
-            inputDesc->toAudioPortConfig(&portConfig);
-        } else {
-            return BAD_VALUE;
-        }
-    } else if (config->type == AUDIO_PORT_TYPE_DEVICE) {
-        sp<DeviceDescriptor> deviceDesc;
-        if (config->role == AUDIO_PORT_ROLE_SOURCE) {
-            deviceDesc = mAvailableInputDevices.getDeviceFromId(config->id);
-        } else if (config->role == AUDIO_PORT_ROLE_SINK) {
-            deviceDesc = mAvailableOutputDevices.getDeviceFromId(config->id);
-        } else {
-            return BAD_VALUE;
-        }
-        if (deviceDesc == NULL) {
-            return BAD_VALUE;
-        }
-        portDesc = deviceDesc;
-        deviceDesc->toAudioPortConfig(&portConfig);
-    } else {
-        return BAD_VALUE;
-    }
-
-    if ((size_t)config->gain.index >= portDesc->mGains.size()) {
-        return INVALID_OPERATION;
-    }
-    const struct audio_gain *gain = &portDesc->mGains[config->gain.index]->mGain;
-    if ((config->gain.mode & ~gain->mode) != 0) {
-        return BAD_VALUE;
-    }
-    if ((config->gain.mode & AUDIO_GAIN_MODE_JOINT) == AUDIO_GAIN_MODE_JOINT) {
-        if ((config->gain.values[0] < gain->min_value) ||
-                    (config->gain.values[0] > gain->max_value)) {
-            return BAD_VALUE;
-        }
-    } else {
-        if ((config->gain.channel_mask & ~gain->channel_mask) != 0) {
-            return BAD_VALUE;
-        }
-        size_t numValues = popcount(config->gain.channel_mask);
-        for (size_t i = 0; i < numValues; i++) {
-            if ((config->gain.values[i] < gain->min_value) ||
-                    (config->gain.values[i] > gain->max_value)) {
-                return BAD_VALUE;
-            }
-        }
-    }
-    if ((config->gain.mode & AUDIO_GAIN_MODE_RAMP) == AUDIO_GAIN_MODE_RAMP) {
-        if ((config->gain.ramp_duration_ms < gain->min_ramp_ms) ||
-                    (config->gain.ramp_duration_ms > gain->max_ramp_ms)) {
-            return BAD_VALUE;
-        }
-    }
-
-    portConfig.gain = config->gain;
-
-    status_t status = mpClientInterface->setAudioPortConfig(&portConfig, 0);
-
-    return status;
-}
-
-void AudioPolicyManager::clearAudioPatches(uid_t uid)
-{
-    for (ssize_t i = 0; i < (ssize_t)mAudioPatches.size(); i++)  {
-        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(i);
-        if (patchDesc->mUid == uid) {
-            // releaseAudioPatch() removes the patch from mAudioPatches
-            if (releaseAudioPatch(mAudioPatches.keyAt(i), uid) == NO_ERROR) {
-                i--;
-            }
-        }
-    }
-}
-
-status_t AudioPolicyManager::addAudioPatch(audio_patch_handle_t handle,
-                                           const sp<AudioPatch>& patch)
-{
-    ssize_t index = mAudioPatches.indexOfKey(handle);
-
-    if (index >= 0) {
-        ALOGW("addAudioPatch() patch %d already in", handle);
-        return ALREADY_EXISTS;
-    }
-    mAudioPatches.add(handle, patch);
-    ALOGV("addAudioPatch() handle %d af handle %d num_sources %d num_sinks %d source handle %d"
-            "sink handle %d",
-          handle, patch->mAfPatchHandle, patch->mPatch.num_sources, patch->mPatch.num_sinks,
-          patch->mPatch.sources[0].id, patch->mPatch.sinks[0].id);
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::removeAudioPatch(audio_patch_handle_t handle)
-{
-    ssize_t index = mAudioPatches.indexOfKey(handle);
-
-    if (index < 0) {
-        ALOGW("removeAudioPatch() patch %d not in", handle);
-        return ALREADY_EXISTS;
-    }
-    ALOGV("removeAudioPatch() handle %d af handle %d", handle,
-                      mAudioPatches.valueAt(index)->mAfPatchHandle);
-    mAudioPatches.removeItemsAt(index);
-    return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-// AudioPolicyManager
-// ----------------------------------------------------------------------------
-
-uint32_t AudioPolicyManager::nextUniqueId()
-{
-    return android_atomic_inc(&mNextUniqueId);
-}
-
-uint32_t AudioPolicyManager::nextAudioPortGeneration()
-{
-    return android_atomic_inc(&mAudioPortGeneration);
-}
-
-AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
-    :
-#ifdef AUDIO_POLICY_TEST
-    Thread(false),
-#endif //AUDIO_POLICY_TEST
-    mPrimaryOutput((audio_io_handle_t)0),
-    mPhoneState(AUDIO_MODE_NORMAL),
-    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
-    mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0),
-    mA2dpSuspended(false),
-    mSpeakerDrcEnabled(false), mNextUniqueId(1),
-    mAudioPortGeneration(1)
-{
-    mUidCached = getuid();
-    mpClientInterface = clientInterface;
-
-    for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) {
-        mForceUse[i] = AUDIO_POLICY_FORCE_NONE;
-    }
-
-    mDefaultOutputDevice = new DeviceDescriptor(String8(""), AUDIO_DEVICE_OUT_SPEAKER);
-    if (loadAudioPolicyConfig(AUDIO_POLICY_VENDOR_CONFIG_FILE) != NO_ERROR) {
-        if (loadAudioPolicyConfig(AUDIO_POLICY_CONFIG_FILE) != NO_ERROR) {
-            ALOGE("could not load audio policy configuration file, setting defaults");
-            defaultAudioPolicyConfig();
-        }
-    }
-    // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
-
-    // must be done after reading the policy
-    initializeVolumeCurves();
-
-    // open all output streams needed to access attached devices
-    audio_devices_t outputDeviceTypes = mAvailableOutputDevices.types();
-    audio_devices_t inputDeviceTypes = mAvailableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
-    for (size_t i = 0; i < mHwModules.size(); i++) {
-        mHwModules[i]->mHandle = mpClientInterface->loadHwModule(mHwModules[i]->mName);
-        if (mHwModules[i]->mHandle == 0) {
-            ALOGW("could not open HW module %s", mHwModules[i]->mName);
-            continue;
-        }
-        // open all output streams needed to access attached devices
-        // except for direct output streams that are only opened when they are actually
-        // required by an app.
-        // This also validates mAvailableOutputDevices list
-        for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
-        {
-            const sp<IOProfile> outProfile = mHwModules[i]->mOutputProfiles[j];
-
-            if (outProfile->mSupportedDevices.isEmpty()) {
-                ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName);
-                continue;
-            }
-
-            audio_devices_t profileTypes = outProfile->mSupportedDevices.types();
-            if ((profileTypes & outputDeviceTypes) &&
-                    ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0)) {
-                AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(outProfile);
-
-                outputDesc->mDevice = (audio_devices_t)(mDefaultOutputDevice->mDeviceType & profileTypes);
-                audio_io_handle_t output = mpClientInterface->openOutput(
-                                                outProfile->mModule->mHandle,
-                                                &outputDesc->mDevice,
-                                                &outputDesc->mSamplingRate,
-                                                &outputDesc->mFormat,
-                                                &outputDesc->mChannelMask,
-                                                &outputDesc->mLatency,
-                                                outputDesc->mFlags);
-                if (output == 0) {
-                    ALOGW("Cannot open output stream for device %08x on hw module %s",
-                          outputDesc->mDevice,
-                          mHwModules[i]->mName);
-                    delete outputDesc;
-                } else {
-                    for (size_t k = 0; k  < outProfile->mSupportedDevices.size(); k++) {
-                        audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType;
-                        ssize_t index =
-                                mAvailableOutputDevices.indexOf(outProfile->mSupportedDevices[k]);
-                        // give a valid ID to an attached device once confirmed it is reachable
-                        if ((index >= 0) && (mAvailableOutputDevices[index]->mId == 0)) {
-                            mAvailableOutputDevices[index]->mId = nextUniqueId();
-                            mAvailableOutputDevices[index]->mModule = mHwModules[i];
-                        }
-                    }
-                    if (mPrimaryOutput == 0 &&
-                            outProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
-                        mPrimaryOutput = output;
-                    }
-                    addOutput(output, outputDesc);
-                    ALOGI("CSTOR setOutputDevice %08x", outputDesc->mDevice);
-                    setOutputDevice(output,
-                                    outputDesc->mDevice,
-                                    true);
-                }
-            }
-        }
-        // open input streams needed to access attached devices to validate
-        // mAvailableInputDevices list
-        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
-        {
-            const sp<IOProfile> inProfile = mHwModules[i]->mInputProfiles[j];
-
-            if (inProfile->mSupportedDevices.isEmpty()) {
-                ALOGW("Input profile contains no device on module %s", mHwModules[i]->mName);
-                continue;
-            }
-
-            audio_devices_t profileTypes = inProfile->mSupportedDevices.types();
-            if (profileTypes & inputDeviceTypes) {
-                AudioInputDescriptor *inputDesc = new AudioInputDescriptor(inProfile);
-
-                inputDesc->mInputSource = AUDIO_SOURCE_MIC;
-                inputDesc->mDevice = inProfile->mSupportedDevices[0]->mDeviceType;
-                audio_io_handle_t input = mpClientInterface->openInput(
-                                                    inProfile->mModule->mHandle,
-                                                    &inputDesc->mDevice,
-                                                    &inputDesc->mSamplingRate,
-                                                    &inputDesc->mFormat,
-                                                    &inputDesc->mChannelMask);
-
-                if (input != 0) {
-                    for (size_t k = 0; k  < inProfile->mSupportedDevices.size(); k++) {
-                        audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType;
-                        ssize_t index =
-                                mAvailableInputDevices.indexOf(inProfile->mSupportedDevices[k]);
-                        // give a valid ID to an attached device once confirmed it is reachable
-                        if ((index >= 0) && (mAvailableInputDevices[index]->mId == 0)) {
-                            mAvailableInputDevices[index]->mId = nextUniqueId();
-                            mAvailableInputDevices[index]->mModule = mHwModules[i];
-                        }
-                    }
-                    mpClientInterface->closeInput(input);
-                } else {
-                    ALOGW("Cannot open input stream for device %08x on hw module %s",
-                          inputDesc->mDevice,
-                          mHwModules[i]->mName);
-                }
-                delete inputDesc;
-            }
-        }
-    }
-    // make sure all attached devices have been allocated a unique ID
-    for (size_t i = 0; i  < mAvailableOutputDevices.size();) {
-        if (mAvailableOutputDevices[i]->mId == 0) {
-            ALOGW("Input device %08x unreachable", mAvailableOutputDevices[i]->mDeviceType);
-            mAvailableOutputDevices.remove(mAvailableOutputDevices[i]);
-            continue;
-        }
-        i++;
-    }
-    for (size_t i = 0; i  < mAvailableInputDevices.size();) {
-        if (mAvailableInputDevices[i]->mId == 0) {
-            ALOGW("Input device %08x unreachable", mAvailableInputDevices[i]->mDeviceType);
-            mAvailableInputDevices.remove(mAvailableInputDevices[i]);
-            continue;
-        }
-        i++;
-    }
-    // make sure default device is reachable
-    if (mAvailableOutputDevices.indexOf(mDefaultOutputDevice) < 0) {
-        ALOGE("Default device %08x is unreachable", mDefaultOutputDevice->mDeviceType);
-    }
-
-    ALOGE_IF((mPrimaryOutput == 0), "Failed to open primary output");
-
-    updateDevicesAndOutputs();
-
-#ifdef AUDIO_POLICY_TEST
-    if (mPrimaryOutput != 0) {
-        AudioParameter outputCmd = AudioParameter();
-        outputCmd.addInt(String8("set_id"), 0);
-        mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
-
-        mTestDevice = AUDIO_DEVICE_OUT_SPEAKER;
-        mTestSamplingRate = 44100;
-        mTestFormat = AUDIO_FORMAT_PCM_16_BIT;
-        mTestChannels =  AUDIO_CHANNEL_OUT_STEREO;
-        mTestLatencyMs = 0;
-        mCurOutput = 0;
-        mDirectOutput = false;
-        for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
-            mTestOutputs[i] = 0;
-        }
-
-        const size_t SIZE = 256;
-        char buffer[SIZE];
-        snprintf(buffer, SIZE, "AudioPolicyManagerTest");
-        run(buffer, ANDROID_PRIORITY_AUDIO);
-    }
-#endif //AUDIO_POLICY_TEST
-}
-
-AudioPolicyManager::~AudioPolicyManager()
-{
-#ifdef AUDIO_POLICY_TEST
-    exit();
-#endif //AUDIO_POLICY_TEST
-   for (size_t i = 0; i < mOutputs.size(); i++) {
-        mpClientInterface->closeOutput(mOutputs.keyAt(i));
-        delete mOutputs.valueAt(i);
-   }
-   for (size_t i = 0; i < mInputs.size(); i++) {
-        mpClientInterface->closeInput(mInputs.keyAt(i));
-        delete mInputs.valueAt(i);
-   }
-   for (size_t i = 0; i < mHwModules.size(); i++) {
-        delete mHwModules[i];
-   }
-   mAvailableOutputDevices.clear();
-   mAvailableInputDevices.clear();
-}
-
-status_t AudioPolicyManager::initCheck()
-{
-    return (mPrimaryOutput == 0) ? NO_INIT : NO_ERROR;
-}
-
-#ifdef AUDIO_POLICY_TEST
-bool AudioPolicyManager::threadLoop()
-{
-    ALOGV("entering threadLoop()");
-    while (!exitPending())
-    {
-        String8 command;
-        int valueInt;
-        String8 value;
-
-        Mutex::Autolock _l(mLock);
-        mWaitWorkCV.waitRelative(mLock, milliseconds(50));
-
-        command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
-        AudioParameter param = AudioParameter(command);
-
-        if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
-            valueInt != 0) {
-            ALOGV("Test command %s received", command.string());
-            String8 target;
-            if (param.get(String8("target"), target) != NO_ERROR) {
-                target = "Manager";
-            }
-            if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_output"));
-                mCurOutput = valueInt;
-            }
-            if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_direct"));
-                if (value == "false") {
-                    mDirectOutput = false;
-                } else if (value == "true") {
-                    mDirectOutput = true;
-                }
-            }
-            if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_input"));
-                mTestInput = valueInt;
-            }
-
-            if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_format"));
-                int format = AUDIO_FORMAT_INVALID;
-                if (value == "PCM 16 bits") {
-                    format = AUDIO_FORMAT_PCM_16_BIT;
-                } else if (value == "PCM 8 bits") {
-                    format = AUDIO_FORMAT_PCM_8_BIT;
-                } else if (value == "Compressed MP3") {
-                    format = AUDIO_FORMAT_MP3;
-                }
-                if (format != AUDIO_FORMAT_INVALID) {
-                    if (target == "Manager") {
-                        mTestFormat = format;
-                    } else if (mTestOutputs[mCurOutput] != 0) {
-                        AudioParameter outputParam = AudioParameter();
-                        outputParam.addInt(String8("format"), format);
-                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
-                    }
-                }
-            }
-            if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_channels"));
-                int channels = 0;
-
-                if (value == "Channels Stereo") {
-                    channels =  AUDIO_CHANNEL_OUT_STEREO;
-                } else if (value == "Channels Mono") {
-                    channels =  AUDIO_CHANNEL_OUT_MONO;
-                }
-                if (channels != 0) {
-                    if (target == "Manager") {
-                        mTestChannels = channels;
-                    } else if (mTestOutputs[mCurOutput] != 0) {
-                        AudioParameter outputParam = AudioParameter();
-                        outputParam.addInt(String8("channels"), channels);
-                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
-                    }
-                }
-            }
-            if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_sampleRate"));
-                if (valueInt >= 0 && valueInt <= 96000) {
-                    int samplingRate = valueInt;
-                    if (target == "Manager") {
-                        mTestSamplingRate = samplingRate;
-                    } else if (mTestOutputs[mCurOutput] != 0) {
-                        AudioParameter outputParam = AudioParameter();
-                        outputParam.addInt(String8("sampling_rate"), samplingRate);
-                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
-                    }
-                }
-            }
-
-            if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_reopen"));
-
-                AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput);
-                mpClientInterface->closeOutput(mPrimaryOutput);
-
-                audio_module_handle_t moduleHandle = outputDesc->mModule->mHandle;
-
-                delete mOutputs.valueFor(mPrimaryOutput);
-                mOutputs.removeItem(mPrimaryOutput);
-
-                AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor(NULL);
-                outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
-                mPrimaryOutput = mpClientInterface->openOutput(moduleHandle,
-                                                &outputDesc->mDevice,
-                                                &outputDesc->mSamplingRate,
-                                                &outputDesc->mFormat,
-                                                &outputDesc->mChannelMask,
-                                                &outputDesc->mLatency,
-                                                outputDesc->mFlags);
-                if (mPrimaryOutput == 0) {
-                    ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d",
-                            outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
-                } else {
-                    AudioParameter outputCmd = AudioParameter();
-                    outputCmd.addInt(String8("set_id"), 0);
-                    mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
-                    addOutput(mPrimaryOutput, outputDesc);
-                }
-            }
-
-
-            mpClientInterface->setParameters(0, String8("test_cmd_policy="));
-        }
-    }
-    return false;
-}
-
-void AudioPolicyManager::exit()
-{
-    {
-        AutoMutex _l(mLock);
-        requestExit();
-        mWaitWorkCV.signal();
-    }
-    requestExitAndWait();
-}
-
-int AudioPolicyManager::testOutputIndex(audio_io_handle_t output)
-{
-    for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
-        if (output == mTestOutputs[i]) return i;
-    }
-    return 0;
-}
-#endif //AUDIO_POLICY_TEST
-
-// ---
-
-void AudioPolicyManager::addOutput(audio_io_handle_t output, AudioOutputDescriptor *outputDesc)
-{
-    outputDesc->mIoHandle = output;
-    outputDesc->mId = nextUniqueId();
-    mOutputs.add(output, outputDesc);
-    nextAudioPortGeneration();
-}
-
-void AudioPolicyManager::addInput(audio_io_handle_t input, AudioInputDescriptor *inputDesc)
-{
-    inputDesc->mIoHandle = input;
-    inputDesc->mId = nextUniqueId();
-    mInputs.add(input, inputDesc);
-    nextAudioPortGeneration();
-}
-
-String8 AudioPolicyManager::addressToParameter(audio_devices_t device, const String8 address)
-{
-    if (device & AUDIO_DEVICE_OUT_ALL_A2DP) {
-        return String8("a2dp_sink_address=")+address;
-    }
-    return address;
-}
-
-status_t AudioPolicyManager::checkOutputsForDevice(audio_devices_t device,
-                                                       audio_policy_dev_state_t state,
-                                                       SortedVector<audio_io_handle_t>& outputs,
-                                                       const String8 address)
-{
-    AudioOutputDescriptor *desc;
-
-    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
-        // first list already open outputs that can be routed to this device
-        for (size_t i = 0; i < mOutputs.size(); i++) {
-            desc = mOutputs.valueAt(i);
-            if (!desc->isDuplicated() && (desc->mProfile->mSupportedDevices.types() & device)) {
-                ALOGV("checkOutputsForDevice(): adding opened output %d", mOutputs.keyAt(i));
-                outputs.add(mOutputs.keyAt(i));
-            }
-        }
-        // then look for output profiles that can be routed to this device
-        SortedVector< sp<IOProfile> > profiles;
-        for (size_t i = 0; i < mHwModules.size(); i++)
-        {
-            if (mHwModules[i]->mHandle == 0) {
-                continue;
-            }
-            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
-            {
-                if (mHwModules[i]->mOutputProfiles[j]->mSupportedDevices.types() & device) {
-                    ALOGV("checkOutputsForDevice(): adding profile %zu from module %zu", j, i);
-                    profiles.add(mHwModules[i]->mOutputProfiles[j]);
-                }
-            }
-        }
-
-        if (profiles.isEmpty() && outputs.isEmpty()) {
-            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
-            return BAD_VALUE;
-        }
-
-        // open outputs for matching profiles if needed. Direct outputs are also opened to
-        // query for dynamic parameters and will be closed later by setDeviceConnectionState()
-        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
-            sp<IOProfile> profile = profiles[profile_index];
-
-            // nothing to do if one output is already opened for this profile
-            size_t j;
-            for (j = 0; j < mOutputs.size(); j++) {
-                desc = mOutputs.valueAt(j);
-                if (!desc->isDuplicated() && desc->mProfile == profile) {
-                    break;
-                }
-            }
-            if (j != mOutputs.size()) {
-                continue;
-            }
-
-            ALOGV("opening output for device %08x with params %s", device, address.string());
-            desc = new AudioOutputDescriptor(profile);
-            desc->mDevice = device;
-            audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
-            offloadInfo.sample_rate = desc->mSamplingRate;
-            offloadInfo.format = desc->mFormat;
-            offloadInfo.channel_mask = desc->mChannelMask;
-
-            audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle,
-                                                                       &desc->mDevice,
-                                                                       &desc->mSamplingRate,
-                                                                       &desc->mFormat,
-                                                                       &desc->mChannelMask,
-                                                                       &desc->mLatency,
-                                                                       desc->mFlags,
-                                                                       &offloadInfo);
-            if (output != 0) {
-                // Here is where the out_set_parameters() for card & device gets called
-                if (!address.isEmpty()) {
-                    mpClientInterface->setParameters(output, addressToParameter(device, address));
-                }
-
-                // Here is where we step through and resolve any "dynamic" fields
-                String8 reply;
-                char *value;
-                if (profile->mSamplingRates[0] == 0) {
-                    reply = mpClientInterface->getParameters(output,
-                                            String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
-                    ALOGV("checkOutputsForDevice() direct output sup sampling rates %s",
-                              reply.string());
-                    value = strpbrk((char *)reply.string(), "=");
-                    if (value != NULL) {
-                        profile->loadSamplingRates(value + 1);
-                    }
-                }
-                if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
-                    reply = mpClientInterface->getParameters(output,
-                                                   String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
-                    ALOGV("checkOutputsForDevice() direct output sup formats %s",
-                              reply.string());
-                    value = strpbrk((char *)reply.string(), "=");
-                    if (value != NULL) {
-                        profile->loadFormats(value + 1);
-                    }
-                }
-                if (profile->mChannelMasks[0] == 0) {
-                    reply = mpClientInterface->getParameters(output,
-                                                  String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
-                    ALOGV("checkOutputsForDevice() direct output sup channel masks %s",
-                              reply.string());
-                    value = strpbrk((char *)reply.string(), "=");
-                    if (value != NULL) {
-                        profile->loadOutChannels(value + 1);
-                    }
-                }
-                if (((profile->mSamplingRates[0] == 0) &&
-                         (profile->mSamplingRates.size() < 2)) ||
-                     ((profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) &&
-                         (profile->mFormats.size() < 2)) ||
-                     ((profile->mChannelMasks[0] == 0) &&
-                         (profile->mChannelMasks.size() < 2))) {
-                    ALOGW("checkOutputsForDevice() direct output missing param");
-                    mpClientInterface->closeOutput(output);
-                    output = 0;
-                } else if (profile->mSamplingRates[0] == 0) {
-                    mpClientInterface->closeOutput(output);
-                    desc->mSamplingRate = profile->mSamplingRates[1];
-                    offloadInfo.sample_rate = desc->mSamplingRate;
-                    output = mpClientInterface->openOutput(
-                                                    profile->mModule->mHandle,
-                                                    &desc->mDevice,
-                                                    &desc->mSamplingRate,
-                                                    &desc->mFormat,
-                                                    &desc->mChannelMask,
-                                                    &desc->mLatency,
-                                                    desc->mFlags,
-                                                    &offloadInfo);
-                }
-
-                if (output != 0) {
-                    addOutput(output, desc);
-                    if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) {
-                        audio_io_handle_t duplicatedOutput = 0;
-
-                        // set initial stream volume for device
-                        applyStreamVolumes(output, device, 0, true);
-
-                        //TODO: configure audio effect output stage here
-
-                        // open a duplicating output thread for the new output and the primary output
-                        duplicatedOutput = mpClientInterface->openDuplicateOutput(output,
-                                                                                  mPrimaryOutput);
-                        if (duplicatedOutput != 0) {
-                            // add duplicated output descriptor
-                            AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor(NULL);
-                            dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput);
-                            dupOutputDesc->mOutput2 = mOutputs.valueFor(output);
-                            dupOutputDesc->mSamplingRate = desc->mSamplingRate;
-                            dupOutputDesc->mFormat = desc->mFormat;
-                            dupOutputDesc->mChannelMask = desc->mChannelMask;
-                            dupOutputDesc->mLatency = desc->mLatency;
-                            addOutput(duplicatedOutput, dupOutputDesc);
-                            applyStreamVolumes(duplicatedOutput, device, 0, true);
-                        } else {
-                            ALOGW("checkOutputsForDevice() could not open dup output for %d and %d",
-                                    mPrimaryOutput, output);
-                            mpClientInterface->closeOutput(output);
-                            mOutputs.removeItem(output);
-                            nextAudioPortGeneration();
-                            output = 0;
-                        }
-                    }
-                }
-            }
-            if (output == 0) {
-                ALOGW("checkOutputsForDevice() could not open output for device %x", device);
-                delete desc;
-                profiles.removeAt(profile_index);
-                profile_index--;
-            } else {
-                outputs.add(output);
-                ALOGV("checkOutputsForDevice(): adding output %d", output);
-            }
-        }
-
-        if (profiles.isEmpty()) {
-            ALOGW("checkOutputsForDevice(): No output available for device %04x", device);
-            return BAD_VALUE;
-        }
-    } else { // Disconnect
-        // check if one opened output is not needed any more after disconnecting one device
-        for (size_t i = 0; i < mOutputs.size(); i++) {
-            desc = mOutputs.valueAt(i);
-            if (!desc->isDuplicated() &&
-                    !(desc->mProfile->mSupportedDevices.types() &
-                            mAvailableOutputDevices.types())) {
-                ALOGV("checkOutputsForDevice(): disconnecting adding output %d", mOutputs.keyAt(i));
-                outputs.add(mOutputs.keyAt(i));
-            }
-        }
-        // Clear any profiles associated with the disconnected device.
-        for (size_t i = 0; i < mHwModules.size(); i++)
-        {
-            if (mHwModules[i]->mHandle == 0) {
-                continue;
-            }
-            for (size_t j = 0; j < mHwModules[i]->mOutputProfiles.size(); j++)
-            {
-                sp<IOProfile> profile = mHwModules[i]->mOutputProfiles[j];
-                if (profile->mSupportedDevices.types() & device) {
-                    ALOGV("checkOutputsForDevice(): "
-                            "clearing direct output profile %zu on module %zu", j, i);
-                    if (profile->mSamplingRates[0] == 0) {
-                        profile->mSamplingRates.clear();
-                        profile->mSamplingRates.add(0);
-                    }
-                    if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
-                        profile->mFormats.clear();
-                        profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
-                    }
-                    if (profile->mChannelMasks[0] == 0) {
-                        profile->mChannelMasks.clear();
-                        profile->mChannelMasks.add(0);
-                    }
-                }
-            }
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManager::checkInputsForDevice(audio_devices_t device,
-                                                      audio_policy_dev_state_t state,
-                                                      SortedVector<audio_io_handle_t>& inputs,
-                                                      const String8 address)
-{
-    AudioInputDescriptor *desc;
-    if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
-        // first list already open inputs that can be routed to this device
-        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
-            desc = mInputs.valueAt(input_index);
-            if (desc->mProfile->mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN)) {
-                ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index));
-               inputs.add(mInputs.keyAt(input_index));
-            }
-        }
-
-        // then look for input profiles that can be routed to this device
-        SortedVector< sp<IOProfile> > profiles;
-        for (size_t module_idx = 0; module_idx < mHwModules.size(); module_idx++)
-        {
-            if (mHwModules[module_idx]->mHandle == 0) {
-                continue;
-            }
-            for (size_t profile_index = 0;
-                 profile_index < mHwModules[module_idx]->mInputProfiles.size();
-                 profile_index++)
-            {
-                if (mHwModules[module_idx]->mInputProfiles[profile_index]->mSupportedDevices.types()
-                        & (device & ~AUDIO_DEVICE_BIT_IN)) {
-                    ALOGV("checkInputsForDevice(): adding profile %d from module %d",
-                          profile_index, module_idx);
-                    profiles.add(mHwModules[module_idx]->mInputProfiles[profile_index]);
-                }
-            }
-        }
-
-        if (profiles.isEmpty() && inputs.isEmpty()) {
-            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
-            return BAD_VALUE;
-        }
-
-        // open inputs for matching profiles if needed. Direct inputs are also opened to
-        // query for dynamic parameters and will be closed later by setDeviceConnectionState()
-        for (ssize_t profile_index = 0; profile_index < (ssize_t)profiles.size(); profile_index++) {
-
-            sp<IOProfile> profile = profiles[profile_index];
-            // nothing to do if one input is already opened for this profile
-            size_t input_index;
-            for (input_index = 0; input_index < mInputs.size(); input_index++) {
-                desc = mInputs.valueAt(input_index);
-                if (desc->mProfile == profile) {
-                    break;
-                }
-            }
-            if (input_index != mInputs.size()) {
-                continue;
-            }
-
-            ALOGV("opening input for device 0x%X with params %s", device, address.string());
-            desc = new AudioInputDescriptor(profile);
-            desc->mDevice = device;
-
-            audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle,
-                                            &desc->mDevice,
-                                            &desc->mSamplingRate,
-                                            &desc->mFormat,
-                                            &desc->mChannelMask);
-
-            if (input != 0) {
-                if (!address.isEmpty()) {
-                    mpClientInterface->setParameters(input, addressToParameter(device, address));
-                }
-
-                // Here is where we step through and resolve any "dynamic" fields
-                String8 reply;
-                char *value;
-                if (profile->mSamplingRates[0] == 0) {
-                    reply = mpClientInterface->getParameters(input,
-                                            String8(AUDIO_PARAMETER_STREAM_SUP_SAMPLING_RATES));
-                    ALOGV("checkInputsForDevice() direct input sup sampling rates %s",
-                              reply.string());
-                    value = strpbrk((char *)reply.string(), "=");
-                    if (value != NULL) {
-                        profile->loadSamplingRates(value + 1);
-                    }
-                }
-                if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
-                    reply = mpClientInterface->getParameters(input,
-                                                   String8(AUDIO_PARAMETER_STREAM_SUP_FORMATS));
-                    ALOGV("checkInputsForDevice() direct input sup formats %s", reply.string());
-                    value = strpbrk((char *)reply.string(), "=");
-                    if (value != NULL) {
-                        profile->loadFormats(value + 1);
-                    }
-                }
-                if (profile->mChannelMasks[0] == 0) {
-                    reply = mpClientInterface->getParameters(input,
-                                                  String8(AUDIO_PARAMETER_STREAM_SUP_CHANNELS));
-                    ALOGV("checkInputsForDevice() direct input sup channel masks %s",
-                              reply.string());
-                    value = strpbrk((char *)reply.string(), "=");
-                    if (value != NULL) {
-                        profile->loadInChannels(value + 1);
-                    }
-                }
-                if (((profile->mSamplingRates[0] == 0) && (profile->mSamplingRates.size() < 2)) ||
-                     ((profile->mFormats[0] == 0) && (profile->mFormats.size() < 2)) ||
-                     ((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) {
-                    ALOGW("checkInputsForDevice() direct input missing param");
-                    mpClientInterface->closeInput(input);
-                    input = 0;
-                }
-
-                if (input != 0) {
-                    addInput(input, desc);
-                }
-            } // endif input != 0
-
-            if (input == 0) {
-                ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
-                delete desc;
-                profiles.removeAt(profile_index);
-                profile_index--;
-            } else {
-                inputs.add(input);
-                ALOGV("checkInputsForDevice(): adding input %d", input);
-            }
-        } // end scan profiles
-
-        if (profiles.isEmpty()) {
-            ALOGW("checkInputsForDevice(): No input available for device 0x%X", device);
-            return BAD_VALUE;
-        }
-    } else {
-        // Disconnect
-        // check if one opened input is not needed any more after disconnecting one device
-        for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
-            desc = mInputs.valueAt(input_index);
-            if (!(desc->mProfile->mSupportedDevices.types() & mAvailableInputDevices.types())) {
-                ALOGV("checkInputsForDevice(): disconnecting adding input %d",
-                      mInputs.keyAt(input_index));
-                inputs.add(mInputs.keyAt(input_index));
-            }
-        }
-        // Clear any profiles associated with the disconnected device.
-        for (size_t module_index = 0; module_index < mHwModules.size(); module_index++) {
-            if (mHwModules[module_index]->mHandle == 0) {
-                continue;
-            }
-            for (size_t profile_index = 0;
-                 profile_index < mHwModules[module_index]->mInputProfiles.size();
-                 profile_index++) {
-                sp<IOProfile> profile = mHwModules[module_index]->mInputProfiles[profile_index];
-                if (profile->mSupportedDevices.types() & device) {
-                    ALOGV("checkInputsForDevice(): clearing direct input profile %d on module %d",
-                          profile_index, module_index);
-                    if (profile->mSamplingRates[0] == 0) {
-                        profile->mSamplingRates.clear();
-                        profile->mSamplingRates.add(0);
-                    }
-                    if (profile->mFormats[0] == AUDIO_FORMAT_DEFAULT) {
-                        profile->mFormats.clear();
-                        profile->mFormats.add(AUDIO_FORMAT_DEFAULT);
-                    }
-                    if (profile->mChannelMasks[0] == 0) {
-                        profile->mChannelMasks.clear();
-                        profile->mChannelMasks.add(0);
-                    }
-                }
-            }
-        }
-    } // end disconnect
-
-    return NO_ERROR;
-}
-
-
-void AudioPolicyManager::closeOutput(audio_io_handle_t output)
-{
-    ALOGV("closeOutput(%d)", output);
-
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
-    if (outputDesc == NULL) {
-        ALOGW("closeOutput() unknown output %d", output);
-        return;
-    }
-
-    // look for duplicated outputs connected to the output being removed.
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        AudioOutputDescriptor *dupOutputDesc = mOutputs.valueAt(i);
-        if (dupOutputDesc->isDuplicated() &&
-                (dupOutputDesc->mOutput1 == outputDesc ||
-                dupOutputDesc->mOutput2 == outputDesc)) {
-            AudioOutputDescriptor *outputDesc2;
-            if (dupOutputDesc->mOutput1 == outputDesc) {
-                outputDesc2 = dupOutputDesc->mOutput2;
-            } else {
-                outputDesc2 = dupOutputDesc->mOutput1;
-            }
-            // As all active tracks on duplicated output will be deleted,
-            // and as they were also referenced on the other output, the reference
-            // count for their stream type must be adjusted accordingly on
-            // the other output.
-            for (int j = 0; j < AUDIO_STREAM_CNT; j++) {
-                int refCount = dupOutputDesc->mRefCount[j];
-                outputDesc2->changeRefCount((audio_stream_type_t)j,-refCount);
-            }
-            audio_io_handle_t duplicatedOutput = mOutputs.keyAt(i);
-            ALOGV("closeOutput() closing also duplicated output %d", duplicatedOutput);
-
-            mpClientInterface->closeOutput(duplicatedOutput);
-            delete mOutputs.valueFor(duplicatedOutput);
-            mOutputs.removeItem(duplicatedOutput);
-        }
-    }
-
-    AudioParameter param;
-    param.add(String8("closing"), String8("true"));
-    mpClientInterface->setParameters(output, param.toString());
-
-    mpClientInterface->closeOutput(output);
-    delete outputDesc;
-    mOutputs.removeItem(output);
-    mPreviousOutputs = mOutputs;
-    nextAudioPortGeneration();
-}
-
-SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevice(audio_devices_t device,
-                        DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs)
-{
-    SortedVector<audio_io_handle_t> outputs;
-
-    ALOGVV("getOutputsForDevice() device %04x", device);
-    for (size_t i = 0; i < openOutputs.size(); i++) {
-        ALOGVV("output %d isDuplicated=%d device=%04x",
-                i, openOutputs.valueAt(i)->isDuplicated(), openOutputs.valueAt(i)->supportedDevices());
-        if ((device & openOutputs.valueAt(i)->supportedDevices()) == device) {
-            ALOGVV("getOutputsForDevice() found output %d", openOutputs.keyAt(i));
-            outputs.add(openOutputs.keyAt(i));
-        }
-    }
-    return outputs;
-}
-
-bool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
-                                   SortedVector<audio_io_handle_t>& outputs2)
-{
-    if (outputs1.size() != outputs2.size()) {
-        return false;
-    }
-    for (size_t i = 0; i < outputs1.size(); i++) {
-        if (outputs1[i] != outputs2[i]) {
-            return false;
-        }
-    }
-    return true;
-}
-
-void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
-{
-    audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
-    audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
-    SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mPreviousOutputs);
-    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
-
-    if (!vectorsEqual(srcOutputs,dstOutputs)) {
-        ALOGV("checkOutputForStrategy() strategy %d, moving from output %d to output %d",
-              strategy, srcOutputs[0], dstOutputs[0]);
-        // mute strategy while moving tracks from one output to another
-        for (size_t i = 0; i < srcOutputs.size(); i++) {
-            AudioOutputDescriptor *desc = mOutputs.valueFor(srcOutputs[i]);
-            if (desc->isStrategyActive(strategy)) {
-                setStrategyMute(strategy, true, srcOutputs[i]);
-                setStrategyMute(strategy, false, srcOutputs[i], MUTE_TIME_MS, newDevice);
-            }
-        }
-
-        // Move effects associated to this strategy from previous output to new output
-        if (strategy == STRATEGY_MEDIA) {
-            audio_io_handle_t fxOutput = selectOutputForEffects(dstOutputs);
-            SortedVector<audio_io_handle_t> moved;
-            for (size_t i = 0; i < mEffects.size(); i++) {
-                EffectDescriptor *desc = mEffects.valueAt(i);
-                if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX &&
-                        desc->mIo != fxOutput) {
-                    if (moved.indexOf(desc->mIo) < 0) {
-                        ALOGV("checkOutputForStrategy() moving effect %d to output %d",
-                              mEffects.keyAt(i), fxOutput);
-                        mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, desc->mIo,
-                                                       fxOutput);
-                        moved.add(desc->mIo);
-                    }
-                    desc->mIo = fxOutput;
-                }
-            }
-        }
-        // Move tracks associated to this strategy from previous output to new output
-        for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
-            if (getStrategy((audio_stream_type_t)i) == strategy) {
-                mpClientInterface->invalidateStream((audio_stream_type_t)i);
-            }
-        }
-    }
-}
-
-void AudioPolicyManager::checkOutputForAllStrategies()
-{
-    checkOutputForStrategy(STRATEGY_ENFORCED_AUDIBLE);
-    checkOutputForStrategy(STRATEGY_PHONE);
-    checkOutputForStrategy(STRATEGY_SONIFICATION);
-    checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
-    checkOutputForStrategy(STRATEGY_MEDIA);
-    checkOutputForStrategy(STRATEGY_DTMF);
-}
-
-audio_io_handle_t AudioPolicyManager::getA2dpOutput()
-{
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
-        if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
-            return mOutputs.keyAt(i);
-        }
-    }
-
-    return 0;
-}
-
-void AudioPolicyManager::checkA2dpSuspend()
-{
-    audio_io_handle_t a2dpOutput = getA2dpOutput();
-    if (a2dpOutput == 0) {
-        mA2dpSuspended = false;
-        return;
-    }
-
-    bool isScoConnected =
-            (mAvailableInputDevices.types() & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) != 0;
-    // suspend A2DP output if:
-    //      (NOT already suspended) &&
-    //      ((SCO device is connected &&
-    //       (forced usage for communication || for record is SCO))) ||
-    //      (phone state is ringing || in call)
-    //
-    // restore A2DP output if:
-    //      (Already suspended) &&
-    //      ((SCO device is NOT connected ||
-    //       (forced usage NOT for communication && NOT for record is SCO))) &&
-    //      (phone state is NOT ringing && NOT in call)
-    //
-    if (mA2dpSuspended) {
-        if ((!isScoConnected ||
-             ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO) &&
-              (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] != AUDIO_POLICY_FORCE_BT_SCO))) &&
-             ((mPhoneState != AUDIO_MODE_IN_CALL) &&
-              (mPhoneState != AUDIO_MODE_RINGTONE))) {
-
-            mpClientInterface->restoreOutput(a2dpOutput);
-            mA2dpSuspended = false;
-        }
-    } else {
-        if ((isScoConnected &&
-             ((mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) ||
-              (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO))) ||
-             ((mPhoneState == AUDIO_MODE_IN_CALL) ||
-              (mPhoneState == AUDIO_MODE_RINGTONE))) {
-
-            mpClientInterface->suspendOutput(a2dpOutput);
-            mA2dpSuspended = true;
-        }
-    }
-}
-
-audio_devices_t AudioPolicyManager::getNewOutputDevice(audio_io_handle_t output, bool fromCache)
-{
-    audio_devices_t device = AUDIO_DEVICE_NONE;
-
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
-
-    ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
-    if (index >= 0) {
-        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
-        if (patchDesc->mUid != mUidCached) {
-            ALOGV("getNewOutputDevice() device %08x forced by patch %d",
-                  outputDesc->device(), outputDesc->mPatchHandle);
-            return outputDesc->device();
-        }
-    }
-
-    // check the following by order of priority to request a routing change if necessary:
-    // 1: the strategy enforced audible is active on the output:
-    //      use device for strategy enforced audible
-    // 2: we are in call or the strategy phone is active on the output:
-    //      use device for strategy phone
-    // 3: the strategy sonification is active on the output:
-    //      use device for strategy sonification
-    // 4: the strategy "respectful" sonification is active on the output:
-    //      use device for strategy "respectful" sonification
-    // 5: the strategy media is active on the output:
-    //      use device for strategy media
-    // 6: the strategy DTMF is active on the output:
-    //      use device for strategy DTMF
-    if (outputDesc->isStrategyActive(STRATEGY_ENFORCED_AUDIBLE)) {
-        device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
-    } else if (isInCall() ||
-                    outputDesc->isStrategyActive(STRATEGY_PHONE)) {
-        device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
-    } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION)) {
-        device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
-    } else if (outputDesc->isStrategyActive(STRATEGY_SONIFICATION_RESPECTFUL)) {
-        device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
-    } else if (outputDesc->isStrategyActive(STRATEGY_MEDIA)) {
-        device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
-    } else if (outputDesc->isStrategyActive(STRATEGY_DTMF)) {
-        device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
-    }
-
-    ALOGV("getNewOutputDevice() selected device %x", device);
-    return device;
-}
-
-audio_devices_t AudioPolicyManager::getNewInputDevice(audio_io_handle_t input)
-{
-    AudioInputDescriptor *inputDesc = mInputs.valueFor(input);
-
-    ssize_t index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
-    if (index >= 0) {
-        sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
-        if (patchDesc->mUid != mUidCached) {
-            ALOGV("getNewInputDevice() device %08x forced by patch %d",
-                  inputDesc->mDevice, inputDesc->mPatchHandle);
-            return inputDesc->mDevice;
-        }
-    }
-
-    audio_devices_t device = getDeviceForInputSource(inputDesc->mInputSource);
-
-    ALOGV("getNewInputDevice() selected device %x", device);
-    return device;
-}
-
-uint32_t AudioPolicyManager::getStrategyForStream(audio_stream_type_t stream) {
-    return (uint32_t)getStrategy(stream);
-}
-
-audio_devices_t AudioPolicyManager::getDevicesForStream(audio_stream_type_t stream) {
-    // By checking the range of stream before calling getStrategy, we avoid
-    // getStrategy's behavior for invalid streams.  getStrategy would do a ALOGE
-    // and then return STRATEGY_MEDIA, but we want to return the empty set.
-    if (stream < (audio_stream_type_t) 0 || stream >= AUDIO_STREAM_CNT) {
-        return AUDIO_DEVICE_NONE;
-    }
-    audio_devices_t devices;
-    AudioPolicyManager::routing_strategy strategy = getStrategy(stream);
-    devices = getDeviceForStrategy(strategy, true /*fromCache*/);
-    SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(devices, mOutputs);
-    for (size_t i = 0; i < outputs.size(); i++) {
-        AudioOutputDescriptor *outputDesc = mOutputs.valueFor(outputs[i]);
-        if (outputDesc->isStrategyActive(strategy)) {
-            devices = outputDesc->device();
-            break;
-        }
-    }
-    return devices;
-}
-
-AudioPolicyManager::routing_strategy AudioPolicyManager::getStrategy(
-        audio_stream_type_t stream) {
-    // stream to strategy mapping
-    switch (stream) {
-    case AUDIO_STREAM_VOICE_CALL:
-    case AUDIO_STREAM_BLUETOOTH_SCO:
-        return STRATEGY_PHONE;
-    case AUDIO_STREAM_RING:
-    case AUDIO_STREAM_ALARM:
-        return STRATEGY_SONIFICATION;
-    case AUDIO_STREAM_NOTIFICATION:
-        return STRATEGY_SONIFICATION_RESPECTFUL;
-    case AUDIO_STREAM_DTMF:
-        return STRATEGY_DTMF;
-    default:
-        ALOGE("unknown stream type");
-    case AUDIO_STREAM_SYSTEM:
-        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
-        // while key clicks are played produces a poor result
-    case AUDIO_STREAM_TTS:
-    case AUDIO_STREAM_MUSIC:
-        return STRATEGY_MEDIA;
-    case AUDIO_STREAM_ENFORCED_AUDIBLE:
-        return STRATEGY_ENFORCED_AUDIBLE;
-    }
-}
-
-void AudioPolicyManager::handleNotificationRoutingForStream(audio_stream_type_t stream) {
-    switch(stream) {
-    case AUDIO_STREAM_MUSIC:
-        checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
-        updateDevicesAndOutputs();
-        break;
-    default:
-        break;
-    }
-}
-
-audio_devices_t AudioPolicyManager::getDeviceForStrategy(routing_strategy strategy,
-                                                             bool fromCache)
-{
-    uint32_t device = AUDIO_DEVICE_NONE;
-
-    if (fromCache) {
-        ALOGVV("getDeviceForStrategy() from cache strategy %d, device %x",
-              strategy, mDeviceForStrategy[strategy]);
-        return mDeviceForStrategy[strategy];
-    }
-    audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
-    switch (strategy) {
-
-    case STRATEGY_SONIFICATION_RESPECTFUL:
-        if (isInCall()) {
-            device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
-        } else if (isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
-                SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
-            // while media is playing on a remote device, use the the sonification behavior.
-            // Note that we test this usecase before testing if media is playing because
-            //   the isStreamActive() method only informs about the activity of a stream, not
-            //   if it's for local playback. Note also that we use the same delay between both tests
-            device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
-        } else if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
-            // while media is playing (or has recently played), use the same device
-            device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
-        } else {
-            // when media is not playing anymore, fall back on the sonification behavior
-            device = getDeviceForStrategy(STRATEGY_SONIFICATION, false /*fromCache*/);
-        }
-
-        break;
-
-    case STRATEGY_DTMF:
-        if (!isInCall()) {
-            // when off call, DTMF strategy follows the same rules as MEDIA strategy
-            device = getDeviceForStrategy(STRATEGY_MEDIA, false /*fromCache*/);
-            break;
-        }
-        // when in call, DTMF and PHONE strategies follow the same rules
-        // FALL THROUGH
-
-    case STRATEGY_PHONE:
-        // for phone strategy, we first consider the forced use and then the available devices by order
-        // of priority
-        switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
-        case AUDIO_POLICY_FORCE_BT_SCO:
-            if (!isInCall() || strategy != STRATEGY_DTMF) {
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
-                if (device) break;
-            }
-            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
-            if (device) break;
-            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
-            if (device) break;
-            // if SCO device is requested but no SCO device is available, fall back to default case
-            // FALL THROUGH
-
-        default:    // FORCE_NONE
-            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
-            if (!isInCall() &&
-                    (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
-                    (getA2dpOutput() != 0) && !mA2dpSuspended) {
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
-                if (device) break;
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
-                if (device) break;
-            }
-            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
-            if (device) break;
-            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;
-            if (device) break;
-            if (mPhoneState != AUDIO_MODE_IN_CALL) {
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
-                if (device) break;
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
-                if (device) break;
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
-                if (device) break;
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
-                if (device) break;
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
-                if (device) break;
-            }
-            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_EARPIECE;
-            if (device) break;
-            device = mDefaultOutputDevice->mDeviceType;
-            if (device == AUDIO_DEVICE_NONE) {
-                ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
-            }
-            break;
-
-        case AUDIO_POLICY_FORCE_SPEAKER:
-            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
-            // A2DP speaker when forcing to speaker output
-            if (!isInCall() &&
-                    (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
-                    (getA2dpOutput() != 0) && !mA2dpSuspended) {
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
-                if (device) break;
-            }
-            if (mPhoneState != AUDIO_MODE_IN_CALL) {
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
-                if (device) break;
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
-                if (device) break;
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
-                if (device) break;
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
-                if (device) break;
-                device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
-                if (device) break;
-            }
-            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
-            if (device) break;
-            device = mDefaultOutputDevice->mDeviceType;
-            if (device == AUDIO_DEVICE_NONE) {
-                ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
-            }
-            break;
-        }
-    break;
-
-    case STRATEGY_SONIFICATION:
-
-        // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
-        // handleIncallSonification().
-        if (isInCall()) {
-            device = getDeviceForStrategy(STRATEGY_PHONE, false /*fromCache*/);
-            break;
-        }
-        // FALL THROUGH
-
-    case STRATEGY_ENFORCED_AUDIBLE:
-        // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
-        // except:
-        //   - when in call where it doesn't default to STRATEGY_PHONE behavior
-        //   - in countries where not enforced in which case it follows STRATEGY_MEDIA
-
-        if ((strategy == STRATEGY_SONIFICATION) ||
-                (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
-            device = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
-            if (device == AUDIO_DEVICE_NONE) {
-                ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
-            }
-        }
-        // The second device used for sonification is the same as the device used by media strategy
-        // FALL THROUGH
-
-    case STRATEGY_MEDIA: {
-        uint32_t device2 = AUDIO_DEVICE_NONE;
-        if (strategy != STRATEGY_SONIFICATION) {
-            // no sonification on remote submix (e.g. WFD)
-            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
-        }
-        if ((device2 == AUDIO_DEVICE_NONE) &&
-                (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
-                (getA2dpOutput() != 0) && !mA2dpSuspended) {
-            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
-            if (device2 == AUDIO_DEVICE_NONE) {
-                device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
-            }
-            if (device2 == AUDIO_DEVICE_NONE) {
-                device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
-            }
-        }
-        if (device2 == AUDIO_DEVICE_NONE) {
-            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
-        }
-        if (device2 == AUDIO_DEVICE_NONE) {
-            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_WIRED_HEADSET;
-        }
-        if (device2 == AUDIO_DEVICE_NONE) {
-            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_ACCESSORY;
-        }
-        if (device2 == AUDIO_DEVICE_NONE) {
-            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_USB_DEVICE;
-        }
-        if (device2 == AUDIO_DEVICE_NONE) {
-            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
-        }
-        if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
-            // no sonification on aux digital (e.g. HDMI)
-            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_AUX_DIGITAL;
-        }
-        if ((device2 == AUDIO_DEVICE_NONE) &&
-                (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
-            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
-        }
-        if (device2 == AUDIO_DEVICE_NONE) {
-            device2 = availableOutputDeviceTypes & AUDIO_DEVICE_OUT_SPEAKER;
-        }
-
-        // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
-        // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
-        device |= device2;
-        if (device) break;
-        device = mDefaultOutputDevice->mDeviceType;
-        if (device == AUDIO_DEVICE_NONE) {
-            ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
-        }
-        } break;
-
-    default:
-        ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
-        break;
-    }
-
-    ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
-    return device;
-}
-
-void AudioPolicyManager::updateDevicesAndOutputs()
-{
-    for (int i = 0; i < NUM_STRATEGIES; i++) {
-        mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
-    }
-    mPreviousOutputs = mOutputs;
-}
-
-uint32_t AudioPolicyManager::checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc,
-                                                       audio_devices_t prevDevice,
-                                                       uint32_t delayMs)
-{
-    // mute/unmute strategies using an incompatible device combination
-    // if muting, wait for the audio in pcm buffer to be drained before proceeding
-    // if unmuting, unmute only after the specified delay
-    if (outputDesc->isDuplicated()) {
-        return 0;
-    }
-
-    uint32_t muteWaitMs = 0;
-    audio_devices_t device = outputDesc->device();
-    bool shouldMute = outputDesc->isActive() && (popcount(device) >= 2);
-
-    for (size_t i = 0; i < NUM_STRATEGIES; i++) {
-        audio_devices_t curDevice = getDeviceForStrategy((routing_strategy)i, false /*fromCache*/);
-        bool mute = shouldMute && (curDevice & device) && (curDevice != device);
-        bool doMute = false;
-
-        if (mute && !outputDesc->mStrategyMutedByDevice[i]) {
-            doMute = true;
-            outputDesc->mStrategyMutedByDevice[i] = true;
-        } else if (!mute && outputDesc->mStrategyMutedByDevice[i]){
-            doMute = true;
-            outputDesc->mStrategyMutedByDevice[i] = false;
-        }
-        if (doMute) {
-            for (size_t j = 0; j < mOutputs.size(); j++) {
-                AudioOutputDescriptor *desc = mOutputs.valueAt(j);
-                // skip output if it does not share any device with current output
-                if ((desc->supportedDevices() & outputDesc->supportedDevices())
-                        == AUDIO_DEVICE_NONE) {
-                    continue;
-                }
-                audio_io_handle_t curOutput = mOutputs.keyAt(j);
-                ALOGVV("checkDeviceMuteStrategies() %s strategy %d (curDevice %04x) on output %d",
-                      mute ? "muting" : "unmuting", i, curDevice, curOutput);
-                setStrategyMute((routing_strategy)i, mute, curOutput, mute ? 0 : delayMs);
-                if (desc->isStrategyActive((routing_strategy)i)) {
-                    if (mute) {
-                        // FIXME: should not need to double latency if volume could be applied
-                        // immediately by the audioflinger mixer. We must account for the delay
-                        // between now and the next time the audioflinger thread for this output
-                        // will process a buffer (which corresponds to one buffer size,
-                        // usually 1/2 or 1/4 of the latency).
-                        if (muteWaitMs < desc->latency() * 2) {
-                            muteWaitMs = desc->latency() * 2;
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    // temporary mute output if device selection changes to avoid volume bursts due to
-    // different per device volumes
-    if (outputDesc->isActive() && (device != prevDevice)) {
-        if (muteWaitMs < outputDesc->latency() * 2) {
-            muteWaitMs = outputDesc->latency() * 2;
-        }
-        for (size_t i = 0; i < NUM_STRATEGIES; i++) {
-            if (outputDesc->isStrategyActive((routing_strategy)i)) {
-                setStrategyMute((routing_strategy)i, true, outputDesc->mIoHandle);
-                // do tempMute unmute after twice the mute wait time
-                setStrategyMute((routing_strategy)i, false, outputDesc->mIoHandle,
-                                muteWaitMs *2, device);
-            }
-        }
-    }
-
-    // wait for the PCM output buffers to empty before proceeding with the rest of the command
-    if (muteWaitMs > delayMs) {
-        muteWaitMs -= delayMs;
-        usleep(muteWaitMs * 1000);
-        return muteWaitMs;
-    }
-    return 0;
-}
-
-uint32_t AudioPolicyManager::setOutputDevice(audio_io_handle_t output,
-                                             audio_devices_t device,
-                                             bool force,
-                                             int delayMs,
-                                             audio_patch_handle_t *patchHandle)
-{
-    ALOGV("setOutputDevice() output %d device %04x delayMs %d", output, device, delayMs);
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
-    AudioParameter param;
-    uint32_t muteWaitMs;
-
-    if (outputDesc->isDuplicated()) {
-        muteWaitMs = setOutputDevice(outputDesc->mOutput1->mIoHandle, device, force, delayMs);
-        muteWaitMs += setOutputDevice(outputDesc->mOutput2->mIoHandle, device, force, delayMs);
-        return muteWaitMs;
-    }
-    // no need to proceed if new device is not AUDIO_DEVICE_NONE and not supported by current
-    // output profile
-    if ((device != AUDIO_DEVICE_NONE) &&
-            ((device & outputDesc->mProfile->mSupportedDevices.types()) == 0)) {
-        return 0;
-    }
-
-    // filter devices according to output selected
-    device = (audio_devices_t)(device & outputDesc->mProfile->mSupportedDevices.types());
-
-    audio_devices_t prevDevice = outputDesc->mDevice;
-
-    ALOGV("setOutputDevice() prevDevice %04x", prevDevice);
-
-    if (device != AUDIO_DEVICE_NONE) {
-        outputDesc->mDevice = device;
-    }
-    muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
-
-    // Do not change the routing if:
-    //  - the requested device is AUDIO_DEVICE_NONE
-    //  - the requested device is the same as current device and force is not specified.
-    // Doing this check here allows the caller to call setOutputDevice() without conditions
-    if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) {
-        ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output);
-        return muteWaitMs;
-    }
-
-    ALOGV("setOutputDevice() changing device");
-
-    // do the routing
-    if (device == AUDIO_DEVICE_NONE) {
-        resetOutputDevice(output, delayMs, NULL);
-    } else {
-        DeviceVector deviceList = mAvailableOutputDevices.getDevicesFromType(device);
-        if (!deviceList.isEmpty()) {
-            struct audio_patch patch;
-            outputDesc->toAudioPortConfig(&patch.sources[0]);
-            patch.num_sources = 1;
-            patch.num_sinks = 0;
-            for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
-                deviceList.itemAt(i)->toAudioPortConfig(&patch.sinks[i]);
-                patch.num_sinks++;
-            }
-            ssize_t index;
-            if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
-                index = mAudioPatches.indexOfKey(*patchHandle);
-            } else {
-                index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
-            }
-            sp< AudioPatch> patchDesc;
-            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
-            if (index >= 0) {
-                patchDesc = mAudioPatches.valueAt(index);
-                afPatchHandle = patchDesc->mAfPatchHandle;
-            }
-
-            status_t status = mpClientInterface->createAudioPatch(&patch,
-                                                                   &afPatchHandle,
-                                                                   delayMs);
-            ALOGV("setOutputDevice() createAudioPatch returned %d patchHandle %d"
-                    "num_sources %d num_sinks %d",
-                                       status, afPatchHandle, patch.num_sources, patch.num_sinks);
-            if (status == NO_ERROR) {
-                if (index < 0) {
-                    patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(),
-                                               &patch, mUidCached);
-                    addAudioPatch(patchDesc->mHandle, patchDesc);
-                } else {
-                    patchDesc->mPatch = patch;
-                }
-                patchDesc->mAfPatchHandle = afPatchHandle;
-                patchDesc->mUid = mUidCached;
-                if (patchHandle) {
-                    *patchHandle = patchDesc->mHandle;
-                }
-                outputDesc->mPatchHandle = patchDesc->mHandle;
-                nextAudioPortGeneration();
-                mpClientInterface->onAudioPatchListUpdate();
-            }
-        }
-    }
-
-    // update stream volumes according to new device
-    applyStreamVolumes(output, device, delayMs);
-
-    return muteWaitMs;
-}
-
-status_t AudioPolicyManager::resetOutputDevice(audio_io_handle_t output,
-                                               int delayMs,
-                                               audio_patch_handle_t *patchHandle)
-{
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
-    ssize_t index;
-    if (patchHandle) {
-        index = mAudioPatches.indexOfKey(*patchHandle);
-    } else {
-        index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
-    }
-    if (index < 0) {
-        return INVALID_OPERATION;
-    }
-    sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
-    status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, delayMs);
-    ALOGV("resetOutputDevice() releaseAudioPatch returned %d", status);
-    outputDesc->mPatchHandle = 0;
-    removeAudioPatch(patchDesc->mHandle);
-    nextAudioPortGeneration();
-    mpClientInterface->onAudioPatchListUpdate();
-    return status;
-}
-
-status_t AudioPolicyManager::setInputDevice(audio_io_handle_t input,
-                                            audio_devices_t device,
-                                            bool force,
-                                            audio_patch_handle_t *patchHandle)
-{
-    status_t status = NO_ERROR;
-
-    AudioInputDescriptor *inputDesc = mInputs.valueFor(input);
-    if ((device != AUDIO_DEVICE_NONE) && ((device != inputDesc->mDevice) || force)) {
-        inputDesc->mDevice = device;
-
-        DeviceVector deviceList = mAvailableInputDevices.getDevicesFromType(device);
-        if (!deviceList.isEmpty()) {
-            struct audio_patch patch;
-            inputDesc->toAudioPortConfig(&patch.sinks[0]);
-            patch.num_sinks = 1;
-            //only one input device for now
-            deviceList.itemAt(0)->toAudioPortConfig(&patch.sources[0]);
-            patch.num_sources = 1;
-            ssize_t index;
-            if (patchHandle && *patchHandle != AUDIO_PATCH_HANDLE_NONE) {
-                index = mAudioPatches.indexOfKey(*patchHandle);
-            } else {
-                index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
-            }
-            sp< AudioPatch> patchDesc;
-            audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
-            if (index >= 0) {
-                patchDesc = mAudioPatches.valueAt(index);
-                afPatchHandle = patchDesc->mAfPatchHandle;
-            }
-
-            status_t status = mpClientInterface->createAudioPatch(&patch,
-                                                                  &afPatchHandle,
-                                                                  0);
-            ALOGV("setInputDevice() createAudioPatch returned %d patchHandle %d",
-                                                                          status, afPatchHandle);
-            if (status == NO_ERROR) {
-                if (index < 0) {
-                    patchDesc = new AudioPatch((audio_patch_handle_t)nextUniqueId(),
-                                               &patch, mUidCached);
-                    addAudioPatch(patchDesc->mHandle, patchDesc);
-                } else {
-                    patchDesc->mPatch = patch;
-                }
-                patchDesc->mAfPatchHandle = afPatchHandle;
-                patchDesc->mUid = mUidCached;
-                if (patchHandle) {
-                    *patchHandle = patchDesc->mHandle;
-                }
-                inputDesc->mPatchHandle = patchDesc->mHandle;
-                nextAudioPortGeneration();
-                mpClientInterface->onAudioPatchListUpdate();
-            }
-        }
-    }
-    return status;
-}
-
-status_t AudioPolicyManager::resetInputDevice(audio_io_handle_t input,
-                                              audio_patch_handle_t *patchHandle)
-{
-    AudioInputDescriptor *inputDesc = mInputs.valueFor(input);
-    ssize_t index;
-    if (patchHandle) {
-        index = mAudioPatches.indexOfKey(*patchHandle);
-    } else {
-        index = mAudioPatches.indexOfKey(inputDesc->mPatchHandle);
-    }
-    if (index < 0) {
-        return INVALID_OPERATION;
-    }
-    sp< AudioPatch> patchDesc = mAudioPatches.valueAt(index);
-    status_t status = mpClientInterface->releaseAudioPatch(patchDesc->mAfPatchHandle, 0);
-    ALOGV("resetInputDevice() releaseAudioPatch returned %d", status);
-    inputDesc->mPatchHandle = 0;
-    removeAudioPatch(patchDesc->mHandle);
-    nextAudioPortGeneration();
-    mpClientInterface->onAudioPatchListUpdate();
-    return status;
-}
-
-sp<AudioPolicyManager::IOProfile> AudioPolicyManager::getInputProfile(audio_devices_t device,
-                                                   uint32_t samplingRate,
-                                                   audio_format_t format,
-                                                   audio_channel_mask_t channelMask)
-{
-    // Choose an input profile based on the requested capture parameters: select the first available
-    // profile supporting all requested parameters.
-
-    for (size_t i = 0; i < mHwModules.size(); i++)
-    {
-        if (mHwModules[i]->mHandle == 0) {
-            continue;
-        }
-        for (size_t j = 0; j < mHwModules[i]->mInputProfiles.size(); j++)
-        {
-            sp<IOProfile> profile = mHwModules[i]->mInputProfiles[j];
-            // profile->log();
-            if (profile->isCompatibleProfile(device, samplingRate, format,
-                                             channelMask, AUDIO_OUTPUT_FLAG_NONE)) {
-                return profile;
-            }
-        }
-    }
-    return NULL;
-}
-
-audio_devices_t AudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource)
-{
-    uint32_t device = AUDIO_DEVICE_NONE;
-    audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() &
-                                            ~AUDIO_DEVICE_BIT_IN;
-    switch (inputSource) {
-    case AUDIO_SOURCE_VOICE_UPLINK:
-      if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
-          device = AUDIO_DEVICE_IN_VOICE_CALL;
-          break;
-      }
-      // FALL THROUGH
-
-    case AUDIO_SOURCE_DEFAULT:
-    case AUDIO_SOURCE_MIC:
-    if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
-        device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
-        break;
-    }
-    // FALL THROUGH
-
-    case AUDIO_SOURCE_VOICE_RECOGNITION:
-    case AUDIO_SOURCE_HOTWORD:
-    case AUDIO_SOURCE_VOICE_COMMUNICATION:
-        if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
-                availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
-            device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
-        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
-            device = AUDIO_DEVICE_IN_WIRED_HEADSET;
-        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
-            device = AUDIO_DEVICE_IN_USB_DEVICE;
-        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
-        }
-        break;
-    case AUDIO_SOURCE_CAMCORDER:
-        if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
-            device = AUDIO_DEVICE_IN_BACK_MIC;
-        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
-            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
-        }
-        break;
-    case AUDIO_SOURCE_VOICE_DOWNLINK:
-    case AUDIO_SOURCE_VOICE_CALL:
-        if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
-            device = AUDIO_DEVICE_IN_VOICE_CALL;
-        }
-        break;
-    case AUDIO_SOURCE_REMOTE_SUBMIX:
-        if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
-            device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
-        }
-        break;
-    default:
-        ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
-        break;
-    }
-    ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
-    return device;
-}
-
-bool AudioPolicyManager::isVirtualInputDevice(audio_devices_t device)
-{
-    if ((device & AUDIO_DEVICE_BIT_IN) != 0) {
-        device &= ~AUDIO_DEVICE_BIT_IN;
-        if ((popcount(device) == 1) && ((device & ~APM_AUDIO_IN_DEVICE_VIRTUAL_ALL) == 0))
-            return true;
-    }
-    return false;
-}
-
-audio_io_handle_t AudioPolicyManager::getActiveInput(bool ignoreVirtualInputs)
-{
-    for (size_t i = 0; i < mInputs.size(); i++) {
-        const AudioInputDescriptor * input_descriptor = mInputs.valueAt(i);
-        if ((input_descriptor->mRefCount > 0)
-                && (!ignoreVirtualInputs || !isVirtualInputDevice(input_descriptor->mDevice))) {
-            return mInputs.keyAt(i);
-        }
-    }
-    return 0;
-}
-
-
-audio_devices_t AudioPolicyManager::getDeviceForVolume(audio_devices_t device)
-{
-    if (device == AUDIO_DEVICE_NONE) {
-        // this happens when forcing a route update and no track is active on an output.
-        // In this case the returned category is not important.
-        device =  AUDIO_DEVICE_OUT_SPEAKER;
-    } else if (popcount(device) > 1) {
-        // Multiple device selection is either:
-        //  - speaker + one other device: give priority to speaker in this case.
-        //  - one A2DP device + another device: happens with duplicated output. In this case
-        // retain the device on the A2DP output as the other must not correspond to an active
-        // selection if not the speaker.
-        if (device & AUDIO_DEVICE_OUT_SPEAKER) {
-            device = AUDIO_DEVICE_OUT_SPEAKER;
-        } else {
-            device = (audio_devices_t)(device & AUDIO_DEVICE_OUT_ALL_A2DP);
-        }
-    }
-
-    ALOGW_IF(popcount(device) != 1,
-            "getDeviceForVolume() invalid device combination: %08x",
-            device);
-
-    return device;
-}
-
-AudioPolicyManager::device_category AudioPolicyManager::getDeviceCategory(audio_devices_t device)
-{
-    switch(getDeviceForVolume(device)) {
-        case AUDIO_DEVICE_OUT_EARPIECE:
-            return DEVICE_CATEGORY_EARPIECE;
-        case AUDIO_DEVICE_OUT_WIRED_HEADSET:
-        case AUDIO_DEVICE_OUT_WIRED_HEADPHONE:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
-            return DEVICE_CATEGORY_HEADSET;
-        case AUDIO_DEVICE_OUT_SPEAKER:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
-        case AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
-        case AUDIO_DEVICE_OUT_AUX_DIGITAL:
-        case AUDIO_DEVICE_OUT_USB_ACCESSORY:
-        case AUDIO_DEVICE_OUT_USB_DEVICE:
-        case AUDIO_DEVICE_OUT_REMOTE_SUBMIX:
-        default:
-            return DEVICE_CATEGORY_SPEAKER;
-    }
-}
-
-float AudioPolicyManager::volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
-        int indexInUi)
-{
-    device_category deviceCategory = getDeviceCategory(device);
-    const VolumeCurvePoint *curve = streamDesc.mVolumeCurve[deviceCategory];
-
-    // the volume index in the UI is relative to the min and max volume indices for this stream type
-    int nbSteps = 1 + curve[VOLMAX].mIndex -
-            curve[VOLMIN].mIndex;
-    int volIdx = (nbSteps * (indexInUi - streamDesc.mIndexMin)) /
-            (streamDesc.mIndexMax - streamDesc.mIndexMin);
-
-    // find what part of the curve this index volume belongs to, or if it's out of bounds
-    int segment = 0;
-    if (volIdx < curve[VOLMIN].mIndex) {         // out of bounds
-        return 0.0f;
-    } else if (volIdx < curve[VOLKNEE1].mIndex) {
-        segment = 0;
-    } else if (volIdx < curve[VOLKNEE2].mIndex) {
-        segment = 1;
-    } else if (volIdx <= curve[VOLMAX].mIndex) {
-        segment = 2;
-    } else {                                                               // out of bounds
-        return 1.0f;
-    }
-
-    // linear interpolation in the attenuation table in dB
-    float decibels = curve[segment].mDBAttenuation +
-            ((float)(volIdx - curve[segment].mIndex)) *
-                ( (curve[segment+1].mDBAttenuation -
-                        curve[segment].mDBAttenuation) /
-                    ((float)(curve[segment+1].mIndex -
-                            curve[segment].mIndex)) );
-
-    float amplification = exp( decibels * 0.115129f); // exp( dB * ln(10) / 20 )
-
-    ALOGVV("VOLUME vol index=[%d %d %d], dB=[%.1f %.1f %.1f] ampl=%.5f",
-            curve[segment].mIndex, volIdx,
-            curve[segment+1].mIndex,
-            curve[segment].mDBAttenuation,
-            decibels,
-            curve[segment+1].mDBAttenuation,
-            amplification);
-
-    return amplification;
-}
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sDefaultVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -49.5f}, {33, -33.5f}, {66, -17.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -58.0f}, {20, -40.0f}, {60, -17.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -56.0f}, {20, -34.0f}, {60, -11.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -29.7f}, {33, -20.1f}, {66, -10.2f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
-    {1, -35.7f}, {33, -26.1f}, {66, -13.2f}, {100, 0.0f}
-};
-
-// AUDIO_STREAM_SYSTEM, AUDIO_STREAM_ENFORCED_AUDIBLE and AUDIO_STREAM_DTMF volume tracks
-// AUDIO_STREAM_RING on phones and AUDIO_STREAM_MUSIC on tablets.
-// AUDIO_STREAM_DTMF tracks AUDIO_STREAM_VOICE_CALL while in call (See AudioService.java).
-// The range is constrained between -24dB and -6dB over speaker and -30dB and -18dB over headset.
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -24.0f}, {33, -18.0f}, {66, -12.0f}, {100, -6.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sDefaultSystemVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
-    {1, -34.0f}, {33, -24.0f}, {66, -15.0f}, {100, -6.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {1, -30.0f}, {33, -26.0f}, {66, -22.0f}, {100, -18.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {0, -42.0f}, {33, -28.0f}, {66, -14.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-    AudioPolicyManager::sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT] = {
-    {0, -24.0f}, {33, -16.0f}, {66, -8.0f}, {100, 0.0f}
-};
-
-const AudioPolicyManager::VolumeCurvePoint
-            *AudioPolicyManager::sVolumeProfiles[AUDIO_STREAM_CNT]
-                                                   [AudioPolicyManager::DEVICE_CATEGORY_CNT] = {
-    { // AUDIO_STREAM_VOICE_CALL
-        sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultVoiceVolumeCurve  // DEVICE_CATEGORY_EARPIECE
-    },
-    { // AUDIO_STREAM_SYSTEM
-        sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultSystemVolumeCurve  // DEVICE_CATEGORY_EARPIECE
-    },
-    { // AUDIO_STREAM_RING
-        sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultVolumeCurve  // DEVICE_CATEGORY_EARPIECE
-    },
-    { // AUDIO_STREAM_MUSIC
-        sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EARPIECE
-    },
-    { // AUDIO_STREAM_ALARM
-        sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultVolumeCurve  // DEVICE_CATEGORY_EARPIECE
-    },
-    { // AUDIO_STREAM_NOTIFICATION
-        sDefaultVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerSonificationVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultVolumeCurve  // DEVICE_CATEGORY_EARPIECE
-    },
-    { // AUDIO_STREAM_BLUETOOTH_SCO
-        sDefaultVoiceVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerVoiceVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultVoiceVolumeCurve  // DEVICE_CATEGORY_EARPIECE
-    },
-    { // AUDIO_STREAM_ENFORCED_AUDIBLE
-        sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultSystemVolumeCurve  // DEVICE_CATEGORY_EARPIECE
-    },
-    {  // AUDIO_STREAM_DTMF
-        sHeadsetSystemVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sDefaultSystemVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultSystemVolumeCurve  // DEVICE_CATEGORY_EARPIECE
-    },
-    { // AUDIO_STREAM_TTS
-        sDefaultMediaVolumeCurve, // DEVICE_CATEGORY_HEADSET
-        sSpeakerMediaVolumeCurve, // DEVICE_CATEGORY_SPEAKER
-        sDefaultMediaVolumeCurve  // DEVICE_CATEGORY_EARPIECE
-    },
-};
-
-void AudioPolicyManager::initializeVolumeCurves()
-{
-    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
-        for (int j = 0; j < DEVICE_CATEGORY_CNT; j++) {
-            mStreams[i].mVolumeCurve[j] =
-                    sVolumeProfiles[i][j];
-        }
-    }
-
-    // Check availability of DRC on speaker path: if available, override some of the speaker curves
-    if (mSpeakerDrcEnabled) {
-        mStreams[AUDIO_STREAM_SYSTEM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
-                sDefaultSystemVolumeCurveDrc;
-        mStreams[AUDIO_STREAM_RING].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
-                sSpeakerSonificationVolumeCurveDrc;
-        mStreams[AUDIO_STREAM_ALARM].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
-                sSpeakerSonificationVolumeCurveDrc;
-        mStreams[AUDIO_STREAM_NOTIFICATION].mVolumeCurve[DEVICE_CATEGORY_SPEAKER] =
-                sSpeakerSonificationVolumeCurveDrc;
-    }
-}
-
-float AudioPolicyManager::computeVolume(audio_stream_type_t stream,
-                                            int index,
-                                            audio_io_handle_t output,
-                                            audio_devices_t device)
-{
-    float volume = 1.0;
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
-    StreamDescriptor &streamDesc = mStreams[stream];
-
-    if (device == AUDIO_DEVICE_NONE) {
-        device = outputDesc->device();
-    }
-
-    // if volume is not 0 (not muted), force media volume to max on digital output
-    if (stream == AUDIO_STREAM_MUSIC &&
-        index != mStreams[stream].mIndexMin &&
-        (device == AUDIO_DEVICE_OUT_AUX_DIGITAL ||
-         device == AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET ||
-         device == AUDIO_DEVICE_OUT_USB_ACCESSORY ||
-         device == AUDIO_DEVICE_OUT_USB_DEVICE)) {
-        return 1.0;
-    }
-
-    volume = volIndexToAmpl(device, streamDesc, index);
-
-    // if a headset is connected, apply the following rules to ring tones and notifications
-    // to avoid sound level bursts in user's ears:
-    // - always attenuate ring tones and notifications volume by 6dB
-    // - if music is playing, always limit the volume to current music volume,
-    // with a minimum threshold at -36dB so that notification is always perceived.
-    const routing_strategy stream_strategy = getStrategy(stream);
-    if ((device & (AUDIO_DEVICE_OUT_BLUETOOTH_A2DP |
-            AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
-            AUDIO_DEVICE_OUT_WIRED_HEADSET |
-            AUDIO_DEVICE_OUT_WIRED_HEADPHONE)) &&
-        ((stream_strategy == STRATEGY_SONIFICATION)
-                || (stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL)
-                || (stream == AUDIO_STREAM_SYSTEM)
-                || ((stream_strategy == STRATEGY_ENFORCED_AUDIBLE) &&
-                    (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) &&
-        streamDesc.mCanBeMuted) {
-        volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
-        // when the phone is ringing we must consider that music could have been paused just before
-        // by the music application and behave as if music was active if the last music track was
-        // just stopped
-        if (isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY) ||
-                mLimitRingtoneVolume) {
-            audio_devices_t musicDevice = getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/);
-            float musicVol = computeVolume(AUDIO_STREAM_MUSIC,
-                               mStreams[AUDIO_STREAM_MUSIC].getVolumeIndex(musicDevice),
-                               output,
-                               musicDevice);
-            float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ?
-                                musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
-            if (volume > minVol) {
-                volume = minVol;
-                ALOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
-            }
-        }
-    }
-
-    return volume;
-}
-
-status_t AudioPolicyManager::checkAndSetVolume(audio_stream_type_t stream,
-                                                   int index,
-                                                   audio_io_handle_t output,
-                                                   audio_devices_t device,
-                                                   int delayMs,
-                                                   bool force)
-{
-
-    // do not change actual stream volume if the stream is muted
-    if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
-        ALOGVV("checkAndSetVolume() stream %d muted count %d",
-              stream, mOutputs.valueFor(output)->mMuteCount[stream]);
-        return NO_ERROR;
-    }
-
-    // do not change in call volume if bluetooth is connected and vice versa
-    if ((stream == AUDIO_STREAM_VOICE_CALL &&
-            mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] == AUDIO_POLICY_FORCE_BT_SCO) ||
-        (stream == AUDIO_STREAM_BLUETOOTH_SCO &&
-                mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION] != AUDIO_POLICY_FORCE_BT_SCO)) {
-        ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
-             stream, mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]);
-        return INVALID_OPERATION;
-    }
-
-    float volume = computeVolume(stream, index, output, device);
-    // We actually change the volume if:
-    // - the float value returned by computeVolume() changed
-    // - the force flag is set
-    if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
-            force) {
-        mOutputs.valueFor(output)->mCurVolume[stream] = volume;
-        ALOGVV("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
-        // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
-        // enabled
-        if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
-            mpClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volume, output, delayMs);
-        }
-        mpClientInterface->setStreamVolume(stream, volume, output, delayMs);
-    }
-
-    if (stream == AUDIO_STREAM_VOICE_CALL ||
-        stream == AUDIO_STREAM_BLUETOOTH_SCO) {
-        float voiceVolume;
-        // Force voice volume to max for bluetooth SCO as volume is managed by the headset
-        if (stream == AUDIO_STREAM_VOICE_CALL) {
-            voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
-        } else {
-            voiceVolume = 1.0;
-        }
-
-        if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) {
-            mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
-            mLastVoiceVolume = voiceVolume;
-        }
-    }
-
-    return NO_ERROR;
-}
-
-void AudioPolicyManager::applyStreamVolumes(audio_io_handle_t output,
-                                                audio_devices_t device,
-                                                int delayMs,
-                                                bool force)
-{
-    ALOGVV("applyStreamVolumes() for output %d and device %x", output, device);
-
-    for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
-        checkAndSetVolume((audio_stream_type_t)stream,
-                          mStreams[stream].getVolumeIndex(device),
-                          output,
-                          device,
-                          delayMs,
-                          force);
-    }
-}
-
-void AudioPolicyManager::setStrategyMute(routing_strategy strategy,
-                                             bool on,
-                                             audio_io_handle_t output,
-                                             int delayMs,
-                                             audio_devices_t device)
-{
-    ALOGVV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
-    for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
-        if (getStrategy((audio_stream_type_t)stream) == strategy) {
-            setStreamMute((audio_stream_type_t)stream, on, output, delayMs, device);
-        }
-    }
-}
-
-void AudioPolicyManager::setStreamMute(audio_stream_type_t stream,
-                                           bool on,
-                                           audio_io_handle_t output,
-                                           int delayMs,
-                                           audio_devices_t device)
-{
-    StreamDescriptor &streamDesc = mStreams[stream];
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
-    if (device == AUDIO_DEVICE_NONE) {
-        device = outputDesc->device();
-    }
-
-    ALOGVV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d device %04x",
-          stream, on, output, outputDesc->mMuteCount[stream], device);
-
-    if (on) {
-        if (outputDesc->mMuteCount[stream] == 0) {
-            if (streamDesc.mCanBeMuted &&
-                    ((stream != AUDIO_STREAM_ENFORCED_AUDIBLE) ||
-                     (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_NONE))) {
-                checkAndSetVolume(stream, 0, output, device, delayMs);
-            }
-        }
-        // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
-        outputDesc->mMuteCount[stream]++;
-    } else {
-        if (outputDesc->mMuteCount[stream] == 0) {
-            ALOGV("setStreamMute() unmuting non muted stream!");
-            return;
-        }
-        if (--outputDesc->mMuteCount[stream] == 0) {
-            checkAndSetVolume(stream,
-                              streamDesc.getVolumeIndex(device),
-                              output,
-                              device,
-                              delayMs);
-        }
-    }
-}
-
-void AudioPolicyManager::handleIncallSonification(audio_stream_type_t stream,
-                                                      bool starting, bool stateChange)
-{
-    // if the stream pertains to sonification strategy and we are in call we must
-    // mute the stream if it is low visibility. If it is high visibility, we must play a tone
-    // in the device used for phone strategy and play the tone if the selected device does not
-    // interfere with the device used for phone strategy
-    // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
-    // many times as there are active tracks on the output
-    const routing_strategy stream_strategy = getStrategy(stream);
-    if ((stream_strategy == STRATEGY_SONIFICATION) ||
-            ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
-        AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mPrimaryOutput);
-        ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
-                stream, starting, outputDesc->mDevice, stateChange);
-        if (outputDesc->mRefCount[stream]) {
-            int muteCount = 1;
-            if (stateChange) {
-                muteCount = outputDesc->mRefCount[stream];
-            }
-            if (audio_is_low_visibility(stream)) {
-                ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
-                for (int i = 0; i < muteCount; i++) {
-                    setStreamMute(stream, starting, mPrimaryOutput);
-                }
-            } else {
-                ALOGV("handleIncallSonification() high visibility");
-                if (outputDesc->device() &
-                        getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
-                    ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
-                    for (int i = 0; i < muteCount; i++) {
-                        setStreamMute(stream, starting, mPrimaryOutput);
-                    }
-                }
-                if (starting) {
-                    mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
-                                                 AUDIO_STREAM_VOICE_CALL);
-                } else {
-                    mpClientInterface->stopTone();
-                }
-            }
-        }
-    }
-}
-
-bool AudioPolicyManager::isInCall()
-{
-    return isStateInCall(mPhoneState);
-}
-
-bool AudioPolicyManager::isStateInCall(int state) {
-    return ((state == AUDIO_MODE_IN_CALL) ||
-            (state == AUDIO_MODE_IN_COMMUNICATION));
-}
-
-uint32_t AudioPolicyManager::getMaxEffectsCpuLoad()
-{
-    return MAX_EFFECTS_CPU_LOAD;
-}
-
-uint32_t AudioPolicyManager::getMaxEffectsMemory()
-{
-    return MAX_EFFECTS_MEMORY;
-}
-
-
-// --- AudioOutputDescriptor class implementation
-
-AudioPolicyManager::AudioOutputDescriptor::AudioOutputDescriptor(
-        const sp<IOProfile>& profile)
-    : mId(0), mIoHandle(0), mSamplingRate(0), mFormat(AUDIO_FORMAT_DEFAULT),
-      mChannelMask(0), mLatency(0),
-    mFlags((audio_output_flags_t)0), mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0),
-    mOutput1(0), mOutput2(0), mProfile(profile), mDirectOpenCount(0)
-{
-    // clear usage count for all stream types
-    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
-        mRefCount[i] = 0;
-        mCurVolume[i] = -1.0;
-        mMuteCount[i] = 0;
-        mStopTime[i] = 0;
-    }
-    for (int i = 0; i < NUM_STRATEGIES; i++) {
-        mStrategyMutedByDevice[i] = false;
-    }
-    if (profile != NULL) {
-        mSamplingRate = profile->mSamplingRates[0];
-        mFormat = profile->mFormats[0];
-        mChannelMask = profile->mChannelMasks[0];
-        mFlags = profile->mFlags;
-    }
-}
-
-audio_devices_t AudioPolicyManager::AudioOutputDescriptor::device() const
-{
-    if (isDuplicated()) {
-        return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
-    } else {
-        return mDevice;
-    }
-}
-
-uint32_t AudioPolicyManager::AudioOutputDescriptor::latency()
-{
-    if (isDuplicated()) {
-        return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
-    } else {
-        return mLatency;
-    }
-}
-
-bool AudioPolicyManager::AudioOutputDescriptor::sharesHwModuleWith(
-        const AudioOutputDescriptor *outputDesc)
-{
-    if (isDuplicated()) {
-        return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
-    } else if (outputDesc->isDuplicated()){
-        return sharesHwModuleWith(outputDesc->mOutput1) || sharesHwModuleWith(outputDesc->mOutput2);
-    } else {
-        return (mProfile->mModule == outputDesc->mProfile->mModule);
-    }
-}
-
-void AudioPolicyManager::AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
-                                                                   int delta)
-{
-    // forward usage count change to attached outputs
-    if (isDuplicated()) {
-        mOutput1->changeRefCount(stream, delta);
-        mOutput2->changeRefCount(stream, delta);
-    }
-    if ((delta + (int)mRefCount[stream]) < 0) {
-        ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
-              delta, stream, mRefCount[stream]);
-        mRefCount[stream] = 0;
-        return;
-    }
-    mRefCount[stream] += delta;
-    ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
-}
-
-audio_devices_t AudioPolicyManager::AudioOutputDescriptor::supportedDevices()
-{
-    if (isDuplicated()) {
-        return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
-    } else {
-        return mProfile->mSupportedDevices.types() ;
-    }
-}
-
-bool AudioPolicyManager::AudioOutputDescriptor::isActive(uint32_t inPastMs) const
-{
-    return isStrategyActive(NUM_STRATEGIES, inPastMs);
-}
-
-bool AudioPolicyManager::AudioOutputDescriptor::isStrategyActive(routing_strategy strategy,
-                                                                       uint32_t inPastMs,
-                                                                       nsecs_t sysTime) const
-{
-    if ((sysTime == 0) && (inPastMs != 0)) {
-        sysTime = systemTime();
-    }
-    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
-        if (((getStrategy((audio_stream_type_t)i) == strategy) ||
-                (NUM_STRATEGIES == strategy)) &&
-                isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool AudioPolicyManager::AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
-                                                                       uint32_t inPastMs,
-                                                                       nsecs_t sysTime) const
-{
-    if (mRefCount[stream] != 0) {
-        return true;
-    }
-    if (inPastMs == 0) {
-        return false;
-    }
-    if (sysTime == 0) {
-        sysTime = systemTime();
-    }
-    if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
-        return true;
-    }
-    return false;
-}
-
-void AudioPolicyManager::AudioOutputDescriptor::toAudioPortConfig(
-                                                 struct audio_port_config *dstConfig,
-                                                 const struct audio_port_config *srcConfig) const
-{
-    dstConfig->id = mId;
-    dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
-    dstConfig->type = AUDIO_PORT_TYPE_MIX;
-    dstConfig->sample_rate = mSamplingRate;
-    dstConfig->channel_mask = mChannelMask;
-    dstConfig->format = mFormat;
-    dstConfig->gain.index = -1;
-    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
-                            AUDIO_PORT_CONFIG_FORMAT;
-    // use supplied variable configuration parameters if any
-    if (srcConfig != NULL) {
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
-            dstConfig->sample_rate = srcConfig->sample_rate;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
-            dstConfig->channel_mask = srcConfig->channel_mask;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
-            dstConfig->format = srcConfig->format;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) {
-            dstConfig->gain = srcConfig->gain;
-            dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
-        }
-    }
-    dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
-    dstConfig->ext.mix.handle = mIoHandle;
-    dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
-}
-
-void AudioPolicyManager::AudioOutputDescriptor::toAudioPort(
-                                                    struct audio_port *port) const
-{
-    mProfile->toAudioPort(port);
-    port->id = mId;
-    toAudioPortConfig(&port->active_config);
-    port->ext.mix.hw_module = mProfile->mModule->mHandle;
-    port->ext.mix.handle = mIoHandle;
-    port->ext.mix.latency_class =
-            mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
-}
-
-status_t AudioPolicyManager::AudioOutputDescriptor::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Devices %08x\n", device());
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
-    result.append(buffer);
-    for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
-        snprintf(buffer, SIZE, " %02d     %.03f     %02d       %02d\n",
-                 i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
-        result.append(buffer);
-    }
-    write(fd, result.string(), result.size());
-
-    return NO_ERROR;
-}
-
-// --- AudioInputDescriptor class implementation
-
-AudioPolicyManager::AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)
-    : mId(0), mIoHandle(0), mSamplingRate(0),
-      mFormat(AUDIO_FORMAT_DEFAULT), mChannelMask(0),
-      mDevice(AUDIO_DEVICE_NONE), mPatchHandle(0), mRefCount(0),
-      mInputSource(AUDIO_SOURCE_DEFAULT), mProfile(profile)
-{
-    if (profile != NULL) {
-        mSamplingRate = profile->mSamplingRates[0];
-        mFormat = profile->mFormats[0];
-        mChannelMask = profile->mChannelMasks[0];
-    }
-}
-
-void AudioPolicyManager::AudioInputDescriptor::toAudioPortConfig(
-                                                   struct audio_port_config *dstConfig,
-                                                   const struct audio_port_config *srcConfig) const
-{
-    dstConfig->id = mId;
-    dstConfig->role = AUDIO_PORT_ROLE_SINK;
-    dstConfig->type = AUDIO_PORT_TYPE_MIX;
-    dstConfig->sample_rate = mSamplingRate;
-    dstConfig->channel_mask = mChannelMask;
-    dstConfig->format = mFormat;
-    dstConfig->gain.index = -1;
-    dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
-                            AUDIO_PORT_CONFIG_FORMAT;
-    // use supplied variable configuration parameters if any
-    if (srcConfig != NULL) {
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
-            dstConfig->sample_rate = srcConfig->sample_rate;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
-            dstConfig->channel_mask = srcConfig->channel_mask;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
-            dstConfig->format = srcConfig->format;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) {
-            dstConfig->gain = srcConfig->gain;
-            dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
-        }
-    }
-    dstConfig->ext.mix.hw_module = mProfile->mModule->mHandle;
-    dstConfig->ext.mix.handle = mIoHandle;
-    dstConfig->ext.mix.usecase.source = mInputSource;
-}
-
-void AudioPolicyManager::AudioInputDescriptor::toAudioPort(
-                                                    struct audio_port *port) const
-{
-    mProfile->toAudioPort(port);
-    port->id = mId;
-    toAudioPortConfig(&port->active_config);
-    port->ext.mix.hw_module = mProfile->mModule->mHandle;
-    port->ext.mix.handle = mIoHandle;
-    port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL;
-}
-
-status_t AudioPolicyManager::AudioInputDescriptor::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-
-    return NO_ERROR;
-}
-
-// --- StreamDescriptor class implementation
-
-AudioPolicyManager::StreamDescriptor::StreamDescriptor()
-    :   mIndexMin(0), mIndexMax(1), mCanBeMuted(true)
-{
-    mIndexCur.add(AUDIO_DEVICE_OUT_DEFAULT, 0);
-}
-
-int AudioPolicyManager::StreamDescriptor::getVolumeIndex(audio_devices_t device)
-{
-    device = AudioPolicyManager::getDeviceForVolume(device);
-    // there is always a valid entry for AUDIO_DEVICE_OUT_DEFAULT
-    if (mIndexCur.indexOfKey(device) < 0) {
-        device = AUDIO_DEVICE_OUT_DEFAULT;
-    }
-    return mIndexCur.valueFor(device);
-}
-
-void AudioPolicyManager::StreamDescriptor::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%s         %02d         %02d         ",
-             mCanBeMuted ? "true " : "false", mIndexMin, mIndexMax);
-    result.append(buffer);
-    for (size_t i = 0; i < mIndexCur.size(); i++) {
-        snprintf(buffer, SIZE, "%04x : %02d, ",
-                 mIndexCur.keyAt(i),
-                 mIndexCur.valueAt(i));
-        result.append(buffer);
-    }
-    result.append("\n");
-
-    write(fd, result.string(), result.size());
-}
-
-// --- EffectDescriptor class implementation
-
-status_t AudioPolicyManager::EffectDescriptor::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, " I/O: %d\n", mIo);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Session: %d\n", mSession);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Name: %s\n",  mDesc.name);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " %s\n",  mEnabled ? "Enabled" : "Disabled");
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-
-    return NO_ERROR;
-}
-
-// --- HwModule class implementation
-
-AudioPolicyManager::HwModule::HwModule(const char *name)
-    : mName(strndup(name, AUDIO_HARDWARE_MODULE_ID_MAX_LEN)), mHandle(0)
-{
-}
-
-AudioPolicyManager::HwModule::~HwModule()
-{
-    for (size_t i = 0; i < mOutputProfiles.size(); i++) {
-        mOutputProfiles[i]->mSupportedDevices.clear();
-    }
-    for (size_t i = 0; i < mInputProfiles.size(); i++) {
-        mInputProfiles[i]->mSupportedDevices.clear();
-    }
-    free((void *)mName);
-}
-
-status_t AudioPolicyManager::HwModule::loadInput(cnode *root)
-{
-    cnode *node = root->first_child;
-
-    sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SINK, this);
-
-    while (node) {
-        if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
-            profile->loadSamplingRates((char *)node->value);
-        } else if (strcmp(node->name, FORMATS_TAG) == 0) {
-            profile->loadFormats((char *)node->value);
-        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
-            profile->loadInChannels((char *)node->value);
-        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
-            profile->mSupportedDevices.loadDevicesFromName((char *)node->value,
-                                                           mDeclaredDevices);
-        } else if (strcmp(node->name, GAINS_TAG) == 0) {
-            profile->loadGains(node);
-        }
-        node = node->next;
-    }
-    ALOGW_IF(profile->mSupportedDevices.isEmpty(),
-            "loadInput() invalid supported devices");
-    ALOGW_IF(profile->mChannelMasks.size() == 0,
-            "loadInput() invalid supported channel masks");
-    ALOGW_IF(profile->mSamplingRates.size() == 0,
-            "loadInput() invalid supported sampling rates");
-    ALOGW_IF(profile->mFormats.size() == 0,
-            "loadInput() invalid supported formats");
-    if (!profile->mSupportedDevices.isEmpty() &&
-            (profile->mChannelMasks.size() != 0) &&
-            (profile->mSamplingRates.size() != 0) &&
-            (profile->mFormats.size() != 0)) {
-
-        ALOGV("loadInput() adding input Supported Devices %04x",
-              profile->mSupportedDevices.types());
-
-        mInputProfiles.add(profile);
-        return NO_ERROR;
-    } else {
-        return BAD_VALUE;
-    }
-}
-
-status_t AudioPolicyManager::HwModule::loadOutput(cnode *root)
-{
-    cnode *node = root->first_child;
-
-    sp<IOProfile> profile = new IOProfile(String8(root->name), AUDIO_PORT_ROLE_SOURCE, this);
-
-    while (node) {
-        if (strcmp(node->name, SAMPLING_RATES_TAG) == 0) {
-            profile->loadSamplingRates((char *)node->value);
-        } else if (strcmp(node->name, FORMATS_TAG) == 0) {
-            profile->loadFormats((char *)node->value);
-        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
-            profile->loadOutChannels((char *)node->value);
-        } else if (strcmp(node->name, DEVICES_TAG) == 0) {
-            profile->mSupportedDevices.loadDevicesFromName((char *)node->value,
-                                                           mDeclaredDevices);
-        } else if (strcmp(node->name, FLAGS_TAG) == 0) {
-            profile->mFlags = parseFlagNames((char *)node->value);
-        } else if (strcmp(node->name, GAINS_TAG) == 0) {
-            profile->loadGains(node);
-        }
-        node = node->next;
-    }
-    ALOGW_IF(profile->mSupportedDevices.isEmpty(),
-            "loadOutput() invalid supported devices");
-    ALOGW_IF(profile->mChannelMasks.size() == 0,
-            "loadOutput() invalid supported channel masks");
-    ALOGW_IF(profile->mSamplingRates.size() == 0,
-            "loadOutput() invalid supported sampling rates");
-    ALOGW_IF(profile->mFormats.size() == 0,
-            "loadOutput() invalid supported formats");
-    if (!profile->mSupportedDevices.isEmpty() &&
-            (profile->mChannelMasks.size() != 0) &&
-            (profile->mSamplingRates.size() != 0) &&
-            (profile->mFormats.size() != 0)) {
-
-        ALOGV("loadOutput() adding output Supported Devices %04x, mFlags %04x",
-              profile->mSupportedDevices.types(), profile->mFlags);
-
-        mOutputProfiles.add(profile);
-        return NO_ERROR;
-    } else {
-        return BAD_VALUE;
-    }
-}
-
-status_t AudioPolicyManager::HwModule::loadDevice(cnode *root)
-{
-    cnode *node = root->first_child;
-
-    audio_devices_t type = AUDIO_DEVICE_NONE;
-    while (node) {
-        if (strcmp(node->name, DEVICE_TYPE) == 0) {
-            type = parseDeviceNames((char *)node->value);
-            break;
-        }
-        node = node->next;
-    }
-    if (type == AUDIO_DEVICE_NONE ||
-            (!audio_is_input_device(type) && !audio_is_output_device(type))) {
-        ALOGW("loadDevice() bad type %08x", type);
-        return BAD_VALUE;
-    }
-    sp<DeviceDescriptor> deviceDesc = new DeviceDescriptor(String8(root->name), type);
-    deviceDesc->mModule = this;
-
-    node = root->first_child;
-    while (node) {
-        if (strcmp(node->name, DEVICE_ADDRESS) == 0) {
-            deviceDesc->mAddress = String8((char *)node->value);
-        } else if (strcmp(node->name, CHANNELS_TAG) == 0) {
-            if (audio_is_input_device(type)) {
-                deviceDesc->loadInChannels((char *)node->value);
-            } else {
-                deviceDesc->loadOutChannels((char *)node->value);
-            }
-        } else if (strcmp(node->name, GAINS_TAG) == 0) {
-            deviceDesc->loadGains(node);
-        }
-        node = node->next;
-    }
-
-    ALOGV("loadDevice() adding device name %s type %08x address %s",
-          deviceDesc->mName.string(), type, deviceDesc->mAddress.string());
-
-    mDeclaredDevices.add(deviceDesc);
-
-    return NO_ERROR;
-}
-
-void AudioPolicyManager::HwModule::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "  - name: %s\n", mName);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "  - handle: %d\n", mHandle);
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-    if (mOutputProfiles.size()) {
-        write(fd, "  - outputs:\n", strlen("  - outputs:\n"));
-        for (size_t i = 0; i < mOutputProfiles.size(); i++) {
-            snprintf(buffer, SIZE, "    output %zu:\n", i);
-            write(fd, buffer, strlen(buffer));
-            mOutputProfiles[i]->dump(fd);
-        }
-    }
-    if (mInputProfiles.size()) {
-        write(fd, "  - inputs:\n", strlen("  - inputs:\n"));
-        for (size_t i = 0; i < mInputProfiles.size(); i++) {
-            snprintf(buffer, SIZE, "    input %zu:\n", i);
-            write(fd, buffer, strlen(buffer));
-            mInputProfiles[i]->dump(fd);
-        }
-    }
-    if (mDeclaredDevices.size()) {
-        write(fd, "  - devices:\n", strlen("  - devices:\n"));
-        for (size_t i = 0; i < mDeclaredDevices.size(); i++) {
-            mDeclaredDevices[i]->dump(fd, 4, i);
-        }
-    }
-}
-
-// --- AudioPort class implementation
-
-void AudioPolicyManager::AudioPort::toAudioPort(struct audio_port *port) const
-{
-    port->role = mRole;
-    port->type = mType;
-    unsigned int i;
-    for (i = 0; i < mSamplingRates.size() && i < AUDIO_PORT_MAX_SAMPLING_RATES; i++) {
-        port->sample_rates[i] = mSamplingRates[i];
-    }
-    port->num_sample_rates = i;
-    for (i = 0; i < mChannelMasks.size() && i < AUDIO_PORT_MAX_CHANNEL_MASKS; i++) {
-        port->channel_masks[i] = mChannelMasks[i];
-    }
-    port->num_channel_masks = i;
-    for (i = 0; i < mFormats.size() && i < AUDIO_PORT_MAX_FORMATS; i++) {
-        port->formats[i] = mFormats[i];
-    }
-    port->num_formats = i;
-
-    ALOGV("AudioPort::toAudioPort() num gains %d", mGains.size());
-
-    for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) {
-        port->gains[i] = mGains[i]->mGain;
-    }
-    port->num_gains = i;
-}
-
-
-void AudioPolicyManager::AudioPort::loadSamplingRates(char *name)
-{
-    char *str = strtok(name, "|");
-
-    // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling
-    // rates should be read from the output stream after it is opened for the first time
-    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
-        mSamplingRates.add(0);
-        return;
-    }
-
-    while (str != NULL) {
-        uint32_t rate = atoi(str);
-        if (rate != 0) {
-            ALOGV("loadSamplingRates() adding rate %d", rate);
-            mSamplingRates.add(rate);
-        }
-        str = strtok(NULL, "|");
-    }
-}
-
-void AudioPolicyManager::AudioPort::loadFormats(char *name)
-{
-    char *str = strtok(name, "|");
-
-    // by convention, "0' in the first entry in mFormats indicates the supported formats
-    // should be read from the output stream after it is opened for the first time
-    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
-        mFormats.add(AUDIO_FORMAT_DEFAULT);
-        return;
-    }
-
-    while (str != NULL) {
-        audio_format_t format = (audio_format_t)stringToEnum(sFormatNameToEnumTable,
-                                                             ARRAY_SIZE(sFormatNameToEnumTable),
-                                                             str);
-        if (format != AUDIO_FORMAT_DEFAULT) {
-            mFormats.add(format);
-        }
-        str = strtok(NULL, "|");
-    }
-}
-
-void AudioPolicyManager::AudioPort::loadInChannels(char *name)
-{
-    const char *str = strtok(name, "|");
-
-    ALOGV("loadInChannels() %s", name);
-
-    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
-        mChannelMasks.add(0);
-        return;
-    }
-
-    while (str != NULL) {
-        audio_channel_mask_t channelMask =
-                (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable,
-                                                   ARRAY_SIZE(sInChannelsNameToEnumTable),
-                                                   str);
-        if (channelMask != 0) {
-            ALOGV("loadInChannels() adding channelMask %04x", channelMask);
-            mChannelMasks.add(channelMask);
-        }
-        str = strtok(NULL, "|");
-    }
-}
-
-void AudioPolicyManager::AudioPort::loadOutChannels(char *name)
-{
-    const char *str = strtok(name, "|");
-
-    ALOGV("loadOutChannels() %s", name);
-
-    // by convention, "0' in the first entry in mChannelMasks indicates the supported channel
-    // masks should be read from the output stream after it is opened for the first time
-    if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) {
-        mChannelMasks.add(0);
-        return;
-    }
-
-    while (str != NULL) {
-        audio_channel_mask_t channelMask =
-                (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable,
-                                                   ARRAY_SIZE(sOutChannelsNameToEnumTable),
-                                                   str);
-        if (channelMask != 0) {
-            mChannelMasks.add(channelMask);
-        }
-        str = strtok(NULL, "|");
-    }
-    return;
-}
-
-audio_gain_mode_t AudioPolicyManager::AudioPort::loadGainMode(char *name)
-{
-    const char *str = strtok(name, "|");
-
-    ALOGV("loadGainMode() %s", name);
-    audio_gain_mode_t mode = 0;
-    while (str != NULL) {
-        mode |= (audio_gain_mode_t)stringToEnum(sGainModeNameToEnumTable,
-                                                ARRAY_SIZE(sGainModeNameToEnumTable),
-                                                str);
-        str = strtok(NULL, "|");
-    }
-    return mode;
-}
-
-void AudioPolicyManager::AudioPort::loadGain(cnode *root)
-{
-    cnode *node = root->first_child;
-
-    sp<AudioGain> gain = new AudioGain();
-
-    while (node) {
-        if (strcmp(node->name, GAIN_MODE) == 0) {
-            gain->mGain.mode = loadGainMode((char *)node->value);
-        } else if (strcmp(node->name, GAIN_CHANNELS) == 0) {
-            if ((mType == AUDIO_PORT_TYPE_DEVICE && mRole == AUDIO_PORT_ROLE_SOURCE) ||
-                    (mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK)) {
-                gain->mGain.channel_mask =
-                        (audio_channel_mask_t)stringToEnum(sInChannelsNameToEnumTable,
-                                                           ARRAY_SIZE(sInChannelsNameToEnumTable),
-                                                           (char *)node->value);
-            } else {
-                gain->mGain.channel_mask =
-                        (audio_channel_mask_t)stringToEnum(sOutChannelsNameToEnumTable,
-                                                           ARRAY_SIZE(sOutChannelsNameToEnumTable),
-                                                           (char *)node->value);
-            }
-        } else if (strcmp(node->name, GAIN_MIN_VALUE) == 0) {
-            gain->mGain.min_value = atoi((char *)node->value);
-        } else if (strcmp(node->name, GAIN_MAX_VALUE) == 0) {
-            gain->mGain.max_value = atoi((char *)node->value);
-        } else if (strcmp(node->name, GAIN_DEFAULT_VALUE) == 0) {
-            gain->mGain.default_value = atoi((char *)node->value);
-        } else if (strcmp(node->name, GAIN_STEP_VALUE) == 0) {
-            gain->mGain.step_value = atoi((char *)node->value);
-        } else if (strcmp(node->name, GAIN_MIN_RAMP_MS) == 0) {
-            gain->mGain.min_ramp_ms = atoi((char *)node->value);
-        } else if (strcmp(node->name, GAIN_MAX_RAMP_MS) == 0) {
-            gain->mGain.max_ramp_ms = atoi((char *)node->value);
-        }
-        node = node->next;
-    }
-
-    ALOGV("loadGain() adding new gain mode %08x channel mask %08x min mB %d max mB %d",
-          gain->mGain.mode, gain->mGain.channel_mask, gain->mGain.min_value, gain->mGain.max_value);
-
-    if (gain->mGain.mode == 0) {
-        return;
-    }
-    mGains.add(gain);
-}
-
-void AudioPolicyManager::AudioPort::loadGains(cnode *root)
-{
-    cnode *node = root->first_child;
-    while (node) {
-        ALOGV("loadGains() loading gain %s", node->name);
-        loadGain(node);
-        node = node->next;
-    }
-}
-
-void AudioPolicyManager::AudioPort::dump(int fd, int spaces) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    if (mName.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string());
-        result.append(buffer);
-    }
-
-    if (mSamplingRates.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- sampling rates: ", spaces, "");
-        result.append(buffer);
-        for (size_t i = 0; i < mSamplingRates.size(); i++) {
-            snprintf(buffer, SIZE, "%d", mSamplingRates[i]);
-            result.append(buffer);
-            result.append(i == (mSamplingRates.size() - 1) ? "" : ", ");
-        }
-        result.append("\n");
-    }
-
-    if (mChannelMasks.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- channel masks: ", spaces, "");
-        result.append(buffer);
-        for (size_t i = 0; i < mChannelMasks.size(); i++) {
-            snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]);
-            result.append(buffer);
-            result.append(i == (mChannelMasks.size() - 1) ? "" : ", ");
-        }
-        result.append("\n");
-    }
-
-    if (mFormats.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- formats: ", spaces, "");
-        result.append(buffer);
-        for (size_t i = 0; i < mFormats.size(); i++) {
-            snprintf(buffer, SIZE, "%-48s", enumToString(sFormatNameToEnumTable,
-                                                          ARRAY_SIZE(sFormatNameToEnumTable),
-                                                          mFormats[i]));
-            result.append(buffer);
-            result.append(i == (mFormats.size() - 1) ? "" : ", ");
-        }
-        result.append("\n");
-    }
-    write(fd, result.string(), result.size());
-    if (mGains.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- gains:\n", spaces, "");
-        write(fd, buffer, strlen(buffer) + 1);
-        result.append(buffer);
-        for (size_t i = 0; i < mGains.size(); i++) {
-            mGains[i]->dump(fd, spaces + 2, i);
-        }
-    }
-}
-
-// --- AudioGain class implementation
-
-AudioPolicyManager::AudioGain::AudioGain()
-{
-    memset(&mGain, 0, sizeof(struct audio_gain));
-}
-
-void AudioPolicyManager::AudioGain::dump(int fd, int spaces, int index) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*sGain %d:\n", spaces, "", index+1);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- mode: %08x\n", spaces, "", mGain.mode);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- channel_mask: %08x\n", spaces, "", mGain.channel_mask);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- min_value: %d mB\n", spaces, "", mGain.min_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- max_value: %d mB\n", spaces, "", mGain.max_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- default_value: %d mB\n", spaces, "", mGain.default_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- step_value: %d mB\n", spaces, "", mGain.step_value);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- min_ramp_ms: %d ms\n", spaces, "", mGain.min_ramp_ms);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms);
-    result.append(buffer);
-
-    write(fd, result.string(), result.size());
-}
-
-// --- IOProfile class implementation
-
-AudioPolicyManager::IOProfile::IOProfile(const String8& name, audio_port_role_t role,
-                                         HwModule *module)
-    : AudioPort(name, AUDIO_PORT_TYPE_MIX, role, module), mFlags((audio_output_flags_t)0)
-{
-}
-
-AudioPolicyManager::IOProfile::~IOProfile()
-{
-}
-
-// checks if the IO profile is compatible with specified parameters.
-// Sampling rate, format and channel mask must be specified in order to
-// get a valid a match
-bool AudioPolicyManager::IOProfile::isCompatibleProfile(audio_devices_t device,
-                                                            uint32_t samplingRate,
-                                                            audio_format_t format,
-                                                            audio_channel_mask_t channelMask,
-                                                            audio_output_flags_t flags) const
-{
-    if (samplingRate == 0 || !audio_is_valid_format(format) || channelMask == 0) {
-         return false;
-     }
-
-     if ((mSupportedDevices.types() & device) != device) {
-         return false;
-     }
-     if ((mFlags & flags) != flags) {
-         return false;
-     }
-     size_t i;
-     for (i = 0; i < mSamplingRates.size(); i++)
-     {
-         if (mSamplingRates[i] == samplingRate) {
-             break;
-         }
-     }
-     if (i == mSamplingRates.size()) {
-         return false;
-     }
-     for (i = 0; i < mFormats.size(); i++)
-     {
-         if (mFormats[i] == format) {
-             break;
-         }
-     }
-     if (i == mFormats.size()) {
-         return false;
-     }
-     for (i = 0; i < mChannelMasks.size(); i++)
-     {
-         if (mChannelMasks[i] == channelMask) {
-             break;
-         }
-     }
-     if (i == mChannelMasks.size()) {
-         return false;
-     }
-     return true;
-}
-
-void AudioPolicyManager::IOProfile::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    AudioPort::dump(fd, 4);
-
-    snprintf(buffer, SIZE, "    - flags: 0x%04x\n", mFlags);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "    - devices:\n");
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-    for (size_t i = 0; i < mSupportedDevices.size(); i++) {
-        mSupportedDevices[i]->dump(fd, 6, i);
-    }
-}
-
-void AudioPolicyManager::IOProfile::log()
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    ALOGV("    - sampling rates: ");
-    for (size_t i = 0; i < mSamplingRates.size(); i++) {
-        ALOGV("  %d", mSamplingRates[i]);
-    }
-
-    ALOGV("    - channel masks: ");
-    for (size_t i = 0; i < mChannelMasks.size(); i++) {
-        ALOGV("  0x%04x", mChannelMasks[i]);
-    }
-
-    ALOGV("    - formats: ");
-    for (size_t i = 0; i < mFormats.size(); i++) {
-        ALOGV("  0x%08x", mFormats[i]);
-    }
-
-    ALOGV("    - devices: 0x%04x\n", mSupportedDevices.types());
-    ALOGV("    - flags: 0x%04x\n", mFlags);
-}
-
-
-// --- DeviceDescriptor implementation
-
-bool AudioPolicyManager::DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
-{
-    // Devices are considered equal if they:
-    // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
-    // - have the same address or one device does not specify the address
-    // - have the same channel mask or one device does not specify the channel mask
-    return (mDeviceType == other->mDeviceType) &&
-           (mAddress == "" || other->mAddress == "" || mAddress == other->mAddress) &&
-           (mChannelMask == 0 || other->mChannelMask == 0 ||
-                mChannelMask == other->mChannelMask);
-}
-
-void AudioPolicyManager::DeviceVector::refreshTypes()
-{
-    mDeviceTypes = AUDIO_DEVICE_NONE;
-    for(size_t i = 0; i < size(); i++) {
-        mDeviceTypes |= itemAt(i)->mDeviceType;
-    }
-    ALOGV("DeviceVector::refreshTypes() mDeviceTypes %08x", mDeviceTypes);
-}
-
-ssize_t AudioPolicyManager::DeviceVector::indexOf(const sp<DeviceDescriptor>& item) const
-{
-    for(size_t i = 0; i < size(); i++) {
-        if (item->equals(itemAt(i))) {
-            return i;
-        }
-    }
-    return -1;
-}
-
-ssize_t AudioPolicyManager::DeviceVector::add(const sp<DeviceDescriptor>& item)
-{
-    ssize_t ret = indexOf(item);
-
-    if (ret < 0) {
-        ret = SortedVector::add(item);
-        if (ret >= 0) {
-            refreshTypes();
-        }
-    } else {
-        ALOGW("DeviceVector::add device %08x already in", item->mDeviceType);
-        ret = -1;
-    }
-    return ret;
-}
-
-ssize_t AudioPolicyManager::DeviceVector::remove(const sp<DeviceDescriptor>& item)
-{
-    size_t i;
-    ssize_t ret = indexOf(item);
-
-    if (ret < 0) {
-        ALOGW("DeviceVector::remove device %08x not in", item->mDeviceType);
-    } else {
-        ret = SortedVector::removeAt(ret);
-        if (ret >= 0) {
-            refreshTypes();
-        }
-    }
-    return ret;
-}
-
-void AudioPolicyManager::DeviceVector::loadDevicesFromType(audio_devices_t types)
-{
-    DeviceVector deviceList;
-
-    uint32_t role_bit = AUDIO_DEVICE_BIT_IN & types;
-    types &= ~role_bit;
-
-    while (types) {
-        uint32_t i = 31 - __builtin_clz(types);
-        uint32_t type = 1 << i;
-        types &= ~type;
-        add(new DeviceDescriptor(String8(""), type | role_bit));
-    }
-}
-
-void AudioPolicyManager::DeviceVector::loadDevicesFromName(char *name,
-                                                           const DeviceVector& declaredDevices)
-{
-    char *devName = strtok(name, "|");
-    while (devName != NULL) {
-        if (strlen(devName) != 0) {
-            audio_devices_t type = stringToEnum(sDeviceNameToEnumTable,
-                                 ARRAY_SIZE(sDeviceNameToEnumTable),
-                                 devName);
-            if (type != AUDIO_DEVICE_NONE) {
-                add(new DeviceDescriptor(String8(""), type));
-            } else {
-                sp<DeviceDescriptor> deviceDesc =
-                        declaredDevices.getDeviceFromName(String8(devName));
-                if (deviceDesc != 0) {
-                    add(deviceDesc);
-                }
-            }
-         }
-        devName = strtok(NULL, "|");
-     }
-}
-
-sp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDevice(
-                                                        audio_devices_t type, String8 address) const
-{
-    sp<DeviceDescriptor> device;
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->mDeviceType == type) {
-            device = itemAt(i);
-            if (itemAt(i)->mAddress = address) {
-                break;
-            }
-        }
-    }
-    ALOGV("DeviceVector::getDevice() for type %d address %s found %p",
-          type, address.string(), device.get());
-    return device;
-}
-
-sp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDeviceFromId(
-                                                                    audio_port_handle_t id) const
-{
-    sp<DeviceDescriptor> device;
-    for (size_t i = 0; i < size(); i++) {
-        ALOGV("DeviceVector::getDeviceFromId(%d) itemAt(%d)->mId %d", id, i, itemAt(i)->mId);
-        if (itemAt(i)->mId == id) {
-            device = itemAt(i);
-            break;
-        }
-    }
-    return device;
-}
-
-AudioPolicyManager::DeviceVector AudioPolicyManager::DeviceVector::getDevicesFromType(
-                                                                        audio_devices_t type) const
-{
-    DeviceVector devices;
-    for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
-        if (itemAt(i)->mDeviceType & type & ~AUDIO_DEVICE_BIT_IN) {
-            devices.add(itemAt(i));
-            type &= ~itemAt(i)->mDeviceType;
-            ALOGV("DeviceVector::getDevicesFromType() for type %x found %p",
-                  itemAt(i)->mDeviceType, itemAt(i).get());
-        }
-    }
-    return devices;
-}
-
-sp<AudioPolicyManager::DeviceDescriptor> AudioPolicyManager::DeviceVector::getDeviceFromName(
-        const String8& name) const
-{
-    sp<DeviceDescriptor> device;
-    for (size_t i = 0; i < size(); i++) {
-        if (itemAt(i)->mName == name) {
-            device = itemAt(i);
-            break;
-        }
-    }
-    return device;
-}
-
-void AudioPolicyManager::DeviceDescriptor::toAudioPortConfig(
-                                                    struct audio_port_config *dstConfig,
-                                                    const struct audio_port_config *srcConfig) const
-{
-    dstConfig->id = mId;
-    dstConfig->role = audio_is_output_device(mDeviceType) ?
-                        AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
-    dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
-    dstConfig->channel_mask = mChannelMask;
-    dstConfig->gain.index = -1;
-    dstConfig->config_mask = AUDIO_PORT_CONFIG_CHANNEL_MASK;
-    // use supplied variable configuration parameters if any
-    if (srcConfig != NULL) {
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
-            dstConfig->channel_mask = srcConfig->channel_mask;
-        }
-        if (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) {
-            dstConfig->gain = srcConfig->gain;
-            dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
-        }
-    }
-    dstConfig->ext.device.type = mDeviceType;
-    dstConfig->ext.device.hw_module = mModule->mHandle;
-    strncpy(dstConfig->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
-}
-
-void AudioPolicyManager::DeviceDescriptor::toAudioPort(struct audio_port *port) const
-{
-    ALOGV("DeviceVector::toAudioPort() handle %d type %x", mId, mDeviceType);
-    AudioPort::toAudioPort(port);
-    port->id = mId;
-    toAudioPortConfig(&port->active_config);
-    port->ext.device.type = mDeviceType;
-    port->ext.device.hw_module = mModule->mHandle;
-    strncpy(port->ext.device.address, mAddress.string(), AUDIO_DEVICE_MAX_ADDRESS_LEN);
-}
-
-status_t AudioPolicyManager::DeviceDescriptor::dump(int fd, int spaces, int index) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "%*sDevice %d:\n", spaces, "", index+1);
-    result.append(buffer);
-    if (mId != 0) {
-        snprintf(buffer, SIZE, "%*s- id: %2d\n", spaces, "", mId);
-        result.append(buffer);
-    }
-    snprintf(buffer, SIZE, "%*s- type: %-48s\n", spaces, "",
-                                              enumToString(sDeviceNameToEnumTable,
-                                                           ARRAY_SIZE(sDeviceNameToEnumTable),
-                                                           mDeviceType));
-    result.append(buffer);
-    if (mAddress.size() != 0) {
-        snprintf(buffer, SIZE, "%*s- address: %-32s\n", spaces, "", mAddress.string());
-        result.append(buffer);
-    }
-    if (mChannelMask != AUDIO_CHANNEL_NONE) {
-        snprintf(buffer, SIZE, "%*s- channel mask: %08x\n", spaces, "", mChannelMask);
-        result.append(buffer);
-    }
-    write(fd, result.string(), result.size());
-    AudioPort::dump(fd, spaces);
-
-    return NO_ERROR;
-}
-
-
-// --- audio_policy.conf file parsing
-
-audio_output_flags_t AudioPolicyManager::parseFlagNames(char *name)
-{
-    uint32_t flag = 0;
-
-    // it is OK to cast name to non const here as we are not going to use it after
-    // strtok() modifies it
-    char *flagName = strtok(name, "|");
-    while (flagName != NULL) {
-        if (strlen(flagName) != 0) {
-            flag |= stringToEnum(sFlagNameToEnumTable,
-                               ARRAY_SIZE(sFlagNameToEnumTable),
-                               flagName);
-        }
-        flagName = strtok(NULL, "|");
-    }
-    //force direct flag if offload flag is set: offloading implies a direct output stream
-    // and all common behaviors are driven by checking only the direct flag
-    // this should normally be set appropriately in the policy configuration file
-    if ((flag & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
-        flag |= AUDIO_OUTPUT_FLAG_DIRECT;
-    }
-
-    return (audio_output_flags_t)flag;
-}
-
-audio_devices_t AudioPolicyManager::parseDeviceNames(char *name)
-{
-    uint32_t device = 0;
-
-    char *devName = strtok(name, "|");
-    while (devName != NULL) {
-        if (strlen(devName) != 0) {
-            device |= stringToEnum(sDeviceNameToEnumTable,
-                                 ARRAY_SIZE(sDeviceNameToEnumTable),
-                                 devName);
-         }
-        devName = strtok(NULL, "|");
-     }
-    return device;
-}
-
-void AudioPolicyManager::loadHwModule(cnode *root)
-{
-    status_t status = NAME_NOT_FOUND;
-    cnode *node;
-    HwModule *module = new HwModule(root->name);
-
-    node = config_find(root, DEVICES_TAG);
-    if (node != NULL) {
-        node = node->first_child;
-        while (node) {
-            ALOGV("loadHwModule() loading device %s", node->name);
-            status_t tmpStatus = module->loadDevice(node);
-            if (status == NAME_NOT_FOUND || status == NO_ERROR) {
-                status = tmpStatus;
-            }
-            node = node->next;
-        }
-    }
-    node = config_find(root, OUTPUTS_TAG);
-    if (node != NULL) {
-        node = node->first_child;
-        while (node) {
-            ALOGV("loadHwModule() loading output %s", node->name);
-            status_t tmpStatus = module->loadOutput(node);
-            if (status == NAME_NOT_FOUND || status == NO_ERROR) {
-                status = tmpStatus;
-            }
-            node = node->next;
-        }
-    }
-    node = config_find(root, INPUTS_TAG);
-    if (node != NULL) {
-        node = node->first_child;
-        while (node) {
-            ALOGV("loadHwModule() loading input %s", node->name);
-            status_t tmpStatus = module->loadInput(node);
-            if (status == NAME_NOT_FOUND || status == NO_ERROR) {
-                status = tmpStatus;
-            }
-            node = node->next;
-        }
-    }
-    loadGlobalConfig(root, module);
-
-    if (status == NO_ERROR) {
-        mHwModules.add(module);
-    } else {
-        delete module;
-    }
-}
-
-void AudioPolicyManager::loadHwModules(cnode *root)
-{
-    cnode *node = config_find(root, AUDIO_HW_MODULE_TAG);
-    if (node == NULL) {
-        return;
-    }
-
-    node = node->first_child;
-    while (node) {
-        ALOGV("loadHwModules() loading module %s", node->name);
-        loadHwModule(node);
-        node = node->next;
-    }
-}
-
-void AudioPolicyManager::loadGlobalConfig(cnode *root, HwModule *module)
-{
-    cnode *node = config_find(root, GLOBAL_CONFIG_TAG);
-    if (node == NULL) {
-        return;
-    }
-    DeviceVector declaredDevices;
-    if (module != NULL) {
-        declaredDevices = module->mDeclaredDevices;
-    }
-
-    node = node->first_child;
-    while (node) {
-        if (strcmp(ATTACHED_OUTPUT_DEVICES_TAG, node->name) == 0) {
-            mAvailableOutputDevices.loadDevicesFromName((char *)node->value,
-                                                        declaredDevices);
-            ALOGV("loadGlobalConfig() Attached Output Devices %08x",
-                  mAvailableOutputDevices.types());
-        } else if (strcmp(DEFAULT_OUTPUT_DEVICE_TAG, node->name) == 0) {
-            audio_devices_t device = (audio_devices_t)stringToEnum(sDeviceNameToEnumTable,
-                                              ARRAY_SIZE(sDeviceNameToEnumTable),
-                                              (char *)node->value);
-            if (device != AUDIO_DEVICE_NONE) {
-                mDefaultOutputDevice = new DeviceDescriptor(String8(""), device);
-            } else {
-                ALOGW("loadGlobalConfig() default device not specified");
-            }
-            ALOGV("loadGlobalConfig() mDefaultOutputDevice %08x", mDefaultOutputDevice->mDeviceType);
-        } else if (strcmp(ATTACHED_INPUT_DEVICES_TAG, node->name) == 0) {
-            mAvailableInputDevices.loadDevicesFromName((char *)node->value,
-                                                       declaredDevices);
-            ALOGV("loadGlobalConfig() Available InputDevices %08x", mAvailableInputDevices.types());
-        } else if (strcmp(SPEAKER_DRC_ENABLED_TAG, node->name) == 0) {
-            mSpeakerDrcEnabled = stringToBool((char *)node->value);
-            ALOGV("loadGlobalConfig() mSpeakerDrcEnabled = %d", mSpeakerDrcEnabled);
-        }
-        node = node->next;
-    }
-}
-
-status_t AudioPolicyManager::loadAudioPolicyConfig(const char *path)
-{
-    cnode *root;
-    char *data;
-
-    data = (char *)load_file(path, NULL);
-    if (data == NULL) {
-        return -ENODEV;
-    }
-    root = config_node("", "");
-    config_load(root, data);
-
-    loadHwModules(root);
-    // legacy audio_policy.conf files have one global_configuration section
-    loadGlobalConfig(root, getModuleFromName(AUDIO_HARDWARE_MODULE_ID_PRIMARY));
-    config_free(root);
-    free(root);
-    free(data);
-
-    ALOGI("loadAudioPolicyConfig() loaded %s\n", path);
-
-    return NO_ERROR;
-}
-
-void AudioPolicyManager::defaultAudioPolicyConfig(void)
-{
-    HwModule *module;
-    sp<IOProfile> profile;
-    sp<DeviceDescriptor> defaultInputDevice = new DeviceDescriptor(String8(""), AUDIO_DEVICE_IN_BUILTIN_MIC);
-    mAvailableOutputDevices.add(mDefaultOutputDevice);
-    mAvailableInputDevices.add(defaultInputDevice);
-
-    module = new HwModule("primary");
-
-    profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SOURCE, module);
-    profile->mSamplingRates.add(44100);
-    profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
-    profile->mChannelMasks.add(AUDIO_CHANNEL_OUT_STEREO);
-    profile->mSupportedDevices.add(mDefaultOutputDevice);
-    profile->mFlags = AUDIO_OUTPUT_FLAG_PRIMARY;
-    module->mOutputProfiles.add(profile);
-
-    profile = new IOProfile(String8("primary"), AUDIO_PORT_ROLE_SINK, module);
-    profile->mSamplingRates.add(8000);
-    profile->mFormats.add(AUDIO_FORMAT_PCM_16_BIT);
-    profile->mChannelMasks.add(AUDIO_CHANNEL_IN_MONO);
-    profile->mSupportedDevices.add(defaultInputDevice);
-    module->mInputProfiles.add(profile);
-
-    mHwModules.add(module);
+    delete interface;
 }
 
 }; // namespace android
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index 0dd015a..9f2b473 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
  * Not a contribution.
  *
  * Copyright (C) 2009 The Android Open Source Project
@@ -20,470 +20,53 @@
 
 #include <stdint.h>
 #include <sys/types.h>
-#include <cutils/config_utils.h>
-#include <cutils/misc.h>
 #include <utils/Timers.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
-#include <utils/SortedVector.h>
-#include "AudioPolicyInterface.h"
+#include <hardware_legacy/AudioPolicyManagerBase.h>
 
 
-namespace android {
+namespace android_audio_legacy {
 
 // ----------------------------------------------------------------------------
 
-// Attenuation applied to STRATEGY_SONIFICATION streams when a headset is connected: 6dB
-#define SONIFICATION_HEADSET_VOLUME_FACTOR 0.5
-// Min volume for STRATEGY_SONIFICATION streams when limited by music volume: -36dB
-#define SONIFICATION_HEADSET_VOLUME_MIN  0.016
-// Time in milliseconds during which we consider that music is still active after a music
-// track was stopped - see computeVolume()
-#define SONIFICATION_HEADSET_MUSIC_DELAY  5000
-// Time in milliseconds after media stopped playing during which we consider that the
-// sonification should be as unobtrusive as during the time media was playing.
-#define SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY 5000
-// Time in milliseconds during witch some streams are muted while the audio path
-// is switched
-#define MUTE_TIME_MS 2000
-
-#define NUM_TEST_OUTPUTS 5
-
-#define NUM_VOL_CURVE_KNEES 2
-
-// Default minimum length allowed for offloading a compressed track
-// Can be overridden by the audio.offload.min.duration.secs property
-#define OFFLOAD_DEFAULT_MIN_DURATION_SECS 60
-
-// ----------------------------------------------------------------------------
-// AudioPolicyManager implements audio policy manager behavior common to all platforms.
-// ----------------------------------------------------------------------------
-
-class AudioPolicyManager: public AudioPolicyInterface
-#ifdef AUDIO_POLICY_TEST
-    , public Thread
-#endif //AUDIO_POLICY_TEST
+class AudioPolicyManager: public AudioPolicyManagerBase
 {
 
 public:
-                AudioPolicyManager(AudioPolicyClientInterface *clientInterface);
-        virtual ~AudioPolicyManager();
+                AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
+                : AudioPolicyManagerBase(clientInterface) {
+                    mHdmiAudioDisabled = false;
+                    mHdmiAudioEvent = false; }
 
-        // AudioPolicyInterface
+        virtual ~AudioPolicyManager() {}
+
         virtual status_t setDeviceConnectionState(audio_devices_t device,
-                                                          audio_policy_dev_state_t state,
+                                                          AudioSystem::device_connection_state state,
                                                           const char *device_address);
-        virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
-                                                                              const char *device_address);
-        virtual void setPhoneState(audio_mode_t state);
-        virtual void setForceUse(audio_policy_force_use_t usage,
-                                 audio_policy_forced_cfg_t config);
-        virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);
-        virtual void setSystemProperty(const char* property, const char* value);
-        virtual status_t initCheck();
-        virtual audio_io_handle_t getOutput(audio_stream_type_t stream,
+        virtual void setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config);
+        virtual audio_io_handle_t getInput(int inputSource,
                                             uint32_t samplingRate,
-                                            audio_format_t format,
-                                            audio_channel_mask_t channelMask,
-                                            audio_output_flags_t flags,
-                                            const audio_offload_info_t *offloadInfo);
-        virtual status_t startOutput(audio_io_handle_t output,
-                                     audio_stream_type_t stream,
-                                     int session = 0);
-        virtual status_t stopOutput(audio_io_handle_t output,
-                                    audio_stream_type_t stream,
-                                    int session = 0);
-        virtual void releaseOutput(audio_io_handle_t output);
-        virtual audio_io_handle_t getInput(audio_source_t inputSource,
-                                            uint32_t samplingRate,
-                                            audio_format_t format,
-                                            audio_channel_mask_t channelMask,
-                                            audio_in_acoustics_t acoustics);
-
-        // indicates to the audio policy manager that the input starts being used.
-        virtual status_t startInput(audio_io_handle_t input);
-
-        // indicates to the audio policy manager that the input stops being used.
-        virtual status_t stopInput(audio_io_handle_t input);
-        virtual void releaseInput(audio_io_handle_t input);
-        virtual void closeAllInputs();
-        virtual void initStreamVolume(audio_stream_type_t stream,
-                                                    int indexMin,
-                                                    int indexMax);
-        virtual status_t setStreamVolumeIndex(audio_stream_type_t stream,
-                                              int index,
-                                              audio_devices_t device);
-        virtual status_t getStreamVolumeIndex(audio_stream_type_t stream,
-                                              int *index,
-                                              audio_devices_t device);
-
-        // return the strategy corresponding to a given stream type
-        virtual uint32_t getStrategyForStream(audio_stream_type_t stream);
-
-        // return the enabled output devices for the given stream type
-        virtual audio_devices_t getDevicesForStream(audio_stream_type_t stream);
-
-        virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc = NULL);
-        virtual status_t registerEffect(const effect_descriptor_t *desc,
-                                        audio_io_handle_t io,
-                                        uint32_t strategy,
-                                        int session,
-                                        int id);
-        virtual status_t unregisterEffect(int id);
-        virtual status_t setEffectEnabled(int id, bool enabled);
-
-        virtual bool isStreamActive(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
-        // return whether a stream is playing remotely, override to change the definition of
-        //   local/remote playback, used for instance by notification manager to not make
-        //   media players lose audio focus when not playing locally
-        virtual bool isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs = 0) const;
-        virtual bool isSourceActive(audio_source_t source) const;
-
-        virtual status_t dump(int fd);
+                                            uint32_t format,
+                                            uint32_t channels,
+                                            AudioSystem::audio_in_acoustics acoustics);
+        virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream,
+                                            uint32_t samplingRate = 0,
+                                            uint32_t format = AudioSystem::FORMAT_DEFAULT,
+                                            uint32_t channels = 0,
+                                            AudioSystem::output_flags flags =
+                                                    AudioSystem::OUTPUT_FLAG_INDIRECT,
+                                            const audio_offload_info_t *offloadInfo = NULL);
 
         virtual bool isOffloadSupported(const audio_offload_info_t& offloadInfo);
 
-        virtual status_t listAudioPorts(audio_port_role_t role,
-                                        audio_port_type_t type,
-                                        unsigned int *num_ports,
-                                        struct audio_port *ports,
-                                        unsigned int *generation);
-        virtual status_t getAudioPort(struct audio_port *port);
-        virtual status_t createAudioPatch(const struct audio_patch *patch,
-                                           audio_patch_handle_t *handle,
-                                           uid_t uid);
-        virtual status_t releaseAudioPatch(audio_patch_handle_t handle,
-                                              uid_t uid);
-        virtual status_t listAudioPatches(unsigned int *num_patches,
-                                          struct audio_patch *patches,
-                                          unsigned int *generation);
-        virtual status_t setAudioPortConfig(const struct audio_port_config *config);
-        virtual void clearAudioPatches(uid_t uid);
+        virtual void setPhoneState(int state);
 
+        // true if given state represents a device in a telephony or VoIP call
+        virtual bool isStateInCall(int state);
 protected:
-
-        enum routing_strategy {
-            STRATEGY_MEDIA,
-            STRATEGY_PHONE,
-            STRATEGY_SONIFICATION,
-            STRATEGY_SONIFICATION_RESPECTFUL,
-            STRATEGY_DTMF,
-            STRATEGY_ENFORCED_AUDIBLE,
-            NUM_STRATEGIES
-        };
-
-        // 4 points to define the volume attenuation curve, each characterized by the volume
-        // index (from 0 to 100) at which they apply, and the attenuation in dB at that index.
-        // we use 100 steps to avoid rounding errors when computing the volume in volIndexToAmpl()
-
-        enum { VOLMIN = 0, VOLKNEE1 = 1, VOLKNEE2 = 2, VOLMAX = 3, VOLCNT = 4};
-
-        class VolumeCurvePoint
-        {
-        public:
-            int mIndex;
-            float mDBAttenuation;
-        };
-
-        // device categories used for volume curve management.
-        enum device_category {
-            DEVICE_CATEGORY_HEADSET,
-            DEVICE_CATEGORY_SPEAKER,
-            DEVICE_CATEGORY_EARPIECE,
-            DEVICE_CATEGORY_CNT
-        };
-
-        class HwModule;
-
-        class AudioGain: public RefBase
-        {
-        public:
-            AudioGain();
-            virtual ~AudioGain() {}
-
-            void dump(int fd, int spaces, int index) const;
-
-            struct audio_gain mGain;
-        };
-
-        class AudioPort: public RefBase
-        {
-        public:
-            AudioPort(const String8& name, audio_port_type_t type,
-                      audio_port_role_t role, HwModule *module) :
-                mName(name), mType(type), mRole(role), mModule(module) {}
-            virtual ~AudioPort() {}
-
-            virtual void toAudioPort(struct audio_port *port) const;
-
-            void loadSamplingRates(char *name);
-            void loadFormats(char *name);
-            void loadOutChannels(char *name);
-            void loadInChannels(char *name);
-
-            audio_gain_mode_t loadGainMode(char *name);
-            void loadGain(cnode *root);
-            void loadGains(cnode *root);
-
-            void dump(int fd, int spaces) const;
-
-            String8           mName;
-            audio_port_type_t mType;
-            audio_port_role_t mRole;
-            // by convention, "0' in the first entry in mSamplingRates, mChannelMasks or mFormats
-            // indicates the supported parameters should be read from the output stream
-            // after it is opened for the first time
-            Vector <uint32_t> mSamplingRates; // supported sampling rates
-            Vector <audio_channel_mask_t> mChannelMasks; // supported channel masks
-            Vector <audio_format_t> mFormats; // supported audio formats
-            Vector < sp<AudioGain> > mGains; // gain controllers
-            HwModule *mModule;                 // audio HW module exposing this I/O stream
-        };
-
-        class AudioPatch: public RefBase
-        {
-        public:
-            AudioPatch(audio_patch_handle_t handle,
-                       const struct audio_patch *patch, uid_t uid) :
-                           mHandle(handle), mPatch(*patch), mUid(uid), mAfPatchHandle(0) {}
-
-            audio_patch_handle_t mHandle;
-            struct audio_patch mPatch;
-            uid_t mUid;
-            audio_patch_handle_t mAfPatchHandle;
-        };
-
-        class DeviceDescriptor: public AudioPort
-        {
-        public:
-            DeviceDescriptor(const String8& name, audio_devices_t type, String8 address,
-                             audio_channel_mask_t channelMask) :
-                                 AudioPort(name, AUDIO_PORT_TYPE_DEVICE,
-                                           audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
-                                                                          AUDIO_PORT_ROLE_SOURCE,
-                                         NULL),
-                                 mDeviceType(type), mAddress(address),
-                                 mChannelMask(channelMask), mId(0) {}
-
-            DeviceDescriptor(String8 name, audio_devices_t type) :
-                                AudioPort(name, AUDIO_PORT_TYPE_DEVICE,
-                                          audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
-                                                                         AUDIO_PORT_ROLE_SOURCE,
-                                        NULL),
-                                mDeviceType(type), mAddress(""),
-                                mChannelMask(0), mId(0) {}
-            virtual ~DeviceDescriptor() {}
-
-            bool equals(const sp<DeviceDescriptor>& other) const;
-            void toAudioPortConfig(struct audio_port_config *dstConfig,
-                                   const struct audio_port_config *srcConfig = NULL) const;
-
-            virtual void toAudioPort(struct audio_port *port) const;
-
-            status_t dump(int fd, int spaces, int index) const;
-
-            audio_devices_t mDeviceType;
-            String8 mAddress;
-            audio_channel_mask_t mChannelMask;
-            audio_port_handle_t mId;
-        };
-
-        class DeviceVector : public SortedVector< sp<DeviceDescriptor> >
-        {
-        public:
-            DeviceVector() : SortedVector(), mDeviceTypes(AUDIO_DEVICE_NONE) {}
-
-            ssize_t         add(const sp<DeviceDescriptor>& item);
-            ssize_t         remove(const sp<DeviceDescriptor>& item);
-            ssize_t         indexOf(const sp<DeviceDescriptor>& item) const;
-
-            audio_devices_t types() const { return mDeviceTypes; }
-
-            void loadDevicesFromType(audio_devices_t types);
-            void loadDevicesFromName(char *name, const DeviceVector& declaredDevices);
-
-            sp<DeviceDescriptor> getDevice(audio_devices_t type, String8 address) const;
-            DeviceVector getDevicesFromType(audio_devices_t types) const;
-            sp<DeviceDescriptor> getDeviceFromId(audio_port_handle_t id) const;
-            sp<DeviceDescriptor> getDeviceFromName(const String8& name) const;
-
-        private:
-            void refreshTypes();
-            audio_devices_t mDeviceTypes;
-        };
-
-        // the IOProfile class describes the capabilities of an output or input stream.
-        // It is currently assumed that all combination of listed parameters are supported.
-        // It is used by the policy manager to determine if an output or input is suitable for
-        // a given use case,  open/close it accordingly and connect/disconnect audio tracks
-        // to/from it.
-        class IOProfile : public AudioPort
-        {
-        public:
-            IOProfile(const String8& name, audio_port_role_t role, HwModule *module);
-            virtual ~IOProfile();
-
-            bool isCompatibleProfile(audio_devices_t device,
-                                     uint32_t samplingRate,
-                                     audio_format_t format,
-                                     audio_channel_mask_t channelMask,
-                                     audio_output_flags_t flags) const;
-
-            void dump(int fd);
-            void log();
-
-            DeviceVector  mSupportedDevices; // supported devices
-                                             // (devices this output can be routed to)
-            audio_output_flags_t mFlags; // attribute flags (e.g primary output,
-                                                // direct output...). For outputs only.
-        };
-
-        class HwModule {
-        public:
-                    HwModule(const char *name);
-                    ~HwModule();
-
-            status_t loadOutput(cnode *root);
-            status_t loadInput(cnode *root);
-            status_t loadDevice(cnode *root);
-
-            void dump(int fd);
-
-            const char *const mName; // base name of the audio HW module (primary, a2dp ...)
-            audio_module_handle_t mHandle;
-            Vector < sp<IOProfile> > mOutputProfiles; // output profiles exposed by this module
-            Vector < sp<IOProfile> > mInputProfiles;  // input profiles exposed by this module
-            DeviceVector             mDeclaredDevices; // devices declared in audio_policy.conf
-
-        };
-
-        // default volume curve
-        static const VolumeCurvePoint sDefaultVolumeCurve[AudioPolicyManager::VOLCNT];
-        // default volume curve for media strategy
-        static const VolumeCurvePoint sDefaultMediaVolumeCurve[AudioPolicyManager::VOLCNT];
-        // volume curve for media strategy on speakers
-        static const VolumeCurvePoint sSpeakerMediaVolumeCurve[AudioPolicyManager::VOLCNT];
-        // volume curve for sonification strategy on speakers
-        static const VolumeCurvePoint sSpeakerSonificationVolumeCurve[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sSpeakerSonificationVolumeCurveDrc[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sDefaultSystemVolumeCurve[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sDefaultSystemVolumeCurveDrc[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sHeadsetSystemVolumeCurve[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sDefaultVoiceVolumeCurve[AudioPolicyManager::VOLCNT];
-        static const VolumeCurvePoint sSpeakerVoiceVolumeCurve[AudioPolicyManager::VOLCNT];
-        // default volume curves per stream and device category. See initializeVolumeCurves()
-        static const VolumeCurvePoint *sVolumeProfiles[AUDIO_STREAM_CNT][DEVICE_CATEGORY_CNT];
-
-        // descriptor for audio outputs. Used to maintain current configuration of each opened audio output
-        // and keep track of the usage of this output by each audio stream type.
-        class AudioOutputDescriptor
-        {
-        public:
-            AudioOutputDescriptor(const sp<IOProfile>& profile);
-
-            status_t    dump(int fd);
-
-            audio_devices_t device() const;
-            void changeRefCount(audio_stream_type_t stream, int delta);
-
-            bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
-            audio_devices_t supportedDevices();
-            uint32_t latency();
-            bool sharesHwModuleWith(const AudioOutputDescriptor *outputDesc);
-            bool isActive(uint32_t inPastMs = 0) const;
-            bool isStreamActive(audio_stream_type_t stream,
-                                uint32_t inPastMs = 0,
-                                nsecs_t sysTime = 0) const;
-            bool isStrategyActive(routing_strategy strategy,
-                             uint32_t inPastMs = 0,
-                             nsecs_t sysTime = 0) const;
-
-            void toAudioPortConfig(struct audio_port_config *dstConfig,
-                                   const struct audio_port_config *srcConfig = NULL) const;
-            void toAudioPort(struct audio_port *port) const;
-
-            audio_port_handle_t mId;
-            audio_io_handle_t mIoHandle;              // output handle
-            uint32_t mSamplingRate;             //
-            audio_format_t mFormat;             //
-            audio_channel_mask_t mChannelMask;     // output configuration
-            uint32_t mLatency;                  //
-            audio_output_flags_t mFlags;   //
-            audio_devices_t mDevice;                   // current device this output is routed to
-            audio_patch_handle_t mPatchHandle;
-            uint32_t mRefCount[AUDIO_STREAM_CNT]; // number of streams of each type using this output
-            nsecs_t mStopTime[AUDIO_STREAM_CNT];
-            AudioOutputDescriptor *mOutput1;    // used by duplicated outputs: first output
-            AudioOutputDescriptor *mOutput2;    // used by duplicated outputs: second output
-            float mCurVolume[AUDIO_STREAM_CNT];   // current stream volume
-            int mMuteCount[AUDIO_STREAM_CNT];     // mute request counter
-            const sp<IOProfile> mProfile;          // I/O profile this output derives from
-            bool mStrategyMutedByDevice[NUM_STRATEGIES]; // strategies muted because of incompatible
-                                                // device selection. See checkDeviceMuteStrategies()
-            uint32_t mDirectOpenCount; // number of clients using this output (direct outputs only)
-        };
-
-        // descriptor for audio inputs. Used to maintain current configuration of each opened audio input
-        // and keep track of the usage of this input.
-        class AudioInputDescriptor
-        {
-        public:
-            AudioInputDescriptor(const sp<IOProfile>& profile);
-
-            status_t    dump(int fd);
-
-            audio_port_handle_t mId;
-            audio_io_handle_t mIoHandle;              // input handle
-            uint32_t mSamplingRate;                     //
-            audio_format_t mFormat;                     // input configuration
-            audio_channel_mask_t mChannelMask;             //
-            audio_devices_t mDevice;                    // current device this input is routed to
-            audio_patch_handle_t mPatchHandle;
-            uint32_t mRefCount;                         // number of AudioRecord clients using this output
-            audio_source_t mInputSource;                // input source selected by application (mediarecorder.h)
-            const sp<IOProfile> mProfile;                  // I/O profile this output derives from
-
-            void toAudioPortConfig(struct audio_port_config *dstConfig,
-                                   const struct audio_port_config *srcConfig = NULL) const;
-            void toAudioPort(struct audio_port *port) const;
-        };
-
-        // stream descriptor used for volume control
-        class StreamDescriptor
-        {
-        public:
-            StreamDescriptor();
-
-            int getVolumeIndex(audio_devices_t device);
-            void dump(int fd);
-
-            int mIndexMin;      // min volume index
-            int mIndexMax;      // max volume index
-            KeyedVector<audio_devices_t, int> mIndexCur;   // current volume index per device
-            bool mCanBeMuted;   // true is the stream can be muted
-
-            const VolumeCurvePoint *mVolumeCurve[DEVICE_CATEGORY_CNT];
-        };
-
-        // stream descriptor used for volume control
-        class EffectDescriptor
-        {
-        public:
-
-            status_t dump(int fd);
-
-            int mIo;                // io the effect is attached to
-            routing_strategy mStrategy; // routing strategy the effect is associated to
-            int mSession;               // audio session the effect is on
-            effect_descriptor_t mDesc;  // effect descriptor
-            bool mEnabled;              // enabled state: CPU load being used or not
-        };
-
-        void addOutput(audio_io_handle_t output, AudioOutputDescriptor *outputDesc);
-        void addInput(audio_io_handle_t input, AudioInputDescriptor *inputDesc);
-
         // return the strategy corresponding to a given stream type
-        static routing_strategy getStrategy(audio_stream_type_t stream);
+        static routing_strategy getStrategy(AudioSystem::stream_type stream);
 
         // return appropriate device for streams handled by the specified strategy according to current
         // phone state, connected devices...
@@ -497,258 +80,32 @@
         //  where conditions are changing (setDeviceConnectionState(), setPhoneState()...) AND
         //  before updateDevicesAndOutputs() is called.
         virtual audio_devices_t getDeviceForStrategy(routing_strategy strategy,
-                                                     bool fromCache);
-
-        // change the route of the specified output. Returns the number of ms we have slept to
-        // allow new routing to take effect in certain cases.
-        uint32_t setOutputDevice(audio_io_handle_t output,
-                             audio_devices_t device,
-                             bool force = false,
-                             int delayMs = 0,
-                             audio_patch_handle_t *patchHandle = NULL);
-        status_t resetOutputDevice(audio_io_handle_t output,
-                                   int delayMs = 0,
-                                   audio_patch_handle_t *patchHandle = NULL);
-        status_t setInputDevice(audio_io_handle_t input,
-                                audio_devices_t device,
-                                bool force = false,
-                                audio_patch_handle_t *patchHandle = NULL);
-        status_t resetInputDevice(audio_io_handle_t input,
-                                  audio_patch_handle_t *patchHandle = NULL);
-
+                                                     bool fromCache = true);
         // select input device corresponding to requested audio source
-        virtual audio_devices_t getDeviceForInputSource(audio_source_t inputSource);
-
-        // return io handle of active input or 0 if no input is active
-        //    Only considers inputs from physical devices (e.g. main mic, headset mic) when
-        //    ignoreVirtualInputs is true.
-        audio_io_handle_t getActiveInput(bool ignoreVirtualInputs = true);
-
-        // initialize volume curves for each strategy and device category
-        void initializeVolumeCurves();
+        virtual audio_devices_t getDeviceForInputSource(int inputSource);
 
         // compute the actual volume for a given stream according to the requested index and a particular
         // device
-        virtual float computeVolume(audio_stream_type_t stream, int index,
-                                    audio_io_handle_t output, audio_devices_t device);
+        virtual float computeVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device);
 
         // check that volume change is permitted, compute and send new volume to audio hardware
-        status_t checkAndSetVolume(audio_stream_type_t stream, int index, audio_io_handle_t output,
-                                   audio_devices_t device, int delayMs = 0, bool force = false);
-
-        // apply all stream volumes to the specified output and device
-        void applyStreamVolumes(audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false);
-
-        // Mute or unmute all streams handled by the specified strategy on the specified output
-        void setStrategyMute(routing_strategy strategy,
-                             bool on,
-                             audio_io_handle_t output,
-                             int delayMs = 0,
-                             audio_devices_t device = (audio_devices_t)0);
-
-        // Mute or unmute the stream on the specified output
-        void setStreamMute(audio_stream_type_t stream,
-                           bool on,
-                           audio_io_handle_t output,
-                           int delayMs = 0,
-                           audio_devices_t device = (audio_devices_t)0);
-
-        // handle special cases for sonification strategy while in call: mute streams or replace by
-        // a special tone in the device used for communication
-        void handleIncallSonification(audio_stream_type_t stream, bool starting, bool stateChange);
-
-        // true if device is in a telephony or VoIP call
-        virtual bool isInCall();
-
-        // true if given state represents a device in a telephony or VoIP call
-        virtual bool isStateInCall(int state);
-
-        // when a device is connected, checks if an open output can be routed
-        // to this device. If none is open, tries to open one of the available outputs.
-        // Returns an output suitable to this device or 0.
-        // when a device is disconnected, checks if an output is not used any more and
-        // returns its handle if any.
-        // transfers the audio tracks and effects from one output thread to another accordingly.
-        status_t checkOutputsForDevice(audio_devices_t device,
-                                       audio_policy_dev_state_t state,
-                                       SortedVector<audio_io_handle_t>& outputs,
-                                       const String8 address);
-
-        status_t checkInputsForDevice(audio_devices_t device,
-                                      audio_policy_dev_state_t state,
-                                      SortedVector<audio_io_handle_t>& inputs,
-                                      const String8 address);
-
-        // close an output and its companion duplicating output.
-        void closeOutput(audio_io_handle_t output);
-
-        // checks and if necessary changes outputs used for all strategies.
-        // must be called every time a condition that affects the output choice for a given strategy
-        // changes: connected device, phone state, force use...
-        // Must be called before updateDevicesAndOutputs()
-        void checkOutputForStrategy(routing_strategy strategy);
-
-        // Same as checkOutputForStrategy() but for a all strategies in order of priority
-        void checkOutputForAllStrategies();
-
-        // manages A2DP output suspend/restore according to phone state and BT SCO usage
-        void checkA2dpSuspend();
-
-        // returns the A2DP output handle if it is open or 0 otherwise
-        audio_io_handle_t getA2dpOutput();
-
-        // selects the most appropriate device on output for current state
-        // must be called every time a condition that affects the device choice for a given output is
-        // changed: connected device, phone state, force use, output start, output stop..
-        // see getDeviceForStrategy() for the use of fromCache parameter
-        audio_devices_t getNewOutputDevice(audio_io_handle_t output, bool fromCache);
-
-        // updates cache of device used by all strategies (mDeviceForStrategy[])
-        // must be called every time a condition that affects the device choice for a given strategy is
-        // changed: connected device, phone state, force use...
-        // cached values are used by getDeviceForStrategy() if parameter fromCache is true.
-         // Must be called after checkOutputForAllStrategies()
-        void updateDevicesAndOutputs();
-
-        // selects the most appropriate device on input for current state
-        audio_devices_t getNewInputDevice(audio_io_handle_t input);
-
-        virtual uint32_t getMaxEffectsCpuLoad();
-        virtual uint32_t getMaxEffectsMemory();
-#ifdef AUDIO_POLICY_TEST
-        virtual     bool        threadLoop();
-                    void        exit();
-        int testOutputIndex(audio_io_handle_t output);
-#endif //AUDIO_POLICY_TEST
-
-        status_t setEffectEnabled(EffectDescriptor *pDesc, bool enabled);
+        status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output, audio_devices_t device, int delayMs = 0, bool force = false);
 
         // returns the category the device belongs to with regard to volume curve management
         static device_category getDeviceCategory(audio_devices_t device);
 
-        // extract one device relevant for volume control from multiple device selection
-        static audio_devices_t getDeviceForVolume(audio_devices_t device);
+        static const char* HDMI_SPKR_STR;
 
-        SortedVector<audio_io_handle_t> getOutputsForDevice(audio_devices_t device,
-                        DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> openOutputs);
-        bool vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
-                                           SortedVector<audio_io_handle_t>& outputs2);
+        //parameter indicates of HDMI speakers disabled from the Qualcomm settings
+        bool mHdmiAudioDisabled;
 
-        // mute/unmute strategies using an incompatible device combination
-        // if muting, wait for the audio in pcm buffer to be drained before proceeding
-        // if unmuting, unmute only after the specified delay
-        // Returns the number of ms waited
-        uint32_t  checkDeviceMuteStrategies(AudioOutputDescriptor *outputDesc,
-                                            audio_devices_t prevDevice,
-                                            uint32_t delayMs);
-
-        audio_io_handle_t selectOutput(const SortedVector<audio_io_handle_t>& outputs,
-                                       audio_output_flags_t flags);
-        sp<IOProfile> getInputProfile(audio_devices_t device,
-                                   uint32_t samplingRate,
-                                   audio_format_t format,
-                                   audio_channel_mask_t channelMask);
-        sp<IOProfile> getProfileForDirectOutput(audio_devices_t device,
-                                                       uint32_t samplingRate,
-                                                       audio_format_t format,
-                                                       audio_channel_mask_t channelMask,
-                                                       audio_output_flags_t flags);
-
-        audio_io_handle_t selectOutputForEffects(const SortedVector<audio_io_handle_t>& outputs);
-
-        bool isNonOffloadableEffectEnabled();
-
-        status_t addAudioPatch(audio_patch_handle_t handle,
-                               const sp<AudioPatch>& patch);
-        status_t removeAudioPatch(audio_patch_handle_t handle);
-
-        AudioOutputDescriptor *getOutputFromId(audio_port_handle_t id) const;
-        AudioInputDescriptor *getInputFromId(audio_port_handle_t id) const;
-        HwModule *getModuleForDevice(audio_devices_t device) const;
-        HwModule *getModuleFromName(const char *name) const;
-        //
-        // Audio policy configuration file parsing (audio_policy.conf)
-        //
-        static uint32_t stringToEnum(const struct StringToEnum *table,
-                                     size_t size,
-                                     const char *name);
-        static const char *enumToString(const struct StringToEnum *table,
-                                      size_t size,
-                                      uint32_t value);
-        static bool stringToBool(const char *value);
-        static audio_output_flags_t parseFlagNames(char *name);
-        static audio_devices_t parseDeviceNames(char *name);
-        void loadHwModule(cnode *root);
-        void loadHwModules(cnode *root);
-        void loadGlobalConfig(cnode *root, HwModule *module);
-        status_t loadAudioPolicyConfig(const char *path);
-        void defaultAudioPolicyConfig(void);
-
-
-        uid_t mUidCached;
-        AudioPolicyClientInterface *mpClientInterface;  // audio policy client interface
-        audio_io_handle_t mPrimaryOutput;              // primary output handle
-        // list of descriptors for outputs currently opened
-        DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> mOutputs;
-        // copy of mOutputs before setDeviceConnectionState() opens new outputs
-        // reset to mOutputs when updateDevicesAndOutputs() is called.
-        DefaultKeyedVector<audio_io_handle_t, AudioOutputDescriptor *> mPreviousOutputs;
-        DefaultKeyedVector<audio_io_handle_t, AudioInputDescriptor *> mInputs;     // list of input descriptors
-        DeviceVector  mAvailableOutputDevices; // all available output devices
-        DeviceVector  mAvailableInputDevices;  // all available input devices
-        int mPhoneState;                                                    // current phone state
-        audio_policy_forced_cfg_t mForceUse[AUDIO_POLICY_FORCE_USE_CNT];   // current forced use configuration
-
-        StreamDescriptor mStreams[AUDIO_STREAM_CNT];           // stream descriptors for volume control
-        bool    mLimitRingtoneVolume;                                       // limit ringtone volume to music volume if headset connected
-        audio_devices_t mDeviceForStrategy[NUM_STRATEGIES];
-        float   mLastVoiceVolume;                                           // last voice volume value sent to audio HAL
-
-        // Maximum CPU load allocated to audio effects in 0.1 MIPS (ARMv5TE, 0 WS memory) units
-        static const uint32_t MAX_EFFECTS_CPU_LOAD = 1000;
-        // Maximum memory allocated to audio effects in KB
-        static const uint32_t MAX_EFFECTS_MEMORY = 512;
-        uint32_t mTotalEffectsCpuLoad; // current CPU load used by effects
-        uint32_t mTotalEffectsMemory;  // current memory used by effects
-        KeyedVector<int, EffectDescriptor *> mEffects;  // list of registered audio effects
-        bool    mA2dpSuspended;  // true if A2DP output is suspended
-        sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
-        bool mSpeakerDrcEnabled;// true on devices that use DRC on the DEVICE_CATEGORY_SPEAKER path
-                                // to boost soft sounds, used to adjust volume curves accordingly
-
-        Vector <HwModule *> mHwModules;
-        volatile int32_t mNextUniqueId;
-        volatile int32_t mAudioPortGeneration;
-
-        DefaultKeyedVector<audio_patch_handle_t, sp<AudioPatch> > mAudioPatches;
-
-#ifdef AUDIO_POLICY_TEST
-        Mutex   mLock;
-        Condition mWaitWorkCV;
-
-        int             mCurOutput;
-        bool            mDirectOutput;
-        audio_io_handle_t mTestOutputs[NUM_TEST_OUTPUTS];
-        int             mTestInput;
-        uint32_t        mTestDevice;
-        uint32_t        mTestSamplingRate;
-        uint32_t        mTestFormat;
-        uint32_t        mTestChannels;
-        uint32_t        mTestLatencyMs;
-#endif //AUDIO_POLICY_TEST
+        //parameter indicates if HDMI plug in/out detected
+        bool mHdmiAudioEvent;
 
 private:
-        static float volIndexToAmpl(audio_devices_t device, const StreamDescriptor& streamDesc,
-                int indexInUi);
-        // updates device caching and output for streams that can influence the
-        //    routing of notifications
-        void handleNotificationRoutingForStream(audio_stream_type_t stream);
-        static bool isVirtualInputDevice(audio_devices_t device);
-        uint32_t nextUniqueId();
-        uint32_t nextAudioPortGeneration();
-        uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
-        // converts device address to string sent to audio HAL via setParameters
-        static String8 addressToParameter(audio_devices_t device, const String8 address);
-};
+        // Used for voip + voice concurrency usecase
+        int mPrevPhoneState;
+        static int mvoice_call_state;
 
 };
+};
