Audio HAL: fixes for issues discovered after client conversion
Several issues addressed:
-- added IDevice.supportsAudioPatches to query whether
create/removeAudioPatch is actually supported by HAL;
-- IStreamOutCallback proxy needs to be owned by IStreamOut
implementation. In order for the client to reset the reference,
added method IStreamOut.clearCallback;
-- IDevice.open{Input|Output}Stream need to return a "suggested" audio
config from HAL;
-- code for converting between system/audio.h and HIDL
data structures has been moved to
android.hardware.audio.common@2.0-util library for reuse;
-- added a workaround for the issue with QC effects HAL trying to write
into the input parameters buffer, which is r/o by Binder design.
Bug: 30222631
Change-Id: I64af24d79c12d6ac3b0f87d085a821913e29237b
Test: tried using with WIP HIDL client on N5X
diff --git a/audio/effect/2.0/default/Effect.cpp b/audio/effect/2.0/default/Effect.cpp
index 82d0292..6553da4 100644
--- a/audio/effect/2.0/default/Effect.cpp
+++ b/audio/effect/2.0/default/Effect.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <memory>
#include <memory.h>
#define LOG_TAG "EffectHAL"
@@ -56,10 +55,15 @@
}
// static
-template<typename T> void Effect::hidlVecToHal(
- const hidl_vec<T>& vec, uint32_t* halDataSize, void** halData) {
- *halDataSize = static_cast<T>(vec.size() * sizeof(T));
- *halData = static_cast<void*>(const_cast<T*>(&vec[0]));
+template<typename T> std::unique_ptr<uint8_t[]> Effect::hidlVecToHal(
+ const hidl_vec<T>& vec, uint32_t* halDataSize) {
+ // Due to bugs in HAL, they may attempt to write into the provided
+ // input buffer. The original binder buffer is r/o, thus it is needed
+ // to create a r/w version.
+ *halDataSize = vec.size() * sizeof(T);
+ std::unique_ptr<uint8_t[]> halData(new uint8_t[*halDataSize]);
+ memcpy(&halData[0], &vec[0], *halDataSize);
+ return halData;
}
// static
@@ -393,12 +397,13 @@
Return<void> Effect::setAndGetVolume(
const hidl_vec<uint32_t>& volumes, setAndGetVolume_cb _hidl_cb) {
uint32_t halDataSize;
- void *halData;
- hidlVecToHal(volumes, &halDataSize, &halData);
+ std::unique_ptr<uint8_t[]> halData = hidlVecToHal(volumes, &halDataSize);
uint32_t halResultSize = halDataSize;
uint32_t halResult[volumes.size()];
Result retval = sendCommandReturningData(
- EFFECT_CMD_SET_VOLUME, "SET_VOLUME", halDataSize, halData, &halResultSize, halResult);
+ EFFECT_CMD_SET_VOLUME, "SET_VOLUME",
+ halDataSize, &halData[0],
+ &halResultSize, halResult);
hidl_vec<uint32_t> result;
if (retval == Result::OK) {
result.setToExternal(&halResult[0], halResultSize);
@@ -528,13 +533,12 @@
uint32_t resultMaxSize,
command_cb _hidl_cb) {
uint32_t halDataSize;
- void *halData;
- hidlVecToHal(data, &halDataSize, &halData);
+ std::unique_ptr<uint8_t[]> halData = hidlVecToHal(data, &halDataSize);
uint32_t halResultSize = resultMaxSize;
std::unique_ptr<uint8_t[]> halResult(new uint8_t[halResultSize]);
memset(&halResult[0], 0, halResultSize);
status_t status = (*mHandle)->command(
- mHandle, commandId, halDataSize, halData, &halResultSize, &halResult[0]);
+ mHandle, commandId, halDataSize, &halData[0], &halResultSize, &halResult[0]);
hidl_vec<uint8_t> result;
if (status == OK) {
result.setToExternal(&halResult[0], halResultSize);