diff --git a/audio/aidl/Android.bp b/audio/aidl/Android.bp index 8f0286f397..674b6447f9 100644 --- a/audio/aidl/Android.bp +++ b/audio/aidl/Android.bp @@ -115,6 +115,7 @@ aidl_interface { "android/hardware/audio/core/IModule.aidl", "android/hardware/audio/core/ISoundDose.aidl", "android/hardware/audio/core/IStreamCallback.aidl", + "android/hardware/audio/core/IStreamCommon.aidl", "android/hardware/audio/core/IStreamIn.aidl", "android/hardware/audio/core/IStreamOut.aidl", "android/hardware/audio/core/ITelephony.aidl", @@ -124,6 +125,7 @@ aidl_interface { "android/hardware/audio/core/ModuleDebug.aidl", "android/hardware/audio/core/StreamDescriptor.aidl", "android/hardware/audio/core/SurroundSoundConfig.aidl", + "android/hardware/audio/core/VendorParameter.aidl", ], imports: [ "android.hardware.common-V2", diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl index 42b12d94b3..ebfa94b5eb 100644 --- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl +++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IModule.aidl @@ -61,6 +61,9 @@ interface IModule { void updateScreenRotation(android.hardware.audio.core.IModule.ScreenRotation rotation); void updateScreenState(boolean isTurnedOn); @nullable android.hardware.audio.core.ISoundDose getSoundDose(); + int generateHwAvSyncId(); + android.hardware.audio.core.VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids); + void setVendorParameters(in android.hardware.audio.core.VendorParameter[] parameters, boolean async); @VintfStability parcelable OpenInputStreamArguments { int portConfigId; diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCommon.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCommon.aidl new file mode 100644 index 0000000000..8471c79a8e --- /dev/null +++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamCommon.aidl @@ -0,0 +1,41 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.audio.core; +@VintfStability +interface IStreamCommon { + void close(); + void updateHwAvSyncId(int hwAvSyncId); + android.hardware.audio.core.VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids); + void setVendorParameters(in android.hardware.audio.core.VendorParameter[] parameters, boolean async); +} diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl index e9c727f571..98acf5fdc2 100644 --- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl +++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamIn.aidl @@ -34,7 +34,7 @@ package android.hardware.audio.core; @VintfStability interface IStreamIn { - void close(); + android.hardware.audio.core.IStreamCommon getStreamCommon(); android.hardware.audio.core.MicrophoneDynamicInfo[] getActiveMicrophones(); android.hardware.audio.core.IStreamIn.MicrophoneDirection getMicrophoneDirection(); void setMicrophoneDirection(android.hardware.audio.core.IStreamIn.MicrophoneDirection direction); diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl index 3021d94c59..5ea2a12d62 100644 --- a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl +++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/IStreamOut.aidl @@ -34,6 +34,6 @@ package android.hardware.audio.core; @VintfStability interface IStreamOut { - void close(); + android.hardware.audio.core.IStreamCommon getStreamCommon(); void updateMetadata(in android.hardware.audio.common.SourceMetadata sourceMetadata); } diff --git a/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/VendorParameter.aidl b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/VendorParameter.aidl new file mode 100644 index 0000000000..bfe33ee4b4 --- /dev/null +++ b/audio/aidl/aidl_api/android.hardware.audio.core/current/android/hardware/audio/core/VendorParameter.aidl @@ -0,0 +1,39 @@ +/* + * 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. + */ +/////////////////////////////////////////////////////////////////////////////// +// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. // +/////////////////////////////////////////////////////////////////////////////// + +// This file is a snapshot of an AIDL file. Do not edit it manually. There are +// two cases: +// 1). this is a frozen version file - do not edit this in any case. +// 2). this is a 'current' file. If you make a backwards compatible change to +// the interface (from the latest frozen version), the build system will +// prompt you to update this file with `m -update-api`. +// +// You must not make a backward incompatible change to any AIDL file built +// with the aidl_interface module type with versions property set. The module +// type is used to build AIDL files in a way that they can be used across +// independently updatable components of the system. If a device is shipped +// with such a backward incompatible change, it has a high risk of breaking +// later when a module using the interface is updated, e.g., Mainline modules. + +package android.hardware.audio.core; +@JavaDerive(equals=true, toString=true) @VintfStability +parcelable VendorParameter { + @utf8InCpp String id; + ParcelableHolder ext; +} diff --git a/audio/aidl/android/hardware/audio/core/IModule.aidl b/audio/aidl/android/hardware/audio/core/IModule.aidl index 2d34df6297..7facc6cbc6 100644 --- a/audio/aidl/android/hardware/audio/core/IModule.aidl +++ b/audio/aidl/android/hardware/audio/core/IModule.aidl @@ -29,6 +29,7 @@ import android.hardware.audio.core.ITelephony; import android.hardware.audio.core.MicrophoneInfo; import android.hardware.audio.core.ModuleDebug; import android.hardware.audio.core.StreamDescriptor; +import android.hardware.audio.core.VendorParameter; import android.media.audio.common.AudioOffloadInfo; import android.media.audio.common.AudioPort; import android.media.audio.common.AudioPortConfig; @@ -684,4 +685,47 @@ interface IModule { * @throws EX_ILLEGAL_STATE If there was an error creating an instance. */ @nullable ISoundDose getSoundDose(); + + /** + * Generate a HW AV Sync identifier for a new audio session. + * + * Creates a new unique identifier which can be further used by the client + * for tagging input / output streams that belong to the same audio + * session and thus must use the same HW AV Sync timestamps sequence. + * + * HW AV Sync timestamps are used for "tunneled" I/O modes and thus + * are not mandatory. + * + * @throws EX_ILLEGAL_STATE If the identifier can not be provided at the moment. + * @throws EX_UNSUPPORTED_OPERATION If synchronization with HW AV Sync markers + * is not supported. + */ + int generateHwAvSyncId(); + + /** + * Get current values of vendor parameters. + * + * Return current values for the parameters corresponding to the provided ids. + * + * @param ids Ids of the parameters to retrieve values of. + * @return Current values of parameters, one per each id. + * @throws EX_ILLEGAL_ARGUMENT If the module does not recognize provided ids. + * @throws EX_ILLEGAL_STATE If parameter values can not be retrieved at the moment. + * @throws EX_UNSUPPORTED_OPERATION If the module does not support vendor parameters. + */ + VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids); + /** + * Set vendor parameters. + * + * Update values for provided vendor parameters. If the 'async' parameter + * is set to 'true', the implementation must return the control back without + * waiting for the application of parameters to complete. + * + * @param parameters Ids and values of parameters to set. + * @param async Whether to return from the method as early as possible. + * @throws EX_ILLEGAL_ARGUMENT If the module does not recognize provided parameters. + * @throws EX_ILLEGAL_STATE If parameters can not be set at the moment. + * @throws EX_UNSUPPORTED_OPERATION If the module does not support vendor parameters. + */ + void setVendorParameters(in VendorParameter[] parameters, boolean async); } diff --git a/audio/aidl/android/hardware/audio/core/IStreamCommon.aidl b/audio/aidl/android/hardware/audio/core/IStreamCommon.aidl new file mode 100644 index 0000000000..84f7309eb5 --- /dev/null +++ b/audio/aidl/android/hardware/audio/core/IStreamCommon.aidl @@ -0,0 +1,89 @@ +/* + * 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. + */ + +package android.hardware.audio.core; + +import android.hardware.audio.core.VendorParameter; + +/** + * This interface contains operations that are common to input and output + * streams (IStreamIn and IStreamOut). The lifetime of the server-side + * implementation object is the same as of the "parent" IStreamIn/Out object. + * The client must release all references to this object together with + * references to the "parent" object. + */ +@VintfStability +interface IStreamCommon { + /** + * Close the stream. + * + * Releases any resources allocated for this stream on the HAL module side. + * This includes the fast message queues and shared memories returned via + * the StreamDescriptor. Thus, the stream can not be operated anymore after + * it has been closed. The client needs to release the audio data I/O + * objects after the call to this method returns. + * + * Methods of IStream* interfaces throw EX_ILLEGAL_STATE for a closed stream. + * + * @throws EX_ILLEGAL_STATE If the stream has already been closed. + */ + void close(); + + /** + * Update the HW AV Sync identifier for the stream. + * + * The argument to this method must be one of the identifiers previously + * returned by the 'IModule.generateHwAvSyncId' method. By tagging streams + * with the same identifier, the client indicates to the HAL that they all + * use the same HW AV Sync timestamps sequence. + * + * HW AV Sync timestamps are used for "tunneled" I/O modes and thus + * are not mandatory. + * + * @throws EX_ILLEGAL_ARGUMENT If the provided ID is unknown to the HAL module. + * @throws EX_ILLEGAL_STATE If the stream is closed. + * @throws EX_UNSUPPORTED_OPERATION If synchronization with HW AV Sync markers + * is not supported. + */ + void updateHwAvSyncId(int hwAvSyncId); + + /** + * Get current values of vendor parameters. + * + * Return current values for the parameters corresponding to the provided ids. + * + * @param ids Ids of the parameters to retrieve values of. + * @return Current values of parameters. + * @throws EX_ILLEGAL_ARGUMENT If the stream does not recognize provided ids. + * @throws EX_ILLEGAL_STATE If parameter values can not be retrieved at the moment. + * @throws EX_UNSUPPORTED_OPERATION If the stream does not support vendor parameters. + */ + VendorParameter[] getVendorParameters(in @utf8InCpp String[] ids); + /** + * Set vendor parameters. + * + * Update values for provided vendor parameters. If the 'async' parameter + * is set to 'true', the implementation must return the control back without + * waiting for the application of parameters to complete. + * + * @param parameters Ids and values of parameters to set. + * @param async Whether to return from the method as early as possible. + * @throws EX_ILLEGAL_ARGUMENT If the stream does not recognize provided parameters. + * @throws EX_ILLEGAL_STATE If parameters can not be set at the moment. + * @throws EX_UNSUPPORTED_OPERATION If the stream does not support vendor parameters. + */ + void setVendorParameters(in VendorParameter[] parameters, boolean async); +} diff --git a/audio/aidl/android/hardware/audio/core/IStreamIn.aidl b/audio/aidl/android/hardware/audio/core/IStreamIn.aidl index 0b6e02cda7..92788a6b99 100644 --- a/audio/aidl/android/hardware/audio/core/IStreamIn.aidl +++ b/audio/aidl/android/hardware/audio/core/IStreamIn.aidl @@ -17,6 +17,7 @@ package android.hardware.audio.core; import android.hardware.audio.common.SinkMetadata; +import android.hardware.audio.core.IStreamCommon; import android.hardware.audio.core.MicrophoneDynamicInfo; /** @@ -25,19 +26,15 @@ import android.hardware.audio.core.MicrophoneDynamicInfo; @VintfStability interface IStreamIn { /** - * Close the stream. + * Return the interface for common stream operations. * - * Releases any resources allocated for this stream on the HAL module side. - * This includes the fast message queues and shared memories returned via - * the StreamDescriptor. Thus, the stream can not be operated anymore after - * it has been closed. The client needs to release the audio data I/O - * objects after the call to this method returns. + * This method must always succeed. The implementation must + * return the same instance object for all subsequent calls to + * this method. * - * Methods of this interface throw EX_ILLEGAL_STATE for a closed stream. - * - * @throws EX_ILLEGAL_STATE If the stream has already been closed. + * @return The interface for common operations. */ - void close(); + IStreamCommon getStreamCommon(); /** * Provides information on the microphones that are active for this stream. diff --git a/audio/aidl/android/hardware/audio/core/IStreamOut.aidl b/audio/aidl/android/hardware/audio/core/IStreamOut.aidl index 9fdb37d07a..f7fc77a2d9 100644 --- a/audio/aidl/android/hardware/audio/core/IStreamOut.aidl +++ b/audio/aidl/android/hardware/audio/core/IStreamOut.aidl @@ -17,6 +17,7 @@ package android.hardware.audio.core; import android.hardware.audio.common.SourceMetadata; +import android.hardware.audio.core.IStreamCommon; /** * This interface provides means for sending audio data to output devices. @@ -24,19 +25,15 @@ import android.hardware.audio.common.SourceMetadata; @VintfStability interface IStreamOut { /** - * Close the stream. + * Return the interface for common stream operations. * - * Releases any resources allocated for this stream on the HAL module side. - * This includes the fast message queues and shared memories returned via - * the StreamDescriptor. Thus, the stream can not be operated anymore after - * it has been closed. The client needs to release the audio data I/O - * objects after the call to this method returns. + * This method must always succeed. The implementation must + * return the same instance object for all subsequent calls to + * this method. * - * Methods of this interface throw EX_ILLEGAL_STATE for a closed stream. - * - * @throws EX_ILLEGAL_STATE If the stream has already been closed. + * @return The interface for common operations. */ - void close(); + IStreamCommon getStreamCommon(); /** * Update stream metadata. diff --git a/audio/aidl/android/hardware/audio/core/VendorParameter.aidl b/audio/aidl/android/hardware/audio/core/VendorParameter.aidl new file mode 100644 index 0000000000..206bd9de4e --- /dev/null +++ b/audio/aidl/android/hardware/audio/core/VendorParameter.aidl @@ -0,0 +1,39 @@ +/* + * 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. + */ + +package android.hardware.audio.core; + +/** + * Vendor parameters are used as a lightweight way to pass vendor-specific + * configuration data back and forth between the HAL and vendor's extension + * to the Android framework, without the need to extend audio interfaces + * from AOSP. + */ +@JavaDerive(equals=true, toString=true) +@VintfStability +parcelable VendorParameter { + /** + * Vendor-generated unique ID of the parameter. In order to avoid + * collisions, vendors must use a vendor-specific prefix for parameter + * ids. The Android framework always passes ids as-is, without any attempt + * to parse their content. + */ + @utf8InCpp String id; + /** + * The payload of the parameter. + */ + ParcelableHolder ext; +} diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp index 38a8cc4b95..d52e328517 100644 --- a/audio/aidl/default/Module.cpp +++ b/audio/aidl/default/Module.cpp @@ -532,9 +532,10 @@ ndk::ScopedAStatus Module::openInputStream(const OpenInputStreamArguments& in_ar return status; } context.fillDescriptor(&_aidl_return->desc); - auto stream = ndk::SharedRefBase::make(in_args.sinkMetadata, std::move(context), - mConfig->microphones); - if (auto status = stream->init(); !status.isOk()) { + std::shared_ptr stream; + if (auto status = StreamIn::createInstance(in_args.sinkMetadata, std::move(context), + mConfig->microphones, &stream); + !status.isOk()) { return status; } StreamWrapper streamWrapper(stream); @@ -584,9 +585,10 @@ ndk::ScopedAStatus Module::openOutputStream(const OpenOutputStreamArguments& in_ return status; } context.fillDescriptor(&_aidl_return->desc); - auto stream = ndk::SharedRefBase::make(in_args.sourceMetadata, std::move(context), - in_args.offloadInfo); - if (auto status = stream->init(); !status.isOk()) { + std::shared_ptr stream; + if (auto status = StreamOut::createInstance(in_args.sourceMetadata, std::move(context), + in_args.offloadInfo, &stream); + !status.isOk()) { return status; } StreamWrapper streamWrapper(stream); @@ -947,4 +949,24 @@ ndk::ScopedAStatus Module::getSoundDose(std::shared_ptr* _aidl_retur return ndk::ScopedAStatus::ok(); } +ndk::ScopedAStatus Module::generateHwAvSyncId(int32_t* _aidl_return) { + LOG(DEBUG) << __func__; + (void)_aidl_return; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ndk::ScopedAStatus Module::getVendorParameters(const std::vector& in_ids, + std::vector* _aidl_return) { + LOG(DEBUG) << __func__ << ": id count: " << in_ids.size(); + (void)_aidl_return; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +ndk::ScopedAStatus Module::setVendorParameters(const std::vector& in_parameters, + bool in_async) { + LOG(DEBUG) << __func__ << ": parameter count " << in_parameters.size() + << ", async: " << in_async; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + } // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/Stream.cpp b/audio/aidl/default/Stream.cpp index be5887c0e4..424c3e4579 100644 --- a/audio/aidl/default/Stream.cpp +++ b/audio/aidl/default/Stream.cpp @@ -16,6 +16,7 @@ #define LOG_TAG "AHAL_Stream" #include +#include #include #include @@ -486,7 +487,7 @@ bool StreamOutWorkerLogic::write(size_t clientSize, StreamDescriptor::Reply* rep } template -StreamCommon::~StreamCommon() { +StreamCommonImpl::~StreamCommonImpl() { if (!isClosed()) { LOG(ERROR) << __func__ << ": stream was not closed prior to destruction, resource leak"; stopWorker(); @@ -495,7 +496,52 @@ StreamCommon::~StreamCommon() { } template -ndk::ScopedAStatus StreamCommon::close() { +void StreamCommonImpl::createStreamCommon( + const std::shared_ptr& delegate) { + if (mCommon != nullptr) { + LOG(FATAL) << __func__ << ": attempting to create the common interface twice"; + } + mCommon = ndk::SharedRefBase::make(delegate); + mCommonBinder = mCommon->asBinder(); + AIBinder_setMinSchedulerPolicy(mCommonBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); +} + +template +ndk::ScopedAStatus StreamCommonImpl::getStreamCommon( + std::shared_ptr* _aidl_return) { + if (mCommon == nullptr) { + LOG(FATAL) << __func__ << ": the common interface was not created"; + } + *_aidl_return = mCommon; + LOG(DEBUG) << __func__ << ": returning " << _aidl_return->get()->asBinder().get(); + return ndk::ScopedAStatus::ok(); +} + +template +ndk::ScopedAStatus StreamCommonImpl::updateHwAvSyncId( + int32_t in_hwAvSyncId) { + LOG(DEBUG) << __func__ << ": id " << in_hwAvSyncId; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +template +ndk::ScopedAStatus StreamCommonImpl::getVendorParameters( + const std::vector& in_ids, std::vector* _aidl_return) { + LOG(DEBUG) << __func__ << ": id count: " << in_ids.size(); + (void)_aidl_return; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +template +ndk::ScopedAStatus StreamCommonImpl::setVendorParameters( + const std::vector& in_parameters, bool in_async) { + LOG(DEBUG) << __func__ << ": parameters count " << in_parameters.size() + << ", async: " << in_async; + return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); +} + +template +ndk::ScopedAStatus StreamCommonImpl::close() { LOG(DEBUG) << __func__; if (!isClosed()) { stopWorker(); @@ -512,7 +558,7 @@ ndk::ScopedAStatus StreamCommon::close() { } template -void StreamCommon::stopWorker() { +void StreamCommonImpl::stopWorker() { if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) { LOG(DEBUG) << __func__ << ": asking the worker to exit..."; auto cmd = StreamDescriptor::Command::make( @@ -529,7 +575,8 @@ void StreamCommon::stopWorker() { } template -ndk::ScopedAStatus StreamCommon::updateMetadata(const Metadata& metadata) { +ndk::ScopedAStatus StreamCommonImpl::updateMetadata( + const Metadata& metadata) { LOG(DEBUG) << __func__; if (!isClosed()) { mMetadata = metadata; @@ -539,6 +586,20 @@ ndk::ScopedAStatus StreamCommon::updateMetadata(const Me return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); } +// static +ndk::ScopedAStatus StreamIn::createInstance(const common::SinkMetadata& sinkMetadata, + StreamContext context, + const std::vector& microphones, + std::shared_ptr* result) { + auto stream = ndk::SharedRefBase::make(sinkMetadata, std::move(context), microphones); + if (auto status = stream->init(); !status.isOk()) { + return status; + } + stream->createStreamCommon(stream); + *result = std::move(stream); + return ndk::ScopedAStatus::ok(); +} + namespace { static std::map transformMicrophones( const std::vector& microphones) { @@ -549,9 +610,9 @@ static std::map transformMicrophones( } } // namespace -StreamIn::StreamIn(const SinkMetadata& sinkMetadata, StreamContext context, +StreamIn::StreamIn(const SinkMetadata& sinkMetadata, StreamContext&& context, const std::vector& microphones) - : StreamCommon(sinkMetadata, std::move(context)), + : StreamCommonImpl(sinkMetadata, std::move(context)), mMicrophones(transformMicrophones(microphones)) { LOG(DEBUG) << __func__; } @@ -597,9 +658,24 @@ ndk::ScopedAStatus StreamIn::setMicrophoneFieldDimension(float in_zoom) { return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); } -StreamOut::StreamOut(const SourceMetadata& sourceMetadata, StreamContext context, +// static +ndk::ScopedAStatus StreamOut::createInstance(const SourceMetadata& sourceMetadata, + StreamContext context, + const std::optional& offloadInfo, + std::shared_ptr* result) { + auto stream = + ndk::SharedRefBase::make(sourceMetadata, std::move(context), offloadInfo); + if (auto status = stream->init(); !status.isOk()) { + return status; + } + stream->createStreamCommon(stream); + *result = std::move(stream); + return ndk::ScopedAStatus::ok(); +} + +StreamOut::StreamOut(const SourceMetadata& sourceMetadata, StreamContext&& context, const std::optional& offloadInfo) - : StreamCommon(sourceMetadata, std::move(context)), + : StreamCommonImpl(sourceMetadata, std::move(context)), mOffloadInfo(offloadInfo) { LOG(DEBUG) << __func__; } diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h index 627208336f..6baaa764b5 100644 --- a/audio/aidl/default/include/core-impl/Module.h +++ b/audio/aidl/default/include/core-impl/Module.h @@ -87,6 +87,11 @@ class Module : public BnModule { ::aidl::android::hardware::audio::core::IModule::ScreenRotation in_rotation) override; ndk::ScopedAStatus updateScreenState(bool in_isTurnedOn) override; ndk::ScopedAStatus getSoundDose(std::shared_ptr* _aidl_return) override; + ndk::ScopedAStatus generateHwAvSyncId(int32_t* _aidl_return) override; + ndk::ScopedAStatus getVendorParameters(const std::vector& in_ids, + std::vector* _aidl_return) override; + ndk::ScopedAStatus setVendorParameters(const std::vector& in_parameters, + bool in_async) override; void cleanUpPatch(int32_t patchId); ndk::ScopedAStatus createStreamContext( diff --git a/audio/aidl/default/include/core-impl/Stream.h b/audio/aidl/default/include/core-impl/Stream.h index 9509a05e7a..5746f9d151 100644 --- a/audio/aidl/default/include/core-impl/Stream.h +++ b/audio/aidl/default/include/core-impl/Stream.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -197,10 +198,67 @@ class StreamOutWorkerLogic : public StreamWorkerCommonLogic { }; using StreamOutWorker = ::android::hardware::audio::common::StreamWorker; -template -class StreamCommon { +// This provides a C++ interface with methods of the IStreamCommon Binder interface, +// but intentionally does not inherit from it. This is needed to avoid inheriting +// StreamIn and StreamOut from two Binder interface classes, as these parts of the class +// will be reference counted separately. +// +// The implementation of these common methods is in the StreamCommonImpl template class. +struct StreamCommonInterface { + virtual ~StreamCommonInterface() = default; + virtual ndk::ScopedAStatus close() = 0; + virtual ndk::ScopedAStatus updateHwAvSyncId(int32_t in_hwAvSyncId) = 0; + virtual ndk::ScopedAStatus getVendorParameters(const std::vector& in_ids, + std::vector* _aidl_return) = 0; + virtual ndk::ScopedAStatus setVendorParameters( + const std::vector& in_parameters, bool in_async) = 0; +}; + +class StreamCommon : public BnStreamCommon { public: - ndk::ScopedAStatus close(); + explicit StreamCommon(const std::shared_ptr& delegate) + : mDelegate(delegate) {} + + private: + ndk::ScopedAStatus close() override { + auto delegate = mDelegate.lock(); + return delegate != nullptr ? delegate->close() + : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + } + ndk::ScopedAStatus updateHwAvSyncId(int32_t in_hwAvSyncId) override { + auto delegate = mDelegate.lock(); + return delegate != nullptr ? delegate->updateHwAvSyncId(in_hwAvSyncId) + : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + } + ndk::ScopedAStatus getVendorParameters(const std::vector& in_ids, + std::vector* _aidl_return) override { + auto delegate = mDelegate.lock(); + return delegate != nullptr ? delegate->getVendorParameters(in_ids, _aidl_return) + : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + } + ndk::ScopedAStatus setVendorParameters(const std::vector& in_parameters, + bool in_async) override { + auto delegate = mDelegate.lock(); + return delegate != nullptr ? delegate->setVendorParameters(in_parameters, in_async) + : ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE); + } + // It is possible that on the client side the proxy for IStreamCommon will outlive + // the IStream* instance, and the server side IStream* instance will get destroyed + // while this IStreamCommon instance is still alive. + std::weak_ptr mDelegate; +}; + +template +class StreamCommonImpl : public StreamCommonInterface { + public: + ndk::ScopedAStatus close() override; + ndk::ScopedAStatus updateHwAvSyncId(int32_t in_hwAvSyncId) override; + ndk::ScopedAStatus getVendorParameters(const std::vector& in_ids, + std::vector* _aidl_return) override; + ndk::ScopedAStatus setVendorParameters(const std::vector& in_parameters, + bool in_async) override; + + ndk::ScopedAStatus getStreamCommon(std::shared_ptr* _aidl_return); ndk::ScopedAStatus init() { return mWorker.start(StreamWorker::kThreadName, ANDROID_PRIORITY_AUDIO) ? ndk::ScopedAStatus::ok() @@ -215,23 +273,26 @@ class StreamCommon { ndk::ScopedAStatus updateMetadata(const Metadata& metadata); protected: - StreamCommon(const Metadata& metadata, StreamContext context) + StreamCommonImpl(const Metadata& metadata, StreamContext&& context) : mMetadata(metadata), mContext(std::move(context)), mWorker(mContext) {} - ~StreamCommon(); + ~StreamCommonImpl(); void stopWorker(); + void createStreamCommon(const std::shared_ptr& delegate); + std::shared_ptr mCommon; + ndk::SpAIBinder mCommonBinder; Metadata mMetadata; StreamContext mContext; StreamWorker mWorker; std::vector<::aidl::android::media::audio::common::AudioDevice> mConnectedDevices; }; -class StreamIn - : public StreamCommon<::aidl::android::hardware::audio::common::SinkMetadata, StreamInWorker>, - public BnStreamIn { - ndk::ScopedAStatus close() override { - return StreamCommon<::aidl::android::hardware::audio::common::SinkMetadata, - StreamInWorker>::close(); +class StreamIn : public StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata, + StreamInWorker>, + public BnStreamIn { + ndk::ScopedAStatus getStreamCommon(std::shared_ptr* _aidl_return) override { + return StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata, + StreamInWorker>::getStreamCommon(_aidl_return); } ndk::ScopedAStatus getActiveMicrophones( std::vector* _aidl_return) override; @@ -241,39 +302,61 @@ class StreamIn ndk::ScopedAStatus setMicrophoneFieldDimension(float in_zoom) override; ndk::ScopedAStatus updateMetadata(const ::aidl::android::hardware::audio::common::SinkMetadata& in_sinkMetadata) override { - return StreamCommon<::aidl::android::hardware::audio::common::SinkMetadata, - StreamInWorker>::updateMetadata(in_sinkMetadata); + return StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata, + StreamInWorker>::updateMetadata(in_sinkMetadata); } public: - StreamIn(const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, - StreamContext context, const std::vector& microphones); + static ndk::ScopedAStatus createInstance( + const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, + StreamContext context, const std::vector& microphones, + std::shared_ptr* result); private: + friend class ndk::SharedRefBase; + StreamIn(const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, + StreamContext&& context, const std::vector& microphones); + void createStreamCommon(const std::shared_ptr& myPtr) { + StreamCommonImpl<::aidl::android::hardware::audio::common::SinkMetadata, + StreamInWorker>::createStreamCommon(myPtr); + } + const std::map<::aidl::android::media::audio::common::AudioDevice, std::string> mMicrophones; }; -class StreamOut : public StreamCommon<::aidl::android::hardware::audio::common::SourceMetadata, - StreamOutWorker>, +class StreamOut : public StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata, + StreamOutWorker>, public BnStreamOut { - ndk::ScopedAStatus close() override { - return StreamCommon<::aidl::android::hardware::audio::common::SourceMetadata, - StreamOutWorker>::close(); + ndk::ScopedAStatus getStreamCommon(std::shared_ptr* _aidl_return) override { + return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata, + StreamOutWorker>::getStreamCommon(_aidl_return); } ndk::ScopedAStatus updateMetadata( const ::aidl::android::hardware::audio::common::SourceMetadata& in_sourceMetadata) override { - return StreamCommon<::aidl::android::hardware::audio::common::SourceMetadata, - StreamOutWorker>::updateMetadata(in_sourceMetadata); + return StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata, + StreamOutWorker>::updateMetadata(in_sourceMetadata); } public: - StreamOut(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, - StreamContext context, - const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& - offloadInfo); + static ndk::ScopedAStatus createInstance( + const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, + StreamContext context, + const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& + offloadInfo, + std::shared_ptr* result); private: + friend class ndk::SharedRefBase; + StreamOut(const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, + StreamContext&& context, + const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& + offloadInfo); + void createStreamCommon(const std::shared_ptr& myPtr) { + StreamCommonImpl<::aidl::android::hardware::audio::common::SourceMetadata, + StreamOutWorker>::createStreamCommon(myPtr); + } + std::optional<::aidl::android::media::audio::common::AudioOffloadInfo> mOffloadInfo; }; diff --git a/audio/aidl/vts/TestUtils.h b/audio/aidl/vts/TestUtils.h index 5e4d56a9dd..4c1d42c762 100644 --- a/audio/aidl/vts/TestUtils.h +++ b/audio/aidl/vts/TestUtils.h @@ -16,6 +16,8 @@ #pragma once +#include +#include #include #include @@ -45,6 +47,19 @@ inline ::testing::AssertionResult assertResult(const char* exp_expr, const char* << "\n but is has completed with: " << status; } +template +inline ::testing::AssertionResult assertResult(const char* exp_expr, const char* act_expr, + const std::initializer_list& expected, + const ::ndk::ScopedAStatus& status) { + if (std::find(expected.begin(), expected.end(), status.getExceptionCode()) != expected.end()) { + return ::testing::AssertionSuccess(); + } + return ::testing::AssertionFailure() << "Expected the transaction \'" << act_expr + << "\' to complete with one of: " << exp_expr + << "\n which is: " << ::testing::PrintToString(expected) + << "\n but is has completed with: " << status; +} + } // namespace detail } // namespace android::hardware::audio::common::testing diff --git a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp index 5dadea384e..1a97004a48 100644 --- a/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp +++ b/audio/aidl/vts/VtsHalAudioCoreModuleTargetTest.cpp @@ -58,6 +58,7 @@ using aidl::android::hardware::audio::core::AudioPatch; using aidl::android::hardware::audio::core::AudioRoute; using aidl::android::hardware::audio::core::IModule; using aidl::android::hardware::audio::core::ISoundDose; +using aidl::android::hardware::audio::core::IStreamCommon; using aidl::android::hardware::audio::core::IStreamIn; using aidl::android::hardware::audio::core::IStreamOut; using aidl::android::hardware::audio::core::ITelephony; @@ -65,6 +66,7 @@ using aidl::android::hardware::audio::core::MicrophoneDynamicInfo; using aidl::android::hardware::audio::core::MicrophoneInfo; using aidl::android::hardware::audio::core::ModuleDebug; using aidl::android::hardware::audio::core::StreamDescriptor; +using aidl::android::hardware::audio::core::VendorParameter; using aidl::android::hardware::common::fmq::SynchronizedReadWrite; using aidl::android::media::audio::common::AudioContentType; using aidl::android::media::audio::common::AudioDevice; @@ -211,6 +213,56 @@ void TestAccessors(Instance* inst, Getter getter, Setter setter, EXPECT_IS_OK((inst->*setter)(initialValue)) << "Failed to restore the initial value"; } +template +void TestGetVendorParameters(Instance* inst, bool* isSupported) { + static const std::vector> kIdsLists = {{}, {"zero"}, {"one", "two"}}; + static const auto kStatuses = {EX_ILLEGAL_ARGUMENT, EX_ILLEGAL_STATE, EX_UNSUPPORTED_OPERATION}; + for (const auto& ids : kIdsLists) { + std::vector params; + if (ndk::ScopedAStatus status = inst->getVendorParameters(ids, ¶ms); status.isOk()) { + EXPECT_EQ(ids.size(), params.size()) << "Size of the returned parameters list must " + << "match the size of the provided ids list"; + for (const auto& param : params) { + EXPECT_NE(ids.end(), std::find(ids.begin(), ids.end(), param.id)) + << "Returned parameter id \"" << param.id << "\" is unexpected"; + } + for (const auto& id : ids) { + EXPECT_NE(params.end(), + std::find_if(params.begin(), params.end(), + [&](const auto& param) { return param.id == id; })) + << "Requested parameter with id \"" << id << "\" was not returned"; + } + } else { + EXPECT_STATUS(kStatuses, status); + if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { + *isSupported = false; + return; + } + } + } + *isSupported = true; +} + +template +void TestSetVendorParameters(Instance* inst, bool* isSupported) { + static const auto kStatuses = {EX_NONE, EX_ILLEGAL_ARGUMENT, EX_ILLEGAL_STATE, + EX_UNSUPPORTED_OPERATION}; + static const std::vector> kParamsLists = { + {}, {VendorParameter{"zero"}}, {VendorParameter{"one"}, VendorParameter{"two"}}}; + for (const auto& params : kParamsLists) { + ndk::ScopedAStatus status = inst->setVendorParameters(params, false); + if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { + *isSupported = false; + return; + } + EXPECT_STATUS(kStatuses, status) + << ::android::internal::ToString(params) << ", async: false"; + EXPECT_STATUS(kStatuses, inst->setVendorParameters(params, true)) + << ::android::internal::ToString(params) << ", async: true"; + } + *isSupported = true; +} + // Can be used as a base for any test here, does not depend on the fixture GTest parameters. class AudioCoreModuleBase { public: @@ -837,6 +889,13 @@ struct IOTraits { template class WithStream { public: + static ndk::ScopedAStatus callClose(std::shared_ptr stream) { + std::shared_ptr common; + ndk::ScopedAStatus status = stream->getStreamCommon(&common); + if (!status.isOk()) return status; + return common->close(); + } + WithStream() {} explicit WithStream(const AudioPortConfig& portConfig) : mPortConfig(portConfig) {} WithStream(const WithStream&) = delete; @@ -844,7 +903,7 @@ class WithStream { ~WithStream() { if (mStream != nullptr) { mContext.reset(); - EXPECT_IS_OK(mStream->close()) << "port config id " << getPortId(); + EXPECT_IS_OK(callClose(mStream)) << "port config id " << getPortId(); } } void SetUpPortConfig(IModule* module) { ASSERT_NO_FATAL_FAILURE(mPortConfig.SetUp(module)); } @@ -1628,6 +1687,40 @@ TEST_P(AudioCoreModule, UpdateScreenState) { EXPECT_IS_OK(module->updateScreenState(true)); } +TEST_P(AudioCoreModule, GenerateHwAvSyncId) { + const auto kStatuses = {EX_NONE, EX_ILLEGAL_STATE}; + int32_t id1; + ndk::ScopedAStatus status = module->generateHwAvSyncId(&id1); + if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { + GTEST_SKIP() << "HW AV Sync is not supported"; + } + EXPECT_STATUS(kStatuses, status); + if (status.isOk()) { + int32_t id2; + ASSERT_IS_OK(module->generateHwAvSyncId(&id2)); + EXPECT_NE(id1, id2) << "HW AV Sync IDs must be unique"; + } +} + +TEST_P(AudioCoreModule, GetVendorParameters) { + bool isGetterSupported = false; + EXPECT_NO_FATAL_FAILURE(TestGetVendorParameters(module.get(), &isGetterSupported)); + ndk::ScopedAStatus status = module->setVendorParameters({}, false); + EXPECT_EQ(isGetterSupported, status.getExceptionCode() != EX_UNSUPPORTED_OPERATION) + << "Support for getting and setting of vendor parameters must be consistent"; + if (!isGetterSupported) { + GTEST_SKIP() << "Vendor parameters are not supported"; + } +} + +TEST_P(AudioCoreModule, SetVendorParameters) { + bool isSupported = false; + EXPECT_NO_FATAL_FAILURE(TestSetVendorParameters(module.get(), &isSupported)); + if (!isSupported) { + GTEST_SKIP() << "Vendor parameters are not supported"; + } +} + class AudioCoreTelephony : public AudioCoreModuleBase, public testing::TestWithParam { public: void SetUp() override { @@ -1733,6 +1826,23 @@ class AudioStream : public AudioCoreModule { ASSERT_NO_FATAL_FAILURE(SetUpModuleConfig()); } + void GetStreamCommon() { + const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits::is_input); + if (!portConfig.has_value()) { + GTEST_SKIP() << "No mix port for attached devices"; + } + WithStream stream(portConfig.value()); + ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames)); + std::shared_ptr streamCommon1; + EXPECT_IS_OK(stream.get()->getStreamCommon(&streamCommon1)); + EXPECT_NE(nullptr, streamCommon1); + std::shared_ptr streamCommon2; + EXPECT_IS_OK(stream.get()->getStreamCommon(&streamCommon2)); + EXPECT_NE(nullptr, streamCommon2); + EXPECT_EQ(streamCommon1->asBinder(), streamCommon2->asBinder()) + << "getStreamCommon must return the same interface instance across invocations"; + } + void CloseTwice() { const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits::is_input); if (!portConfig.has_value()) { @@ -1744,7 +1854,8 @@ class AudioStream : public AudioCoreModule { ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames)); heldStream = stream.getSharedPointer(); } - EXPECT_STATUS(EX_ILLEGAL_STATE, heldStream->close()) << "when closing the stream twice"; + EXPECT_STATUS(EX_ILLEGAL_STATE, WithStream::callClose(heldStream)) + << "when closing the stream twice"; } void OpenAllConfigs() { @@ -1849,6 +1960,65 @@ class AudioStream : public AudioCoreModule { EXPECT_NO_FATAL_FAILURE(SendInvalidCommandImpl(portConfig.value())); } + void UpdateHwAvSyncId() { + const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits::is_input); + if (!portConfig.has_value()) { + GTEST_SKIP() << "No mix port for attached devices"; + } + WithStream stream(portConfig.value()); + ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames)); + std::shared_ptr streamCommon; + ASSERT_IS_OK(stream.get()->getStreamCommon(&streamCommon)); + ASSERT_NE(nullptr, streamCommon); + const auto kStatuses = {EX_NONE, EX_ILLEGAL_ARGUMENT, EX_ILLEGAL_STATE}; + for (const auto id : {-100, -1, 0, 1, 100}) { + ndk::ScopedAStatus status = streamCommon->updateHwAvSyncId(id); + if (status.getExceptionCode() == EX_UNSUPPORTED_OPERATION) { + GTEST_SKIP() << "HW AV Sync is not supported"; + } + EXPECT_STATUS(kStatuses, status) << "id: " << id; + } + } + + void GetVendorParameters() { + const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits::is_input); + if (!portConfig.has_value()) { + GTEST_SKIP() << "No mix port for attached devices"; + } + WithStream stream(portConfig.value()); + ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames)); + std::shared_ptr streamCommon; + ASSERT_IS_OK(stream.get()->getStreamCommon(&streamCommon)); + ASSERT_NE(nullptr, streamCommon); + + bool isGetterSupported = false; + EXPECT_NO_FATAL_FAILURE(TestGetVendorParameters(module.get(), &isGetterSupported)); + ndk::ScopedAStatus status = module->setVendorParameters({}, false); + EXPECT_EQ(isGetterSupported, status.getExceptionCode() != EX_UNSUPPORTED_OPERATION) + << "Support for getting and setting of vendor parameters must be consistent"; + if (!isGetterSupported) { + GTEST_SKIP() << "Vendor parameters are not supported"; + } + } + + void SetVendorParameters() { + const auto portConfig = moduleConfig->getSingleConfigForMixPort(IOTraits::is_input); + if (!portConfig.has_value()) { + GTEST_SKIP() << "No mix port for attached devices"; + } + WithStream stream(portConfig.value()); + ASSERT_NO_FATAL_FAILURE(stream.SetUp(module.get(), kDefaultBufferSizeFrames)); + std::shared_ptr streamCommon; + ASSERT_IS_OK(stream.get()->getStreamCommon(&streamCommon)); + ASSERT_NE(nullptr, streamCommon); + + bool isSupported = false; + EXPECT_NO_FATAL_FAILURE(TestSetVendorParameters(module.get(), &isSupported)); + if (!isSupported) { + GTEST_SKIP() << "Vendor parameters are not supported"; + } + } + void OpenTwiceSamePortConfigImpl(const AudioPortConfig& portConfig) { WithStream stream1(portConfig); ASSERT_NO_FATAL_FAILURE(stream1.SetUp(module.get(), kDefaultBufferSizeFrames)); @@ -1914,6 +2084,7 @@ using AudioStreamOut = AudioStream; } TEST_IN_AND_OUT_STREAM(CloseTwice); +TEST_IN_AND_OUT_STREAM(GetStreamCommon); TEST_IN_AND_OUT_STREAM(OpenAllConfigs); TEST_IN_AND_OUT_STREAM(OpenInvalidBufferSize); TEST_IN_AND_OUT_STREAM(OpenInvalidDirection); @@ -1921,6 +2092,9 @@ TEST_IN_AND_OUT_STREAM(OpenOverMaxCount); TEST_IN_AND_OUT_STREAM(OpenTwiceSamePortConfig); TEST_IN_AND_OUT_STREAM(ResetPortConfigWithOpenStream); TEST_IN_AND_OUT_STREAM(SendInvalidCommand); +TEST_IN_AND_OUT_STREAM(UpdateHwAvSyncId); +TEST_IN_AND_OUT_STREAM(GetVendorParameters); +TEST_IN_AND_OUT_STREAM(SetVendorParameters); namespace aidl::android::hardware::audio::core { std::ostream& operator<<(std::ostream& os, const IStreamIn::MicrophoneDirection& md) {