Merge "Update HAL with new PWLE V2 APIs" 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.202404.xml b/compatibility_matrices/compatibility_matrix.202404.xml
index 9ea476a..aa6b8f0 100644
--- a/compatibility_matrices/compatibility_matrix.202404.xml
+++ b/compatibility_matrices/compatibility_matrix.202404.xml
@@ -28,7 +28,7 @@
</hal>
<hal format="aidl">
<name>android.hardware.audio.sounddose</name>
- <version>1-2</version>
+ <version>1-3</version>
<interface>
<name>ISoundDoseFactory</name>
<instance>default</instance>
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/graphics/composer/aidl/vts/ReadbackVts.cpp b/graphics/composer/aidl/vts/ReadbackVts.cpp
index 283b8ce..9d5928d 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.cpp
+++ b/graphics/composer/aidl/vts/ReadbackVts.cpp
@@ -16,6 +16,7 @@
#include "ReadbackVts.h"
#include <aidl/android/hardware/graphics/common/BufferUsage.h>
+#include <cmath>
#include "RenderEngineVts.h"
#include "renderengine/ExternalTexture.h"
#include "renderengine/impl/ExternalTexture.h"
@@ -106,37 +107,72 @@
return layerSettings;
}
-int32_t ReadbackHelper::GetBytesPerPixel(common::PixelFormat pixelFormat) {
+int32_t ReadbackHelper::GetBitsPerChannel(common::PixelFormat pixelFormat) {
switch (pixelFormat) {
+ case common::PixelFormat::RGBA_1010102:
+ return 10;
case common::PixelFormat::RGBA_8888:
- return 4;
case common::PixelFormat::RGB_888:
- return 3;
+ return 8;
default:
return -1;
}
}
-void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
+int32_t ReadbackHelper::GetAlphaBits(common::PixelFormat pixelFormat) {
+ switch (pixelFormat) {
+ case common::PixelFormat::RGBA_8888:
+ return 8;
+ case common::PixelFormat::RGBA_1010102:
+ return 2;
+ case common::PixelFormat::RGB_888:
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+void ReadbackHelper::fillBuffer(uint32_t width, uint32_t height, uint32_t stride,
+ int32_t bytesPerPixel, void* bufferData,
common::PixelFormat pixelFormat,
std::vector<Color> desiredPixelColors) {
ASSERT_TRUE(pixelFormat == common::PixelFormat::RGB_888 ||
- pixelFormat == common::PixelFormat::RGBA_8888);
- int32_t bytesPerPixel = GetBytesPerPixel(pixelFormat);
+ pixelFormat == common::PixelFormat::RGBA_8888 ||
+ pixelFormat == common::PixelFormat::RGBA_1010102);
+ int32_t bitsPerChannel = GetBitsPerChannel(pixelFormat);
+ int32_t alphaBits = GetAlphaBits(pixelFormat);
+ ASSERT_NE(-1, alphaBits);
+ ASSERT_NE(-1, bitsPerChannel);
ASSERT_NE(-1, bytesPerPixel);
- for (int row = 0; row < height; row++) {
- for (int col = 0; col < width; col++) {
- auto pixel = row * static_cast<int32_t>(width) + col;
+
+ uint32_t maxValue = (1 << bitsPerChannel) - 1;
+ uint32_t maxAlphaValue = (1 << alphaBits) - 1;
+ for (uint32_t row = 0; row < height; row++) {
+ for (uint32_t col = 0; col < width; col++) {
+ auto pixel = row * width + col;
Color srcColor = desiredPixelColors[static_cast<size_t>(pixel)];
- int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
- uint8_t* pixelColor = (uint8_t*)bufferData + offset;
- pixelColor[0] = static_cast<uint8_t>(std::round(255.0f * srcColor.r));
- pixelColor[1] = static_cast<uint8_t>(std::round(255.0f * srcColor.g));
- pixelColor[2] = static_cast<uint8_t>(std::round(255.0f * srcColor.b));
+ uint32_t offset = (row * stride + col) * static_cast<uint32_t>(bytesPerPixel);
- if (bytesPerPixel == 4) {
- pixelColor[3] = static_cast<uint8_t>(std::round(255.0f * srcColor.a));
+ uint32_t* pixelStart = (uint32_t*)((uint8_t*)bufferData + offset);
+
+ uint32_t red = static_cast<uint32_t>(std::round(maxValue * srcColor.r));
+ uint32_t green = static_cast<uint32_t>(std::round(maxValue * srcColor.g));
+ uint32_t blue = static_cast<uint32_t>(std::round(maxValue * srcColor.b));
+
+ // Boo we're not word aligned so special case this.
+ if (pixelFormat == common::PixelFormat::RGB_888) {
+ uint8_t* pixelColor = (uint8_t*)pixelStart;
+ pixelColor[0] = static_cast<uint8_t>(red);
+ pixelColor[1] = static_cast<uint8_t>(green);
+ pixelColor[2] = static_cast<uint8_t>(blue);
+ } else {
+ uint32_t alpha = static_cast<uint32_t>(std::round(maxAlphaValue * srcColor.a));
+ uint32_t color = (alpha << (32 - alphaBits)) |
+ (blue << (32 - alphaBits - bitsPerChannel)) |
+ (green << (32 - alphaBits - bitsPerChannel * 2)) |
+ (red << (32 - alphaBits - bitsPerChannel * 3));
+ *pixelStart = color;
}
}
}
@@ -165,7 +201,8 @@
bool ReadbackHelper::readbackSupported(const common::PixelFormat& pixelFormat,
const common::Dataspace& dataspace) {
if (pixelFormat != common::PixelFormat::RGB_888 &&
- pixelFormat != common::PixelFormat::RGBA_8888) {
+ pixelFormat != common::PixelFormat::RGBA_8888 &&
+ pixelFormat != common::PixelFormat::RGBA_1010102) {
return false;
}
if (std::find(dataspaces.begin(), dataspaces.end(), dataspace) == dataspaces.end()) {
@@ -175,36 +212,110 @@
}
void ReadbackHelper::compareColorBuffers(const std::vector<Color>& expectedColors, void* bufferData,
- const uint32_t stride, const uint32_t width,
- const uint32_t height, common::PixelFormat pixelFormat) {
- const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
- ASSERT_NE(-1, bytesPerPixel);
- for (int row = 0; row < height; row++) {
- for (int col = 0; col < width; col++) {
- auto pixel = row * static_cast<int32_t>(width) + col;
- int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
- uint8_t* pixelColor = (uint8_t*)bufferData + offset;
+ const uint32_t stride, int32_t bytesPerPixel,
+ const uint32_t width, const uint32_t height,
+ common::PixelFormat pixelFormat) {
+ int32_t bitsPerChannel = GetBitsPerChannel(pixelFormat);
+ int32_t alphaBits = GetAlphaBits(pixelFormat);
+ ASSERT_GT(bytesPerPixel, 0);
+ ASSERT_NE(-1, alphaBits);
+ ASSERT_NE(-1, bitsPerChannel);
+ uint32_t maxValue = (1 << bitsPerChannel) - 1;
+ uint32_t maxAlphaValue = (1 << alphaBits) - 1;
+ for (uint32_t row = 0; row < height; row++) {
+ for (uint32_t col = 0; col < width; col++) {
+ auto pixel = row * width + col;
const Color expectedColor = expectedColors[static_cast<size_t>(pixel)];
- ASSERT_EQ(std::round(255.0f * expectedColor.r), pixelColor[0]);
- ASSERT_EQ(std::round(255.0f * expectedColor.g), pixelColor[1]);
- ASSERT_EQ(std::round(255.0f * expectedColor.b), pixelColor[2]);
+
+ uint32_t offset = (row * stride + col) * static_cast<uint32_t>(bytesPerPixel);
+ uint32_t* pixelStart = (uint32_t*)((uint8_t*)bufferData + offset);
+
+ uint32_t expectedRed = static_cast<uint32_t>(std::round(maxValue * expectedColor.r));
+ uint32_t expectedGreen = static_cast<uint32_t>(std::round(maxValue * expectedColor.g));
+ uint32_t expectedBlue = static_cast<uint32_t>(std::round(maxValue * expectedColor.b));
+
+ // Boo we're not word aligned so special case this.
+ if (pixelFormat == common::PixelFormat::RGB_888) {
+ uint8_t* pixelColor = (uint8_t*)pixelStart;
+ ASSERT_EQ(pixelColor[0], static_cast<uint8_t>(expectedRed))
+ << "Red channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(pixelColor[1], static_cast<uint8_t>(expectedGreen))
+ << "Green channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(pixelColor[2], static_cast<uint8_t>(expectedBlue))
+ << "Blue channel mismatch at (" << row << ", " << col << ")";
+ } else {
+ uint32_t expectedAlpha =
+ static_cast<uint32_t>(std::round(maxAlphaValue * expectedColor.a));
+
+ uint32_t actualRed =
+ (*pixelStart >> (32 - alphaBits - bitsPerChannel * 3)) & maxValue;
+ uint32_t actualGreen =
+ (*pixelStart >> (32 - alphaBits - bitsPerChannel * 2)) & maxValue;
+ uint32_t actualBlue = (*pixelStart >> (32 - alphaBits - bitsPerChannel)) & maxValue;
+ uint32_t actualAlpha = (*pixelStart >> (32 - alphaBits)) & maxAlphaValue;
+
+ ASSERT_EQ(expectedRed, actualRed)
+ << "Red channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(expectedGreen, actualGreen)
+ << "Green channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(expectedBlue, actualBlue)
+ << "Blue channel mismatch at (" << row << ", " << col << ")";
+ }
}
}
}
void ReadbackHelper::compareColorBuffers(void* expectedBuffer, void* actualBuffer,
- const uint32_t stride, const uint32_t width,
- const uint32_t height, common::PixelFormat pixelFormat) {
- const int32_t bytesPerPixel = ReadbackHelper::GetBytesPerPixel(pixelFormat);
- ASSERT_NE(-1, bytesPerPixel);
- for (int row = 0; row < height; row++) {
- for (int col = 0; col < width; col++) {
- int offset = (row * static_cast<int32_t>(stride) + col) * bytesPerPixel;
- uint8_t* expectedColor = (uint8_t*)expectedBuffer + offset;
- uint8_t* actualColor = (uint8_t*)actualBuffer + offset;
- ASSERT_EQ(expectedColor[0], actualColor[0]);
- ASSERT_EQ(expectedColor[1], actualColor[1]);
- ASSERT_EQ(expectedColor[2], actualColor[2]);
+ const uint32_t stride, int32_t bytesPerPixel,
+ const uint32_t width, const uint32_t height,
+ common::PixelFormat pixelFormat) {
+ int32_t bitsPerChannel = GetBitsPerChannel(pixelFormat);
+ int32_t alphaBits = GetAlphaBits(pixelFormat);
+ ASSERT_GT(bytesPerPixel, 0);
+ ASSERT_NE(-1, alphaBits);
+ ASSERT_NE(-1, bitsPerChannel);
+ uint32_t maxValue = (1 << bitsPerChannel) - 1;
+ uint32_t maxAlphaValue = (1 << alphaBits) - 1;
+ for (uint32_t row = 0; row < height; row++) {
+ for (uint32_t col = 0; col < width; col++) {
+ uint32_t offset = (row * stride + col) * static_cast<uint32_t>(bytesPerPixel);
+ uint32_t* expectedStart = (uint32_t*)((uint8_t*)expectedBuffer + offset);
+ uint32_t* actualStart = (uint32_t*)((uint8_t*)actualBuffer + offset);
+
+ // Boo we're not word aligned so special case this.
+ if (pixelFormat == common::PixelFormat::RGB_888) {
+ uint8_t* expectedPixel = (uint8_t*)expectedStart;
+ uint8_t* actualPixel = (uint8_t*)actualStart;
+ ASSERT_EQ(actualPixel[0], expectedPixel[0])
+ << "Red channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(actualPixel[1], expectedPixel[1])
+ << "Green channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(actualPixel[2], expectedPixel[2])
+ << "Blue channel mismatch at (" << row << ", " << col << ")";
+ } else {
+ uint32_t expectedRed =
+ (*expectedStart >> (32 - alphaBits - bitsPerChannel * 3)) & maxValue;
+ uint32_t expectedGreen =
+ (*expectedStart >> (32 - alphaBits - bitsPerChannel * 2)) & maxValue;
+ uint32_t expectedBlue =
+ (*expectedStart >> (32 - alphaBits - bitsPerChannel)) & maxValue;
+ uint32_t expectedAlpha = (*expectedStart >> (32 - alphaBits)) & maxAlphaValue;
+
+ uint32_t actualRed =
+ (*actualStart >> (32 - alphaBits - bitsPerChannel * 3)) & maxValue;
+ uint32_t actualGreen =
+ (*actualStart >> (32 - alphaBits - bitsPerChannel * 2)) & maxValue;
+ uint32_t actualBlue =
+ (*actualStart >> (32 - alphaBits - bitsPerChannel)) & maxValue;
+ uint32_t actualAlpha = (*actualStart >> (32 - alphaBits)) & maxAlphaValue;
+
+ ASSERT_EQ(expectedRed, actualRed)
+ << "Red channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(expectedGreen, actualGreen)
+ << "Green channel mismatch at (" << row << ", " << col << ")";
+ ASSERT_EQ(expectedBlue, actualBlue)
+ << "Blue channel mismatch at (" << row << ", " << col << ")";
+ }
}
}
}
@@ -258,12 +369,13 @@
auto status = mGraphicBuffer->lockAsync(mUsage, mAccessRegion, &bufData, dup(bufferFence.get()),
&bytesPerPixel, &bytesPerStride);
EXPECT_EQ(::android::OK, status);
- ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888);
+ ASSERT_TRUE(mPixelFormat == PixelFormat::RGB_888 || mPixelFormat == PixelFormat::RGBA_8888 ||
+ mPixelFormat == PixelFormat::RGBA_1010102);
const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
: mGraphicBuffer->getStride();
- ReadbackHelper::compareColorBuffers(expectedColors, bufData, stride, mWidth, mHeight,
- mPixelFormat);
+ ReadbackHelper::compareColorBuffers(expectedColors, bufData, stride, bytesPerPixel, mWidth,
+ mHeight, mPixelFormat);
status = mGraphicBuffer->unlock();
EXPECT_EQ(::android::OK, status);
}
@@ -353,8 +465,8 @@
? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
: mGraphicBuffer->getStride();
EXPECT_EQ(::android::OK, status);
- ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, stride, bufData,
- mPixelFormat, expectedColors));
+ ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(mWidth, mHeight, stride, bytesPerPixel,
+ bufData, mPixelFormat, expectedColors));
const auto unlockStatus = mGraphicBuffer->unlockAsync(&mFillFence);
ASSERT_EQ(::android::OK, unlockStatus);
diff --git a/graphics/composer/aidl/vts/ReadbackVts.h b/graphics/composer/aidl/vts/ReadbackVts.h
index 8ac0f4b..e3b2384 100644
--- a/graphics/composer/aidl/vts/ReadbackVts.h
+++ b/graphics/composer/aidl/vts/ReadbackVts.h
@@ -172,10 +172,12 @@
static Dataspace getDataspaceForColorMode(ColorMode mode);
- static int32_t GetBytesPerPixel(PixelFormat pixelFormat);
+ static int32_t GetBitsPerChannel(PixelFormat pixelFormat);
+ static int32_t GetAlphaBits(PixelFormat pixelFormat);
- static void fillBuffer(uint32_t width, uint32_t height, uint32_t stride, void* bufferData,
- PixelFormat pixelFormat, std::vector<Color> desiredPixelColors);
+ static void fillBuffer(uint32_t width, uint32_t height, uint32_t stride, int32_t bytesPerPixel,
+ void* bufferData, PixelFormat pixelFormat,
+ std::vector<Color> desiredPixelColors);
static void clearColors(std::vector<Color>& expectedColors, int32_t width, int32_t height,
int32_t displayWidth);
@@ -189,11 +191,12 @@
static const std::vector<Dataspace> dataspaces;
static void compareColorBuffers(const std::vector<Color>& expectedColors, void* bufferData,
- const uint32_t stride, const uint32_t width,
- const uint32_t height, PixelFormat pixelFormat);
- static void compareColorBuffers(void* expectedBuffer, void* actualBuffer, const uint32_t stride,
+ const uint32_t stride, int32_t bytesPerPixel,
const uint32_t width, const uint32_t height,
PixelFormat pixelFormat);
+ static void compareColorBuffers(void* expectedBuffer, void* actualBuffer, const uint32_t stride,
+ int32_t bytesPerPixel, const uint32_t width,
+ const uint32_t height, PixelFormat pixelFormat);
};
class ReadbackBuffer {
diff --git a/graphics/composer/aidl/vts/RenderEngineVts.cpp b/graphics/composer/aidl/vts/RenderEngineVts.cpp
index 4e7f773..48cb8ae 100644
--- a/graphics/composer/aidl/vts/RenderEngineVts.cpp
+++ b/graphics/composer/aidl/vts/RenderEngineVts.cpp
@@ -83,7 +83,7 @@
const uint32_t stride = (bytesPerPixel > 0 && bytesPerStride > 0)
? static_cast<uint32_t>(bytesPerStride / bytesPerPixel)
: mGraphicBuffer->getStride();
- ReadbackHelper::compareColorBuffers(expectedColors, bufferData, stride,
+ ReadbackHelper::compareColorBuffers(expectedColors, bufferData, stride, bytesPerPixel,
mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(),
mFormat);
ASSERT_EQ(::android::OK, mGraphicBuffer->unlock());
@@ -110,7 +110,7 @@
ASSERT_EQ(renderedStride, bufferStride);
- ReadbackHelper::compareColorBuffers(renderedBufferData, bufferData, bufferStride,
+ ReadbackHelper::compareColorBuffers(renderedBufferData, bufferData, bufferStride, bytesPerPixel,
mGraphicBuffer->getWidth(), mGraphicBuffer->getHeight(),
mFormat);
ASSERT_EQ(::android::OK, buffer->unlock());
diff --git a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
index 3d9253f..9db8794 100644
--- a/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
+++ b/graphics/composer/aidl/vts/VtsHalGraphicsComposer3_ReadbackTest.cpp
@@ -496,11 +496,14 @@
const auto& buffer = graphicBuffer->handle;
void* clientBufData;
const auto stride = static_cast<uint32_t>(graphicBuffer->stride);
- graphicBuffer->lock(clientUsage, layer->getAccessRegion(), &clientBufData);
+ int bytesPerPixel = -1;
+ int bytesPerStride = -1;
+ graphicBuffer->lock(clientUsage, layer->getAccessRegion(), &clientBufData,
+ &bytesPerPixel, &bytesPerStride);
- ASSERT_NO_FATAL_FAILURE(
- ReadbackHelper::fillBuffer(layer->getWidth(), layer->getHeight(), stride,
- clientBufData, clientFormat, expectedColors));
+ ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(
+ layer->getWidth(), layer->getHeight(), stride, bytesPerPixel, clientBufData,
+ clientFormat, expectedColors));
int32_t clientFence;
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
ASSERT_EQ(::android::OK, unlockStatus);
@@ -677,15 +680,18 @@
const auto& buffer = graphicBuffer->handle;
void* clientBufData;
+ int bytesPerPixel = -1;
+ int bytesPerStride = -1;
graphicBuffer->lock(clientUsage, {0, 0, getDisplayWidth(), getDisplayHeight()},
- &clientBufData);
+ &clientBufData, &bytesPerPixel, &bytesPerStride);
std::vector<Color> clientColors(
static_cast<size_t>(getDisplayWidth() * getDisplayHeight()));
ReadbackHelper::fillColorsArea(clientColors, getDisplayWidth(), clientFrame, RED);
ASSERT_NO_FATAL_FAILURE(ReadbackHelper::fillBuffer(
static_cast<uint32_t>(getDisplayWidth()), static_cast<uint32_t>(getDisplayHeight()),
- graphicBuffer->getStride(), clientBufData, clientFormat, clientColors));
+ graphicBuffer->getStride(), bytesPerPixel, clientBufData, clientFormat,
+ clientColors));
int32_t clientFence;
const auto unlockStatus = graphicBuffer->unlockAsync(&clientFence);
ASSERT_EQ(::android::OK, unlockStatus);
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",