audio policy: engine configurable: fix support of multiple devices of same type

The configurable policy is using criteria for the available devices based on
the type. If multiple devices of the same type (as remote submix) are removed
and added, the bit associated to this type within the criterion shall be set
as far as at least one device of this type is connected.
It was not the case, this patch is fixing this issue.

Change-Id: Id6a83b753907a9b0f07bf8552e50ee28e990a83e
Signed-off-by: François Gaffie <francois.gaffie@intel.com>
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.cpp b/services/audiopolicy/engineconfigurable/src/Engine.cpp
index 32341ec..074af50 100755
--- a/services/audiopolicy/engineconfigurable/src/Engine.cpp
+++ b/services/audiopolicy/engineconfigurable/src/Engine.cpp
@@ -246,10 +246,17 @@
     return mPolicyParameterMgr->getForceUse(usage);
 }
 
-status_t Engine::setDeviceConnectionState(audio_devices_t devices, audio_policy_dev_state_t state,
-                                          const char *deviceAddress)
+status_t Engine::setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+                                          audio_policy_dev_state_t /*state*/)
 {
-    return mPolicyParameterMgr->setDeviceConnectionState(devices, state, deviceAddress);
+    if (audio_is_output_device(devDesc->type())) {
+        return mPolicyParameterMgr->setAvailableOutputDevices(
+                    mApmObserver->getAvailableOutputDevices().types());
+    } else if (audio_is_input_device(devDesc->type())) {
+        return mPolicyParameterMgr->setAvailableInputDevices(
+                    mApmObserver->getAvailableInputDevices().types());
+    }
+    return BAD_TYPE;
 }
 
 template <>
diff --git a/services/audiopolicy/engineconfigurable/src/Engine.h b/services/audiopolicy/engineconfigurable/src/Engine.h
index 79bc8ff..8a15e5e 100755
--- a/services/audiopolicy/engineconfigurable/src/Engine.h
+++ b/services/audiopolicy/engineconfigurable/src/Engine.h
@@ -86,8 +86,7 @@
         virtual android::status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
                                                            audio_policy_dev_state_t state)
         {
-            return mPolicyEngine->setDeviceConnectionState(devDesc->type(), state,
-                                                           devDesc->mAddress);
+            return mPolicyEngine->setDeviceConnectionState(devDesc, state);
         }
         virtual status_t initStreamVolume(audio_stream_type_t stream,
                                                    int indexMin, int indexMax)
@@ -180,9 +179,8 @@
     audio_mode_t getPhoneState() const;
     status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
     audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const;
-    status_t setDeviceConnectionState(audio_devices_t devices, audio_policy_dev_state_t state,
-                                      const char *deviceAddress);
-
+    status_t setDeviceConnectionState(const sp<DeviceDescriptor> devDesc,
+                                      audio_policy_dev_state_t state);
     float volIndexToDb(device_category category, audio_stream_type_t stream, int indexInUi);
     status_t initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax);
 
diff --git a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
index cfe49d4..3e40a2b 100755
--- a/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
+++ b/services/audiopolicy/engineconfigurable/wrapper/ParameterManagerWrapper.cpp
@@ -387,41 +387,26 @@
     return interface->getLiteralValue(valueToCheck, literalValue);
 }
 
-status_t ParameterManagerWrapper::setDeviceConnectionState(audio_devices_t devices,
-                                                           audio_policy_dev_state_t state,
-                                                           const char */*deviceAddres*/)
+status_t ParameterManagerWrapper::setAvailableInputDevices(audio_devices_t inputDevices)
 {
-    ISelectionCriterionInterface *criterion = NULL;
-
-    if (audio_is_output_devices(devices)) {
-        criterion = mPolicyCriteria[gOutputDeviceCriterionTag];
-    } else if (devices & AUDIO_DEVICE_BIT_IN) {
-        criterion = mPolicyCriteria[gInputDeviceCriterionTag];
-    } else {
-        return BAD_TYPE;
-    }
+    ISelectionCriterionInterface *criterion = mPolicyCriteria[gInputDeviceCriterionTag];
     if (criterion == NULL) {
-        ALOGE("%s: no criterion found for devices", __FUNCTION__);
+        ALOGE("%s: no criterion found for input devices", __FUNCTION__);
         return DEAD_OBJECT;
     }
+    criterion->setCriterionState(inputDevices & ~AUDIO_DEVICE_BIT_IN);
+    applyPlatformConfiguration();
+    return NO_ERROR;
+}
 
-    int32_t previousDevices = criterion->getCriterionState();
-    switch (state)
-    {
-    case AUDIO_POLICY_DEVICE_STATE_AVAILABLE:
-        criterion->setCriterionState(previousDevices |= devices);
-        break;
-
-    case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE:
-        if (devices & AUDIO_DEVICE_BIT_IN) {
-            devices &= ~AUDIO_DEVICE_BIT_IN;
-        }
-        criterion->setCriterionState(previousDevices &= ~devices);
-        break;
-
-    default:
-        return BAD_VALUE;
+status_t ParameterManagerWrapper::setAvailableOutputDevices(audio_devices_t outputDevices)
+{
+    ISelectionCriterionInterface *criterion = mPolicyCriteria[gOutputDeviceCriterionTag];
+    if (criterion == NULL) {
+        ALOGE("%s: no criterion found for output devices", __FUNCTION__);
+        return DEAD_OBJECT;
     }
+    criterion->setCriterionState(outputDevices);
     applyPlatformConfiguration();
     return NO_ERROR;
 }
diff --git a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
index 3c5f2c0..4c1acfe 100755
--- a/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
+++ b/services/audiopolicy/engineconfigurable/wrapper/include/ParameterManagerWrapper.h
@@ -103,18 +103,22 @@
     audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage) const;
 
     /**
-     * Set the connection state of device(s).
-     * It will set the associated policy parameter framework criterion.
+     * Set the available input devices i.e. set the associated policy parameter framework criterion
      *
-     * @param[in] devices mask of devices for which the state has changed.
-     * @param[in] state of availability of this(these) device(s).
-     * @param[in] deviceAddress: the mask might not be enough, as it may represents a type of
-     *            device, so address of the device will help precise identification.
+     * @param[in] inputDevices mask of available input devices.
      *
      * @return NO_ERROR if devices criterion updated correctly, error code otherwise.
      */
-    status_t setDeviceConnectionState(audio_devices_t devices, audio_policy_dev_state_t state,
-                                      const char *deviceAddress);
+    status_t setAvailableInputDevices(audio_devices_t inputDevices);
+
+    /**
+     * Set the available output devices i.e. set the associated policy parameter framework criterion
+     *
+     * @param[in] outputDevices mask of available output devices.
+     *
+     * @return NO_ERROR if devices criterion updated correctly, error code otherwise.
+     */
+    status_t setAvailableOutputDevices(audio_devices_t outputDevices);
 
 private:
     /**