audiopolicy:Enable custom audio policy.

Change-Id: I493c9155b230373f5041df814508b1c6996fe559
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 13a2a4b..345f9e4 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -104,25 +104,27 @@
      delete interface;
 }
 
-status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t device,
+status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t deviceType,
                                                          audio_policy_dev_state_t state,
                                                          const char *device_address,
-                                                         const char *device_name)
+                                                         const char *device_name,
+                                                         audio_format_t encodedFormat)
 {
-    ALOGD("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
-            device, state, device_address, device_name);
+    ALOGD("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s encodedFormat = 0x%X",
+            deviceType, state, device_address, device_name, encodedFormat);
 
     // connect/disconnect only 1 device at a time
-    if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
+    if (!audio_is_output_device(deviceType) && !audio_is_input_device(deviceType)) return BAD_VALUE;
 
-    sp<DeviceDescriptor> devDesc =
-            mHwModules.getDeviceDescriptor(device, device_address, device_name);
+    sp<DeviceDescriptor> device =
+            mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, encodedFormat,
+                                           state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
 
     // handle output devices
-    if (audio_is_output_device(device)) {
+    if (audio_is_output_device(deviceType)) {
         SortedVector <audio_io_handle_t> outputs;
 
-        ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
+        ssize_t index = mAvailableOutputDevices.indexOf(device);
 
         // save a copy of the opened output descriptors before any output is opened or closed
         // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
@@ -133,41 +135,42 @@
         case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
             if (index >= 0) {
                 if (mApmConfigs->isHDMISpkEnabled() &&
-                        (popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+                        (popcount(deviceType) == 1) && (deviceType & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
                    if (!strncmp(device_address, "hdmi_spkr", 9)) {
                         mHdmiAudioDisabled = false;
                     } else {
                         mHdmiAudioEvent = true;
                     }
                 }
-                ALOGW("setDeviceConnectionState() device already connected: %x", device);
+                ALOGW("setDeviceConnectionState() device already connected: %x", deviceType);
                 return INVALID_OPERATION;
             }
-            ALOGV("setDeviceConnectionState() connecting device %x", device);
+            ALOGV("setDeviceConnectionState() connecting device %x", deviceType);
 
             // register new device as available
-            index = mAvailableOutputDevices.add(devDesc);
+            index = mAvailableOutputDevices.add(device);
             if (mApmConfigs->isHDMISpkEnabled() &&
-                    (popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+                    (popcount(deviceType) == 1) && (deviceType & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
                 if (!strncmp(device_address, "hdmi_spkr", 9)) {
                     mHdmiAudioDisabled = false;
                 } else {
                     mHdmiAudioEvent = true;
                 }
                 if (mHdmiAudioDisabled || !mHdmiAudioEvent) {
-                    mAvailableOutputDevices.remove(devDesc);
+                    mAvailableOutputDevices.remove(device);
                     ALOGW("HDMI sink not connected, do not route audio to HDMI out");
                     return INVALID_OPERATION;
                 }
             }
             if (index >= 0) {
-                sp<HwModule> module = mHwModules.getModuleForDevice(device);
+                sp<HwModule> module = mHwModules.getModuleForDevice(device, encodedFormat);
                 if (module == 0) {
                     ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
-                          device);
-                    mAvailableOutputDevices.remove(devDesc);
+                          deviceType);
+                    mAvailableOutputDevices.remove(device);
                     return INVALID_OPERATION;
                 }
+                ALOGV("setDeviceConnectionState() module name=%s", module->getName());
                 mAvailableOutputDevices[index]->attach(module);
             } else {
                 return NO_MEMORY;
@@ -175,20 +178,23 @@
 
             // Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
             // parameters on newly connected devices (instead of opening the outputs...)
-            broadcastDeviceConnectionState(device, state, devDesc->address());
+            broadcastDeviceConnectionState(device, state);
 
-            if (checkOutputsForDevice(devDesc, state, outputs, devDesc->address()) != NO_ERROR) {
-                mAvailableOutputDevices.remove(devDesc);
+            if (checkOutputsForDevice(device, state, outputs) != NO_ERROR) {
+                mAvailableOutputDevices.remove(device);
 
-                broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                               devDesc->address());
+                broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
                 return INVALID_OPERATION;
             }
             // Propagate device availability to Engine
-            mEngine->setDeviceConnectionState(devDesc, state);
-            if (device == AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+            mEngine->setDeviceConnectionState(device, state);
+//TODO CP Begin
+#if 0
+            if (deviceType == AUDIO_DEVICE_OUT_AUX_DIGITAL) {
                 chkDpConnAndAllowedForVoice();
             }
+#endif
+//TODO CP End
 
             // outputs should never be empty here
             ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
@@ -201,39 +207,46 @@
         case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
             if (index < 0) {
                 if (mApmConfigs->isHDMISpkEnabled() &&
-                        (popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+                        (popcount(deviceType) == 1) && (deviceType & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
                     if (!strncmp(device_address, "hdmi_spkr", 9)) {
                         mHdmiAudioDisabled = true;
                     } else {
                         mHdmiAudioEvent = false;
                     }
                 }
-                ALOGW("setDeviceConnectionState() device not connected: %x", device);
+                ALOGW("setDeviceConnectionState() device not connected: %x", deviceType);
                 return INVALID_OPERATION;
             }
 
-            ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
+            ALOGV("setDeviceConnectionState() disconnecting output device %x", deviceType);
 
             // Send Disconnect to HALs
-            broadcastDeviceConnectionState(device, state, devDesc->address());
+            broadcastDeviceConnectionState(device, state);
 
             // remove device from available output devices
-            mAvailableOutputDevices.remove(devDesc);
+            mAvailableOutputDevices.remove(device);
             if (mApmConfigs->isHDMISpkEnabled() &&
-                    (popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
+                    (popcount(deviceType) == 1) && (deviceType & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
                 if (!strncmp(device_address, "hdmi_spkr", 9)) {
                     mHdmiAudioDisabled = true;
                 } else {
                     mHdmiAudioEvent = false;
                 }
             }
-            checkOutputsForDevice(devDesc, state, outputs, devDesc->address());
+            checkOutputsForDevice(device, state, outputs);
+
+            // Reset active device codec
+            device->setEncodedFormat(AUDIO_FORMAT_DEFAULT);
 
             // Propagate device availability to Engine
-            mEngine->setDeviceConnectionState(devDesc, state);
-            if (device == AUDIO_DEVICE_OUT_AUX_DIGITAL) {
+            mEngine->setDeviceConnectionState(device, state);
+//TODO CP Begin
+#if 0
+            if (deviceType == AUDIO_DEVICE_OUT_AUX_DIGITAL) {
                 mEngine->setDpConnAndAllowedForVoice(false);
             }
+#endif
+//TODO CP End
             } break;
 
         default:
@@ -275,8 +288,10 @@
         }
 
         // handle FM device connection state to trigger FM AFE loopback
+//TODO CP Begin
+#if 0
         if (mApmConfigs->isFMPowerOptEnabled() &&
-               device == AUDIO_DEVICE_OUT_FM && hasPrimaryOutput()) {
+               deviceType == AUDIO_DEVICE_OUT_FM && hasPrimaryOutput()) {
            audio_devices_t newDevice = AUDIO_DEVICE_NONE;
            if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
                /*
@@ -323,30 +338,32 @@
            param.addInt(String8("handle_fm"), (int)newDevice);
            mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, param.toString());
         }
+#endif
+//TODO CP End
 
         updateDevicesAndOutputs();
         if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
-            audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
-            updateCallRouting(newDevice);
+            DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
+            updateCallRouting(newDevices);
         }
 
         for (size_t i = 0; i < mOutputs.size(); i++) {
             sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
             if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
-                audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
+                DeviceVector newDevices = getNewOutputDevices(desc, true /*fromCache*/);
                 // 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.
                 bool force = !desc->isDuplicated()
-                        && (!device_distinguishes_on_address(device)
+                        && (!device_distinguishes_on_address(deviceType)
                                 // always force when disconnecting (a non-duplicated device)
                                 || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
-                setOutputDevice(desc, newDevice, force, 0);
+                setOutputDevices(desc, newDevices, force, 0);
             }
         }
 
         if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
-            cleanUpForDevice(devDesc);
+            cleanUpForDevice(device);
         }
 
         mpClientInterface->onAudioPortListUpdate();
@@ -354,36 +371,35 @@
     }  // end if is output device
 
     // handle input devices
-    if (audio_is_input_device(device)) {
+    if (audio_is_input_device(deviceType)) {
         SortedVector <audio_io_handle_t> inputs;
 
-        ssize_t index = mAvailableInputDevices.indexOf(devDesc);
+        ssize_t index = mAvailableInputDevices.indexOf(device);
         switch (state)
         {
         // handle input device connection
         case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
             if (index >= 0) {
-                ALOGW("setDeviceConnectionState() device already connected: %d", device);
+                ALOGW("setDeviceConnectionState() device already connected: %d", deviceType);
                 return INVALID_OPERATION;
             }
-            sp<HwModule> module = mHwModules.getModuleForDevice(device);
+            sp<HwModule> module = mHwModules.getModuleForDevice(device, AUDIO_FORMAT_DEFAULT);
             if (module == NULL) {
                 ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
-                      device);
+                      deviceType);
                 return INVALID_OPERATION;
             }
 
             // Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
             // parameters on newly connected devices (instead of opening the inputs...)
-            broadcastDeviceConnectionState(device, state, devDesc->address());
+            broadcastDeviceConnectionState(device, state);
 
-            if (checkInputsForDevice(devDesc, state, inputs, devDesc->address()) != NO_ERROR) {
-                broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                               devDesc->address());
+            if (checkInputsForDevice(device, state, inputs) != NO_ERROR) {
+                broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
                 return INVALID_OPERATION;
             }
 
-            index = mAvailableInputDevices.add(devDesc);
+            index = mAvailableInputDevices.add(device);
             if (index >= 0) {
                 mAvailableInputDevices[index]->attach(module);
             } else {
@@ -391,26 +407,26 @@
             }
 
             // Propagate device availability to Engine
-            mEngine->setDeviceConnectionState(devDesc, state);
+            mEngine->setDeviceConnectionState(device, state);
         } break;
 
         // handle input device disconnection
         case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
             if (index < 0) {
-                ALOGW("setDeviceConnectionState() device not connected: %d", device);
+                ALOGW("setDeviceConnectionState() device not connected: %d", deviceType);
                 return INVALID_OPERATION;
             }
 
-            ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
+            ALOGV("setDeviceConnectionState() disconnecting input device %x", deviceType);
 
             // Set Disconnect to HALs
-            broadcastDeviceConnectionState(device, state, devDesc->address());
+            broadcastDeviceConnectionState(device, state);
 
-            checkInputsForDevice(devDesc, state, inputs, devDesc->address());
-            mAvailableInputDevices.remove(devDesc);
+            checkInputsForDevice(device, state, inputs);
+            mAvailableInputDevices.remove(device);
 
             // Propagate device availability to Engine
-            mEngine->setDeviceConnectionState(devDesc, state);
+            mEngine->setDeviceConnectionState(device, state);
         } break;
 
         default:
@@ -425,22 +441,26 @@
         updateDevicesAndOutputs();
 
         if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
-            audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
-            updateCallRouting(newDevice);
+            DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
+            updateCallRouting(newDevices);
         }
 
         if (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
-            cleanUpForDevice(devDesc);
+            cleanUpForDevice(device);
         }
 
         mpClientInterface->onAudioPortListUpdate();
         return NO_ERROR;
     } // end if is input device
 
-    ALOGW("setDeviceConnectionState() invalid device: %x", device);
+    ALOGW("setDeviceConnectionState() invalid device: %x", deviceType);
     return BAD_VALUE;
 }
 
+
+//TODO CP Begin
+#if 0
+
 void AudioPolicyManagerCustom::chkDpConnAndAllowedForVoice()
 {
     String8 value;
@@ -454,10 +474,12 @@
     }
     mEngine->setDpConnAndAllowedForVoice(connAndAllowed);
 }
+#endif
+//TODO CP End
 
-bool AudioPolicyManagerCustom::isInvalidationOfMusicStreamNeeded(routing_strategy strategy)
+bool AudioPolicyManagerCustom::isInvalidationOfMusicStreamNeeded(const audio_attributes_t &attr)
 {
-    if (strategy == STRATEGY_MEDIA) {
+    if (followsSameRouting(attr, attributes_initializer(AUDIO_USAGE_MEDIA))) {
         for (size_t i = 0; i < mOutputs.size(); i++) {
             sp<SwAudioOutputDescriptor> newOutputDesc = mOutputs.valueAt(i);
             if (newOutputDesc->mFormat == AUDIO_FORMAT_DSD)
@@ -467,33 +489,35 @@
     return true;
 }
 
-void AudioPolicyManagerCustom::checkOutputForStrategy(routing_strategy strategy)
+
+void AudioPolicyManagerCustom::checkOutputForAttributes(const audio_attributes_t &attr)
 {
-    audio_devices_t oldDevice = getDeviceForStrategy(strategy, true /*fromCache*/);
-    audio_devices_t newDevice = getDeviceForStrategy(strategy, false /*fromCache*/);
-    SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevice(oldDevice, mOutputs);
-    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevice(newDevice, mOutputs);
+
+    DeviceVector oldDevices = mEngine->getOutputDevicesForAttributes(attr, 0, true /*fromCache*/);
+    DeviceVector newDevices = mEngine->getOutputDevicesForAttributes(attr, 0, false /*fromCache*/);
+    SortedVector<audio_io_handle_t> srcOutputs = getOutputsForDevices(oldDevices, mPreviousOutputs);
+    SortedVector<audio_io_handle_t> dstOutputs = getOutputsForDevices(newDevices, mOutputs);
 
     // also take into account external policy-related changes: add all outputs which are
     // associated with policies in the "before" and "after" output vectors
-    ALOGV("checkOutputForStrategy(): policy related outputs");
+    ALOGVV("%s(): policy related outputs", __func__);
     for (size_t i = 0 ; i < mPreviousOutputs.size() ; i++) {
         const sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueAt(i);
         if (desc != 0 && desc->mPolicyMix != NULL) {
             srcOutputs.add(desc->mIoHandle);
-            ALOGV(" previous outputs: adding %d", desc->mIoHandle);
+            ALOGVV(" previous outputs: adding %d", desc->mIoHandle);
         }
     }
     for (size_t i = 0 ; i < mOutputs.size() ; i++) {
         const sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
         if (desc != 0 && desc->mPolicyMix != NULL) {
             dstOutputs.add(desc->mIoHandle);
-            ALOGV(" new outputs: adding %d", desc->mIoHandle);
+            ALOGVV(" new outputs: adding %d", desc->mIoHandle);
         }
     }
 
-    if ((srcOutputs != dstOutputs) && isInvalidationOfMusicStreamNeeded(strategy)) {
-        AudioPolicyManager::checkOutputForStrategy(strategy);
+    if ((srcOutputs != dstOutputs) && isInvalidationOfMusicStreamNeeded(attr)) {
+        AudioPolicyManager::checkOutputForAttributes(attr);
     }
 }
 
@@ -502,6 +526,7 @@
 // of the system.
 bool AudioPolicyManagerCustom::isOffloadSupported(const audio_offload_info_t& offloadInfo)
 {
+    DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
     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,
@@ -526,7 +551,8 @@
     }
     if (mApmConfigs->isRecPlayConcEnabled()) {
         if (mApmConfigs->isRecPlayConcDisabled() &&
-             ((true == mIsInputRequestOnProgress) || (mInputs.activeInputsCountOnDevices() > 0))) {
+             ((true == mIsInputRequestOnProgress) ||
+             (mInputs.activeInputsCountOnDevices(primaryInputDevices) > 0))) {
             ALOGD("copl: blocking  compress offload for record concurrency");
             return false;
         }
@@ -650,7 +676,7 @@
 
     // See if there is a profile to support this.
     // AUDIO_DEVICE_NONE
-    sp<IOProfile> profile = getProfileForOutput(AUDIO_DEVICE_NONE /*ignore device */,
+    sp<IOProfile> profile = getProfileForOutput(DeviceVector() /*ignore device */,
                                             offloadInfo.sample_rate,
                                             offloadInfo.format,
                                             offloadInfo.channel_mask,
@@ -664,7 +690,6 @@
 {
     ALOGD("setPhoneState() state %d", state);
     // store previous phone state for management of sonification strategy below
-    audio_devices_t newDevice = AUDIO_DEVICE_NONE;
     int oldState = mEngine->getPhoneState();
 
     if (mEngine->setPhoneState(state) != NO_ERROR) {
@@ -707,18 +732,18 @@
                 if (activeInputs.size() != 0) {
                    for (size_t i = 0; i <  activeInputs.size(); i++) {
                        sp<AudioInputDescriptor> activeInput = activeInputs[i];
-                       switch(activeInput->inputSource()) {
+                       switch(activeInput->source()) {
                            case AUDIO_SOURCE_VOICE_UPLINK:
                            case AUDIO_SOURCE_VOICE_DOWNLINK:
                            case AUDIO_SOURCE_VOICE_CALL:
                                ALOGD("voice_conc:FOUND active input during call active: %d",
-                                       activeInput->inputSource());
+                                       activeInput->source());
                            break;
 
                            case  AUDIO_SOURCE_VOICE_COMMUNICATION:
                                 if (prop_voip_enabled) {
                                     ALOGD("voice_conc:CLOSING VoIP input source on call setup :%d ",
-                                            activeInput->inputSource());
+                                            activeInput->source());
                                     RecordClientVector activeClients = activeInput->clientsList(true /*activeOnly*/);
                                     for (const auto& activeClient : activeClients) {
                                         closeClient(activeClient->portId());
@@ -728,7 +753,7 @@
 
                            default:
                                ALOGD("voice_conc:CLOSING input on call setup  for inputSource: %d",
-                                       activeInput->inputSource());
+                                       activeInput->source());
                                RecordClientVector activeClients = activeInput->clientsList(true /*activeOnly*/);
                                for (const auto& activeClient : activeClients) {
                                    closeClient(activeClient->portId());
@@ -742,8 +767,8 @@
                 if (activeInputs.size() != 0) {
                     for (size_t i = 0; i <  activeInputs.size(); i++) {
                         sp<AudioInputDescriptor> activeInput = activeInputs[i];
-                        if (AUDIO_SOURCE_VOICE_COMMUNICATION == activeInput->inputSource()) {
-                            ALOGD("voice_conc:CLOSING VoIP on call setup : %d",activeInput->inputSource());
+                        if (AUDIO_SOURCE_VOICE_COMMUNICATION == activeInput->source()) {
+                            ALOGD("voice_conc:CLOSING VoIP on call setup : %d",activeInput->source());
                             RecordClientVector activeClients = activeInput->clientsList(true /*activeOnly*/);
                             for (const auto& activeClient : activeClients) {
                                 closeClient(activeClient->portId());
@@ -897,41 +922,46 @@
     int delayMs = 0;
     if (isStateInCall(state)) {
         nsecs_t sysTime = systemTime();
+        auto musicStrategy = streamToStrategy(AUDIO_STREAM_MUSIC);
+        auto sonificationStrategy = streamToStrategy(AUDIO_STREAM_ALARM);
+
         for (size_t i = 0; i < mOutputs.size(); i++) {
             sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
             // mute media and sonification strategies and delay device switch by the largest
             // latency of any output where either strategy is active.
             // This avoid sending the ring tone or music tail into the earpiece or headset.
-            if ((isStrategyActive(desc, STRATEGY_MEDIA,
+            if ((desc->isStrategyActive(musicStrategy,
                                   SONIFICATION_HEADSET_MUSIC_DELAY,
                                   sysTime) ||
-                 isStrategyActive(desc, STRATEGY_SONIFICATION,
+                 desc->isStrategyActive(sonificationStrategy,
                                   SONIFICATION_HEADSET_MUSIC_DELAY,
                                   sysTime)) &&
                     (delayMs < (int)desc->latency()*2)) {
                 delayMs = desc->latency()*2;
             }
-            setStrategyMute(STRATEGY_MEDIA, true, desc);
-            setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
-                getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
-            setStrategyMute(STRATEGY_SONIFICATION, true, desc);
-            setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
-                getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
+            setStrategyMute(musicStrategy, true, desc);
+            setStrategyMute(musicStrategy, false, desc, MUTE_TIME_MS,
+                mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_MEDIA),
+                                                       nullptr, true /*fromCache*/).types());
+            setStrategyMute(sonificationStrategy, true, desc);
+            setStrategyMute(sonificationStrategy, false, desc, MUTE_TIME_MS,
+                 mEngine->getOutputDevicesForAttributes(attributes_initializer(AUDIO_USAGE_ALARM),
+                                                       nullptr, true /*fromCache*/).types());
         }
     }
 
     if (hasPrimaryOutput()) {
         // Note that despite the fact that getNewOutputDevice() is called on the primary output,
         // the device returned is not necessarily reachable via this output
-        audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
+        DeviceVector rxDevices = getNewOutputDevices(mPrimaryOutput, false /*fromCache*/);
         // force routing command to audio hardware when ending call
         // even if no device change is needed
-        if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
-            rxDevice = mPrimaryOutput->device();
+        if (isStateInCall(oldState) && rxDevices.isEmpty()) {
+            rxDevices = mPrimaryOutput->devices();
         }
 
         if (state == AUDIO_MODE_IN_CALL) {
-            updateCallRouting(rxDevice, delayMs);
+            updateCallRouting(rxDevices, delayMs);
         } else if (oldState == AUDIO_MODE_IN_CALL) {
             if (mCallRxPatch != 0) {
                 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
@@ -941,17 +971,17 @@
                 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
                 mCallTxPatch.clear();
             }
-            setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
+            setOutputDevices(mPrimaryOutput, rxDevices, force, 0);
         } else {
-            setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
+            setOutputDevices(mPrimaryOutput, rxDevices, force, 0);
         }
     }
     //update device for all non-primary outputs
     for (size_t i = 0; i < mOutputs.size(); i++) {
         audio_io_handle_t output = mOutputs.keyAt(i);
         if (output != mPrimaryOutput->mIoHandle) {
-            newDevice = getNewOutputDevice(mOutputs.valueFor(output), false /*fromCache*/);
-            setOutputDevice(mOutputs.valueFor(output), newDevice, (newDevice != AUDIO_DEVICE_NONE));
+            DeviceVector newDevices = getNewOutputDevices(mOutputs.valueFor(output), false /*fromCache*/);
+            setOutputDevices(mOutputs.valueFor(output), newDevices, !newDevices.isEmpty());
         }
     }
     if (isStateInCall(state)) {
@@ -1000,11 +1030,11 @@
         delayMs = TOUCH_SOUND_FIXED_DELAY_MS;
     }
     if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
-        audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
-        if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
-            applyStreamVolumes(mPrimaryOutput, newDevice, delayMs, true);
+        DeviceVector newDevices = getNewOutputDevices(mPrimaryOutput, true /*fromCache*/);
+        if (forceVolumeReeval && !newDevices.isEmpty()) {
+            applyStreamVolumes(mPrimaryOutput, newDevices.types(), delayMs, true);
         }
-        waitMs = updateCallRouting(newDevice, delayMs);
+        waitMs = updateCallRouting(newDevices, delayMs);
     }
     // Use reverse loop to make sure any low latency usecases (generally tones)
     // are not routed before non LL usecases (generally music).
@@ -1015,13 +1045,13 @@
     //       gets routing update while processing first output itself.
     for (size_t i = mOutputs.size(); i > 0; i--) {
         sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i-1);
-        audio_devices_t newDevice = getNewOutputDevice(outputDesc, true /*fromCache*/);
+        DeviceVector newDevices = getNewOutputDevices(outputDesc, true /*fromCache*/);
         if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (outputDesc != mPrimaryOutput)) {
-            waitMs = setOutputDevice(outputDesc, newDevice, (newDevice != AUDIO_DEVICE_NONE),
+            waitMs = setOutputDevices(outputDesc, newDevices, !newDevices.isEmpty(),
                                      delayMs);
 
-            if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
-                applyStreamVolumes(outputDesc, newDevice, waitMs, true);
+            if (forceVolumeReeval && !newDevices.isEmpty()) {
+                applyStreamVolumes(outputDesc, newDevices.types(), waitMs, true);
             }
          }
     }
@@ -1035,10 +1065,9 @@
             activeDesc->source() == AUDIO_SOURCE_HOTWORD) {
             continue;
         }
-        audio_devices_t newDevice = getNewInputDevice(activeDesc);
+        auto newDevice = getNewInputDevice(activeDesc);
         // Force new input selection if the new device can not be reached via current input
-        if (activeDesc->mProfile->getSupportedDevices().types() &
-                (newDevice & ~AUDIO_DEVICE_BIT_IN)) {
+        if (activeDesc->mProfile->getSupportedDevices().contains(newDevice)) {
             setInputDevice(activeDesc->mIoHandle, newDevice);
         } else {
             closeInput(activeDesc->mIoHandle);
@@ -1062,18 +1091,18 @@
         if (outputDesc->streamActiveCount(stream) == 1) {
             // Automatically disable the remote submix input when output is stopped on a
             // re routing mix of type MIX_TYPE_RECORDERS
-            if (audio_is_remote_submix_device(outputDesc->mDevice) &&
+            if (audio_is_remote_submix_device(outputDesc->devices().types()) &&
                 outputDesc->mPolicyMix != NULL &&
                 outputDesc->mPolicyMix->mMixType == MIX_TYPE_RECORDERS) {
                 setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
                                             AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
                                             outputDesc->mPolicyMix->mDeviceAddress,
-                                            "remote-submix");
+                                            "remote-submix", AUDIO_FORMAT_DEFAULT);
             }
         }
         bool forceDeviceUpdate = false;
         if (client->hasPreferredDevice(true)) {
-            checkStrategyRoute(getStrategy(stream), AUDIO_IO_HANDLE_NONE);
+            checkStrategyRoute(client->strategy(), AUDIO_IO_HANDLE_NONE);
             forceDeviceUpdate = true;
         }
         // decrement usage count of this stream on the output
@@ -1083,40 +1112,40 @@
         // store time at which the stream was stopped - see isStreamActive()
         if (outputDesc->streamActiveCount(stream) == 0 || forceDeviceUpdate) {
             outputDesc->mStopTime[stream] = systemTime();
-            audio_devices_t prevDevice = outputDesc->device();
-            audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
+            DeviceVector prevDevices = outputDesc->devices();
+            DeviceVector newDevices = getNewOutputDevices(outputDesc, 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(outputDesc, newDevice, false, outputDesc->latency()*2);
+            setOutputDevices(outputDesc, newDevices, false, outputDesc->latency()*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);
-                sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
+                sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
                 if (desc != outputDesc &&
                         desc->isActive() &&
                         outputDesc->sharesHwModuleWith(desc) &&
-                        (newDevice != desc->device())) {
-                        audio_devices_t dev = getNewOutputDevice(mOutputs.valueFor(curOutput), false /*fromCache*/);
-                        bool force = prevDevice != dev;
+                        (newDevices != desc->devices())) {
+                        DeviceVector dev = getNewOutputDevices(mOutputs.valueFor(curOutput), false /*fromCache*/);
+                        bool force = prevDevices != dev;
                         uint32_t delayMs;
-                        if (dev == prevDevice) {
+                        if (dev == prevDevices) {
                             delayMs = 0;
                         } else {
                             delayMs = outputDesc->latency()*2;
                         }
-                        setOutputDevice(desc,
+                        setOutputDevices(desc,
                                     dev,
                                     force,
                                     delayMs);
                     /*audio policy: fix media volume after ringtone*/
                     // re-apply device specific volume if not done by setOutputDevice()
                      if (!force) {
-                         applyStreamVolumes(desc, dev, delayMs);
+                         applyStreamVolumes(desc, dev.types(), delayMs);
                      }
                 }
             }
@@ -1140,6 +1169,7 @@
     // cannot start playback of STREAM_TTS if any other output is being used
     uint32_t beaconMuteLatency = 0;
     audio_stream_type_t stream = client->stream();
+    auto clientAttr = client->attributes();
 
     if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
         ALOGW("startSource() invalid stream %d", stream);
@@ -1164,17 +1194,20 @@
     bool force = !outputDesc->isActive() &&
             (outputDesc->getPatchHandle() == AUDIO_PATCH_HANDLE_NONE);
 
-    audio_devices_t device = AUDIO_DEVICE_NONE;
+    DeviceVector devices;
     AudioMix *policyMix = NULL;
     const char *address = NULL;
     if (outputDesc->mPolicyMix != NULL) {
         policyMix = outputDesc->mPolicyMix;
+        audio_devices_t newDeviceType;
         address = policyMix->mDeviceAddress.string();
         if ((policyMix->mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
-            device = policyMix->mDeviceType;
+            newDeviceType = policyMix->mDeviceType;
         } else {
-            device = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
+            newDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
         }
+        devices.add(mAvailableOutputDevices.getDevice(newDeviceType,
+                                                      String8(address), AUDIO_FORMAT_DEFAULT));
     }
 
     // increment usage count for this stream on the requested output:
@@ -1186,18 +1219,18 @@
         selectOutputForMusicEffects();
     }
 
-    if (outputDesc->streamActiveCount(stream) == 1 || device != AUDIO_DEVICE_NONE) {
+    if (outputDesc->streamActiveCount(stream) == 1 || !devices.isEmpty()) {
         // starting an output being rerouted?
-        if (device == AUDIO_DEVICE_NONE) {
-            device = getNewOutputDevice(outputDesc, false /*fromCache*/);
+        if (devices.isEmpty()) {
+            devices = getNewOutputDevices(outputDesc, false /*fromCache*/);
         }
-        routing_strategy strategy = getStrategy(stream);
-        bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
-                            (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
-                            (beaconMuteLatency > 0);
+        bool shouldWait = (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM)) ||
+             followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_NOTIFICATION)) ||
+             (beaconMuteLatency > 0));
+
         uint32_t waitMs = beaconMuteLatency;
         for (size_t i = 0; i < mOutputs.size(); i++) {
-            sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
+            sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
             if (desc != outputDesc) {
                 // force a device change if any other output is:
                 // - managed by the same hw module
@@ -1207,8 +1240,8 @@
                 // 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() != device &&
-                        desc->supportedDevices() & device &&
+                        desc->devices() != devices &&
+                        !(desc->filterSupportedDevices(devices).isEmpty()) &&
                         desc->getPatchHandle() != AUDIO_PATCH_HANDLE_NONE) {
                     force = true;
                 }
@@ -1221,20 +1254,20 @@
                 }
             }
         }
-        uint32_t muteWaitMs = setOutputDevice(outputDesc, device, force, 0, NULL, address);
+        uint32_t muteWaitMs = setOutputDevices(outputDesc, devices, force, 0, NULL, address);
 
         // apply volume rules for current stream and device if necessary
         checkAndSetVolume(stream,
-                          mVolumeCurves->getVolumeIndex(stream, device),
+                          mVolumeCurves->getVolumeIndex(stream, outputDesc->devices().types()),
                           outputDesc,
-                          device);
+                          outputDesc->devices().types());
 
         // update the outputs if starting an output with a stream that can affect notification
         // routing
         handleNotificationRoutingForStream(stream);
 
         // force reevaluating accessibility routing when ringtone or alarm starts
-        if (strategy == STRATEGY_SONIFICATION) {
+        if (followsSameRouting(clientAttr, attributes_initializer(AUDIO_USAGE_ALARM))) {
             mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
         }
         if (waitMs > muteWaitMs) {
@@ -1248,7 +1281,7 @@
 void AudioPolicyManagerCustom::handleNotificationRoutingForStream(audio_stream_type_t stream) {
     switch(stream) {
     case AUDIO_STREAM_MUSIC:
-        checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
+        checkOutputForAttributes(attributes_initializer(AUDIO_USAGE_NOTIFICATION));
         updateDevicesAndOutputs();
         break;
     default:
@@ -1284,7 +1317,7 @@
     }
 
     if (device == AUDIO_DEVICE_NONE) {
-        device = outputDesc->device();
+        device = outputDesc->devices().types();
     }
 
     float volumeDb = computeVolume(stream, index, device);
@@ -1355,7 +1388,8 @@
                                                     const audio_config_t *config,
                                                     audio_output_flags_t *flags,
                                                     audio_port_handle_t *selectedDeviceId,
-                                                    audio_port_handle_t *portId)
+                                                    audio_port_handle_t *portId,
+                                                    std::vector<audio_io_handle_t> *secondaryOutputs)
 {
     audio_offload_info_t tOffloadInfo = AUDIO_INFO_INITIALIZER;
     audio_config_t tConfig;
@@ -1382,11 +1416,12 @@
                                                 (uid_t)uid, &tConfig,
                                                 flags,
                                                 (audio_port_handle_t*)selectedDeviceId,
-                                                portId);
+                                                portId,
+                                                secondaryOutputs);
 }
 
-audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevice(
-        audio_devices_t device,
+audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevices(
+        const DeviceVector &devices,
         audio_session_t session,
         audio_stream_type_t stream,
         const audio_config_t *config,
@@ -1464,7 +1499,7 @@
                  if (desc->mFlags == (AUDIO_OUTPUT_FLAG_VOIP_RX | AUDIO_OUTPUT_FLAG_DIRECT)) {
                      //close voip output if currently open by the same client with different device
                      if (desc->mDirectClientSession == session &&
-                         desc->device() != device) {
+                         desc->devices() != devices) {
                          closeOutput(desc->mIoHandle);
                      } else {
                          voip_pcm_already_in_use = true;
@@ -1564,8 +1599,10 @@
     }
     if (mApmConfigs->isRecPlayConcEnabled()) {
         bool prop_rec_play_enabled = mApmConfigs->isRecPlayConcDisabled();
+        DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
         if ((prop_rec_play_enabled) &&
-                ((true == mIsInputRequestOnProgress) || (mInputs.activeInputsCountOnDevices() > 0))) {
+                ((true == mIsInputRequestOnProgress) ||
+                (mInputs.activeInputsCountOnDevices(primaryInputDevices) > 0))) {
             if (AUDIO_MODE_IN_COMMUNICATION == mEngine->getPhoneState()) {
                 if (AUDIO_OUTPUT_FLAG_VOIP_RX & *flags) {
                     // allow VoIP using voice path
@@ -1674,7 +1711,7 @@
         *flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_VOIP_RX |
                                        AUDIO_OUTPUT_FLAG_DIRECT);
         ALOGV("Set VoIP and Direct output flags for PCM format");
-    } else if (device == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
+    } else if (devices.types() == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
         stream == AUDIO_STREAM_MUSIC &&
         audio_is_linear_pcm(config->format) &&
         isInCall()) {
@@ -1707,7 +1744,7 @@
         goto non_direct_output;
     }
 
-    profile = getProfileForOutput(device,
+    profile = getProfileForOutput(devices,
                                         config->sample_rate,
                                         config->format,
                                         config->channel_mask,
@@ -1764,10 +1801,10 @@
 
                 outputDesc =
                         new SwAudioOutputDescriptor(profile, mpClientInterface);
-                DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromTypeMask(device);
+                DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromTypeMask(devices.types());
                 String8 address = outputDevices.size() > 0 ? outputDevices.itemAt(0)->address()
                         : String8("");
-                status = outputDesc->open(config, device, address, stream, *flags, &output);
+                status = outputDesc->open(config, devices, stream, *flags, &output);
 
                 // only accept an output with the requested parameters
                 if (status != NO_ERROR ||
@@ -1823,7 +1860,7 @@
     if (audio_is_linear_pcm(config->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);
+        SortedVector<audio_io_handle_t> outputs = getOutputsForDevices(devices, mOutputs);
 
         // at this stage we should ignore the DIRECT flag as no direct output could be found earlier
         *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
@@ -1932,7 +1969,7 @@
         const sp<AudioInputDescriptor>  inputDescriptor = mInputs.valueAt(i);
         if (inputDescriptor->isActive() && !inputDescriptor->isSoundTrigger() &&
                 ((devices == AUDIO_DEVICE_IN_DEFAULT) ||
-                 ((inputDescriptor->mDevice & devices & ~AUDIO_DEVICE_BIT_IN) != 0))) {
+                 ((inputDescriptor->getDeviceType() & devices & ~AUDIO_DEVICE_BIT_IN) != 0))) {
             count++;
         }
     }
@@ -1980,8 +2017,8 @@
 
     if (mApmConfigs->isRecPlayConcEnabled()) {
         mIsInputRequestOnProgress = true;
-
-        if (mApmConfigs->isRecPlayConcDisabled() && (mInputs.activeInputsCountOnDevices() == 0)) {
+        DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
+        if (mApmConfigs->isRecPlayConcDisabled() && (mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0)) {
             // send update to HAL on record playback concurrency
             AudioParameter param = AudioParameter();
             param.add(String8("rec_play_conc_on"), String8("true"));
@@ -2026,7 +2063,7 @@
 
     // indicate active capture to sound trigger service if starting capture from a mic on
     // primary HW module
-    audio_devices_t device = getNewInputDevice(inputDesc);
+    sp<DeviceDescriptor> device = getNewInputDevice(inputDesc);
     setInputDevice(input, device, true /* force */);
 
     if (inputDesc->activeCount()  == 1) {
@@ -2037,10 +2074,10 @@
                     MIX_STATE_MIXING);
         }
 
-        audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
-        if ((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) {
+        DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
+        if ((primaryInputDevices.contains(device) && (device->type() & ~AUDIO_DEVICE_BIT_IN)) != 0) {
             if (mApmConfigs->isVAConcEnabled()) {
-                if (activeNonSoundTriggerInputsCountOnDevices(primaryInputDevices) == 1)
+                if (activeNonSoundTriggerInputsCountOnDevices(primaryInputDevices.types()) == 1)
                     SoundTrigger::setCaptureState(true);
             } else if (mInputs.activeInputsCountOnDevices(primaryInputDevices) == 1)
                 SoundTrigger::setCaptureState(true);
@@ -2049,7 +2086,7 @@
         // automatically enable the remote submix output when input is started if not
         // used by a policy mix of type MIX_TYPE_RECORDERS
         // For remote submix (a virtual device), we open only one input per capture request.
-        if (audio_is_remote_submix_device(inputDesc->mDevice)) {
+        if (audio_is_remote_submix_device(inputDesc->getDeviceType())) {
             String8 address = String8("");
             if (inputDesc->mPolicyMix == NULL) {
                 address = String8("0");
@@ -2059,7 +2096,7 @@
             if (address != "") {
                 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
                         AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                        address, "remote-submix");
+                        address, "remote-submix", AUDIO_FORMAT_DEFAULT);
             }
         }
     }
@@ -2084,18 +2121,17 @@
     audio_io_handle_t input = inputDesc->mIoHandle;
 
     ALOGV("stopInput() input %d", input);
+    DeviceVector primaryInputDevices = availablePrimaryModuleInputDevices();
     if (mApmConfigs->isVAConcEnabled()) {
         sp<AudioInputDescriptor> inputDesc = mInputs.getInputForClient(portId);
-        audio_devices_t device = inputDesc->mDevice;
-        audio_devices_t primaryInputDevices = availablePrimaryInputDevices();
-        if (((device & primaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
-                activeNonSoundTriggerInputsCountOnDevices(primaryInputDevices) == 0) {
+        if ((primaryInputDevices.contains(inputDesc->getDevice()) &&
+                activeNonSoundTriggerInputsCountOnDevices(primaryInputDevices.types())) == 0) {
                 SoundTrigger::setCaptureState(false);
         }
     }
     if (mApmConfigs->isRecPlayConcEnabled()) {
         if (mApmConfigs->isRecPlayConcDisabled() &&
-                (mInputs.activeInputsCountOnDevices() == 0)) {
+                (mInputs.activeInputsCountOnDevices(primaryInputDevices) == 0)) {
             //send update to HAL on record playback concurrency
             AudioParameter param = AudioParameter();
             param.add(String8("rec_play_conc_on"), String8("false"));
@@ -2115,7 +2151,6 @@
     }
     return status;
 }
-
 AudioPolicyManagerCustom::AudioPolicyManagerCustom(AudioPolicyClientInterface *clientInterface)
     : AudioPolicyManager(clientInterface),
       mFallBackflag(AUDIO_OUTPUT_FLAG_NONE),
diff --git a/policy_hal/AudioPolicyManager.h b/policy_hal/AudioPolicyManager.h
index 3dfddeb..37fb806 100644
--- a/policy_hal/AudioPolicyManager.h
+++ b/policy_hal/AudioPolicyManager.h
@@ -86,7 +86,8 @@
         status_t setDeviceConnectionStateInt(audio_devices_t device,
                                           audio_policy_dev_state_t state,
                                           const char *device_address,
-                                          const char *device_name);
+                                          const char *device_name,
+                                          audio_format_t encodedFormat);
         virtual void setPhoneState(audio_mode_t state);
         virtual void setForceUse(audio_policy_force_use_t usage,
                                  audio_policy_forced_cfg_t config);
@@ -114,7 +115,6 @@
         static sp<APMConfigHelper> mApmConfigs;
 
 protected:
-
          status_t checkAndSetVolume(audio_stream_type_t stream,
                                                    int index,
                                                    const sp<AudioOutputDescriptor>& outputDesc,
@@ -123,11 +123,11 @@
 
         // avoid invalidation for active music stream on  previous outputs
         // which is supported on the new device.
-        bool isInvalidationOfMusicStreamNeeded(routing_strategy strategy);
+
+        bool isInvalidationOfMusicStreamNeeded(const audio_attributes_t &attr);
 
         // Must be called before updateDevicesAndOutputs()
-        void checkOutputForStrategy(routing_strategy strategy);
-
+        void checkOutputForAttributes(const audio_attributes_t &attr);
         // returns true if given output is direct output
         bool isDirectOutput(audio_io_handle_t output);
 
@@ -141,28 +141,30 @@
         // event is one of STARTING_OUTPUT, STARTING_BEACON, STOPPING_OUTPUT, STOPPING_BEACON
         // returns 0 if no mute/unmute event happened, the largest latency of the device where
         //   the mute/unmute happened
+
         uint32_t handleEventForBeacon(int){return 0;}
         uint32_t setBeaconMute(bool){return 0;}
         static audio_output_flags_t getFallBackPath();
         int mFallBackflag;
         void moveGlobalEffect();
-
         //parameter indicates of HDMI speakers disabled
         bool mHdmiAudioDisabled;
         //parameter indicates if HDMI plug in/out detected
         bool mHdmiAudioEvent;
+
 private:
         // updates device caching and output for streams that can influence the
         //    routing of notifications
         void handleNotificationRoutingForStream(audio_stream_type_t stream);
         // internal method to return the output handle for the given device and format
-        audio_io_handle_t getOutputForDevice(
-                audio_devices_t device,
+        audio_io_handle_t getOutputForDevices(
+                const DeviceVector &devices,
                 audio_session_t session,
                 audio_stream_type_t stream,
                 const audio_config_t *config,
                 audio_output_flags_t *flags);
 
+
         // internal method to fill offload info in case of Direct PCM
         status_t getOutputForAttr(const audio_attributes_t *attr,
                 audio_io_handle_t *output,
@@ -172,7 +174,12 @@
                 const audio_config_t *config,
                 audio_output_flags_t *flags,
                 audio_port_handle_t *selectedDeviceId,
-                audio_port_handle_t *portId);
+                audio_port_handle_t *portId,
+                std::vector<audio_io_handle_t> *secondaryOutputs);
+
+
+
+
         // internal method to query hal for whether display-port is connected
         // and can be used for voip/voice call
         void chkDpConnAndAllowedForVoice();