Merge "Support 10-bit VTS readback" into main
diff --git a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
index 8addab7..aa1a86f 100644
--- a/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
+++ b/audio/aidl/aidl_api/android.hardware.audio.effect/current/android/hardware/audio/effect/HapticGenerator.aidl
@@ -55,6 +55,9 @@
parcelable HapticScale {
int id;
android.hardware.audio.effect.HapticGenerator.VibratorScale scale = android.hardware.audio.effect.HapticGenerator.VibratorScale.MUTE;
+ float scaleFactor = (-1.0f) /* -1.000000f */;
+ float adaptiveScaleFactor = (-1.0f) /* -1.000000f */;
+ const float UNDEFINED_SCALE_FACTOR = (-1.0f) /* -1.000000f */;
}
@VintfStability
parcelable VibratorInformation {
diff --git a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
index 3cc5acb..f882d63 100644
--- a/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
+++ b/audio/aidl/android/hardware/audio/effect/HapticGenerator.aidl
@@ -56,13 +56,51 @@
@VintfStability
parcelable HapticScale {
/**
+ * Representation of undefined scale factor, applied by default for backwards compatibility.
+ */
+ const float UNDEFINED_SCALE_FACTOR = -1.0f;
+
+ /**
* Audio track ID.
*/
int id;
+
/**
* Haptic intensity.
+ *
+ * This represents haptics scale as fixed levels defined by VibrationScale. If the field
+ * scaleFactor is defined then this will be ignored in favor of scaleFactor, otherwise this
+ * will be used to define the intensity for the haptics.
*/
VibratorScale scale = VibratorScale.MUTE;
+
+ /**
+ * Haptic scale factor.
+ *
+ * This is a continuous scale representation of VibratorScale, allowing flexible number of
+ * scale levels. If this field is defined then it will be used to define the intensity of
+ * the haptics, instead of the old VibratorScale field. If this field is undefined then the
+ * old VibratorScale field will be used.
+ *
+ * The value zero represents the same as VibratorScale.MUTE and the value one represents
+ * VibratorScale.NONE. Values in (0,1) should scale down, and values > 1 should scale up
+ * within hardware bounds. Negative values will be ignored.
+ */
+ float scaleFactor = -1.0f; // UNDEFINED_SCALE_FACTOR
+
+ /**
+ * Haptic adaptive scale factor.
+ *
+ * This is an additional scale value that should be applied on top of the vibrator scale to
+ * adapt to the device current state. This should be applied to linearly scale the haptic
+ * data after scale/scaleFactor is applied.
+ *
+ * The value zero mutes the haptics, even if the scale/scaleFactor are not set to MUTE/zero.
+ * The value one will not scale the haptics, and can be used as a constant for no-op.
+ * Values in (0,1) should scale down. Values > 1 should scale up within hardware bounds.
+ * Negative values will be ignored.
+ */
+ float adaptiveScaleFactor = -1.0f; // UNDEFINED_SCALE_FACTOR
}
/**
diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp
index 389860f..eecc972 100644
--- a/audio/aidl/default/Stream.cpp
+++ b/audio/aidl/default/Stream.cpp
@@ -663,10 +663,14 @@
}
StreamCommonImpl::~StreamCommonImpl() {
- if (!isClosed()) {
- LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak";
- stopWorker();
- // The worker and the context should clean up by themselves via destructors.
+ // It is responsibility of the class that implements 'DriverInterface' to call 'cleanupWorker'
+ // in the destructor. Note that 'cleanupWorker' can not be properly called from this destructor
+ // because any subclasses have already been destroyed and thus the 'DriverInterface'
+ // implementation is not valid. Thus, here it can only be asserted whether the subclass has done
+ // its job.
+ if (!mWorkerStopIssued && !isClosed()) {
+ LOG(FATAL) << __func__ << ": the stream implementation must call 'cleanupWorker' "
+ << "in order to clean up the worker thread.";
}
}
@@ -770,10 +774,7 @@
ndk::ScopedAStatus StreamCommonImpl::close() {
LOG(DEBUG) << __func__;
if (!isClosed()) {
- stopWorker();
- LOG(DEBUG) << __func__ << ": joining the worker thread...";
- mWorker->join();
- LOG(DEBUG) << __func__ << ": worker thread joined";
+ stopAndJoinWorker();
onClose(mWorker->setClosed());
return ndk::ScopedAStatus::ok();
} else {
@@ -791,6 +792,20 @@
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
}
+void StreamCommonImpl::cleanupWorker() {
+ if (!isClosed()) {
+ LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak";
+ stopAndJoinWorker();
+ }
+}
+
+void StreamCommonImpl::stopAndJoinWorker() {
+ stopWorker();
+ LOG(DEBUG) << __func__ << ": joining the worker thread...";
+ mWorker->join();
+ LOG(DEBUG) << __func__ << ": worker thread joined";
+}
+
void StreamCommonImpl::stopWorker() {
if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) {
LOG(DEBUG) << __func__ << ": asking the worker to exit...";
@@ -805,6 +820,7 @@
}
LOG(DEBUG) << __func__ << ": done";
}
+ mWorkerStopIssued = true;
}
ndk::ScopedAStatus StreamCommonImpl::updateMetadataCommon(const Metadata& metadata) {
diff --git a/audio/aidl/default/alsa/StreamAlsa.cpp b/audio/aidl/default/alsa/StreamAlsa.cpp
index e57d538..f548903 100644
--- a/audio/aidl/default/alsa/StreamAlsa.cpp
+++ b/audio/aidl/default/alsa/StreamAlsa.cpp
@@ -37,6 +37,10 @@
mConfig(alsa::getPcmConfig(getContext(), mIsInput)),
mReadWriteRetries(readWriteRetries) {}
+StreamAlsa::~StreamAlsa() {
+ cleanupWorker();
+}
+
::android::status_t StreamAlsa::init() {
return mConfig.has_value() ? ::android::OK : ::android::NO_INIT;
}
diff --git a/audio/aidl/default/bluetooth/StreamBluetooth.cpp b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
index efab470..6e1a811 100644
--- a/audio/aidl/default/bluetooth/StreamBluetooth.cpp
+++ b/audio/aidl/default/bluetooth/StreamBluetooth.cpp
@@ -66,6 +66,10 @@
1000),
mBtDeviceProxy(btDeviceProxy) {}
+StreamBluetooth::~StreamBluetooth() {
+ cleanupWorker();
+}
+
::android::status_t StreamBluetooth::init() {
std::lock_guard guard(mLock);
if (mBtDeviceProxy == nullptr) {
diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h
index 93ace96..100b4c8 100644
--- a/audio/aidl/default/include/core-impl/Stream.h
+++ b/audio/aidl/default/include/core-impl/Stream.h
@@ -457,6 +457,11 @@
}
virtual void onClose(StreamDescriptor::State statePriorToClosing) = 0;
+ // Any stream class implementing 'DriverInterface::shutdown' must call 'cleanupWorker' in
+ // the destructor in order to stop and join the worker thread in the case when the client
+ // has not called 'IStreamCommon::close' method.
+ void cleanupWorker();
+ void stopAndJoinWorker();
void stopWorker();
const StreamContext& mContext;
@@ -464,6 +469,9 @@
std::unique_ptr<StreamWorkerInterface> mWorker;
ChildInterface<StreamCommonDelegator> mCommon;
ConnectedDevices mConnectedDevices;
+
+ private:
+ std::atomic<bool> mWorkerStopIssued = false;
};
// Note: 'StreamIn/Out' can not be used on their own. Instead, they must be used for defining
diff --git a/audio/aidl/default/include/core-impl/StreamAlsa.h b/audio/aidl/default/include/core-impl/StreamAlsa.h
index 2c3b284..0356946 100644
--- a/audio/aidl/default/include/core-impl/StreamAlsa.h
+++ b/audio/aidl/default/include/core-impl/StreamAlsa.h
@@ -32,6 +32,8 @@
class StreamAlsa : public StreamCommonImpl {
public:
StreamAlsa(StreamContext* context, const Metadata& metadata, int readWriteRetries);
+ ~StreamAlsa();
+
// Methods of 'DriverInterface'.
::android::status_t init() override;
::android::status_t drain(StreamDescriptor::DrainMode) override;
diff --git a/audio/aidl/default/include/core-impl/StreamBluetooth.h b/audio/aidl/default/include/core-impl/StreamBluetooth.h
index 7f4239c..357a546 100644
--- a/audio/aidl/default/include/core-impl/StreamBluetooth.h
+++ b/audio/aidl/default/include/core-impl/StreamBluetooth.h
@@ -41,6 +41,8 @@
const std::shared_ptr<::android::bluetooth::audio::aidl::BluetoothAudioPortAidl>&
btDeviceProxy,
const ::aidl::android::hardware::bluetooth::audio::PcmConfiguration& pcmConfig);
+ ~StreamBluetooth();
+
// Methods of 'DriverInterface'.
::android::status_t init() override;
::android::status_t drain(StreamDescriptor::DrainMode) override;
diff --git a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
index 0d50c96..6ea7968 100644
--- a/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
+++ b/audio/aidl/default/include/core-impl/StreamRemoteSubmix.h
@@ -29,7 +29,9 @@
StreamRemoteSubmix(
StreamContext* context, const Metadata& metadata,
const ::aidl::android::media::audio::common::AudioDeviceAddress& deviceAddress);
+ ~StreamRemoteSubmix();
+ // Methods of 'DriverInterface'.
::android::status_t init() override;
::android::status_t drain(StreamDescriptor::DrainMode) override;
::android::status_t flush() override;
diff --git a/audio/aidl/default/include/core-impl/StreamStub.h b/audio/aidl/default/include/core-impl/StreamStub.h
index 3857e0e..22b2020 100644
--- a/audio/aidl/default/include/core-impl/StreamStub.h
+++ b/audio/aidl/default/include/core-impl/StreamStub.h
@@ -23,6 +23,8 @@
class StreamStub : public StreamCommonImpl {
public:
StreamStub(StreamContext* context, const Metadata& metadata);
+ ~StreamStub();
+
// Methods of 'DriverInterface'.
::android::status_t init() override;
::android::status_t drain(StreamDescriptor::DrainMode) override;
@@ -42,6 +44,10 @@
const bool mIsInput;
bool mIsInitialized = false; // Used for validating the state machine logic.
bool mIsStandby = true; // Used for validating the state machine logic.
+
+ // Used by the worker thread.
+ int64_t mStartTimeNs = 0;
+ long mFramesSinceStart = 0;
};
class StreamInStub final : public StreamIn, public StreamStub {
diff --git a/audio/aidl/default/include/core-impl/StreamUsb.h b/audio/aidl/default/include/core-impl/StreamUsb.h
index 608f27d..694fccf 100644
--- a/audio/aidl/default/include/core-impl/StreamUsb.h
+++ b/audio/aidl/default/include/core-impl/StreamUsb.h
@@ -29,6 +29,7 @@
class StreamUsb : public StreamAlsa {
public:
StreamUsb(StreamContext* context, const Metadata& metadata);
+
// Methods of 'DriverInterface'.
::android::status_t transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
int32_t* latencyMs) override;
diff --git a/audio/aidl/default/main.cpp b/audio/aidl/default/main.cpp
index 6ab747d..0b3e3ba 100644
--- a/audio/aidl/default/main.cpp
+++ b/audio/aidl/default/main.cpp
@@ -71,6 +71,7 @@
// For more logs, use VERBOSE, however this may hinder performance.
// android::base::SetMinimumLogSeverity(::android::base::VERBOSE);
ABinderProcess_setThreadPoolMaxThreadCount(16);
+ ABinderProcess_startThreadPool();
// Guaranteed log for b/210919187 and logd_integration_test
LOG(INFO) << "Init for Audio AIDL HAL";
diff --git a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
index a266b54..db105b6 100644
--- a/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
+++ b/audio/aidl/default/r_submix/StreamRemoteSubmix.cpp
@@ -43,6 +43,10 @@
mStreamConfig.sampleRate = context->getSampleRate();
}
+StreamRemoteSubmix::~StreamRemoteSubmix() {
+ cleanupWorker();
+}
+
::android::status_t StreamRemoteSubmix::init() {
mCurrentRoute = SubmixRoute::findOrCreateRoute(mDeviceAddress, mStreamConfig);
if (mCurrentRoute == nullptr) {
diff --git a/audio/aidl/default/stub/StreamStub.cpp b/audio/aidl/default/stub/StreamStub.cpp
index 2422fe4..a3d99a8 100644
--- a/audio/aidl/default/stub/StreamStub.cpp
+++ b/audio/aidl/default/stub/StreamStub.cpp
@@ -39,6 +39,10 @@
mIsAsynchronous(!!getContext().getAsyncCallback()),
mIsInput(isInput(metadata)) {}
+StreamStub::~StreamStub() {
+ cleanupWorker();
+}
+
::android::status_t StreamStub::init() {
mIsInitialized = true;
return ::android::OK;
@@ -79,7 +83,6 @@
if (!mIsInitialized) {
LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
}
- usleep(500);
mIsStandby = true;
return ::android::OK;
}
@@ -88,8 +91,9 @@
if (!mIsInitialized) {
LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
}
- usleep(500);
mIsStandby = false;
+ mStartTimeNs = ::android::uptimeNanos();
+ mFramesSinceStart = 0;
return ::android::OK;
}
@@ -101,14 +105,23 @@
if (mIsStandby) {
LOG(FATAL) << __func__ << ": must not happen while in standby";
}
- static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
- static constexpr float kScaleFactor = .8f;
+ *actualFrameCount = frameCount;
if (mIsAsynchronous) {
usleep(500);
} else {
- const size_t delayUs = static_cast<size_t>(
- std::roundf(kScaleFactor * frameCount * kMicrosPerSecond / mSampleRate));
- usleep(delayUs);
+ mFramesSinceStart += *actualFrameCount;
+ const long bufferDurationUs =
+ (*actualFrameCount) * MICROS_PER_SECOND / mContext.getSampleRate();
+ const auto totalDurationUs =
+ (::android::uptimeNanos() - mStartTimeNs) / NANOS_PER_MICROSECOND;
+ const long totalOffsetUs =
+ mFramesSinceStart * MICROS_PER_SECOND / mContext.getSampleRate() - totalDurationUs;
+ LOG(VERBOSE) << __func__ << ": totalOffsetUs " << totalOffsetUs;
+ if (totalOffsetUs > 0) {
+ const long sleepTimeUs = std::min(totalOffsetUs, bufferDurationUs);
+ LOG(VERBOSE) << __func__ << ": sleeping for " << sleepTimeUs << " us";
+ usleep(sleepTimeUs);
+ }
}
if (mIsInput) {
uint8_t* byteBuffer = static_cast<uint8_t*>(buffer);
@@ -116,7 +129,6 @@
byteBuffer[i] = std::rand() % 255;
}
}
- *actualFrameCount = frameCount;
return ::android::OK;
}
diff --git a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
index 6af326d..d8332aa 100644
--- a/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
+++ b/audio/aidl/vts/VtsHalHapticGeneratorTargetTest.cpp
@@ -42,13 +42,15 @@
PARAM_INSTANCE_NAME,
PARAM_HAPTIC_SCALE_ID,
PARAM_HAPTIC_SCALE_VIBRATOR_SCALE,
+ PARAM_HAPTIC_SCALE_SCALE_FACTOR,
+ PARAM_HAPTIC_SCALE_ADAPTIVE_SCALE_FACTOR,
PARAM_VIBRATION_INFORMATION_RESONANT_FREQUENCY,
PARAM_VIBRATION_INFORMATION_Q_FACTOR,
PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE,
};
using HapticGeneratorParamTestParam =
std::tuple<std::pair<std::shared_ptr<IFactory>, Descriptor>, int,
- HapticGenerator::VibratorScale, float, float, float>;
+ HapticGenerator::VibratorScale, float, float, float, float, float>;
/*
* Testing parameter range, assuming the parameter supported by effect is in this range.
@@ -67,6 +69,10 @@
const std::vector<HapticGenerator::VibratorScale> kVibratorScaleValues = {
ndk::enum_range<HapticGenerator::VibratorScale>().begin(),
ndk::enum_range<HapticGenerator::VibratorScale>().end()};
+const std::vector<float> kScaleFactorValues = {HapticGenerator::HapticScale::UNDEFINED_SCALE_FACTOR,
+ 0.0f, 0.5f, 1.0f, MAX_FLOAT};
+const std::vector<float> kAdaptiveScaleFactorValues = {
+ HapticGenerator::HapticScale::UNDEFINED_SCALE_FACTOR, 0.0f, 0.5f, 1.0f, MAX_FLOAT};
const std::vector<float> kResonantFrequencyValues = {MIN_FLOAT, 100, MAX_FLOAT};
const std::vector<float> kQFactorValues = {MIN_FLOAT, 100, MAX_FLOAT};
@@ -78,6 +84,8 @@
HapticGeneratorParamTest()
: mParamHapticScaleId(std::get<PARAM_HAPTIC_SCALE_ID>(GetParam())),
mParamVibratorScale(std::get<PARAM_HAPTIC_SCALE_VIBRATOR_SCALE>(GetParam())),
+ mParamScaleFactor(std::get<PARAM_HAPTIC_SCALE_SCALE_FACTOR>(GetParam())),
+ mParamAdaptiveScaleFactor(std::get<PARAM_HAPTIC_SCALE_ADAPTIVE_SCALE_FACTOR>(GetParam())),
mParamResonantFrequency(
std::get<PARAM_VIBRATION_INFORMATION_RESONANT_FREQUENCY>(GetParam())),
mParamQFactor(std::get<PARAM_VIBRATION_INFORMATION_Q_FACTOR>(GetParam())),
@@ -107,6 +115,8 @@
Descriptor mDescriptor;
int mParamHapticScaleId = 0;
HapticGenerator::VibratorScale mParamVibratorScale = HapticGenerator::VibratorScale::MUTE;
+ float mParamScaleFactor = HapticGenerator::HapticScale::UNDEFINED_SCALE_FACTOR;
+ float mParamAdaptiveScaleFactor = HapticGenerator::HapticScale::UNDEFINED_SCALE_FACTOR;
float mParamResonantFrequency = 0;
float mParamQFactor = 0;
float mParamMaxAmplitude = 0;
@@ -135,9 +145,14 @@
}
}
- void addHapticScaleParam(int id, HapticGenerator::VibratorScale scale) {
+ void addHapticScaleParam(int id, HapticGenerator::VibratorScale scale, float scaleFactor,
+ float adaptiveScaleFactor) {
HapticGenerator setHg;
- std::vector<HapticGenerator::HapticScale> hapticScales = {{.id = id, .scale = scale}};
+ std::vector<HapticGenerator::HapticScale> hapticScales = {
+ {.id = id,
+ .scale = scale,
+ .scaleFactor = scaleFactor,
+ .adaptiveScaleFactor = adaptiveScaleFactor}};
setHg.set<HapticGenerator::hapticScales>(hapticScales);
mTags.push_back({HapticGenerator::hapticScales, setHg});
}
@@ -160,13 +175,16 @@
};
TEST_P(HapticGeneratorParamTest, SetAndGetHapticScale) {
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale,
+ mParamScaleFactor, mParamAdaptiveScaleFactor));
SetAndGetHapticGeneratorParameters();
}
TEST_P(HapticGeneratorParamTest, SetAndGetMultipleHapticScales) {
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
- EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale));
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale,
+ mParamScaleFactor, mParamAdaptiveScaleFactor));
+ EXPECT_NO_FATAL_FAILURE(addHapticScaleParam(mParamHapticScaleId, mParamVibratorScale,
+ mParamScaleFactor, mParamAdaptiveScaleFactor));
SetAndGetHapticGeneratorParameters();
}
@@ -182,6 +200,8 @@
IFactory::descriptor, getEffectTypeUuidHapticGenerator())),
testing::ValuesIn(kHapticScaleIdValues),
testing::ValuesIn(kVibratorScaleValues),
+ testing::ValuesIn(kScaleFactorValues),
+ testing::ValuesIn(kAdaptiveScaleFactorValues),
testing::ValuesIn(kResonantFrequencyValues),
testing::ValuesIn(kQFactorValues), testing::ValuesIn(kMaxAmplitude)),
[](const testing::TestParamInfo<HapticGeneratorParamTest::ParamType>& info) {
@@ -189,6 +209,10 @@
std::string hapticScaleID = std::to_string(std::get<PARAM_HAPTIC_SCALE_ID>(info.param));
std::string hapticScaleVibScale = std::to_string(
static_cast<int>(std::get<PARAM_HAPTIC_SCALE_VIBRATOR_SCALE>(info.param)));
+ std::string hapticScaleFactor =
+ std::to_string(std::get<PARAM_HAPTIC_SCALE_SCALE_FACTOR>(info.param));
+ std::string hapticAdaptiveScaleFactor =
+ std::to_string(std::get<PARAM_HAPTIC_SCALE_ADAPTIVE_SCALE_FACTOR>(info.param));
std::string resonantFrequency = std::to_string(
std::get<PARAM_VIBRATION_INFORMATION_RESONANT_FREQUENCY>(info.param));
std::string qFactor =
@@ -196,7 +220,9 @@
std::string maxAmplitude =
std::to_string(std::get<PARAM_VIBRATION_INFORMATION_MAX_AMPLITUDE>(info.param));
std::string name = getPrefix(descriptor) + "_hapticScaleId" + hapticScaleID +
- "_hapticScaleVibScale" + hapticScaleVibScale + "_resonantFrequency" +
+ "_hapticScaleVibScale" + hapticScaleVibScale + "_hapticScaleFactor" +
+ hapticScaleFactor + "_hapticAdaptiveScaleFactor" +
+ hapticAdaptiveScaleFactor + "_resonantFrequency" +
resonantFrequency + "_qFactor" + qFactor + "_maxAmplitude" +
maxAmplitude;
std::replace_if(
@@ -210,6 +236,8 @@
IFactory::descriptor, getEffectTypeUuidHapticGenerator())),
testing::Values(MIN_ID),
testing::Values(HapticGenerator::VibratorScale::NONE),
+ testing::Values(HapticGenerator::HapticScale::UNDEFINED_SCALE_FACTOR),
+ testing::Values(HapticGenerator::HapticScale::UNDEFINED_SCALE_FACTOR),
testing::Values(MIN_FLOAT), testing::Values(MIN_FLOAT),
testing::Values(MIN_FLOAT)),
[](const testing::TestParamInfo<HapticGeneratorParamTest::ParamType>& info) {
@@ -217,6 +245,10 @@
std::string hapticScaleID = std::to_string(std::get<PARAM_HAPTIC_SCALE_ID>(info.param));
std::string hapticScaleVibScale = std::to_string(
static_cast<int>(std::get<PARAM_HAPTIC_SCALE_VIBRATOR_SCALE>(info.param)));
+ std::string hapticScaleFactor =
+ std::to_string(std::get<PARAM_HAPTIC_SCALE_SCALE_FACTOR>(info.param));
+ std::string hapticAdaptiveScaleFactor =
+ std::to_string(std::get<PARAM_HAPTIC_SCALE_ADAPTIVE_SCALE_FACTOR>(info.param));
std::string resonantFrequency = std::to_string(
std::get<PARAM_VIBRATION_INFORMATION_RESONANT_FREQUENCY>(info.param));
std::string qFactor =
@@ -227,6 +259,8 @@
descriptor.common.name + "_UUID_" +
toString(descriptor.common.id.uuid) + "_hapticScaleId" +
hapticScaleID + "_hapticScaleVibScale" + hapticScaleVibScale +
+ "_hapticScaleFactor" + hapticScaleFactor +
+ "_hapticAdaptiveScaleFactor" + hapticAdaptiveScaleFactor +
"_resonantFrequency" + resonantFrequency + "_qFactor" + qFactor +
"_maxAmplitude" + maxAmplitude;
std::replace_if(
diff --git a/automotive/vehicle/aidl/impl/proto/Android.bp b/automotive/vehicle/aidl/impl/proto/Android.bp
index b2edf75..1d35e0c 100644
--- a/automotive/vehicle/aidl/impl/proto/Android.bp
+++ b/automotive/vehicle/aidl/impl/proto/Android.bp
@@ -106,3 +106,17 @@
"-Wno-unused-parameter",
],
}
+
+rust_protobuf {
+ name: "libvehicle_hal_property_protos",
+ crate_name: "vehicle_hal_property_protos",
+ protos: [":VehicleHalProtoFiles"],
+ source_stem: "vehicle_hal_property_protos",
+ host_supported: true,
+ vendor_available: true,
+ product_available: true,
+ exported_include_dirs: ["."],
+ proto_flags: [
+ "-I external/protobuf/src",
+ ],
+}
diff --git a/compatibility_matrices/compatibility_matrix.202504.xml b/compatibility_matrices/compatibility_matrix.202504.xml
index 30ddec4..9b7866c 100644
--- a/compatibility_matrices/compatibility_matrix.202504.xml
+++ b/compatibility_matrices/compatibility_matrix.202504.xml
@@ -26,14 +26,6 @@
<instance>default</instance>
</interface>
</hal>
- <hal format="aidl">
- <name>android.hardware.audio.sounddose</name>
- <version>1-3</version>
- <interface>
- <name>ISoundDoseFactory</name>
- <instance>default</instance>
- </interface>
- </hal>
<hal format="aidl" updatable-via-apex="true">
<name>android.hardware.authsecret</name>
<version>1</version>
diff --git a/compatibility_matrices/exclude/fcm_exclude.cpp b/compatibility_matrices/exclude/fcm_exclude.cpp
index fca9e1c..b86f399 100644
--- a/compatibility_matrices/exclude/fcm_exclude.cpp
+++ b/compatibility_matrices/exclude/fcm_exclude.cpp
@@ -167,6 +167,7 @@
"android.hardware.audio.core.sounddose@3",
// Deprecated HALs.
+ "android.hardware.audio.sounddose@3",
"android.hardware.bluetooth.audio@1",
};
diff --git a/media/bufferpool/aidl/default/BufferPoolClient.cpp b/media/bufferpool/aidl/default/BufferPoolClient.cpp
index ce4ad8e..b61893f 100644
--- a/media/bufferpool/aidl/default/BufferPoolClient.cpp
+++ b/media/bufferpool/aidl/default/BufferPoolClient.cpp
@@ -748,6 +748,10 @@
} else {
connection = mRemoteConnection;
}
+ if (!connection) {
+ ALOGE("connection null: fetchBufferHandle()");
+ return ResultStatus::CRITICAL_ERROR;
+ }
std::vector<FetchInfo> infos;
std::vector<FetchResult> results;
infos.emplace_back(FetchInfo{ToAidl(transactionId), ToAidl(bufferId)});
diff --git a/tv/tuner/aidl/Android.bp b/tv/tuner/aidl/Android.bp
index 6cbf362..efcc327 100644
--- a/tv/tuner/aidl/Android.bp
+++ b/tv/tuner/aidl/Android.bp
@@ -41,6 +41,5 @@
},
],
- frozen: true,
}
diff --git a/tv/tuner/aidl/default/Android.bp b/tv/tuner/aidl/default/Android.bp
index ed97d9c..5dbc7f6 100644
--- a/tv/tuner/aidl/default/Android.bp
+++ b/tv/tuner/aidl/default/Android.bp
@@ -30,7 +30,7 @@
],
shared_libs: [
"android.hardware.common.fmq-V1-ndk",
- "android.hardware.tv.tuner-V2-ndk",
+ "android.hardware.tv.tuner-V3-ndk",
"libbase",
"libbinder_ndk",
"libcutils",
diff --git a/tv/tuner/aidl/vts/functional/Android.bp b/tv/tuner/aidl/vts/functional/Android.bp
index 09e63fc..0057b6f 100644
--- a/tv/tuner/aidl/vts/functional/Android.bp
+++ b/tv/tuner/aidl/vts/functional/Android.bp
@@ -55,7 +55,7 @@
"android.hardware.cas-V1-ndk",
"android.hardware.common-V2-ndk",
"android.hardware.common.fmq-V1-ndk",
- "android.hardware.tv.tuner-V2-ndk",
+ "android.hardware.tv.tuner-V3-ndk",
"libaidlcommonsupport",
"libfmq",
"libcutils",
diff --git a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VendorEffect.aidl b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VendorEffect.aidl
index 1900084..62a7380 100644
--- a/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VendorEffect.aidl
+++ b/vibrator/aidl/aidl_api/android.hardware.vibrator/current/android/hardware/vibrator/VendorEffect.aidl
@@ -37,4 +37,5 @@
android.os.PersistableBundle vendorData;
android.hardware.vibrator.EffectStrength strength = android.hardware.vibrator.EffectStrength.MEDIUM;
float scale;
+ float vendorScale;
}
diff --git a/vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl b/vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl
index 2155aca..6b1af53 100644
--- a/vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl
+++ b/vibrator/aidl/android/hardware/vibrator/VendorEffect.aidl
@@ -36,16 +36,35 @@
/**
* The intensity of the haptic effect.
+ *
+ * This value is defined by discrete scale levels that represents the intensity of this haptic
+ * effect. This is a discrete representation of the scale parameter below.
*/
EffectStrength strength = EffectStrength.MEDIUM;
/**
- * A scale to be applied to the haptic effect intensity.
+ * The intensity of the haptic effect.
*
- * This value represents a linear scale that should be applied on top of the effect strength to
- * dynamically adapt to the device state.
+ * This value is defined by continuous scale that represents the intensity of this haptic
+ * effect. The vendor implementation can follow the platform scaling function or customize the
+ * implementation to their needs. This is a continuous representation of the strength parameter
+ * above.
*
* Values in [0,1) should scale down. Values > 1 should scale up within hardware bounds.
*/
float scale;
+
+ /**
+ * The dynamic scale parameter provided by the vendor vibrator controller.
+ *
+ * This value is the same provided by the vendor to the platform IVibratorControlService and
+ * should be applied on top of the effect intensity provided by the strength/scale fields.
+ * The vendor can use this to dynamically adapt the haptic effect intensity to the device state.
+ *
+ * See frameworks/hardware/interfaces/vibrator for more documentation on vendor vibrator
+ * controller, and ScaleParam for more about this scale parameter.
+ *
+ * Values in [0,1) should scale down. Values > 1 should scale up within hardware bounds.
+ */
+ float vendorScale;
}
diff --git a/vibrator/aidl/default/Vibrator.cpp b/vibrator/aidl/default/Vibrator.cpp
index acf7d34..29e7d18 100644
--- a/vibrator/aidl/default/Vibrator.cpp
+++ b/vibrator/aidl/default/Vibrator.cpp
@@ -117,6 +117,10 @@
if (scale <= 0) {
return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
}
+ float vendorScale = effect.vendorScale;
+ if (vendorScale <= 0) {
+ return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
+ }
int32_t durationMs = 0;
if (!effect.vendorData.getInt("DURATION_MS", &durationMs) || durationMs <= 0) {
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 706ab41..2502589 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -366,7 +366,8 @@
TEST_P(VibratorAidl, PerformVendorEffectSupported) {
if ((capabilities & IVibrator::CAP_PERFORM_VENDOR_EFFECTS) == 0) return;
- float scale = 0.5f;
+ float scale = 0.0f;
+ float vendorScale = 0.0f;
for (EffectStrength strength : kEffectStrengths) {
PersistableBundle vendorData;
::aidl::android::hardware::vibrator::testing::fillBasicData(&vendorData);
@@ -379,7 +380,9 @@
effect.vendorData = vendorData;
effect.strength = strength;
effect.scale = scale;
- scale *= 1.5f;
+ effect.vendorScale = vendorScale;
+ scale += 0.5f;
+ vendorScale += 0.2f;
auto callback = ndk::SharedRefBase::make<CompletionCallback>([] {});
ndk::ScopedAStatus status = vibrator->performVendorEffect(effect, callback);
@@ -408,6 +411,7 @@
for (EffectStrength strength : kEffectStrengths) {
float scale = 0.5f;
+ float vendorScale = 0.2f;
for (uint8_t i = 0; i < iterations; i++) {
PersistableBundle vendorData;
::aidl::android::hardware::vibrator::testing::fillRandomData(&vendorData);
@@ -416,7 +420,9 @@
effect.vendorData = vendorData;
effect.strength = strength;
effect.scale = scale;
+ effect.vendorScale = vendorScale;
scale *= 2;
+ vendorScale *= 1.5f;
auto callback = ndk::SharedRefBase::make<CompletionCallback>([] {});
ndk::ScopedAStatus status = vibrator->performVendorEffect(effect, callback);
@@ -444,6 +450,7 @@
VendorEffect effect;
effect.strength = strength;
effect.scale = 1.0f;
+ effect.vendorScale = 1.0f;
ndk::ScopedAStatus status = vibrator->performVendorEffect(effect, nullptr /*callback*/);
@@ -459,10 +466,12 @@
VendorEffect effect;
effect.strength = EffectStrength::MEDIUM;
- effect.scale = 0.0f;
+ effect.scale = -1.0f;
+ effect.vendorScale = 1.0f;
EXPECT_ILLEGAL_ARGUMENT(vibrator->performVendorEffect(effect, nullptr /*callback*/));
- effect.scale = -1.0f;
+ effect.scale = 1.0f;
+ effect.vendorScale = -1.0f;
EXPECT_ILLEGAL_ARGUMENT(vibrator->performVendorEffect(effect, nullptr /*callback*/));
}
@@ -473,6 +482,7 @@
VendorEffect effect;
effect.strength = strength;
effect.scale = 1.0f;
+ effect.vendorScale = 1.0f;
EXPECT_UNKNOWN_OR_UNSUPPORTED(vibrator->performVendorEffect(effect, nullptr /*callback*/))
<< "\n For vendor effect with strength " << toString(strength);