Merge "TunerHAL Handle PES Header in MediaFilterHandler"
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 05d5c4e..4b76a0b 100644
--- a/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
+++ b/audio/core/all-versions/vts/functional/7.0/AudioPrimaryHidlHalTest.cpp
@@ -896,10 +896,49 @@
}
};
+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()) {
@@ -910,8 +949,7 @@
GTEST_SKIP() << "Compressed offload mix port does not support gapless offload";
}
}
- // FIXME: The presentation position is not updated if there is no zero padding in data.
- std::vector<uint8_t> offloadData(stream->getBufferSize());
+ 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());
@@ -921,38 +959,70 @@
const int delay = 576 + 1000;
const int padding = 756 + 1000;
const int durationMs = 3000 - 44;
- // 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
- // 'onDataWrap' callback each time it wraps around the buffer.
+ 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), [&]() /* onDataWrap */ {
- Parameters::set(stream,
- {{AUDIO_OFFLOAD_CODEC_DELAY_SAMPLES, std::to_string(delay)},
+ 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)}});
- stream->drain(AudioDrain::EARLY_NOTIFY);
+ 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());
- ASSERT_TRUE(writer.waitForAtLeastOneCycle());
- // Decrease the volume since the test plays a loud sine wave.
- ASSERT_OK(stream->setVolume(0.1, 0.1));
// 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);
- std::vector<float> presentationEndTimes;
- uint64_t previousPosition = std::numeric_limits<uint64_t>::max();
- for (int i = 0; i < playbackNumber; ++i) {
- const auto start = std::chrono::steady_clock::now();
- ASSERT_NO_FATAL_FAILURE(
- waitForPresentationPositionAdvance(writer, &previousPosition, &previousPosition));
- presentationEndTimes.push_back(std::chrono::duration_cast<std::chrono::milliseconds>(
- std::chrono::steady_clock::now() - start)
- .count());
+ 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();
- EXPECT_NEAR(durationMs, avgDuration, presentationeEndPrecisionMs * 0.1);
+ 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();
}
diff --git a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
index 6c5584d..e46e5b4 100644
--- a/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
+++ b/audio/core/all-versions/vts/functional/AudioPrimaryHidlHalTest.h
@@ -938,12 +938,13 @@
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()> onDataWrap)
+ std::function<void()> onDataStart, std::function<bool()> onDataWrap)
: mStream(stream),
mBufferSize(bufferSize),
mData(std::move(data)),
+ mOnDataStart(onDataStart),
mOnDataWrap(onDataWrap) {
- ALOGW("StreamWriter data size: %d", (int)mData.size());
+ ALOGI("StreamWriter data size: %d", (int)mData.size());
}
~StreamWriter() {
stop();
@@ -1010,6 +1011,7 @@
ALOGE("command message queue write failed");
return false;
}
+ 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");
@@ -1040,7 +1042,9 @@
ALOGE("bad wait status: %d", ret);
success = false;
}
- if (success && mDataPosition == 0) mOnDataWrap();
+ if (success && mDataPosition == 0) {
+ success = mOnDataWrap();
+ }
return success;
}
@@ -1048,7 +1052,8 @@
IStreamOut* const mStream;
const size_t mBufferSize;
std::vector<uint8_t> mData;
- std::function<void()> mOnDataWrap = []() {};
+ std::function<void()> mOnDataStart = []() {};
+ std::function<bool()> mOnDataWrap = []() { return true; };
size_t mDataPosition = 0;
std::unique_ptr<CommandMQ> mCommandMQ;
std::unique_ptr<DataMQ> mDataMQ;
diff --git a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
index 4d37cd3..14a694d 100644
--- a/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
+++ b/automotive/vehicle/aidl/generated_lib/cpp/AccessForVehicleProperty.h
@@ -77,7 +77,7 @@
{VehicleProperty::IGNITION_STATE, VehiclePropertyAccess::READ},
{VehicleProperty::ABS_ACTIVE, VehiclePropertyAccess::READ},
{VehicleProperty::TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess::READ},
- {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyAccess::READ},
+ {VehicleProperty::HVAC_FAN_SPEED, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HVAC_FAN_DIRECTION, VehiclePropertyAccess::READ_WRITE},
{VehicleProperty::HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess::READ},
{VehicleProperty::HVAC_TEMPERATURE_SET, VehiclePropertyAccess::READ_WRITE},
diff --git a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
index fdf6c64..0a17ba1 100644
--- a/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
+++ b/automotive/vehicle/aidl/generated_lib/java/AccessForVehicleProperty.java
@@ -69,7 +69,7 @@
Map.entry(VehicleProperty.IGNITION_STATE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.ABS_ACTIVE, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.TRACTION_CONTROL_ACTIVE, VehiclePropertyAccess.READ),
- Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyAccess.READ),
+ Map.entry(VehicleProperty.HVAC_FAN_SPEED, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HVAC_FAN_DIRECTION, VehiclePropertyAccess.READ_WRITE),
Map.entry(VehicleProperty.HVAC_TEMPERATURE_CURRENT, VehiclePropertyAccess.READ),
Map.entry(VehicleProperty.HVAC_TEMPERATURE_SET, VehiclePropertyAccess.READ_WRITE),
diff --git a/automotive/vehicle/tools/generate_annotation_enums.py b/automotive/vehicle/tools/generate_annotation_enums.py
index 154fe65..fc6f157 100644
--- a/automotive/vehicle/tools/generate_annotation_enums.py
+++ b/automotive/vehicle/tools/generate_annotation_enums.py
@@ -41,7 +41,7 @@
TAB = " "
RE_ENUM_START = re.compile("\s*enum VehicleProperty \{")
RE_ENUM_END = re.compile("\s*\}\;")
-RE_COMMENT_BEGIN = re.compile("\s*\/\*\*")
+RE_COMMENT_BEGIN = re.compile("\s*\/\*\*?")
RE_COMMENT_END = re.compile("\s*\*\/")
RE_CHANGE_MODE = re.compile("\s*\* @change_mode (\S+)\s*")
RE_ACCESS = re.compile("\s*\* @access (\S+)\s*")
diff --git a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
index d95bd03..b7984fa 100644
--- a/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
+++ b/wifi/supplicant/aidl/vts/functional/supplicant_p2p_iface_aidl_test.cpp
@@ -19,6 +19,7 @@
#include <aidl/Vintf.h>
#include <aidl/android/hardware/wifi/supplicant/BnSupplicant.h>
#include <aidl/android/hardware/wifi/supplicant/BnSupplicantP2pIfaceCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.h>
#include <android/binder_manager.h>
#include <android/binder_status.h>
#include <binder/IServiceManager.h>
@@ -38,6 +39,7 @@
using aidl::android::hardware::wifi::supplicant::P2pGroupCapabilityMask;
using aidl::android::hardware::wifi::supplicant::P2pProvDiscStatusCode;
using aidl::android::hardware::wifi::supplicant::P2pStatusCode;
+using aidl::android::hardware::wifi::supplicant::SupplicantStatusCode;
using aidl::android::hardware::wifi::supplicant::WpsConfigMethods;
using aidl::android::hardware::wifi::supplicant::WpsDevPasswordId;
using aidl::android::hardware::wifi::supplicant::WpsProvisionMethod;
@@ -413,7 +415,12 @@
*/
TEST_P(SupplicantP2pIfaceAidlTest, EnableMacRandomization) {
// Enable twice
- EXPECT_TRUE(p2p_iface_->setMacRandomization(true).isOk());
+ auto status = p2p_iface_->setMacRandomization(true);
+ if (!status.isOk() && status.getServiceSpecificError() ==
+ static_cast<int32_t>(SupplicantStatusCode::FAILURE_UNSUPPORTED)) {
+ GTEST_SKIP() << "Mac randomization is not supported.";
+ }
+ EXPECT_TRUE(status.isOk());
EXPECT_TRUE(p2p_iface_->setMacRandomization(true).isOk());
// Disable twice