Revert^2 "Support device role for capture preset."
bcfb2ce24a4eb736d701197293d4337f23ba59c4
Change-Id: I368d562ec2aae68aa239dce75d54ca2772b30e76
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 0f3ed14..93819f5 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -306,6 +306,25 @@
virtual status_t getDevicesForRoleAndStrategy(product_strategy_t strategy,
device_role_t role,
AudioDeviceTypeAddrVector &devices) = 0;
+
+ virtual status_t setDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
+
+ virtual status_t addDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
+
+ virtual status_t removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector& devices) = 0;
+
+ virtual status_t clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role) = 0;
+
+ virtual status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices) = 0;
};
diff --git a/services/audiopolicy/engine/common/include/EngineBase.h b/services/audiopolicy/engine/common/include/EngineBase.h
index 804a802..4510f63 100755
--- a/services/audiopolicy/engine/common/include/EngineBase.h
+++ b/services/audiopolicy/engine/common/include/EngineBase.h
@@ -127,11 +127,36 @@
status_t restoreOriginVolumeCurve(audio_stream_type_t stream);
+ status_t setDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) override;
+
+ status_t addDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) override;
+
+ /**
+ * Remove devices role for capture preset. When `forceMatched` is true, the devices to be
+ * removed must all show as role for the capture preset. Otherwise, only devices that has shown
+ * as role for the capture preset will be remove.
+ */
+ status_t doRemoveDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role, const AudioDeviceTypeAddrVector& devices,
+ bool forceMatched=true);
+
+ status_t removeDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role, const AudioDeviceTypeAddrVector& devices) override;
+
+ status_t clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role) override;
+
+ status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role, AudioDeviceTypeAddrVector &devices) const override;
+
private:
AudioPolicyManagerObserver *mApmObserver = nullptr;
ProductStrategyMap mProductStrategies;
ProductStrategyPreferredRoutingMap mProductStrategyPreferredDevices;
+ CapturePresetDevicesRoleMap mCapturePresetDevicesRole;
VolumeGroupMap mVolumeGroups;
LastRemovableMediaDevices mLastRemovableMediaDevices;
audio_mode_t mPhoneState = AUDIO_MODE_NORMAL; /**< current phone state. */
diff --git a/services/audiopolicy/engine/common/src/EngineBase.cpp b/services/audiopolicy/engine/common/src/EngineBase.cpp
index ae4f7f4..1875c10 100644
--- a/services/audiopolicy/engine/common/src/EngineBase.cpp
+++ b/services/audiopolicy/engine/common/src/EngineBase.cpp
@@ -19,6 +19,7 @@
#include "EngineBase.h"
#include "EngineDefaultConfig.h"
+#include "../include/EngineBase.h"
#include <TypeConverter.h>
namespace android {
@@ -423,6 +424,171 @@
return NO_ERROR;
}
+status_t EngineBase::setDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices)
+{
+ // verify if the audio source is valid
+ if (!audio_is_valid_audio_source(audioSource)) {
+ ALOGE("%s unknown audio source %u", __func__, audioSource);
+ }
+
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED:
+ mCapturePresetDevicesRole[audioSource][role] = devices;
+ // When the devices are set as preferred devices, remove them from the disabled devices.
+ doRemoveDevicesRoleForCapturePreset(
+ audioSource, DEVICE_ROLE_DISABLED, devices, false /*forceMatched*/);
+ break;
+ case DEVICE_ROLE_DISABLED:
+ // TODO: support setting devices role as disabled for capture preset.
+ ALOGI("%s no implemented for role as %d", __func__, role);
+ break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as it is no need to set device role as none
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+status_t EngineBase::addDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices)
+{
+ // verify if the audio source is valid
+ if (!audio_is_valid_audio_source(audioSource)) {
+ ALOGE("%s unknown audio source %u", __func__, audioSource);
+ }
+
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED:
+ mCapturePresetDevicesRole[audioSource][role] = excludeDeviceTypeAddrsFrom(
+ mCapturePresetDevicesRole[audioSource][role], devices);
+ for (const auto& device : devices) {
+ mCapturePresetDevicesRole[audioSource][role].push_back(device);
+ }
+ // When the devices are set as preferred devices, remove them from the disabled devices.
+ doRemoveDevicesRoleForCapturePreset(
+ audioSource, DEVICE_ROLE_DISABLED, devices, false /*forceMatched*/);
+ break;
+ case DEVICE_ROLE_DISABLED:
+ // TODO: support setting devices role as disabled for capture preset.
+ ALOGI("%s no implemented for role as %d", __func__, role);
+ break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as it is no need to set device role as none
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+status_t EngineBase::removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector& devices) {
+ return doRemoveDevicesRoleForCapturePreset(audioSource, role, devices);
+}
+
+status_t EngineBase::doRemoveDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role, const AudioDeviceTypeAddrVector& devices, bool forceMatched)
+{
+ // verify if the audio source is valid
+ if (!audio_is_valid_audio_source(audioSource)) {
+ ALOGE("%s unknown audio source %u", __func__, audioSource);
+ }
+
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED:
+ case DEVICE_ROLE_DISABLED: {
+ if (mCapturePresetDevicesRole.count(audioSource) == 0 ||
+ mCapturePresetDevicesRole[audioSource].count(role) == 0) {
+ return NAME_NOT_FOUND;
+ }
+ AudioDeviceTypeAddrVector remainingDevices = excludeDeviceTypeAddrsFrom(
+ mCapturePresetDevicesRole[audioSource][role], devices);
+ if (forceMatched && remainingDevices.size() !=
+ mCapturePresetDevicesRole[audioSource][role].size() - devices.size()) {
+ // There are some devices from `devicesToRemove` that are not shown in the cached record
+ return BAD_VALUE;
+ }
+ mCapturePresetDevicesRole[audioSource][role] = remainingDevices;
+ if (mCapturePresetDevicesRole[audioSource][role].empty()) {
+ // Remove the role when device list is empty
+ mCapturePresetDevicesRole[audioSource].erase(role);
+ }
+ } break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as it makes no sense to remove devices with
+ // role as DEVICE_ROLE_NONE
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+status_t EngineBase::clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role)
+{
+ // verify if the audio source is valid
+ if (!audio_is_valid_audio_source(audioSource)) {
+ ALOGE("%s unknown audio source %u", __func__, audioSource);
+ }
+
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED:
+ if (mCapturePresetDevicesRole.count(audioSource) == 0 ||
+ mCapturePresetDevicesRole[audioSource].erase(role) == 0) {
+ // no preferred device for the given audio source
+ return NAME_NOT_FOUND;
+ }
+ break;
+ case DEVICE_ROLE_DISABLED:
+ // TODO: support remove devices role as disabled for strategy.
+ ALOGI("%s no implemented for role as %d", __func__, role);
+ break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as it makes no sense to remove devices with
+ // role as DEVICE_ROLE_NONE for a strategy
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
+status_t EngineBase::getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role, AudioDeviceTypeAddrVector &devices) const
+{
+ // verify if the audio source is valid
+ if (!audio_is_valid_audio_source(audioSource)) {
+ ALOGE("%s unknown audio source %u", __func__, audioSource);
+ return BAD_VALUE;
+ }
+
+ switch (role) {
+ case DEVICE_ROLE_PREFERRED:
+ case DEVICE_ROLE_DISABLED: {
+ if (mCapturePresetDevicesRole.count(audioSource) == 0) {
+ return NAME_NOT_FOUND;
+ }
+ auto devIt = mCapturePresetDevicesRole.at(audioSource).find(role);
+ if (devIt == mCapturePresetDevicesRole.at(audioSource).end()) {
+ ALOGV("%s no devices role(%d) for capture preset %u", __func__, role, audioSource);
+ return NAME_NOT_FOUND;
+ }
+
+ devices = devIt->second;
+ } break;
+ case DEVICE_ROLE_NONE:
+ // Intentionally fall-through as the DEVICE_ROLE_NONE is never set
+ default:
+ ALOGE("%s invalid role %d", __func__, role);
+ return BAD_VALUE;
+ }
+ return NO_ERROR;
+}
+
void EngineBase::dump(String8 *dst) const
{
mProductStrategies.dump(dst, 2);
diff --git a/services/audiopolicy/engine/interface/EngineInterface.h b/services/audiopolicy/engine/interface/EngineInterface.h
index d45e71c..f64608d 100644
--- a/services/audiopolicy/engine/interface/EngineInterface.h
+++ b/services/audiopolicy/engine/interface/EngineInterface.h
@@ -34,6 +34,8 @@
using DeviceStrategyMap = std::map<product_strategy_t, DeviceVector>;
using StrategyVector = std::vector<product_strategy_t>;
using VolumeGroupVector = std::vector<volume_group_t>;
+using CapturePresetDevicesRoleMap =
+ std::map<audio_source_t, std::map<device_role_t, AudioDeviceTypeAddrVector>>;
/**
* This interface is dedicated to the policy manager that a Policy Engine shall implement.
@@ -332,6 +334,75 @@
virtual status_t getDevicesForRoleAndStrategy(product_strategy_t strategy, device_role_t role,
AudioDeviceTypeAddrVector &devices) const = 0;
+ /**
+ * @brief setDevicesRoleForCapturePreset sets devices role for a capture preset when available.
+ * To remove devices role, removeDevicesRoleForCapturePreset must be called. Calling
+ * clearDevicesRoleForCapturePreset will remove all devices as role. When devices role is set
+ * successfully, previously set devices for the same role and capture preset will be removed.
+ * @param audioSource the audio capture preset whose routing will be affected
+ * @param role the role of the devices for the capture preset. All device roles are defined at
+ * system/media/audio/include/system/audio_policy.h. DEVICE_ROLE_NONE is invalid
+ * for setting.
+ * @param devices the audio devices to be set
+ * @return BAD_VALUE if the capture preset or role is invalid,
+ * or NO_ERROR if the role of the devices for capture preset was set
+ */
+ virtual status_t setDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
+
+ /**
+ * @brief addDevicesRoleForCapturePreset adds devices role for a capture preset when available.
+ * To remove devices role, removeDevicesRoleForCapturePreset must be called. Calling
+ * clearDevicesRoleForCapturePreset will remove all devices as role.
+ * @param audioSource the audio capture preset whose routing will be affected
+ * @param role the role of the devices for the capture preset. All device roles are defined at
+ * system/media/audio/include/system/audio_policy.h. DEVICE_ROLE_NONE is invalid
+ * for setting.
+ * @param devices the audio devices to be added
+ * @return BAD_VALUE if the capture preset or role is invalid,
+ * or NO_ERROR if the role of the devices for capture preset was added
+ */
+ virtual status_t addDevicesRoleForCapturePreset(audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector &devices) = 0;
+
+ /**
+ * @brief removeDevicesRoleForCapturePreset removes the role of device(s) previously set
+ * for the given capture preset
+ * @param audioSource the audio capture preset whose routing will be affected
+ * @param role the role of the devices for the capture preset
+ * @param devices the devices to be removed
+ * @return BAD_VALUE if 1) the capture preset is invalid, 2) role is invalid or 3) the list of
+ * devices to be removed are not all present as role for a capture preset
+ * or NO_ERROR if the devices for this role was removed
+ */
+ virtual status_t removeDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role, const AudioDeviceTypeAddrVector& devices) = 0;
+
+ /**
+ * @brief clearDevicesRoleForCapturePreset removes the role of all device(s) previously set
+ * for the given capture preset
+ * @param audioSource the audio capture preset whose routing will be affected
+ * @param role the role of the devices for the capture preset
+ * @return BAD_VALUE if the capture preset or role is invalid,
+ * or NO_ERROR if the devices for this role was removed
+ */
+ virtual status_t clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role);
+
+ /**
+ * @brief getDevicesForRoleAndCapturePreset queries which devices have the specified role for
+ * the specified capture preset
+ * @param audioSource the capture preset to query
+ * @param role the role of the devices to query
+ * @param devices returns list of devices with matching role for the specified capture preset.
+ * DEVICE_ROLE_NONE is invalid as input.
+ * @return BAD_VALUE if the capture preset or role is invalid,
+ * or NAME_NOT_FOUND if no device for the role and capture preset was set
+ * or NO_ERROR if the devices parameter contains a list of devices
+ */
+ virtual status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role, AudioDeviceTypeAddrVector &devices) const = 0;
+
virtual void dump(String8 *dst) const = 0;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 04c5cba..cb3725e 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -3115,7 +3115,7 @@
devices[i].mType, devices[i].getAddress(), String8(),
AUDIO_FORMAT_DEFAULT, false /*allowToCreate*/, true /*matchAddress*/);
if (devDesc == nullptr || (predicate != nullptr && !predicate(devices[i].mType))) {
- ALOGE("%s: device type %#x address %s not supported or not an output device",
+ ALOGE("%s: device type %#x address %s not supported or not match predicate",
context, devices[i].mType, devices[i].getAddress());
return false;
}
@@ -3223,6 +3223,72 @@
return mEngine->getDevicesForRoleAndStrategy(strategy, role, devices);
}
+status_t AudioPolicyManager::setDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector &devices) {
+ ALOGV("%s() audioSource=%d role=%d %s", __func__, audioSource, role,
+ dumpAudioDeviceTypeAddrVector(devices).c_str());
+
+ if (!areAllDevicesSupported(devices, audio_is_input_device, __func__)) {
+ return BAD_VALUE;
+ }
+ status_t status = mEngine->setDevicesRoleForCapturePreset(audioSource, role, devices);
+ ALOGW_IF(status != NO_ERROR,
+ "Engine could not set preferred devices %s for audio source %d role %d",
+ dumpAudioDeviceTypeAddrVector(devices).c_str(), audioSource, role);
+
+ return status;
+}
+
+status_t AudioPolicyManager::addDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector &devices) {
+ ALOGV("%s() audioSource=%d role=%d %s", __func__, audioSource, role,
+ dumpAudioDeviceTypeAddrVector(devices).c_str());
+
+ if (!areAllDevicesSupported(devices, audio_is_input_device, __func__)) {
+ return BAD_VALUE;
+ }
+ status_t status = mEngine->addDevicesRoleForCapturePreset(audioSource, role, devices);
+ ALOGW_IF(status != NO_ERROR,
+ "Engine could not add preferred devices %s for audio source %d role %d",
+ dumpAudioDeviceTypeAddrVector(devices).c_str(), audioSource, role);
+
+ return status;
+}
+
+status_t AudioPolicyManager::removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector& devices)
+{
+ ALOGV("%s() audioSource=%d role=%d devices=%s", __func__, audioSource, role,
+ dumpAudioDeviceTypeAddrVector(devices).c_str());
+
+ if (!areAllDevicesSupported(devices, audio_is_input_device, __func__)) {
+ return BAD_VALUE;
+ }
+
+ status_t status = mEngine->removeDevicesRoleForCapturePreset(
+ audioSource, role, devices);
+ ALOGW_IF(status != NO_ERROR,
+ "Engine could not remove devices role (%d) for capture preset %d", role, audioSource);
+
+ return status;
+}
+
+status_t AudioPolicyManager::clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role) {
+ ALOGV("%s() audioSource=%d role=%d", __func__, audioSource, role);
+
+ status_t status = mEngine->clearDevicesRoleForCapturePreset(audioSource, role);
+ ALOGW_IF(status != NO_ERROR,
+ "Engine could not clear devices role (%d) for capture preset %d", role, audioSource);
+
+ return status;
+}
+
+status_t AudioPolicyManager::getDevicesForRoleAndCapturePreset(
+ audio_source_t audioSource, device_role_t role, AudioDeviceTypeAddrVector &devices) {
+ return mEngine->getDevicesForRoleAndCapturePreset(audioSource, role, devices);
+}
+
status_t AudioPolicyManager::setUserIdDeviceAffinities(int userId,
const AudioDeviceTypeAddrVector& devices) {
ALOGI("%s() userId=%d num devices %zu", __func__, userId, devices.size());
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 11077f1..217013f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -281,6 +281,25 @@
device_role_t role,
AudioDeviceTypeAddrVector &devices);
+ virtual status_t setDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices);
+
+ virtual status_t addDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices);
+
+ virtual status_t removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector& devices);
+
+ virtual status_t clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role);
+
+ virtual status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices);
+
virtual status_t startAudioSource(const struct audio_port_config *source,
const audio_attributes_t *attributes,
audio_port_handle_t *portId,
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 7d1ad63..14e5236 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -1534,4 +1534,55 @@
return NO_ERROR;
}
+status_t AudioPolicyService::setDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector &devices)
+{
+ if (mAudioPolicyManager == nullptr) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->setDevicesRoleForCapturePreset(audioSource, role, devices);
+}
+
+status_t AudioPolicyService::addDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector &devices)
+{
+ if (mAudioPolicyManager == nullptr) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->addDevicesRoleForCapturePreset(audioSource, role, devices);
+}
+
+status_t AudioPolicyService::removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role, const AudioDeviceTypeAddrVector& devices)
+{
+ if (mAudioPolicyManager == nullptr) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->removeDevicesRoleForCapturePreset(audioSource, role, devices);
+}
+
+status_t AudioPolicyService::clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role)
+{
+ if (mAudioPolicyManager == nullptr) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->clearDevicesRoleForCapturePreset(audioSource, role);
+}
+
+status_t AudioPolicyService::getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices)
+{
+ if (mAudioPolicyManager == nullptr) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ return mAudioPolicyManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices);
+}
+
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index a851863..0b218c2 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -240,6 +240,25 @@
device_role_t role,
AudioDeviceTypeAddrVector &devices);
+ virtual status_t setDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices);
+
+ virtual status_t addDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ const AudioDeviceTypeAddrVector &devices);
+
+ virtual status_t removeDevicesRoleForCapturePreset(
+ audio_source_t audioSource, device_role_t role,
+ const AudioDeviceTypeAddrVector& devices);
+
+ virtual status_t clearDevicesRoleForCapturePreset(audio_source_t audioSource,
+ device_role_t role);
+
+ virtual status_t getDevicesForRoleAndCapturePreset(audio_source_t audioSource,
+ device_role_t role,
+ AudioDeviceTypeAddrVector &devices);
+
virtual status_t setUserIdDeviceAffinities(int userId,
const AudioDeviceTypeAddrVector& devices);
diff --git a/services/audiopolicy/tests/Android.bp b/services/audiopolicy/tests/Android.bp
index efdb241..ca03e1f 100644
--- a/services/audiopolicy/tests/Android.bp
+++ b/services/audiopolicy/tests/Android.bp
@@ -18,7 +18,10 @@
"libxml2",
],
- static_libs: ["libaudiopolicycomponents"],
+ static_libs: [
+ "libaudiopolicycomponents",
+ "libgmock"
+ ],
header_libs: [
"libaudiopolicycommon",
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index a0074bc..ed9ec8c 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -20,6 +20,7 @@
#include <unistd.h>
#include <gtest/gtest.h>
+#include <gmock/gmock.h>
#define LOG_TAG "APM_Test"
#include <Serializer.h>
@@ -36,6 +37,7 @@
#include "AudioPolicyTestManager.h"
using namespace android;
+using testing::UnorderedElementsAre;
TEST(AudioPolicyManagerTestInit, EngineFailure) {
AudioPolicyTestClient client;
@@ -1188,3 +1190,109 @@
EXPECT_GT(mClient->getAudioPortListUpdateCount(), prevAudioPortListUpdateCount);
EXPECT_GT(mManager->getAudioPortGeneration(), prevAudioPortGeneration);
}
+
+using DevicesRoleForCapturePresetParam = std::tuple<audio_source_t, device_role_t>;
+
+class AudioPolicyManagerDevicesRoleForCapturePresetTest
+ : public AudioPolicyManagerTestWithConfigurationFile,
+ public testing::WithParamInterface<DevicesRoleForCapturePresetParam> {
+protected:
+ // The `inputDevice` and `inputDevice2` indicate the audio devices type to be used for setting
+ // device role. They must be declared in the test_audio_policy_configuration.xml
+ AudioDeviceTypeAddr inputDevice = AudioDeviceTypeAddr(AUDIO_DEVICE_IN_BUILTIN_MIC, "");
+ AudioDeviceTypeAddr inputDevice2 = AudioDeviceTypeAddr(AUDIO_DEVICE_IN_HDMI, "");
+};
+
+TEST_P(AudioPolicyManagerDevicesRoleForCapturePresetTest, DevicesRoleForCapturePreset) {
+ const audio_source_t audioSource = std::get<0>(GetParam());
+ const device_role_t role = std::get<1>(GetParam());
+
+ // Test invalid device when setting
+ const AudioDeviceTypeAddr outputDevice(AUDIO_DEVICE_OUT_SPEAKER, "");
+ const AudioDeviceTypeAddrVector outputDevices = {outputDevice};
+ ASSERT_EQ(BAD_VALUE,
+ mManager->setDevicesRoleForCapturePreset(audioSource, role, outputDevices));
+ ASSERT_EQ(BAD_VALUE,
+ mManager->addDevicesRoleForCapturePreset(audioSource, role, outputDevices));
+ AudioDeviceTypeAddrVector devices;
+ ASSERT_EQ(NAME_NOT_FOUND,
+ mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ ASSERT_TRUE(devices.empty());
+ ASSERT_EQ(BAD_VALUE,
+ mManager->removeDevicesRoleForCapturePreset(audioSource, role, outputDevices));
+
+ // Without setting, call get/remove/clear must fail
+ ASSERT_EQ(NAME_NOT_FOUND,
+ mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ ASSERT_EQ(NAME_NOT_FOUND,
+ mManager->removeDevicesRoleForCapturePreset(audioSource, role, devices));
+ ASSERT_EQ(NAME_NOT_FOUND,
+ mManager->clearDevicesRoleForCapturePreset(audioSource, role));
+
+ // Test set/get devices role
+ const AudioDeviceTypeAddrVector inputDevices = {inputDevice};
+ ASSERT_EQ(NO_ERROR,
+ mManager->setDevicesRoleForCapturePreset(audioSource, role, inputDevices));
+ ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_THAT(devices, UnorderedElementsAre(inputDevice));
+
+ // Test setting will change the previously set devices
+ const AudioDeviceTypeAddrVector inputDevices2 = {inputDevice2};
+ ASSERT_EQ(NO_ERROR,
+ mManager->setDevicesRoleForCapturePreset(audioSource, role, inputDevices2));
+ devices.clear();
+ ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_THAT(devices, UnorderedElementsAre(inputDevice2));
+
+ // Test add devices
+ ASSERT_EQ(NO_ERROR,
+ mManager->addDevicesRoleForCapturePreset(audioSource, role, inputDevices));
+ devices.clear();
+ ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_THAT(devices, UnorderedElementsAre(inputDevice, inputDevice2));
+
+ // Test remove devices
+ ASSERT_EQ(NO_ERROR,
+ mManager->removeDevicesRoleForCapturePreset(audioSource, role, inputDevices));
+ devices.clear();
+ ASSERT_EQ(NO_ERROR, mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+ EXPECT_THAT(devices, UnorderedElementsAre(inputDevice2));
+
+ // Test remove devices that are not set as the device role
+ ASSERT_EQ(BAD_VALUE,
+ mManager->removeDevicesRoleForCapturePreset(audioSource, role, inputDevices));
+
+ // Test clear devices
+ ASSERT_EQ(NO_ERROR,
+ mManager->clearDevicesRoleForCapturePreset(audioSource, role));
+ devices.clear();
+ ASSERT_EQ(NAME_NOT_FOUND,
+ mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
+}
+
+INSTANTIATE_TEST_CASE_P(
+ DevicesRoleForCapturePresetOperation,
+ AudioPolicyManagerDevicesRoleForCapturePresetTest,
+ testing::Values(
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_MIC, DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_UPLINK,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_DOWNLINK,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_CALL, DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_CAMCORDER, DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_RECOGNITION,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_COMMUNICATION,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_REMOTE_SUBMIX,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_UNPROCESSED, DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_VOICE_PERFORMANCE,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_ECHO_REFERENCE,
+ DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_FM_TUNER, DEVICE_ROLE_PREFERRED}),
+ DevicesRoleForCapturePresetParam({AUDIO_SOURCE_HOTWORD, DEVICE_ROLE_PREFERRED})
+ )
+ );