audiopolicy: apm: switch to new Engine APIs

Test: make
Change-Id: Iedc2268852ee0bce32b67cfd324395c48cb33424
Signed-off-by: François Gaffie <francois.gaffie@renault.com>
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index a04254c..1b09e3d 100644
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -32,6 +32,7 @@
 
 #include <EngineConfig.h>
 #include <policy.h>
+#include <AudioIODescriptorInterface.h>
 #include <ParameterManagerWrapper.h>
 
 using std::string;
@@ -330,10 +331,20 @@
         ALOGV("%s explicit Routing on device %s", __func__, preferredDevice->toString().c_str());
         return DeviceVector(preferredDevice);
     }
-    product_strategy_t strategy = EngineBase::getProductStrategyForAttributes(attributes);
+    product_strategy_t strategy = getProductStrategyForAttributes(attributes);
+    const DeviceVector &availableOutputDevices = getApmObserver()->getAvailableOutputDevices();
+    const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
     //
-    // @TODO: manage dynamic mix
+    // @TODO: what is the priority of explicit routing? Shall it be considered first as it used to
+    // be by APM?
     //
+    // Honor explicit routing requests only if all active clients have a preferred route in which
+    // case the last active client route is used
+    sp<DeviceDescriptor> device = findPreferredDevice(outputs, strategy, availableOutputDevices);
+    if (device != nullptr) {
+        return DeviceVector(device);
+    }
+
     return fromCache? mDevicesForStrategies.at(strategy) : getDevicesForProductStrategy(strategy);
 }
 
@@ -344,13 +355,29 @@
 }
 
 sp<DeviceDescriptor> Engine::getInputDeviceForAttributes(const audio_attributes_t &attr,
-                                                         AudioMix **/*mix*/) const
+                                                         AudioMix **mix) const
 {
-    const auto &availInputDevices = getApmObserver()->getAvailableInputDevices();
+    const auto &policyMixes = getApmObserver()->getAudioPolicyMixCollection();
+    const auto &availableInputDevices = getApmObserver()->getAvailableInputDevices();
+    const auto &inputs = getApmObserver()->getInputs();
     std::string address;
     //
-    // @TODO: manage explicit routing and dynamic mix
+    // Explicit Routing ??? what is the priority of explicit routing? Shall it be considered
+    // first as it used to be by APM?
     //
+    // Honor explicit routing requests only if all active clients have a preferred route in which
+    // case the last active client route is used
+    sp<DeviceDescriptor> device =
+            findPreferredDevice(inputs, attr.source, availableInputDevices);
+    if (device != nullptr) {
+        return device;
+    }
+
+    device = policyMixes.getDeviceAndMixForInputSource(attr.source, availableInputDevices, mix);
+    if (device != nullptr) {
+        return device;
+    }
+
     audio_devices_t deviceType = getPropertyForKey<audio_devices_t, audio_source_t>(attr.source);
 
     if (audio_is_remote_submix_device(deviceType)) {
@@ -361,7 +388,7 @@
             address = tags.substr(pos + std::strlen("addr="));
         }
     }
-    return availInputDevices.getDevice(deviceType, String8(address.c_str()), AUDIO_FORMAT_DEFAULT);
+    return availableInputDevices.getDevice(deviceType, String8(address.c_str()), AUDIO_FORMAT_DEFAULT);
 }
 
 void Engine::updateDeviceSelectionCache()