Merge "audio HAL: Support for external device connections"
diff --git a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
index dfc2386..505c54c 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -14,7 +14,11 @@
* limitations under the License.
*/
+#include <fstream>
+#include <numeric>
+
#include <android-base/chrono_utils.h>
+#include <cutils/properties.h>
#include "Generators.h"
@@ -517,20 +521,10 @@
}
bool canQueryPresentationPosition() const {
- auto maybeSinkAddress =
- getCachedPolicyConfig().getSinkDeviceForMixPort(getDeviceName(), getMixPortName());
- // Returning 'true' when no sink is found so the test can fail later with a more clear
- // problem description.
- return !maybeSinkAddress.has_value() ||
- !xsd::isTelephonyDevice(maybeSinkAddress.value().deviceType);
+ return !xsd::isTelephonyDevice(address.deviceType);
}
void createPatchIfNeeded() {
- auto maybeSinkAddress =
- getCachedPolicyConfig().getSinkDeviceForMixPort(getDeviceName(), getMixPortName());
- ASSERT_TRUE(maybeSinkAddress.has_value())
- << "No sink device found for mix port " << getMixPortName() << " (module "
- << getDeviceName() << ")";
if (areAudioPatchesSupported()) {
AudioPortConfig source;
source.base.format.value(getConfig().base.format);
@@ -540,13 +534,13 @@
source.ext.mix().ioHandle = helper.getIoHandle();
source.ext.mix().useCase.stream({});
AudioPortConfig sink;
- sink.ext.device(maybeSinkAddress.value());
+ sink.ext.device(address);
EXPECT_OK(getDevice()->createAudioPatch(hidl_vec<AudioPortConfig>{source},
hidl_vec<AudioPortConfig>{sink},
returnIn(res, mPatchHandle)));
mHasPatch = res == Result::OK;
} else {
- EXPECT_OK(stream->setDevices({maybeSinkAddress.value()}));
+ EXPECT_OK(stream->setDevices({address}));
}
}
@@ -556,10 +550,6 @@
EXPECT_OK(getDevice()->releaseAudioPatch(mPatchHandle));
mHasPatch = false;
}
- } else {
- if (stream) {
- EXPECT_OK(stream->setDevices({address}));
- }
}
}
@@ -575,16 +565,22 @@
// Sometimes HAL doesn't have enough information until the audio data actually gets
// consumed by the hardware.
bool timedOut = false;
- res = Result::INVALID_STATE;
- for (android::base::Timer elapsed;
- res != Result::OK && !writer.hasError() &&
- !(timedOut = (elapsed.duration() >= kPositionChangeTimeout));) {
- usleep(kWriteDurationUs);
- ASSERT_OK(stream->getPresentationPosition(returnIn(res, framesInitial, ts)));
- ASSERT_RESULT(okOrInvalidState, res);
+ if (!firstPosition || *firstPosition == std::numeric_limits<uint64_t>::max()) {
+ res = Result::INVALID_STATE;
+ for (android::base::Timer elapsed;
+ res != Result::OK && !writer.hasError() &&
+ !(timedOut = (elapsed.duration() >= kPositionChangeTimeout));) {
+ usleep(kWriteDurationUs);
+ ASSERT_OK(stream->getPresentationPosition(returnIn(res, framesInitial, ts)));
+ ASSERT_RESULT(okOrInvalidState, res);
+ }
+ ASSERT_FALSE(writer.hasError());
+ ASSERT_FALSE(timedOut);
+ } else {
+ // Use `firstPosition` instead of querying it from the HAL. This is used when
+ // `waitForPresentationPositionAdvance` is called in a loop.
+ framesInitial = *firstPosition;
}
- ASSERT_FALSE(writer.hasError());
- ASSERT_FALSE(timedOut);
uint64_t frames = framesInitial;
for (android::base::Timer elapsed;
@@ -646,7 +642,7 @@
ASSERT_OK(stream->standby());
writer.resume();
- uint64_t frames;
+ uint64_t frames = std::numeric_limits<uint64_t>::max();
ASSERT_NO_FATAL_FAILURE(waitForPresentationPositionAdvance(writer, &frames));
EXPECT_GT(frames, framesInitial);
@@ -691,24 +687,12 @@
InputStreamTest::TearDown();
}
- bool canQueryCapturePosition() const {
- auto maybeSourceAddress = getCachedPolicyConfig().getSourceDeviceForMixPort(
- getDeviceName(), getMixPortName());
- // Returning 'true' when no source is found so the test can fail later with a more clear
- // problem description.
- return !maybeSourceAddress.has_value() ||
- !xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType);
- }
+ bool canQueryCapturePosition() const { return !xsd::isTelephonyDevice(address.deviceType); }
void createPatchIfNeeded() {
- auto maybeSourceAddress = getCachedPolicyConfig().getSourceDeviceForMixPort(
- getDeviceName(), getMixPortName());
- ASSERT_TRUE(maybeSourceAddress.has_value())
- << "No source device found for mix port " << getMixPortName() << " (module "
- << getDeviceName() << ")";
if (areAudioPatchesSupported()) {
AudioPortConfig source;
- source.ext.device(maybeSourceAddress.value());
+ source.ext.device(address);
AudioPortConfig sink;
sink.base.format.value(getConfig().base.format);
sink.base.sampleRateHz.value(getConfig().base.sampleRateHz);
@@ -721,7 +705,7 @@
returnIn(res, mPatchHandle)));
mHasPatch = res == Result::OK;
} else {
- EXPECT_OK(stream->setDevices({maybeSourceAddress.value()}));
+ EXPECT_OK(stream->setDevices({address}));
}
}
@@ -731,10 +715,6 @@
EXPECT_OK(getDevice()->releaseAudioPatch(mPatchHandle));
mHasPatch = false;
}
- } else {
- if (stream) {
- EXPECT_OK(stream->setDevices({address}));
- }
}
}
@@ -864,14 +844,8 @@
}
ASSERT_OK(res);
- auto maybeSourceAddress =
- getCachedPolicyConfig().getSourceDeviceForMixPort(getDeviceName(), getMixPortName());
- ASSERT_TRUE(maybeSourceAddress.has_value())
- << "No source device found for mix port " << getMixPortName() << " (module "
- << getDeviceName() << ")";
-
for (auto microphone : microphones) {
- if (microphone.deviceAddress == maybeSourceAddress.value()) {
+ if (microphone.deviceAddress == address) {
StreamReader reader(stream.get(), stream->getBufferSize());
ASSERT_TRUE(reader.start());
reader.pause(); // This ensures that at least one read has happened.
@@ -889,3 +863,176 @@
::testing::ValuesIn(getBuiltinMicConfigParameters()),
&DeviceConfigParameterToString);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MicrophoneInfoInputStreamTest);
+
+static const std::vector<DeviceConfigParameter>& getOutputDeviceCompressedConfigParameters(
+ const AudioConfigBase& configToMatch) {
+ static const std::vector<DeviceConfigParameter> parameters = [&] {
+ auto allParams = getOutputDeviceConfigParameters();
+ std::vector<DeviceConfigParameter> compressedParams;
+ std::copy_if(allParams.begin(), allParams.end(), std::back_inserter(compressedParams),
+ [&](auto cfg) {
+ if (std::get<PARAM_CONFIG>(cfg).base != configToMatch) return false;
+ const auto& flags = std::get<PARAM_FLAGS>(cfg);
+ return std::find_if(flags.begin(), flags.end(), [](const auto& flag) {
+ return flag ==
+ toString(xsd::AudioInOutFlag::
+ AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
+ }) != flags.end();
+ });
+ return compressedParams;
+ }();
+ return parameters;
+}
+
+class CompressedOffloadOutputStreamTest : public PcmOnlyConfigOutputStreamTest {
+ public:
+ void loadData(const std::string& fileName, std::vector<uint8_t>* data) {
+ std::ifstream is(fileName, std::ios::in | std::ios::binary);
+ ASSERT_TRUE(is.good()) << "Failed to open file " << fileName;
+ is.seekg(0, is.end);
+ data->reserve(data->size() + is.tellg());
+ is.seekg(0, is.beg);
+ data->insert(data->end(), std::istreambuf_iterator<char>(is),
+ std::istreambuf_iterator<char>());
+ ASSERT_TRUE(!is.fail()) << "Failed to read from file " << fileName;
+ }
+};
+
+class OffloadCallbacks : public IStreamOutCallback {
+ public:
+ Return<void> onDrainReady() override {
+ ALOGI("onDrainReady");
+ {
+ std::lock_guard lg(mLock);
+ mOnDrainReady = true;
+ }
+ mCondVar.notify_one();
+ return {};
+ }
+ Return<void> onWriteReady() override { return {}; }
+ Return<void> onError() override {
+ ALOGW("onError");
+ {
+ std::lock_guard lg(mLock);
+ mOnError = true;
+ }
+ mCondVar.notify_one();
+ return {};
+ }
+ bool waitForDrainReadyOrError() {
+ std::unique_lock l(mLock);
+ if (!mOnDrainReady && !mOnError) {
+ mCondVar.wait(l, [&]() { return mOnDrainReady || mOnError; });
+ }
+ const bool success = !mOnError;
+ mOnDrainReady = mOnError = false;
+ return success;
+ }
+
+ private:
+ std::mutex mLock;
+ bool mOnDrainReady = false;
+ bool mOnError = false;
+ std::condition_variable mCondVar;
+};
+
+TEST_P(CompressedOffloadOutputStreamTest, Mp3FormatGaplessOffload) {
+ doc::test("Check that compressed offload mix ports for MP3 implement gapless offload");
+ const auto& flags = getOutputFlags();
+ const bool isNewDeviceLaunchingOnTPlus = property_get_int32("ro.vendor.api_level", 0) >= 33;
+ // See test instantiation, only offload MP3 mix ports are used.
+ if (std::find_if(flags.begin(), flags.end(), [](const auto& flag) {
+ return flag == toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_GAPLESS_OFFLOAD);
+ }) == flags.end()) {
+ if (isNewDeviceLaunchingOnTPlus) {
+ FAIL() << "New devices launching on Android T+ must support gapless offload, "
+ << "see VSR-4.3-001";
+ } else {
+ GTEST_SKIP() << "Compressed offload mix port does not support gapless offload";
+ }
+ }
+ std::vector<uint8_t> offloadData;
+ ASSERT_NO_FATAL_FAILURE(loadData("/data/local/tmp/sine882hz3s.mp3", &offloadData));
+ ASSERT_FALSE(offloadData.empty());
+ ASSERT_NO_FATAL_FAILURE(createPatchIfNeeded());
+ const int presentationeEndPrecisionMs = 1000;
+ const int sampleRate = 44100;
+ const int significantSampleNumber = (presentationeEndPrecisionMs * sampleRate) / 1000;
+ const int delay = 576 + 1000;
+ const int padding = 756 + 1000;
+ const int durationMs = 3000 - 44;
+ auto start = std::chrono::steady_clock::now();
+ auto callbacks = sp<OffloadCallbacks>::make();
+ std::mutex presentationEndLock;
+ std::vector<float> presentationEndTimes;
+ // StreamWriter plays 'offloadData' in a loop, possibly using multiple calls to 'write', this
+ // depends on the relative sizes of 'offloadData' and the HAL buffer. Writer calls 'onDataStart'
+ // each time it starts writing the buffer from the beginning, and 'onDataWrap' callback each
+ // time it wraps around the buffer.
+ StreamWriter writer(
+ stream.get(), stream->getBufferSize(), std::move(offloadData),
+ [&]() /* onDataStart */ { start = std::chrono::steady_clock::now(); },
+ [&]() /* onDataWrap */ {
+ Return<Result> ret(Result::OK);
+ // Decrease the volume since the test plays a loud sine wave.
+ ret = stream->setVolume(0.1, 0.1);
+ if (!ret.isOk() || ret != Result::OK) {
+ ALOGE("%s: setVolume failed: %s", __func__, toString(ret).c_str());
+ return false;
+ }
+ ret = Parameters::set(
+ stream, {{AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES, std::to_string(delay)},
+ {AUDIO_OFFLOAD_CODEC_PADDING_SAMPLES, std::to_string(padding)}});
+ if (!ret.isOk() || ret != Result::OK) {
+ ALOGE("%s: setParameters failed: %s", __func__, toString(ret).c_str());
+ return false;
+ }
+ ret = stream->drain(AudioDrain::EARLY_NOTIFY);
+ if (!ret.isOk() || ret != Result::OK) {
+ ALOGE("%s: drain failed: %s", __func__, toString(ret).c_str());
+ return false;
+ }
+ // FIXME: On some SoCs intermittent errors are possible, ignore them.
+ if (callbacks->waitForDrainReadyOrError()) {
+ const float duration = std::chrono::duration_cast<std::chrono::milliseconds>(
+ std::chrono::steady_clock::now() - start)
+ .count();
+ std::lock_guard lg(presentationEndLock);
+ presentationEndTimes.push_back(duration);
+ }
+ return true;
+ });
+ ASSERT_OK(stream->setCallback(callbacks));
+ ASSERT_TRUE(writer.start());
+ // How many times to loop the track so that the sum of gapless delay and padding from
+ // the first presentation end to the last is at least 'presentationeEndPrecisionMs'.
+ const int playbackNumber = (int)(significantSampleNumber / ((float)delay + padding) + 1);
+ for (bool done = false; !done;) {
+ usleep(presentationeEndPrecisionMs * 1000);
+ {
+ std::lock_guard lg(presentationEndLock);
+ done = presentationEndTimes.size() >= playbackNumber;
+ }
+ ASSERT_FALSE(writer.hasError()) << "Recent write or drain operation has failed";
+ }
+ const float avgDuration =
+ std::accumulate(presentationEndTimes.begin(), presentationEndTimes.end(), 0.0) /
+ presentationEndTimes.size();
+ std::stringstream observedEndTimes;
+ std::copy(presentationEndTimes.begin(), presentationEndTimes.end(),
+ std::ostream_iterator<float>(observedEndTimes, ", "));
+ EXPECT_NEAR(durationMs, avgDuration, presentationeEndPrecisionMs * 0.1)
+ << "Observed durations: " << observedEndTimes.str();
+ writer.stop();
+ EXPECT_OK(stream->clearCallback());
+ releasePatchIfNeeded();
+}
+
+INSTANTIATE_TEST_CASE_P(
+ CompressedOffloadOutputStream, CompressedOffloadOutputStreamTest,
+ ::testing::ValuesIn(getOutputDeviceCompressedConfigParameters(AudioConfigBase{
+ .format = xsd::toString(xsd::AudioFormat::AUDIO_FORMAT_MP3),
+ .sampleRateHz = 44100,
+ .channelMask = xsd::toString(xsd::AudioChannelMask::AUDIO_CHANNEL_OUT_STEREO)})),
+ &DeviceConfigParameterToString);
+GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(CompressedOffloadOutputStreamTest);
diff --git a/audio/core/all-versions/vts/functional/7.0/Generators.cpp b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
index f936d0a..8b955b6 100644
--- a/audio/core/all-versions/vts/functional/7.0/Generators.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/Generators.cpp
@@ -57,9 +57,6 @@
static std::tuple<std::vector<AudioInOutFlag>, bool> generateOutFlags(
const xsd::MixPorts::MixPort& mixPort) {
- static const std::vector<AudioInOutFlag> offloadFlags = {
- toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
- toString(xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_DIRECT)};
std::vector<AudioInOutFlag> flags;
bool isOffload = false;
if (mixPort.hasFlags()) {
@@ -67,14 +64,10 @@
isOffload = std::find(xsdFlags.begin(), xsdFlags.end(),
xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) !=
xsdFlags.end();
- if (!isOffload) {
- for (auto flag : xsdFlags) {
- if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) {
- flags.push_back(toString(flag));
- }
+ for (auto flag : xsdFlags) {
+ if (flag != xsd::AudioInOutFlag::AUDIO_OUTPUT_FLAG_PRIMARY) {
+ flags.push_back(toString(flag));
}
- } else {
- flags = offloadFlags;
}
}
return {flags, isOffload};
@@ -85,10 +78,10 @@
.base = base,
.streamType = toString(xsd::AudioStreamType::AUDIO_STREAM_MUSIC),
.usage = toString(xsd::AudioUsage::AUDIO_USAGE_MEDIA),
- .bitRatePerSecond = 320,
+ .bitRatePerSecond = 192, // as in sine882hz3s.mp3
.durationMicroseconds = -1,
.bitWidth = 16,
- .bufferSize = 256 // arbitrary value
+ .bufferSize = 72000 // 3 seconds at 192 kbps, as in sine882hz3s.mp3
};
}
@@ -100,11 +93,10 @@
if (!module || !module->getFirstMixPorts()) break;
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::source) continue; // not an output profile
- if (getCachedPolicyConfig()
- .getAttachedSinkDeviceForMixPort(moduleName, mixPort.getName())
- .empty()) {
- continue; // no attached device
- }
+ const auto attachedDeviceAddress =
+ getCachedPolicyConfig().getDeviceAddressOfSinkDeviceAttachedToMixPort(
+ moduleName, mixPort.getName());
+ if (!attachedDeviceAddress.has_value()) continue;
auto [flags, isOffload] = generateOutFlags(mixPort);
for (const auto& profile : mixPort.getProfile()) {
if (!profile.hasFormat() || !profile.hasSamplingRates() ||
@@ -118,7 +110,8 @@
if (isOffload) {
config.offloadInfo.info(generateOffloadInfo(config.base));
}
- result.emplace_back(device, mixPort.getName(), config, flags);
+ result.emplace_back(device, mixPort.getName(), attachedDeviceAddress.value(),
+ config, flags);
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
@@ -162,13 +155,16 @@
profile.getFormat(),
static_cast<uint32_t>(profile.getSamplingRates()[0]),
toString(profile.getChannelMasks()[0])};
+ DeviceAddress defaultDevice = {
+ toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT), {}};
{
AudioConfig config{.base = validBase};
config.base.channelMask = "random_string";
if (isOffload) {
config.offloadInfo.info(generateOffloadInfo(validBase));
}
- result.emplace_back(device, mixPort.getName(), config, validFlags);
+ result.emplace_back(device, mixPort.getName(), defaultDevice, config,
+ validFlags);
}
{
AudioConfig config{.base = validBase};
@@ -176,7 +172,8 @@
if (isOffload) {
config.offloadInfo.info(generateOffloadInfo(validBase));
}
- result.emplace_back(device, mixPort.getName(), config, validFlags);
+ result.emplace_back(device, mixPort.getName(), defaultDevice, config,
+ validFlags);
}
if (generateInvalidFlags) {
AudioConfig config{.base = validBase};
@@ -184,32 +181,37 @@
config.offloadInfo.info(generateOffloadInfo(validBase));
}
std::vector<AudioInOutFlag> flags = {"random_string", ""};
- result.emplace_back(device, mixPort.getName(), config, flags);
+ result.emplace_back(device, mixPort.getName(), defaultDevice, config,
+ flags);
}
if (isOffload) {
{
AudioConfig config{.base = validBase};
config.offloadInfo.info(generateOffloadInfo(validBase));
config.offloadInfo.info().base.channelMask = "random_string";
- result.emplace_back(device, mixPort.getName(), config, validFlags);
+ result.emplace_back(device, mixPort.getName(), defaultDevice, config,
+ validFlags);
}
{
AudioConfig config{.base = validBase};
config.offloadInfo.info(generateOffloadInfo(validBase));
config.offloadInfo.info().base.format = "random_string";
- result.emplace_back(device, mixPort.getName(), config, validFlags);
+ result.emplace_back(device, mixPort.getName(), defaultDevice, config,
+ validFlags);
}
{
AudioConfig config{.base = validBase};
config.offloadInfo.info(generateOffloadInfo(validBase));
config.offloadInfo.info().streamType = "random_string";
- result.emplace_back(device, mixPort.getName(), config, validFlags);
+ result.emplace_back(device, mixPort.getName(), defaultDevice, config,
+ validFlags);
}
{
AudioConfig config{.base = validBase};
config.offloadInfo.info(generateOffloadInfo(validBase));
config.offloadInfo.info().usage = "random_string";
- result.emplace_back(device, mixPort.getName(), config, validFlags);
+ result.emplace_back(device, mixPort.getName(), defaultDevice, config,
+ validFlags);
}
hasOffloadConfig = true;
} else {
@@ -233,11 +235,10 @@
if (!module || !module->getFirstMixPorts()) break;
for (const auto& mixPort : module->getFirstMixPorts()->getMixPort()) {
if (mixPort.getRole() != xsd::Role::sink) continue; // not an input profile
- if (getCachedPolicyConfig()
- .getAttachedSourceDeviceForMixPort(moduleName, mixPort.getName())
- .empty()) {
- continue; // no attached device
- }
+ const auto attachedDeviceAddress =
+ getCachedPolicyConfig().getDeviceAddressOfSourceDeviceAttachedToMixPort(
+ moduleName, mixPort.getName());
+ if (!attachedDeviceAddress.has_value()) continue;
std::vector<AudioInOutFlag> flags;
if (mixPort.hasFlags()) {
std::transform(mixPort.getFlags().begin(), mixPort.getFlags().end(),
@@ -250,7 +251,8 @@
auto configs = combineAudioConfig(profile.getChannelMasks(),
profile.getSamplingRates(), profile.getFormat());
for (const auto& config : configs) {
- result.emplace_back(device, mixPort.getName(), config, flags);
+ result.emplace_back(device, mixPort.getName(), attachedDeviceAddress.value(),
+ config, flags);
if (oneProfilePerDevice) break;
}
if (oneProfilePerDevice) break;
@@ -298,20 +300,25 @@
profile.getFormat(),
static_cast<uint32_t>(profile.getSamplingRates()[0]),
toString(profile.getChannelMasks()[0])};
+ DeviceAddress defaultDevice = {
+ toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT), {}};
{
AudioConfig config{.base = validBase};
config.base.channelMask = "random_string";
- result.emplace_back(device, mixPort.getName(), config, validFlags);
+ result.emplace_back(device, mixPort.getName(), defaultDevice, config,
+ validFlags);
}
{
AudioConfig config{.base = validBase};
config.base.format = "random_string";
- result.emplace_back(device, mixPort.getName(), config, validFlags);
+ result.emplace_back(device, mixPort.getName(), defaultDevice, config,
+ validFlags);
}
if (generateInvalidFlags) {
AudioConfig config{.base = validBase};
std::vector<AudioInOutFlag> flags = {"random_string", ""};
- result.emplace_back(device, mixPort.getName(), config, flags);
+ result.emplace_back(device, mixPort.getName(), defaultDevice, config,
+ flags);
}
hasConfig = true;
break;
diff --git a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
index 4aea503..c1d5669 100644
--- a/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
+++ b/audio/core/all-versions/vts/functional/7.0/PolicyConfig.h
@@ -61,6 +61,18 @@
const std::set<std::string>& getModulesWithDevicesNames() const {
return mModulesWithDevicesNames;
}
+ std::optional<DeviceAddress> getDeviceAddressOfSinkDeviceAttachedToMixPort(
+ const std::string& moduleName, const std::string& mixPortName) const {
+ const auto attachedDevicePort = getAttachedSinkDeviceForMixPort(moduleName, mixPortName);
+ if (attachedDevicePort.empty()) return {};
+ return getDeviceAddressOfDevicePort(moduleName, attachedDevicePort);
+ }
+ std::optional<DeviceAddress> getDeviceAddressOfSourceDeviceAttachedToMixPort(
+ const std::string& moduleName, const std::string& mixPortName) const {
+ const auto attachedDevicePort = getAttachedSourceDeviceForMixPort(moduleName, mixPortName);
+ if (attachedDevicePort.empty()) return {};
+ return getDeviceAddressOfDevicePort(moduleName, attachedDevicePort);
+ }
std::string getAttachedSinkDeviceForMixPort(const std::string& moduleName,
const std::string& mixPortName) const {
return findAttachedDevice(getAttachedDevices(moduleName),
@@ -84,8 +96,6 @@
const std::vector<std::string>& getAttachedDevices(const std::string& moduleName) const;
std::optional<DeviceAddress> getDeviceAddressOfDevicePort(
const std::string& moduleName, const std::string& devicePortName) const;
- std::string getDevicePortTagNameFromType(const std::string& moduleName,
- const AudioDevice& deviceType) const;
std::set<std::string> getSinkDevicesForMixPort(const std::string& moduleName,
const std::string& mixPortName) const;
std::set<std::string> getSourceDevicesForMixPort(const std::string& moduleName,
diff --git a/audio/core/all-versions/vts/functional/Android.bp b/audio/core/all-versions/vts/functional/Android.bp
index c757032..daed7a8 100644
--- a/audio/core/all-versions/vts/functional/Android.bp
+++ b/audio/core/all-versions/vts/functional/Android.bp
@@ -34,6 +34,7 @@
],
shared_libs: [
"libbinder",
+ "libcutils",
"libfmq",
"libxml2",
],
@@ -190,6 +191,7 @@
],
data: [
":audio_policy_configuration_V7_0",
+ "data/sine882hz3s.mp3",
],
// Use test_config for vts suite.
// TODO(b/146104851): Add auto-gen rules and remove it.
@@ -223,6 +225,7 @@
],
data: [
":audio_policy_configuration_V7_1",
+ "data/sine882hz3s.mp3",
],
// Use test_config for vts suite.
// TODO(b/146104851): Add auto-gen rules and remove it.
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 38e9e5f..e46e5b4 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -617,7 +617,8 @@
std::get<PARAM_FLAGS>(info.param)));
#elif MAJOR_VERSION >= 7
const auto configPart =
- std::to_string(config.base.sampleRateHz) + "_" +
+ ::testing::PrintToString(std::get<PARAM_ATTACHED_DEV_ADDR>(info.param).deviceType) +
+ "_" + std::to_string(config.base.sampleRateHz) + "_" +
// The channel masks and flags are vectors of strings, just need to sanitize them.
SanitizeStringForGTestName(::testing::PrintToString(config.base.channelMask)) + "_" +
SanitizeStringForGTestName(::testing::PrintToString(std::get<PARAM_FLAGS>(info.param)));
@@ -658,6 +659,9 @@
std::get<INDEX_OUTPUT>(std::get<PARAM_FLAGS>(GetParam())));
}
#elif MAJOR_VERSION >= 7
+ DeviceAddress getAttachedDeviceAddress() const {
+ return std::get<PARAM_ATTACHED_DEV_ADDR>(GetParam());
+ }
hidl_vec<AudioInOutFlag> getInputFlags() const { return std::get<PARAM_FLAGS>(GetParam()); }
hidl_vec<AudioInOutFlag> getOutputFlags() const { return std::get<PARAM_FLAGS>(GetParam()); }
#endif
@@ -933,6 +937,15 @@
StreamWriter(IStreamOut* stream, size_t bufferSize)
: mStream(stream), mBufferSize(bufferSize), mData(mBufferSize) {}
+ StreamWriter(IStreamOut* stream, size_t bufferSize, std::vector<uint8_t>&& data,
+ std::function<void()> onDataStart, std::function<bool()> onDataWrap)
+ : mStream(stream),
+ mBufferSize(bufferSize),
+ mData(std::move(data)),
+ mOnDataStart(onDataStart),
+ mOnDataWrap(onDataWrap) {
+ ALOGI("StreamWriter data size: %d", (int)mData.size());
+ }
~StreamWriter() {
stop();
if (mEfGroup) {
@@ -998,9 +1011,12 @@
ALOGE("command message queue write failed");
return false;
}
- const size_t dataSize = std::min(mData.size(), mDataMQ->availableToWrite());
- bool success = mDataMQ->write(mData.data(), dataSize);
+ if (mDataPosition == 0) mOnDataStart();
+ const size_t dataSize = std::min(mData.size() - mDataPosition, mDataMQ->availableToWrite());
+ bool success = mDataMQ->write(mData.data() + mDataPosition, dataSize);
ALOGE_IF(!success, "data message queue write failed");
+ mDataPosition += dataSize;
+ if (mDataPosition >= mData.size()) mDataPosition = 0;
mEfGroup->wake(static_cast<uint32_t>(MessageQueueFlagBits::NOT_EMPTY));
uint32_t efState = 0;
@@ -1026,6 +1042,9 @@
ALOGE("bad wait status: %d", ret);
success = false;
}
+ if (success && mDataPosition == 0) {
+ success = mOnDataWrap();
+ }
return success;
}
@@ -1033,6 +1052,9 @@
IStreamOut* const mStream;
const size_t mBufferSize;
std::vector<uint8_t> mData;
+ std::function<void()> mOnDataStart = []() {};
+ std::function<bool()> mOnDataWrap = []() { return true; };
+ size_t mDataPosition = 0;
std::unique_ptr<CommandMQ> mCommandMQ;
std::unique_ptr<DataMQ> mDataMQ;
std::unique_ptr<StatusMQ> mStatusMQ;
@@ -1047,7 +1069,7 @@
#if MAJOR_VERSION <= 6
address.device = AudioDevice::OUT_DEFAULT;
#elif MAJOR_VERSION >= 7
- address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_OUT_DEFAULT);
+ address = getAttachedDeviceAddress();
#endif
const AudioConfig& config = getConfig();
auto flags = getOutputFlags();
@@ -1243,16 +1265,11 @@
#if MAJOR_VERSION <= 6
address.device = AudioDevice::IN_DEFAULT;
#elif MAJOR_VERSION >= 7
- auto maybeSourceAddress = getCachedPolicyConfig().getSourceDeviceForMixPort(
- getDeviceName(), getMixPortName());
+ address = getAttachedDeviceAddress();
auto& metadata = initMetadata.tracks[0];
- if (maybeSourceAddress.has_value() &&
- !xsd::isTelephonyDevice(maybeSourceAddress.value().deviceType)) {
- address = maybeSourceAddress.value();
+ if (!xsd::isTelephonyDevice(address.deviceType)) {
metadata.source = toString(xsd::AudioSource::AUDIO_SOURCE_UNPROCESSED);
metadata.channelMask = getConfig().base.channelMask;
- } else {
- address.deviceType = toString(xsd::AudioDevice::AUDIO_DEVICE_IN_DEFAULT);
}
#if MAJOR_VERSION == 7 && MINOR_VERSION >= 1
auto flagsIt = std::find(flags.begin(), flags.end(),
diff --git a/audio/core/all-versions/vts/functional/AudioTestDefinitions.h b/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
index 802b87b..3de06c3 100644
--- a/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
+++ b/audio/core/all-versions/vts/functional/AudioTestDefinitions.h
@@ -39,9 +39,10 @@
std::variant<android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioInputFlag,
android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioOutputFlag>>;
#elif MAJOR_VERSION >= 7
-enum { PARAM_DEVICE, PARAM_PORT_NAME, PARAM_CONFIG, PARAM_FLAGS };
+enum { PARAM_DEVICE, PARAM_PORT_NAME, PARAM_ATTACHED_DEV_ADDR, PARAM_CONFIG, PARAM_FLAGS };
using DeviceConfigParameter =
std::tuple<DeviceParameter, std::string,
+ android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::DeviceAddress,
android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioConfig,
std::vector<android::hardware::audio::CORE_TYPES_CPP_VERSION::AudioInOutFlag>>;
#endif
diff --git a/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml b/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml
index f0e2695..8da5744 100644
--- a/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml
+++ b/audio/core/all-versions/vts/functional/VtsHalAudioV7_0TargetTest.xml
@@ -29,6 +29,7 @@
<option name="cleanup" value="true" />
<option name="push" value="VtsHalAudioV7_0TargetTest->/data/local/tmp/VtsHalAudioV7_0TargetTest" />
<option name="push" value="audio_policy_configuration_V7_0.xsd->/data/local/tmp/audio_policy_configuration_V7_0.xsd" />
+ <option name="push" value="sine882hz3s.mp3->/data/local/tmp/sine882hz3s.mp3" />
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
diff --git a/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml b/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
index 7ce1477..227df18 100644
--- a/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
+++ b/audio/core/all-versions/vts/functional/VtsHalAudioV7_1TargetTest.xml
@@ -29,6 +29,8 @@
<option name="cleanup" value="true" />
<option name="push" value="VtsHalAudioV7_1TargetTest->/data/local/tmp/VtsHalAudioV7_1TargetTest" />
<option name="push" value="audio_policy_configuration_V7_1.xsd->/data/local/tmp/audio_policy_configuration_V7_1.xsd" />
+ <option name="push" value="sine882hz3s.mp3->/data/local/tmp/sine882hz3s.mp3" />
+
</target_preparer>
<test class="com.android.tradefed.testtype.GTest" >
diff --git a/audio/core/all-versions/vts/functional/data/sine882hz3s.mp3 b/audio/core/all-versions/vts/functional/data/sine882hz3s.mp3
new file mode 100644
index 0000000..0604f9b
--- /dev/null
+++ b/audio/core/all-versions/vts/functional/data/sine882hz3s.mp3
Binary files differ
diff --git a/camera/common/1.0/default/HandleImporter.cpp b/camera/common/1.0/default/HandleImporter.cpp
index fbe8686..d2fdf02 100644
--- a/camera/common/1.0/default/HandleImporter.cpp
+++ b/camera/common/1.0/default/HandleImporter.cpp
@@ -18,6 +18,7 @@
#include "HandleImporter.h"
#include <gralloctypes/Gralloc4.h>
+#include "aidl/android/hardware/graphics/common/Smpte2086.h"
#include <log/log.h>
namespace android {
@@ -30,6 +31,7 @@
using aidl::android::hardware::graphics::common::PlaneLayout;
using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
+using aidl::android::hardware::graphics::common::Smpte2086;
using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
using MapperErrorV2 = android::hardware::graphics::mapper::V2_0::Error;
using MapperErrorV3 = android::hardware::graphics::mapper::V3_0::Error;
@@ -127,16 +129,35 @@
bool isMetadataPesent(const sp<IMapperV4> mapper, const buffer_handle_t& buf,
MetadataType metadataType) {
auto buffer = const_cast<native_handle_t*>(buf);
- mapper->get(buffer, metadataType, [] (const auto& tmpError,
+ bool ret = false;
+ hidl_vec<uint8_t> vec;
+ mapper->get(buffer, metadataType, [&] (const auto& tmpError,
const auto& tmpMetadata) {
if (tmpError == MapperErrorV4::NONE) {
- return tmpMetadata.size() > 0;
+ vec = tmpMetadata;
} else {
ALOGE("%s: failed to get metadata %d!", __FUNCTION__, tmpError);
- return false;
}});
- return false;
+ if (vec.size() > 0) {
+ if (metadataType == gralloc4::MetadataType_Smpte2086){
+ std::optional<Smpte2086> realSmpte2086;
+ gralloc4::decodeSmpte2086(vec, &realSmpte2086);
+ ret = realSmpte2086.has_value();
+ } else if (metadataType == gralloc4::MetadataType_Smpte2094_10) {
+ std::optional<std::vector<uint8_t>> realSmpte2094_10;
+ gralloc4::decodeSmpte2094_10(vec, &realSmpte2094_10);
+ ret = realSmpte2094_10.has_value();
+ } else if (metadataType == gralloc4::MetadataType_Smpte2094_40) {
+ std::optional<std::vector<uint8_t>> realSmpte2094_40;
+ gralloc4::decodeSmpte2094_40(vec, &realSmpte2094_40);
+ ret = realSmpte2094_40.has_value();
+ } else {
+ ALOGE("%s: Unknown metadata type!", __FUNCTION__);
+ }
+ }
+
+ return ret;
}
std::vector<PlaneLayout> getPlaneLayouts(const sp<IMapperV4> mapper, buffer_handle_t& buf) {
diff --git a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
index fe03732..70ab7a0 100644
--- a/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
+++ b/camera/provider/aidl/vts/VtsAidlHalCameraProvider_TargetTest.cpp
@@ -1739,6 +1739,10 @@
std::list<PixelFormat> pixelFormats = {PixelFormat::YCBCR_420_888, PixelFormat::RAW16};
for (PixelFormat format : pixelFormats) {
+ previewStream.usage =
+ static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+ GRALLOC1_CONSUMER_USAGE_CPU_READ);
+ previewStream.dataSpace = Dataspace::UNKNOWN;
configureStreams(name, mProvider, format, &mSession, &previewStream, &halStreams,
&supportsPartialResults, &partialResultCount, &useHalBufManager, &cb,
0, /*maxResolution*/ true);
@@ -1843,7 +1847,6 @@
TEST_P(CameraAidlTest, process10BitDynamicRangeRequest) {
std::vector<std::string> cameraDeviceNames = getCameraDeviceNames(mProvider);
int64_t bufferId = 1;
- int32_t frameNumber = 1;
CameraMetadata settings;
for (const auto& name : cameraDeviceNames) {
@@ -1866,7 +1869,7 @@
CameraMetadata req;
android::hardware::camera::common::V1_0::helper::CameraMetadata defaultSettings;
ndk::ScopedAStatus ret =
- mSession->constructDefaultRequestSettings(RequestTemplate::STILL_CAPTURE, &req);
+ mSession->constructDefaultRequestSettings(RequestTemplate::PREVIEW, &req);
ASSERT_TRUE(ret.isOk());
const camera_metadata_t* metadata =
@@ -1896,6 +1899,10 @@
Stream previewStream;
std::shared_ptr<DeviceCb> cb;
for (const auto& profile : profileList) {
+ previewStream.usage =
+ static_cast<aidl::android::hardware::graphics::common::BufferUsage>(
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER);
+ previewStream.dataSpace = getDataspace(PixelFormat::IMPLEMENTATION_DEFINED);
configureStreams(name, mProvider, PixelFormat::IMPLEMENTATION_DEFINED, &mSession,
&previewStream, &halStreams, &supportsPartialResults,
&partialResultCount, &useHalBufManager, &cb, 0,
@@ -1916,63 +1923,75 @@
// Don't use the queue onwards.
}
- std::vector<buffer_handle_t> graphicBuffers;
- graphicBuffers.reserve(halStreams.size());
+ mInflightMap.clear();
+ // Stream as long as needed to fill the Hal inflight queue
+ std::vector<CaptureRequest> requests(halStreams[0].maxBuffers);
- std::shared_ptr<InFlightRequest> inflightReq = std::make_shared<InFlightRequest>(
- static_cast<ssize_t>(halStreams.size()), false, supportsPartialResults,
- partialResultCount, std::unordered_set<std::string>(), resultQueue);
+ for (int32_t frameNumber = 0; frameNumber < requests.size(); frameNumber++) {
+ std::shared_ptr<InFlightRequest> inflightReq = std::make_shared<InFlightRequest>(
+ static_cast<ssize_t>(halStreams.size()), false, supportsPartialResults,
+ partialResultCount, std::unordered_set<std::string>(), resultQueue);
- std::vector<CaptureRequest> requests(1);
- CaptureRequest& request = requests[0];
- std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
- outputBuffers.resize(halStreams.size());
+ CaptureRequest& request = requests[frameNumber];
+ std::vector<StreamBuffer>& outputBuffers = request.outputBuffers;
+ outputBuffers.resize(halStreams.size());
- size_t k = 0;
- for (const auto& halStream : halStreams) {
- buffer_handle_t buffer_handle;
- if (useHalBufManager) {
- outputBuffers[k] = {halStream.id, 0,
- NativeHandle(), BufferStatus::OK,
- NativeHandle(), NativeHandle()};
- } else {
- allocateGraphicBuffer(previewStream.width, previewStream.height,
- android_convertGralloc1To0Usage(
- static_cast<uint64_t>(halStream.producerUsage),
- static_cast<uint64_t>(halStream.consumerUsage)),
- halStream.overrideFormat, &buffer_handle);
+ size_t k = 0;
+ inflightReq->mOutstandingBufferIds.resize(halStreams.size());
+ std::vector<buffer_handle_t> graphicBuffers;
+ graphicBuffers.reserve(halStreams.size());
- graphicBuffers.push_back(buffer_handle);
- outputBuffers[k] = {
- halStream.id, bufferId, android::makeToAidl(buffer_handle),
- BufferStatus::OK, NativeHandle(), NativeHandle()};
- bufferId++;
+ for (const auto& halStream : halStreams) {
+ buffer_handle_t buffer_handle;
+ if (useHalBufManager) {
+ outputBuffers[k] = {halStream.id, 0,
+ NativeHandle(), BufferStatus::OK,
+ NativeHandle(), NativeHandle()};
+ } else {
+ auto usage = android_convertGralloc1To0Usage(
+ static_cast<uint64_t>(halStream.producerUsage),
+ static_cast<uint64_t>(halStream.consumerUsage));
+ allocateGraphicBuffer(previewStream.width, previewStream.height, usage,
+ halStream.overrideFormat, &buffer_handle);
+
+ inflightReq->mOutstandingBufferIds[halStream.id][bufferId] = buffer_handle;
+ graphicBuffers.push_back(buffer_handle);
+ outputBuffers[k] = {halStream.id, bufferId,
+ android::makeToAidl(buffer_handle), BufferStatus::OK, NativeHandle(),
+ NativeHandle()};
+ bufferId++;
+ }
+ k++;
}
- k++;
- }
- request.inputBuffer = {
- -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
- request.frameNumber = frameNumber;
- request.fmqSettingsSize = 0;
- request.settings = settings;
- request.inputWidth = 0;
- request.inputHeight = 0;
+ request.inputBuffer = {
+ -1, 0, NativeHandle(), BufferStatus::ERROR, NativeHandle(), NativeHandle()};
+ request.frameNumber = frameNumber;
+ request.fmqSettingsSize = 0;
+ request.settings = settings;
+ request.inputWidth = 0;
+ request.inputHeight = 0;
- {
- std::unique_lock<std::mutex> l(mLock);
- mInflightMap.clear();
- mInflightMap[frameNumber] = inflightReq;
+ {
+ std::unique_lock<std::mutex> l(mLock);
+ mInflightMap[frameNumber] = inflightReq;
+ }
+
}
int32_t numRequestProcessed = 0;
std::vector<BufferCache> cachesToRemove;
ndk::ScopedAStatus returnStatus =
- mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
+ mSession->processCaptureRequest(requests, cachesToRemove, &numRequestProcessed);
ASSERT_TRUE(returnStatus.isOk());
- ASSERT_EQ(numRequestProcessed, 1u);
+ ASSERT_EQ(numRequestProcessed, requests.size());
- {
+ returnStatus = mSession->repeatingRequestEnd(requests.size() - 1,
+ std::vector<int32_t> {halStreams[0].id});
+ ASSERT_TRUE(returnStatus.isOk());
+
+ for (int32_t frameNumber = 0; frameNumber < requests.size(); frameNumber++) {
+ const auto& inflightReq = mInflightMap[frameNumber];
std::unique_lock<std::mutex> l(mLock);
while (!inflightReq->errorCodeValid &&
((0 < inflightReq->numBuffersLeft) || (!inflightReq->haveResultMetadata))) {
@@ -1985,6 +2004,7 @@
ASSERT_NE(inflightReq->resultOutputBuffers.size(), 0u);
verify10BitMetadata(mHandleImporter, *inflightReq, profile);
}
+
if (useHalBufManager) {
std::vector<int32_t> streamIds(halStreams.size());
for (size_t i = 0; i < streamIds.size(); i++) {
diff --git a/camera/provider/aidl/vts/camera_aidl_test.cpp b/camera/provider/aidl/vts/camera_aidl_test.cpp
index c11fc0c..20f32bf 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.cpp
+++ b/camera/provider/aidl/vts/camera_aidl_test.cpp
@@ -2639,8 +2639,20 @@
outputStreams.clear();
Size maxSize;
- auto rc = getMaxOutputSizeForFormat(staticMeta, format, &maxSize, maxResolution);
- ASSERT_EQ(Status::OK, rc);
+ if (maxResolution) {
+ auto rc = getMaxOutputSizeForFormat(staticMeta, format, &maxSize, maxResolution);
+ ASSERT_EQ(Status::OK, rc);
+ } else {
+ AvailableStream previewThreshold = {kMaxPreviewWidth, kMaxPreviewHeight,
+ static_cast<int32_t>(format)};
+ auto rc = getAvailableOutputStreams(staticMeta, outputStreams, &previewThreshold);
+
+ ASSERT_EQ(Status::OK, rc);
+ ASSERT_FALSE(outputStreams.empty());
+ maxSize.width = outputStreams[0].width;
+ maxSize.height = outputStreams[0].height;
+ }
+
std::vector<Stream> streams(1);
streams[0] = {0,
@@ -2648,9 +2660,8 @@
maxSize.width,
maxSize.height,
format,
- static_cast<::aidl::android::hardware::graphics::common::BufferUsage>(
- GRALLOC1_CONSUMER_USAGE_CPU_READ),
- Dataspace::UNKNOWN,
+ previewStream->usage,
+ previewStream->dataSpace,
StreamRotation::ROTATION_0,
"",
0,
@@ -2736,7 +2747,8 @@
HandleImporter& importer, const InFlightRequest& request,
aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap
profile) {
- for (const auto& b : request.resultOutputBuffers) {
+ for (auto b : request.resultOutputBuffers) {
+ importer.importBuffer(b.buffer.buffer);
bool smpte2086Present = importer.isSmpte2086Present(b.buffer.buffer);
bool smpte2094_10Present = importer.isSmpte2094_10Present(b.buffer.buffer);
bool smpte2094_40Present = importer.isSmpte2094_40Present(b.buffer.buffer);
@@ -2753,7 +2765,6 @@
ASSERT_FALSE(smpte2094_40Present);
break;
case ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_HDR10_PLUS:
- ASSERT_FALSE(smpte2086Present);
ASSERT_FALSE(smpte2094_10Present);
ASSERT_TRUE(smpte2094_40Present);
break;
@@ -2774,6 +2785,7 @@
profile);
ADD_FAILURE();
}
+ importer.freeBuffer(b.buffer.buffer);
}
}
diff --git a/camera/provider/aidl/vts/camera_aidl_test.h b/camera/provider/aidl/vts/camera_aidl_test.h
index ac4b2c9..d828cee 100644
--- a/camera/provider/aidl/vts/camera_aidl_test.h
+++ b/camera/provider/aidl/vts/camera_aidl_test.h
@@ -399,6 +399,10 @@
// Result metadata
::android::hardware::camera::common::V1_0::helper::CameraMetadata collectedResult;
+ // Inflight buffers
+ using OutstandingBuffers = std::unordered_map<uint64_t, buffer_handle_t>;
+ std::vector<OutstandingBuffers> mOutstandingBufferIds;
+
// A copy-able StreamBuffer using buffer_handle_t instead of AIDLs NativeHandle
struct NativeStreamBuffer {
int32_t streamId;
diff --git a/camera/provider/aidl/vts/device_cb.cpp b/camera/provider/aidl/vts/device_cb.cpp
index e5f2f1e..4698b4a 100644
--- a/camera/provider/aidl/vts/device_cb.cpp
+++ b/camera/provider/aidl/vts/device_cb.cpp
@@ -155,7 +155,7 @@
BufferStatus::OK, NativeHandle(), NativeHandle(),
};
- mOutstandingBufferIds[idx][mNextBufferId++] = ::android::dupToAidl(handle);
+ mOutstandingBufferIds[idx][mNextBufferId++] = handle;
}
atLeastOneStreamOk = true;
bufRets[i].streamId = stream.id;
@@ -427,9 +427,13 @@
}
CameraAidlTest::InFlightRequest::StreamBufferAndTimestamp streamBufferAndTimestamp;
+ auto outstandingBuffers = mUseHalBufManager ? mOutstandingBufferIds :
+ request->mOutstandingBufferIds;
+ auto outputBuffer = outstandingBuffers.empty() ? ::android::makeFromAidl(buffer.buffer) :
+ outstandingBuffers[buffer.streamId][buffer.bufferId];
streamBufferAndTimestamp.buffer = {buffer.streamId,
buffer.bufferId,
- ::android::makeFromAidl(buffer.buffer),
+ outputBuffer,
buffer.status,
::android::makeFromAidl(buffer.acquireFence),
::android::makeFromAidl(buffer.releaseFence)};
diff --git a/camera/provider/aidl/vts/device_cb.h b/camera/provider/aidl/vts/device_cb.h
index 82ca10d..3ae7d10 100644
--- a/camera/provider/aidl/vts/device_cb.h
+++ b/camera/provider/aidl/vts/device_cb.h
@@ -73,7 +73,7 @@
std::vector<Stream> mStreams;
std::vector<HalStream> mHalStreams;
int64_t mNextBufferId = 1;
- using OutstandingBuffers = std::unordered_map<uint64_t, NativeHandle>;
+ using OutstandingBuffers = std::unordered_map<uint64_t, buffer_handle_t>;
// size == mStreams.size(). Tracking each streams outstanding buffers
std::vector<OutstandingBuffers> mOutstandingBufferIds;
std::condition_variable mFlushedCondition;
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index 0d426da..4eb3cb1 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -192,33 +192,14 @@
name: "android.hardware.health-service.aidl_fuzzer",
defaults: [
"libhealth_aidl_impl_user",
+ "service_fuzzer_defaults",
],
static_libs: [
"android.hardware.health-V1-ndk",
"libbase",
- "libbinder_random_parcel",
- "libcutils",
"liblog",
- "libutils",
"fuzz_libhealth_aidl_impl",
],
- target: {
- android: {
- shared_libs: [
- "libbinder_ndk",
- "libbinder",
- ],
- },
- host: {
- static_libs: [
- "libbinder_ndk",
- "libbinder",
- ],
- },
- darwin: {
- enabled: false,
- },
- },
srcs: ["fuzzer.cpp"],
fuzz_config: {
cc: [
diff --git a/sensors/aidl/vts/AndroidTest.xml b/sensors/aidl/vts/AndroidTest.xml
new file mode 100644
index 0000000..99caf28
--- /dev/null
+++ b/sensors/aidl/vts/AndroidTest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Runs VtsAidlHalSensorsTargetTest.">
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="apct-native" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+ <target_preparer class="com.android.tradefed.targetprep.StopServicesSetup"/>
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="push" value="VtsAidlHalSensorsTargetTest->/data/local/tmp/VtsAidlHalSensorsTargetTest" />
+ </target_preparer>
+
+ <test class="com.android.tradefed.testtype.GTest" >
+ <option name="native-test-timeout" value="900000" />
+ <option name="runtime-hint" value="300000"/>
+ <option name="native-test-device-path" value="/data/local/tmp" />
+ <option name="module-name" value="VtsAidlHalSensorsTargetTest" />
+ </test>
+</configuration>
diff --git a/vibrator/aidl/default/Android.bp b/vibrator/aidl/default/Android.bp
index c4140be..78bb4ed 100644
--- a/vibrator/aidl/default/Android.bp
+++ b/vibrator/aidl/default/Android.bp
@@ -57,33 +57,12 @@
cc_fuzz {
name: "android.hardware.vibrator-service.example_fuzzer",
host_supported: true,
+ defaults: ["service_fuzzer_defaults"],
static_libs: [
"android.hardware.vibrator-V2-ndk",
- "libbase",
- "libbinder_random_parcel",
- "libcutils",
"liblog",
"libvibratorexampleimpl",
],
- target: {
- android: {
- shared_libs: [
- "libbinder_ndk",
- "libbinder",
- "libutils",
- ],
- },
- host: {
- static_libs: [
- "libbinder_ndk",
- "libbinder",
- "libutils",
- ],
- },
- darwin: {
- enabled: false,
- },
- },
srcs: ["fuzzer.cpp"],
fuzz_config: {
cc: [