Merge "CodecListTest is not part of MTS" into udc-dev
diff --git a/media/codec2/TEST_MAPPING b/media/codec2/TEST_MAPPING
index 90bb054..8a894f3 100644
--- a/media/codec2/TEST_MAPPING
+++ b/media/codec2/TEST_MAPPING
@@ -8,17 +8,6 @@
],
"presubmit-large": [
{
- "name": "CtsMediaMiscTestCases",
- "options": [
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
- "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
- }
- ]
- },
- {
"name": "CtsMediaAudioTestCases",
"options": [
{
@@ -35,50 +24,6 @@
"exclude-filter": "android.media.audio.cts.AudioRecordTest"
}
]
- },
- {
- "name": "CtsMediaDecoderTestCases",
- "options": [
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
- "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
- }
- ]
- },
- {
- "name": "CtsMediaEncoderTestCases",
- "options": [
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
- "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
- }
- ]
- },
- {
- "name": "CtsMediaCodecTestCases",
- "options": [
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
- "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
- }
- ]
- },
- {
- "name": "CtsMediaPlayerTestCases",
- "options": [
- {
- "include-annotation": "android.platform.test.annotations.Presubmit"
- },
- {
- "exclude-annotation": "android.platform.test.annotations.RequiresDevice"
- }
- ]
}
]
}
diff --git a/media/codec2/components/aom/C2SoftAomEnc.cpp b/media/codec2/components/aom/C2SoftAomEnc.cpp
index d147fb4..81c593f 100644
--- a/media/codec2/components/aom/C2SoftAomEnc.cpp
+++ b/media/codec2/components/aom/C2SoftAomEnc.cpp
@@ -799,6 +799,28 @@
}
break;
}
+ case C2PlanarLayout::TYPE_YUVA: {
+ if (mConversionBuffer.size() >= stride * vstride * 3) {
+ uint16_t *dstY, *dstU, *dstV;
+ dstY = (uint16_t*)mConversionBuffer.data();
+ dstU = dstY + stride * vstride;
+ dstV = dstU + (stride * vstride) / 4;
+ convertRGBA1010102ToYUV420Planar16(dstY, dstU, dstV, (uint32_t*)(rView->data()[0]),
+ layout.planes[layout.PLANE_Y].rowInc / 4, stride,
+ vstride, mColorAspects->matrix,
+ mColorAspects->range);
+ aom_img_wrap(&raw_frame, AOM_IMG_FMT_I42016, stride, vstride, mStrideAlign,
+ mConversionBuffer.data());
+ aom_img_set_rect(&raw_frame, 0, 0, width, height, 0);
+ } else {
+ ALOGE("Conversion buffer is too small: %u x %u for %zu", stride, vstride,
+ mConversionBuffer.size());
+ work->result = C2_BAD_VALUE;
+ return;
+ }
+ break;
+ }
+
default:
ALOGE("Unrecognized plane type: %d", layout.type);
work->result = C2_BAD_VALUE;
diff --git a/media/codec2/components/base/SimpleC2Component.cpp b/media/codec2/components/base/SimpleC2Component.cpp
index 32f8fa8..55a1164 100644
--- a/media/codec2/components/base/SimpleC2Component.cpp
+++ b/media/codec2/components/base/SimpleC2Component.cpp
@@ -452,6 +452,60 @@
}
}
+static const int16_t bt709Matrix_10bit[2][3][3] = {
+ { { 218, 732, 74 }, { -117, -395, 512 }, { 512, -465, -47 } }, /* RANGE_FULL */
+ { { 186, 627, 63 }, { -103, -345, 448 }, { 448, -407, -41 } }, /* RANGE_LIMITED */
+};
+
+static const int16_t bt2020Matrix_10bit[2][3][3] = {
+ { { 269, 694, 61 }, { -143, -369, 512 }, { 512, -471, -41 } }, /* RANGE_FULL */
+ { { 230, 594, 52 }, { -125, -323, 448 }, { 448, -412, -36 } }, /* RANGE_LIMITED */
+};
+
+void convertRGBA1010102ToYUV420Planar16(uint16_t* dstY, uint16_t* dstU, uint16_t* dstV,
+ const uint32_t* srcRGBA, size_t srcRGBStride, size_t width,
+ size_t height, C2Color::matrix_t colorMatrix,
+ C2Color::range_t colorRange) {
+ uint16_t r, g, b;
+ int32_t i32Y, i32U, i32V;
+ uint16_t zeroLvl = colorRange == C2Color::RANGE_FULL ? 0 : 64;
+ uint16_t maxLvlLuma = colorRange == C2Color::RANGE_FULL ? 1023 : 940;
+ uint16_t maxLvlChroma = colorRange == C2Color::RANGE_FULL ? 1023 : 960;
+ // set default range as limited
+ if (colorRange != C2Color::RANGE_FULL) {
+ colorRange = C2Color::RANGE_LIMITED;
+ }
+ const int16_t(*weights)[3] = (colorMatrix == C2Color::MATRIX_BT709)
+ ? bt709Matrix_10bit[colorRange - 1]
+ : bt2020Matrix_10bit[colorRange - 1];
+
+ for (size_t y = 0; y < height; ++y) {
+ for (size_t x = 0; x < width; ++x) {
+ b = (srcRGBA[x] >> 20) & 0x3FF;
+ g = (srcRGBA[x] >> 10) & 0x3FF;
+ r = srcRGBA[x] & 0x3FF;
+
+ i32Y = ((r * weights[0][0] + g * weights[0][1] + b * weights[0][2] + 512) >> 10) +
+ zeroLvl;
+ dstY[x] = CLIP3(zeroLvl, i32Y, maxLvlLuma);
+ if (y % 2 == 0 && x % 2 == 0) {
+ i32U = ((r * weights[1][0] + g * weights[1][1] + b * weights[1][2] + 512) >> 10) +
+ 512;
+ i32V = ((r * weights[2][0] + g * weights[2][1] + b * weights[2][2] + 512) >> 10) +
+ 512;
+ dstU[x >> 1] = CLIP3(zeroLvl, i32U, maxLvlChroma);
+ dstV[x >> 1] = CLIP3(zeroLvl, i32V, maxLvlChroma);
+ }
+ }
+ srcRGBA += srcRGBStride;
+ dstY += width;
+ if (y % 2 == 0) {
+ dstU += width / 2;
+ dstV += width / 2;
+ }
+ }
+}
+
std::unique_ptr<C2Work> SimpleC2Component::WorkQueue::pop_front() {
std::unique_ptr<C2Work> work = std::move(mQueue.front().work);
mQueue.pop_front();
diff --git a/media/codec2/components/base/include/SimpleC2Component.h b/media/codec2/components/base/include/SimpleC2Component.h
index 051f798..bc27474 100644
--- a/media/codec2/components/base/include/SimpleC2Component.h
+++ b/media/codec2/components/base/include/SimpleC2Component.h
@@ -21,6 +21,7 @@
#include <unordered_map>
#include <C2Component.h>
+#include <C2Config.h>
#include <media/stagefright/foundation/AHandler.h>
#include <media/stagefright/foundation/ALooper.h>
@@ -61,6 +62,11 @@
size_t dstUStride, size_t dstVStride, size_t width,
size_t height, bool isMonochrome = false);
+void convertRGBA1010102ToYUV420Planar16(uint16_t* dstY, uint16_t* dstU, uint16_t* dstV,
+ const uint32_t* srcRGBA, size_t srcRGBStride, size_t width,
+ size_t height, C2Color::matrix_t colorMatrix,
+ C2Color::range_t colorRange);
+
class SimpleC2Component
: public C2Component, public std::enable_shared_from_this<SimpleC2Component> {
public:
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 05c4dde..4955e13 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -884,6 +884,16 @@
if (msg->findInt32(KEY_PUSH_BLANK_BUFFERS_ON_STOP, &pushBlankBuffersOnStop)) {
config->mPushBlankBuffersOnStop = pushBlankBuffersOnStop == 1;
}
+ // secure compoment or protected content default with
+ // "push-blank-buffers-on-shutdown" flag
+ if (!config->mPushBlankBuffersOnStop) {
+ int32_t usageProtected;
+ if (comp->getName().find(".secure") != std::string::npos) {
+ config->mPushBlankBuffersOnStop = true;
+ } else if (msg->findInt32("protected", &usageProtected) && usageProtected) {
+ config->mPushBlankBuffersOnStop = true;
+ }
+ }
}
}
setSurface(surface);
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index 9d67b67..04b7008 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -21,8 +21,11 @@
#include <cstdint>
#include <audio_utils/clock.h>
+#include <media/AidlConversionCppNdk.h>
#include <media/AidlConversionUtil.h>
+#include <media/AudioParameter.h>
#include <mediautils/TimeCheck.h>
+#include <system/audio.h>
#include <utils/Log.h>
#include "DeviceHalAidl.h"
@@ -33,6 +36,7 @@
using ::aidl::android::hardware::audio::core::IStreamIn;
using ::aidl::android::hardware::audio::core::IStreamOut;
using ::aidl::android::hardware::audio::core::StreamDescriptor;
+using ::aidl::android::legacy2aidl_audio_channel_mask_t_AudioChannelLayout;
namespace android {
@@ -483,7 +487,13 @@
const std::shared_ptr<IStreamOut>& stream, const sp<CallbackBroker>& callbackBroker)
: StreamHalAidl("StreamOutHalAidl", false /*isInput*/, config, nominalLatency,
std::move(context), getStreamCommon(stream)),
- mStream(stream), mCallbackBroker(callbackBroker) {}
+ mStream(stream), mCallbackBroker(callbackBroker) {
+ // Initialize the offload metadata
+ mOffloadMetadata.sampleRate = static_cast<int32_t>(config.sample_rate);
+ mOffloadMetadata.channelMask = VALUE_OR_FATAL(
+ legacy2aidl_audio_channel_mask_t_AudioChannelLayout(config.channel_mask, false));
+ mOffloadMetadata.averageBitRatePerSecond = static_cast<int32_t>(config.offload_info.bit_rate);
+}
StreamOutHalAidl::~StreamOutHalAidl() {
if (auto broker = mCallbackBroker.promote(); broker != nullptr) {
@@ -491,6 +501,19 @@
}
}
+status_t StreamOutHalAidl::setParameters(const String8& kvPairs) {
+ if (!mStream) return NO_INIT;
+
+ AudioParameter parameters(kvPairs);
+ ALOGD("%s parameters: %s", __func__, parameters.toString().c_str());
+
+ if (filterAndUpdateOffloadMetadata(parameters) != OK) {
+ ALOGW("%s filtering or updating offload metadata gets failed", __func__);
+ }
+
+ return StreamHalAidl::setParameters(parameters.toString());
+}
+
status_t StreamOutHalAidl::getLatency(uint32_t *latency) {
return StreamHalAidl::getLatency(latency);
}
@@ -693,6 +716,78 @@
return StreamHalAidl::exit();
}
+status_t StreamOutHalAidl::filterAndUpdateOffloadMetadata(AudioParameter ¶meters) {
+ TIME_CHECK();
+
+ if (parameters.containsKey(String8(AudioParameter::keyOffloadCodecAverageBitRate)) ||
+ parameters.containsKey(String8(AudioParameter::keyOffloadCodecSampleRate)) ||
+ parameters.containsKey(String8(AudioParameter::keyOffloadCodecChannels)) ||
+ parameters.containsKey(String8(AudioParameter::keyOffloadCodecDelaySamples)) ||
+ parameters.containsKey(String8(AudioParameter::keyOffloadCodecPaddingSamples))) {
+ int value = 0;
+ if (parameters.getInt(String8(AudioParameter::keyOffloadCodecAverageBitRate), value)
+ == NO_ERROR) {
+ if (value <= 0) {
+ return BAD_VALUE;
+ }
+ mOffloadMetadata.averageBitRatePerSecond = value;
+ parameters.remove(String8(AudioParameter::keyOffloadCodecAverageBitRate));
+ }
+
+ if (parameters.getInt(String8(AudioParameter::keyOffloadCodecSampleRate), value)
+ == NO_ERROR) {
+ if (value <= 0) {
+ return BAD_VALUE;
+ }
+ mOffloadMetadata.sampleRate = value;
+ parameters.remove(String8(AudioParameter::keyOffloadCodecSampleRate));
+ }
+
+ if (parameters.getInt(String8(AudioParameter::keyOffloadCodecChannels), value)
+ == NO_ERROR) {
+ if (value <= 0) {
+ return BAD_VALUE;
+ }
+ audio_channel_mask_t channel_mask =
+ audio_channel_out_mask_from_count(static_cast<uint32_t>(value));
+ if (channel_mask == AUDIO_CHANNEL_INVALID) {
+ return BAD_VALUE;
+ }
+ mOffloadMetadata.channelMask =
+ VALUE_OR_RETURN_STATUS(legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
+ channel_mask, false));
+ parameters.remove(String8(AudioParameter::keyOffloadCodecChannels));
+ }
+
+ // The legacy keys are misnamed. The delay and padding are in frame.
+ if (parameters.getInt(String8(AudioParameter::keyOffloadCodecDelaySamples), value)
+ == NO_ERROR) {
+ if (value < 0) {
+ return BAD_VALUE;
+ }
+ mOffloadMetadata.delayFrames = value;
+ parameters.remove(String8(AudioParameter::keyOffloadCodecDelaySamples));
+ }
+
+ if (parameters.getInt(String8(AudioParameter::keyOffloadCodecPaddingSamples), value)
+ == NO_ERROR) {
+ if (value < 0) {
+ return BAD_VALUE;
+ }
+ mOffloadMetadata.paddingFrames = value;
+ parameters.remove(String8(AudioParameter::keyOffloadCodecPaddingSamples));
+ }
+
+ ALOGD("%s set offload metadata %s", __func__, mOffloadMetadata.toString().c_str());
+ status_t status = statusTFromBinderStatus(mStream->updateOffloadMetadata(mOffloadMetadata));
+ if (status != OK) {
+ ALOGE("%s: updateOffloadMetadata failed %d", __func__, status);
+ return status;
+ }
+ }
+ return OK;
+}
+
StreamInHalAidl::StreamInHalAidl(
const audio_config& config, StreamContextAidl&& context, int32_t nominalLatency,
const std::shared_ptr<IStreamIn>& stream)
diff --git a/media/libaudiohal/impl/StreamHalAidl.h b/media/libaudiohal/impl/StreamHalAidl.h
index d00774c..8e59513 100644
--- a/media/libaudiohal/impl/StreamHalAidl.h
+++ b/media/libaudiohal/impl/StreamHalAidl.h
@@ -21,16 +21,20 @@
#include <mutex>
#include <string_view>
+#include <aidl/android/hardware/audio/common/AudioOffloadMetadata.h>
#include <aidl/android/hardware/audio/core/BpStreamCommon.h>
#include <aidl/android/hardware/audio/core/BpStreamIn.h>
#include <aidl/android/hardware/audio/core/BpStreamOut.h>
#include <fmq/AidlMessageQueue.h>
#include <media/audiohal/EffectHalInterface.h>
#include <media/audiohal/StreamHalInterface.h>
+#include <media/AudioParameter.h>
#include "ConversionHelperAidl.h"
#include "StreamPowerLog.h"
+using ::aidl::android::hardware::audio::common::AudioOffloadMetadata;
+
namespace android {
class StreamContextAidl {
@@ -230,6 +234,9 @@
class StreamOutHalAidl : public StreamOutHalInterface, public StreamHalAidl {
public:
+ // Extract the output stream parameters and set by AIDL APIs.
+ status_t setParameters(const String8& kvPairs) override;
+
// Return the audio hardware driver estimated latency in milliseconds.
status_t getLatency(uint32_t *latency) override;
@@ -309,6 +316,8 @@
const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut> mStream;
const wp<CallbackBroker> mCallbackBroker;
+ AudioOffloadMetadata mOffloadMetadata;
+
// Can not be constructed directly by clients.
StreamOutHalAidl(
const audio_config& config, StreamContextAidl&& context, int32_t nominalLatency,
@@ -316,6 +325,10 @@
const sp<CallbackBroker>& callbackBroker);
~StreamOutHalAidl() override;
+
+ // Filter and update the offload metadata. The parameters which are related to the offload
+ // metadata will be removed after filtering.
+ status_t filterAndUpdateOffloadMetadata(AudioParameter ¶meters);
};
class StreamInHalAidl : public StreamInHalInterface, public StreamHalAidl {
diff --git a/media/libmediahelper/AudioParameter.cpp b/media/libmediahelper/AudioParameter.cpp
index 382a920..9a8156e 100644
--- a/media/libmediahelper/AudioParameter.cpp
+++ b/media/libmediahelper/AudioParameter.cpp
@@ -61,6 +61,12 @@
AUDIO_PARAMETER_DEVICE_ADDITIONAL_OUTPUT_DELAY;
const char * const AudioParameter::keyMaxAdditionalOutputDeviceDelay =
AUDIO_PARAMETER_DEVICE_MAX_ADDITIONAL_OUTPUT_DELAY;
+const char * const AudioParameter::keyOffloadCodecAverageBitRate = AUDIO_OFFLOAD_CODEC_AVG_BIT_RATE;
+const char * const AudioParameter::keyOffloadCodecSampleRate = AUDIO_OFFLOAD_CODEC_SAMPLE_RATE;
+const char * const AudioParameter::keyOffloadCodecChannels = AUDIO_OFFLOAD_CODEC_NUM_CHANNEL;
+const char * const AudioParameter::keyOffloadCodecDelaySamples = AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES;
+const char * const AudioParameter::keyOffloadCodecPaddingSamples =
+ AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES;
AudioParameter::AudioParameter(const String8& keyValuePairs)
{
@@ -226,4 +232,9 @@
}
}
+bool AudioParameter::containsKey(const String8& key) const
+{
+ return mParameters.indexOfKey(key) >= 0;
+}
+
} // namespace android
diff --git a/media/libmediahelper/include/media/AudioParameter.h b/media/libmediahelper/include/media/AudioParameter.h
index 9a6ca8a..350f472 100644
--- a/media/libmediahelper/include/media/AudioParameter.h
+++ b/media/libmediahelper/include/media/AudioParameter.h
@@ -107,6 +107,12 @@
static const char * const keyAdditionalOutputDeviceDelay;
static const char * const keyMaxAdditionalOutputDeviceDelay;
+ static const char * const keyOffloadCodecAverageBitRate;
+ static const char * const keyOffloadCodecSampleRate;
+ static const char * const keyOffloadCodecChannels;
+ static const char * const keyOffloadCodecDelaySamples;
+ static const char * const keyOffloadCodecPaddingSamples;
+
String8 toString() const { return toStringImpl(true); }
String8 keysToString() const { return toStringImpl(false); }
@@ -125,6 +131,7 @@
size_t size() const { return mParameters.size(); }
+ bool containsKey(const String8& key) const;
private:
String8 mKeyValuePairs;
KeyedVector <String8, String8> mParameters;
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index f2df7ac..a6821c7 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -479,6 +479,37 @@
return devices;
}
+DeviceVector Engine::getPreferredAvailableDevicesForInputSource(
+ const DeviceVector& availableInputDevices, audio_source_t inputSource) const {
+ DeviceVector preferredAvailableDevVec = {};
+ AudioDeviceTypeAddrVector preferredDevices;
+ const status_t status = getDevicesForRoleAndCapturePreset(
+ inputSource, DEVICE_ROLE_PREFERRED, preferredDevices);
+ if (status == NO_ERROR) {
+ // Only use preferred devices when they are all available.
+ preferredAvailableDevVec =
+ availableInputDevices.getDevicesFromDeviceTypeAddrVec(preferredDevices);
+ if (preferredAvailableDevVec.size() == preferredDevices.size()) {
+ ALOGVV("%s using pref device %s for source %u",
+ __func__, preferredAvailableDevVec.toString().c_str(), inputSource);
+ return preferredAvailableDevVec;
+ }
+ }
+ return preferredAvailableDevVec;
+}
+
+DeviceVector Engine::getDisabledDevicesForInputSource(
+ const DeviceVector& availableInputDevices, audio_source_t inputSource) const {
+ DeviceVector disabledDevices = {};
+ AudioDeviceTypeAddrVector disabledDevicesTypeAddr;
+ const status_t status = getDevicesForRoleAndCapturePreset(
+ inputSource, DEVICE_ROLE_DISABLED, disabledDevicesTypeAddr);
+ if (status == NO_ERROR) {
+ disabledDevices =
+ availableInputDevices.getDevicesFromDeviceTypeAddrVec(disabledDevicesTypeAddr);
+ }
+ return disabledDevices;
+}
sp<DeviceDescriptor> Engine::getDeviceForInputSource(audio_source_t inputSource) const
{
@@ -510,6 +541,20 @@
}
}
+ // Use the preferred device for the input source if it is available.
+ DeviceVector preferredInputDevices = getPreferredAvailableDevicesForInputSource(
+ availableDevices, inputSource);
+ if (!preferredInputDevices.isEmpty()) {
+ // Currently, only support single device for input. The public JAVA API also only
+ // support setting single device as preferred device. In that case, returning the
+ // first device is OK here.
+ return preferredInputDevices[0];
+ }
+ // Remove the disabled device for the input source from the available input device list.
+ DeviceVector disabledInputDevices = getDisabledDevicesForInputSource(
+ availableDevices, inputSource);
+ availableDevices.remove(disabledInputDevices);
+
audio_devices_t commDeviceType =
getPreferredDeviceTypeForLegacyStrategy(availableOutputDevices, STRATEGY_PHONE);
diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h
index ab556ee..e27a03b 100644
--- a/services/audiopolicy/enginedefault/src/Engine.h
+++ b/services/audiopolicy/enginedefault/src/Engine.h
@@ -99,6 +99,10 @@
const DeviceVector& availableOutputDevices, product_strategy_t strategy) const;
DeviceVector getDisabledDevicesForProductStrategy(
const DeviceVector& availableOutputDevices, product_strategy_t strategy) const;
+ DeviceVector getPreferredAvailableDevicesForInputSource(
+ const DeviceVector& availableInputDevices, audio_source_t inputSource) const;
+ DeviceVector getDisabledDevicesForInputSource(
+ const DeviceVector& availableInputDevices, audio_source_t inputSource) const;
DeviceStrategyMap mDevicesForStrategies;
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index ef829e1..ed77936 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -2833,6 +2833,108 @@
mManager->getDevicesForRoleAndCapturePreset(audioSource, role, devices));
}
+TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, PreferredDeviceUsedForInput) {
+ const audio_source_t source = AUDIO_SOURCE_MIC;
+ const device_role_t role = DEVICE_ROLE_PREFERRED;
+ const std::string address = "card=1;device=0";
+ const std::string deviceName = "randomName";
+
+ ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
+ AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+ address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
+ auto availableDevices = mManager->getAvailableInputDevices();
+ ASSERT_GT(availableDevices.size(), 1);
+
+ audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
+ attr.source = source;
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ 48000));
+ auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId);
+ ASSERT_NE(nullptr, selectedDevice);
+
+ sp<DeviceDescriptor> preferredDevice = nullptr;
+ for (const auto& device : availableDevices) {
+ if (device != selectedDevice) {
+ preferredDevice = device;
+ break;
+ }
+ }
+ ASSERT_NE(nullptr, preferredDevice);
+ // After setting preferred device for capture preset, the selected device for input should be
+ // the preferred device.
+ ASSERT_EQ(NO_ERROR,
+ mManager->setDevicesRoleForCapturePreset(source, role,
+ {preferredDevice->getDeviceTypeAddr()}));
+ selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ 48000));
+ ASSERT_EQ(preferredDevice, availableDevices.getDeviceFromId(selectedDeviceId));
+
+ // After clearing preferred device for capture preset, the selected device for input should be
+ // the same as original one.
+ ASSERT_EQ(NO_ERROR,
+ mManager->clearDevicesRoleForCapturePreset(source, role));
+ selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ 48000));
+ ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));
+
+ ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
+ AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
+}
+
+TEST_F(AudioPolicyManagerDevicesRoleForCapturePresetTest, DisabledDeviceNotUsedForInput) {
+ const audio_source_t source = AUDIO_SOURCE_MIC;
+ const device_role_t role = DEVICE_ROLE_DISABLED;
+ const std::string address = "card=1;device=0";
+ const std::string deviceName = "randomName";
+
+ ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
+ AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
+ address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
+ auto availableDevices = mManager->getAvailableInputDevices();
+ ASSERT_GT(availableDevices.size(), 1);
+
+ audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
+ attr.source = source;
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ 48000));
+ auto selectedDevice = availableDevices.getDeviceFromId(selectedDeviceId);
+ ASSERT_NE(nullptr, selectedDevice);
+
+ // After setting disabled device for capture preset, the disabled device must not be
+ // selected for input.
+ ASSERT_EQ(NO_ERROR,
+ mManager->setDevicesRoleForCapturePreset(source, role,
+ {selectedDevice->getDeviceTypeAddr()}));
+ selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ 48000));
+ ASSERT_NE(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));
+
+ // After clearing disabled device for capture preset, the selected device for input should be
+ // the original one.
+ ASSERT_EQ(NO_ERROR,
+ mManager->clearDevicesRoleForCapturePreset(source, role));
+ selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ ASSERT_NO_FATAL_FAILURE(getInputForAttr(attr, AUDIO_SESSION_NONE, 1, &selectedDeviceId,
+ AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_STEREO,
+ 48000));
+ ASSERT_EQ(selectedDevice, availableDevices.getDeviceFromId(selectedDeviceId));
+
+ ASSERT_EQ(NO_ERROR, mManager->setDeviceConnectionState(
+ AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
+ address.c_str(), deviceName.c_str(), AUDIO_FORMAT_DEFAULT));
+}
+
INSTANTIATE_TEST_CASE_P(
DevicesRoleForCapturePresetOperation,
AudioPolicyManagerDevicesRoleForCapturePresetTest,
diff --git a/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml b/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
index 2eb771d..50ca26a 100644
--- a/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
+++ b/services/audiopolicy/tests/resources/test_audio_policy_configuration.xml
@@ -77,12 +77,14 @@
</devicePort>
<devicePort tagName="USB Device Out" type="AUDIO_DEVICE_OUT_USB_DEVICE" role="sink">
</devicePort>
+ <devicePort tagName="USB Device In" type="AUDIO_DEVICE_IN_USB_DEVICE" role="source">
+ </devicePort>
</devicePorts>
<routes>
<route type="mix" sink="Speaker"
sources="primary output,voip_rx"/>
<route type="mix" sink="primary input"
- sources="Built-In Mic,Hdmi-In Mic"/>
+ sources="Built-In Mic,Hdmi-In Mic,USB Device In"/>
<route type="mix" sink="voip_tx"
sources="Built-In Mic"/>
<route type="mix" sink="Hdmi"
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index 78e5270..7f228c7 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -105,7 +105,7 @@
while (true) {
if (formatsTried.find(audioFormat) != formatsTried.end()) {
// APM returning something that has already tried.
- ALOGW("Have already tried to open #x, but failed before");
+ ALOGW("Have already tried to open with format=%#x, but failed before", audioFormat);
break;
}
formatsTried.insert(audioFormat);
@@ -195,7 +195,7 @@
// not match the hardware.
ALOGD("%s() - openMmapStream() returned status=%d, suggested format=%#x, sample_rate=%u, "
"channel_mask=%#x",
- __func__, status, config.format, config.sample_rate, config.format);
+ __func__, status, config.format, config.sample_rate, config.channel_mask);
*nextFormatToTry = config.format != audioFormat ? config.format
: *nextFormatToTry;
return AAUDIO_ERROR_UNAVAILABLE;