From 521fc49fba3de4f0843a04625ebc369933b47352 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Tue, 11 Jul 2023 17:24:08 -0700 Subject: [PATCH] audio: Create ModulePrimary and ModuleStub Make 'Module' more abstract by moving stream creation methods to more concrete 'ModulePrimary' and 'ModuleStub'. 'ModulePrimary' is now closer to the CF primary module: it was stripped off USB devices from its configuration, these got moved to 'ModuleUsb', and got rid of BT A2DP and LE interfaces, these will be on 'ModuleBluetooth'. Note that 'ModulePrimary' still uses stub streams, this will be changed in subsequent patches. 'ModuleStub' is what 'Module' used to be, just a module for improving test coverage. It includes simulation of offload streams and dummy BT objects. Bug: 264712385 Test: atest VtsHalAudioCoreTargetTest Change-Id: I5e4da0c32c00d65688f2eda78b2c79594e4e4671 --- audio/aidl/default/Android.bp | 4 +- audio/aidl/default/Configuration.cpp | 171 +++++++++++++----- audio/aidl/default/Module.cpp | 68 +++---- audio/aidl/default/ModulePrimary.cpp | 60 ++++++ .../android.hardware.audio.service-aidl.xml | 5 + .../include/core-impl/ChildInterface.h | 48 +++++ .../default/include/core-impl/Configuration.h | 1 + audio/aidl/default/include/core-impl/Module.h | 34 +--- .../default/include/core-impl/ModulePrimary.h | 46 +++++ .../include/core-impl/ModuleRemoteSubmix.h | 2 +- .../default/include/core-impl/ModuleStub.h | 50 +++++ .../default/include/core-impl/ModuleUsb.h | 2 +- audio/aidl/default/main.cpp | 18 +- audio/aidl/default/stub/ModuleStub.cpp | 78 ++++++++ audio/aidl/default/{ => stub}/StreamStub.cpp | 0 15 files changed, 463 insertions(+), 124 deletions(-) create mode 100644 audio/aidl/default/ModulePrimary.cpp create mode 100644 audio/aidl/default/include/core-impl/ChildInterface.h create mode 100644 audio/aidl/default/include/core-impl/ModulePrimary.h create mode 100644 audio/aidl/default/include/core-impl/ModuleStub.h create mode 100644 audio/aidl/default/stub/ModuleStub.cpp rename audio/aidl/default/{ => stub}/StreamStub.cpp (100%) diff --git a/audio/aidl/default/Android.bp b/audio/aidl/default/Android.bp index 65bbe9e9a1..934c7ee39d 100644 --- a/audio/aidl/default/Android.bp +++ b/audio/aidl/default/Android.bp @@ -73,9 +73,9 @@ cc_library { "Configuration.cpp", "EngineConfigXmlConverter.cpp", "Module.cpp", + "ModulePrimary.cpp", "SoundDose.cpp", "Stream.cpp", - "StreamStub.cpp", "Telephony.cpp", "alsa/Mixer.cpp", "alsa/ModuleAlsa.cpp", @@ -85,6 +85,8 @@ cc_library { "r_submix/RemoteSubmixUtils.cpp", "r_submix/SubmixRoute.cpp", "r_submix/StreamRemoteSubmix.cpp", + "stub/ModuleStub.cpp", + "stub/StreamStub.cpp", "usb/ModuleUsb.cpp", "usb/StreamUsb.cpp", "usb/UsbAlsaMixerControl.cpp", diff --git a/audio/aidl/default/Configuration.cpp b/audio/aidl/default/Configuration.cpp index d41ea67329..a71c6ea734 100644 --- a/audio/aidl/default/Configuration.cpp +++ b/audio/aidl/default/Configuration.cpp @@ -144,10 +144,6 @@ static AudioRoute createRoute(const std::vector& sources, const Audio // - no profiles specified // * "FM Tuner", IN_FM_TUNER // - no profiles specified -// * "USB Out", OUT_DEVICE, CONNECTION_USB -// - no profiles specified -// * "USB In", IN_DEVICE, CONNECTION_USB -// - no profiles specified // // Mix ports: // * "primary output", PRIMARY, 1 max open, 1 max active stream @@ -172,8 +168,7 @@ static AudioRoute createRoute(const std::vector& sources, const Audio // // Routes: // "primary out", "compressed offload" -> "Speaker" -// "primary out", "compressed offload" -> "USB Out" -// "Built-in Mic", "USB In" -> "primary input" +// "Built-in Mic" -> "primary input" // "telephony_tx" -> "Telephony Tx" // "Telephony Rx" -> "telephony_rx" // "FM Tuner" -> "fm_tuner" @@ -185,14 +180,6 @@ static AudioRoute createRoute(const std::vector& sources, const Audio // * "Telephony Rx" device port: PCM 24-bit; MONO; 48000 // * "FM Tuner" device port: PCM 24-bit; STEREO; 48000 // -// Profiles for device port connected state: -// * USB Out": -// - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 -// - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 -// * USB In": -// - profile PCM 16-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 -// - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 -// std::unique_ptr getPrimaryConfiguration() { static const Configuration configuration = []() { const std::vector standardPcmAudioProfiles = { @@ -252,19 +239,6 @@ std::unique_ptr getPrimaryConfiguration() { AudioChannelLayout::LAYOUT_STEREO, 48000, 0, true, createDeviceExt(AudioDeviceType::IN_FM_TUNER, 0))); - AudioPort usbOutDevice = - createPort(c.nextPortId++, "USB Out", 0, false, - createDeviceExt(AudioDeviceType::OUT_DEVICE, 0, - AudioDeviceDescription::CONNECTION_USB)); - c.ports.push_back(usbOutDevice); - c.connectedProfiles[usbOutDevice.id] = standardPcmAudioProfiles; - - AudioPort usbInDevice = createPort(c.nextPortId++, "USB In", 0, true, - createDeviceExt(AudioDeviceType::IN_DEVICE, 0, - AudioDeviceDescription::CONNECTION_USB)); - c.ports.push_back(usbInDevice); - c.connectedProfiles[usbInDevice.id] = standardPcmAudioProfiles; - // Mix ports AudioPort primaryOutMix = createPort(c.nextPortId++, "primary output", @@ -323,8 +297,7 @@ std::unique_ptr getPrimaryConfiguration() { c.ports.push_back(fmTunerInMix); c.routes.push_back(createRoute({primaryOutMix, compressedOffloadOutMix}, speakerOutDevice)); - c.routes.push_back(createRoute({primaryOutMix, compressedOffloadOutMix}, usbOutDevice)); - c.routes.push_back(createRoute({micInDevice, usbInDevice}, primaryInMix)); + c.routes.push_back(createRoute({micInDevice}, primaryInMix)); c.routes.push_back(createRoute({telephonyTxOutMix}, telephonyTxOutDevice)); c.routes.push_back(createRoute({telephonyRxInDevice}, telephonyRxInMix)); c.routes.push_back(createRoute({fmTunerInDevice}, fmTunerInMix)); @@ -406,22 +379,31 @@ std::unique_ptr getRSubmixConfiguration() { // Usb configuration: // // Device ports: +// * "USB Device Out", OUT_DEVICE, CONNECTION_USB +// - no profiles specified // * "USB Headset Out", OUT_HEADSET, CONNECTION_USB // - no profiles specified +// * "USB Device In", IN_DEVICE, CONNECTION_USB +// - no profiles specified // * "USB Headset In", IN_HEADSET, CONNECTION_USB // - no profiles specified // // Mix ports: -// * "usb_headset output", 1 max open, 1 max active stream +// * "usb_device output", 1 max open, 1 max active stream // - no profiles specified -// * "usb_headset input", 1 max open, 1 max active stream +// * "usb_device input", 1 max open, 1 max active stream // - no profiles specified // +// Routes: +// * "usb_device output" -> "USB Device Out" +// * "usb_device output" -> "USB Headset Out" +// * "USB Device In", "USB Headset In" -> "usb_device input" +// // Profiles for device port connected state: -// * USB Headset Out": +// * "USB Device Out", "USB Headset Out": // - profile PCM 16-bit; MONO, STEREO, INDEX_MASK_1, INDEX_MASK_2; 44100, 48000 // - profile PCM 24-bit; MONO, STEREO, INDEX_MASK_1, INDEX_MASK_2; 44100, 48000 -// * USB Headset In": +// * "USB Device In", "USB Headset In": // - profile PCM 16-bit; MONO, STEREO, INDEX_MASK_1, INDEX_MASK_2; 44100, 48000 // - profile PCM 24-bit; MONO, STEREO, INDEX_MASK_1, INDEX_MASK_2; 44100, 48000 // @@ -440,6 +422,13 @@ std::unique_ptr getUsbConfiguration() { // Device ports + AudioPort usbOutDevice = + createPort(c.nextPortId++, "USB Device Out", 0, false, + createDeviceExt(AudioDeviceType::OUT_DEVICE, 0, + AudioDeviceDescription::CONNECTION_USB)); + c.ports.push_back(usbOutDevice); + c.connectedProfiles[usbOutDevice.id] = standardPcmAudioProfiles; + AudioPort usbOutHeadset = createPort(c.nextPortId++, "USB Headset Out", 0, false, createDeviceExt(AudioDeviceType::OUT_HEADSET, 0, @@ -447,6 +436,12 @@ std::unique_ptr getUsbConfiguration() { c.ports.push_back(usbOutHeadset); c.connectedProfiles[usbOutHeadset.id] = standardPcmAudioProfiles; + AudioPort usbInDevice = createPort(c.nextPortId++, "USB Device In", 0, true, + createDeviceExt(AudioDeviceType::IN_DEVICE, 0, + AudioDeviceDescription::CONNECTION_USB)); + c.ports.push_back(usbInDevice); + c.connectedProfiles[usbInDevice.id] = standardPcmAudioProfiles; + AudioPort usbInHeadset = createPort(c.nextPortId++, "USB Headset In", 0, true, createDeviceExt(AudioDeviceType::IN_HEADSET, 0, @@ -456,16 +451,110 @@ std::unique_ptr getUsbConfiguration() { // Mix ports - AudioPort usbHeadsetOutMix = - createPort(c.nextPortId++, "usb_headset output", 0, false, createPortMixExt(1, 1)); - c.ports.push_back(usbHeadsetOutMix); + AudioPort usbDeviceOutMix = + createPort(c.nextPortId++, "usb_device output", 0, false, createPortMixExt(1, 1)); + c.ports.push_back(usbDeviceOutMix); - AudioPort usbHeadsetInMix = - createPort(c.nextPortId++, "usb_headset input", 0, true, createPortMixExt(1, 1)); - c.ports.push_back(usbHeadsetInMix); + AudioPort usbDeviceInMix = + createPort(c.nextPortId++, "usb_device input", 0, true, createPortMixExt(1, 1)); + c.ports.push_back(usbDeviceInMix); - c.routes.push_back(createRoute({usbHeadsetOutMix}, usbOutHeadset)); - c.routes.push_back(createRoute({usbInHeadset}, usbHeadsetInMix)); + c.routes.push_back(createRoute({usbDeviceOutMix}, usbOutDevice)); + c.routes.push_back(createRoute({usbDeviceOutMix}, usbOutHeadset)); + c.routes.push_back(createRoute({usbInDevice, usbInHeadset}, usbDeviceInMix)); + + return c; + }(); + return std::make_unique(configuration); +} + +// Stub configuration: +// +// Device ports: +// * "Test Out", OUT_AFE_PROXY +// - no profiles specified +// * "Test In", IN_AFE_PROXY +// - no profiles specified +// +// Mix ports: +// * "test output", 1 max open, 1 max active stream +// - profile PCM 24-bit; MONO, STEREO; 8000, 11025, 16000, 32000, 44100, 48000 +// * "compressed offload", DIRECT|COMPRESS_OFFLOAD|NON_BLOCKING, 1 max open, 1 max active stream +// - profile MP3; MONO, STEREO; 44100, 48000 +// * "test input", 2 max open, 2 max active streams +// - profile PCM 24-bit; MONO, STEREO, FRONT_BACK; +// 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000 +// +// Routes: +// "test output", "compressed offload" -> "Test Out" +// "Test In" -> "test input" +// +// Initial port configs: +// * "Test Out" device port: PCM 24-bit; STEREO; 48000 +// * "Test In" device port: PCM 24-bit; MONO; 48000 +// +std::unique_ptr getStubConfiguration() { + static const Configuration configuration = []() { + Configuration c; + + // Device ports + + AudioPort testOutDevice = createPort(c.nextPortId++, "Test Out", 0, false, + createDeviceExt(AudioDeviceType::OUT_AFE_PROXY, 0)); + c.ports.push_back(testOutDevice); + c.initialConfigs.push_back( + createPortConfig(testOutDevice.id, testOutDevice.id, PcmType::INT_24_BIT, + AudioChannelLayout::LAYOUT_STEREO, 48000, 0, false, + createDeviceExt(AudioDeviceType::OUT_AFE_PROXY, 0))); + + AudioPort testInDevice = createPort(c.nextPortId++, "Test In", 0, true, + createDeviceExt(AudioDeviceType::IN_AFE_PROXY, 0)); + c.ports.push_back(testInDevice); + c.initialConfigs.push_back( + createPortConfig(testInDevice.id, testInDevice.id, PcmType::INT_24_BIT, + AudioChannelLayout::LAYOUT_MONO, 48000, 0, true, + createDeviceExt(AudioDeviceType::IN_AFE_PROXY, 0))); + + // Mix ports + + AudioPort testOutMix = + createPort(c.nextPortId++, "test output", 0, false, createPortMixExt(1, 1)); + testOutMix.profiles.push_back( + createProfile(PcmType::INT_24_BIT, + {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO}, + {8000, 11025, 16000, 32000, 44100, 48000})); + c.ports.push_back(testOutMix); + + AudioPort compressedOffloadOutMix = + createPort(c.nextPortId++, "compressed offload", + makeBitPositionFlagMask({AudioOutputFlags::DIRECT, + AudioOutputFlags::COMPRESS_OFFLOAD, + AudioOutputFlags::NON_BLOCKING}), + false, createPortMixExt(1, 1)); + compressedOffloadOutMix.profiles.push_back( + createProfile(::android::MEDIA_MIMETYPE_AUDIO_MPEG, + {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO}, + {44100, 48000})); + c.ports.push_back(compressedOffloadOutMix); + + AudioPort testInMIx = + createPort(c.nextPortId++, "test input", 0, true, createPortMixExt(2, 2)); + testInMIx.profiles.push_back( + createProfile(PcmType::INT_16_BIT, + {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO, + AudioChannelLayout::LAYOUT_FRONT_BACK}, + {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000})); + testInMIx.profiles.push_back( + createProfile(PcmType::INT_24_BIT, + {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO, + AudioChannelLayout::LAYOUT_FRONT_BACK}, + {8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000})); + c.ports.push_back(testInMIx); + + c.routes.push_back(createRoute({testOutMix, compressedOffloadOutMix}, testOutDevice)); + c.routes.push_back(createRoute({testInDevice}, testInMIx)); + + c.portConfigs.insert(c.portConfigs.end(), c.initialConfigs.begin(), c.initialConfigs.end()); return c; }(); diff --git a/audio/aidl/default/Module.cpp b/audio/aidl/default/Module.cpp index 48d14580a7..12bbbb0cba 100644 --- a/audio/aidl/default/Module.cpp +++ b/audio/aidl/default/Module.cpp @@ -25,13 +25,12 @@ #include #include -#include "core-impl/Bluetooth.h" #include "core-impl/Module.h" +#include "core-impl/ModulePrimary.h" #include "core-impl/ModuleRemoteSubmix.h" +#include "core-impl/ModuleStub.h" #include "core-impl/ModuleUsb.h" #include "core-impl/SoundDose.h" -#include "core-impl/StreamStub.h" -#include "core-impl/Telephony.h" #include "core-impl/utils.h" using aidl::android::hardware::audio::common::getFrameSizeInBytes; @@ -110,13 +109,14 @@ bool findAudioProfile(const AudioPort& port, const AudioFormatDescription& forma // static std::shared_ptr Module::createInstance(Type type) { switch (type) { - case Module::Type::USB: - return ndk::SharedRefBase::make(type); - case Type::R_SUBMIX: - return ndk::SharedRefBase::make(type); case Type::DEFAULT: - default: - return ndk::SharedRefBase::make(type); + return ndk::SharedRefBase::make(); + case Type::R_SUBMIX: + return ndk::SharedRefBase::make(); + case Type::STUB: + return ndk::SharedRefBase::make(); + case Type::USB: + return ndk::SharedRefBase::make(); } } @@ -128,6 +128,9 @@ std::ostream& operator<<(std::ostream& os, Module::Type t) { case Module::Type::R_SUBMIX: os << "r_submix"; break; + case Module::Type::STUB: + os << "stub"; + break; case Module::Type::USB: os << "usb"; break; @@ -292,6 +295,9 @@ internal::Configuration& Module::getConfig() { case Type::R_SUBMIX: mConfig = std::move(internal::getRSubmixConfiguration()); break; + case Type::STUB: + mConfig = std::move(internal::getStubConfiguration()); + break; case Type::USB: mConfig = std::move(internal::getUsbConfiguration()); break; @@ -395,38 +401,26 @@ ndk::ScopedAStatus Module::setModuleDebug( } ndk::ScopedAStatus Module::getTelephony(std::shared_ptr* _aidl_return) { - if (!mTelephony) { - mTelephony = ndk::SharedRefBase::make(); - } - *_aidl_return = mTelephony.getPtr(); - LOG(DEBUG) << __func__ << ": returning instance of ITelephony: " << _aidl_return->get(); + *_aidl_return = nullptr; + LOG(DEBUG) << __func__ << ": returning null"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Module::getBluetooth(std::shared_ptr* _aidl_return) { - if (!mBluetooth) { - mBluetooth = ndk::SharedRefBase::make(); - } - *_aidl_return = mBluetooth.getPtr(); - LOG(DEBUG) << __func__ << ": returning instance of IBluetooth: " << _aidl_return->get(); + *_aidl_return = nullptr; + LOG(DEBUG) << __func__ << ": returning null"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Module::getBluetoothA2dp(std::shared_ptr* _aidl_return) { - if (!mBluetoothA2dp) { - mBluetoothA2dp = ndk::SharedRefBase::make(); - } - *_aidl_return = mBluetoothA2dp.getPtr(); - LOG(DEBUG) << __func__ << ": returning instance of IBluetoothA2dp: " << _aidl_return->get(); + *_aidl_return = nullptr; + LOG(DEBUG) << __func__ << ": returning null"; return ndk::ScopedAStatus::ok(); } ndk::ScopedAStatus Module::getBluetoothLe(std::shared_ptr* _aidl_return) { - if (!mBluetoothLe) { - mBluetoothLe = ndk::SharedRefBase::make(); - } - *_aidl_return = mBluetoothLe.getPtr(); - LOG(DEBUG) << __func__ << ": returning instance of IBluetoothLe: " << _aidl_return->get(); + *_aidl_return = nullptr; + LOG(DEBUG) << __func__ << ": returning null"; return ndk::ScopedAStatus::ok(); } @@ -1334,22 +1328,6 @@ bool Module::isMmapSupported() { return mIsMmapSupported.value(); } -ndk::ScopedAStatus Module::createInputStream(const SinkMetadata& sinkMetadata, - StreamContext&& context, - const std::vector& microphones, - std::shared_ptr* result) { - return createStreamInstance(result, sinkMetadata, std::move(context), - microphones); -} - -ndk::ScopedAStatus Module::createOutputStream(const SourceMetadata& sourceMetadata, - StreamContext&& context, - const std::optional& offloadInfo, - std::shared_ptr* result) { - return createStreamInstance(result, sourceMetadata, std::move(context), - offloadInfo); -} - ndk::ScopedAStatus Module::populateConnectedDevicePort(AudioPort* audioPort __unused) { LOG(VERBOSE) << __func__ << ": do nothing and return ok"; return ndk::ScopedAStatus::ok(); diff --git a/audio/aidl/default/ModulePrimary.cpp b/audio/aidl/default/ModulePrimary.cpp new file mode 100644 index 0000000000..cbb6730372 --- /dev/null +++ b/audio/aidl/default/ModulePrimary.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2023 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. + */ + +#include + +#define LOG_TAG "AHAL_ModulePrimary" +#include +#include + +#include "core-impl/ModulePrimary.h" +#include "core-impl/StreamStub.h" +#include "core-impl/Telephony.h" + +using aidl::android::hardware::audio::common::SinkMetadata; +using aidl::android::hardware::audio::common::SourceMetadata; +using aidl::android::media::audio::common::AudioOffloadInfo; +using aidl::android::media::audio::common::AudioPort; +using aidl::android::media::audio::common::AudioPortConfig; +using aidl::android::media::audio::common::MicrophoneInfo; + +namespace aidl::android::hardware::audio::core { + +ndk::ScopedAStatus ModulePrimary::getTelephony(std::shared_ptr* _aidl_return) { + if (!mTelephony) { + mTelephony = ndk::SharedRefBase::make(); + } + *_aidl_return = mTelephony.getPtr(); + LOG(DEBUG) << __func__ << ": returning instance of ITelephony: " << _aidl_return->get(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus ModulePrimary::createInputStream(const SinkMetadata& sinkMetadata, + StreamContext&& context, + const std::vector& microphones, + std::shared_ptr* result) { + return createStreamInstance(result, sinkMetadata, std::move(context), + microphones); +} + +ndk::ScopedAStatus ModulePrimary::createOutputStream( + const SourceMetadata& sourceMetadata, StreamContext&& context, + const std::optional& offloadInfo, std::shared_ptr* result) { + return createStreamInstance(result, sourceMetadata, std::move(context), + offloadInfo); +} + +} // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/android.hardware.audio.service-aidl.xml b/audio/aidl/default/android.hardware.audio.service-aidl.xml index 9636a58d48..c9d6314e32 100644 --- a/audio/aidl/default/android.hardware.audio.service-aidl.xml +++ b/audio/aidl/default/android.hardware.audio.service-aidl.xml @@ -9,6 +9,11 @@ 1 IModule/r_submix + + android.hardware.audio.core + 1 + IModule/stub + android.hardware.audio.core 1 diff --git a/audio/aidl/default/include/core-impl/ChildInterface.h b/audio/aidl/default/include/core-impl/ChildInterface.h new file mode 100644 index 0000000000..1b31691556 --- /dev/null +++ b/audio/aidl/default/include/core-impl/ChildInterface.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 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. + */ + +#pragma once + +#include +#include + +#include +#include +#include + +namespace aidl::android::hardware::audio::core { + +// Helper used for interfaces that require a persistent instance. We hold them via a strong +// pointer. The binder token is retained for a call to 'setMinSchedulerPolicy'. +template +struct ChildInterface : private std::pair, ndk::SpAIBinder> { + ChildInterface() = default; + ChildInterface& operator=(const std::shared_ptr& c) { + return operator=(std::shared_ptr(c)); + } + ChildInterface& operator=(std::shared_ptr&& c) { + this->first = std::move(c); + this->second = this->first->asBinder(); + AIBinder_setMinSchedulerPolicy(this->second.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); + return *this; + } + explicit operator bool() const { return !!this->first; } + C& operator*() const { return *(this->first); } + C* operator->() const { return this->first; } + std::shared_ptr getPtr() const { return this->first; } +}; + +} // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/include/core-impl/Configuration.h b/audio/aidl/default/include/core-impl/Configuration.h index 70320e46aa..25bf7afa81 100644 --- a/audio/aidl/default/include/core-impl/Configuration.h +++ b/audio/aidl/default/include/core-impl/Configuration.h @@ -45,6 +45,7 @@ struct Configuration { std::unique_ptr getPrimaryConfiguration(); std::unique_ptr getRSubmixConfiguration(); +std::unique_ptr getStubConfiguration(); std::unique_ptr getUsbConfiguration(); } // namespace aidl::android::hardware::audio::core::internal diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h index 4a23637d86..ee0458be49 100644 --- a/audio/aidl/default/include/core-impl/Module.h +++ b/audio/aidl/default/include/core-impl/Module.h @@ -16,12 +16,14 @@ #pragma once +#include #include #include #include #include +#include "core-impl/ChildInterface.h" #include "core-impl/Configuration.h" #include "core-impl/Stream.h" @@ -31,7 +33,7 @@ class Module : public BnModule { public: // This value is used for all AudioPatches and reported by all streams. static constexpr int32_t kLatencyMs = 10; - enum Type : int { DEFAULT, R_SUBMIX, USB }; + enum Type : int { DEFAULT, R_SUBMIX, STUB, USB }; static std::shared_ptr createInstance(Type type); @@ -132,26 +134,6 @@ class Module : public BnModule { bool forceTransientBurst = false; bool forceSynchronousDrain = false; }; - // Helper used for interfaces that require a persistent instance. We hold them via a strong - // pointer. The binder token is retained for a call to 'setMinSchedulerPolicy'. - template - struct ChildInterface : private std::pair, ndk::SpAIBinder> { - ChildInterface() {} - ChildInterface& operator=(const std::shared_ptr& c) { - return operator=(std::shared_ptr(c)); - } - ChildInterface& operator=(std::shared_ptr&& c) { - this->first = std::move(c); - this->second = this->first->asBinder(); - AIBinder_setMinSchedulerPolicy(this->second.get(), SCHED_NORMAL, - ANDROID_PRIORITY_AUDIO); - return *this; - } - explicit operator bool() const { return !!this->first; } - C& operator*() const { return *(this->first); } - C* operator->() const { return this->first; } - std::shared_ptr getPtr() const { return this->first; } - }; // ids of device ports created at runtime via 'connectExternalDevice'. // Also stores a list of ids of mix ports with dynamic profiles that were populated from // the connected port. This list can be empty, thus an int->int multimap can't be used. @@ -164,10 +146,6 @@ class Module : public BnModule { std::unique_ptr mConfig; ModuleDebug mDebug; VendorDebug mVendorDebug; - ChildInterface mTelephony; - ChildInterface mBluetooth; - ChildInterface mBluetoothA2dp; - ChildInterface mBluetoothLe; ConnectedDevicePorts mConnectedDevicePorts; Streams mStreams; Patches mPatches; @@ -184,13 +162,13 @@ class Module : public BnModule { const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, StreamContext&& context, const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, - std::shared_ptr* result); + std::shared_ptr* result) = 0; virtual ndk::ScopedAStatus createOutputStream( const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, StreamContext&& context, const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& offloadInfo, - std::shared_ptr* result); + std::shared_ptr* result) = 0; // If the module is unable to populate the connected device port correctly, the returned error // code must correspond to the errors of `IModule.connectedExternalDevice` method. virtual ndk::ScopedAStatus populateConnectedDevicePort( @@ -232,4 +210,6 @@ class Module : public BnModule { const AudioPatch& newPatch); }; +std::ostream& operator<<(std::ostream& os, Module::Type t); + } // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/include/core-impl/ModulePrimary.h b/audio/aidl/default/include/core-impl/ModulePrimary.h new file mode 100644 index 0000000000..bc808ab03d --- /dev/null +++ b/audio/aidl/default/include/core-impl/ModulePrimary.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2023 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. + */ + +#pragma once + +#include "core-impl/Module.h" + +namespace aidl::android::hardware::audio::core { + +class ModulePrimary final : public Module { + public: + ModulePrimary() : Module(Type::DEFAULT) {} + + protected: + ndk::ScopedAStatus getTelephony(std::shared_ptr* _aidl_return) override; + + ndk::ScopedAStatus createInputStream( + const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, + StreamContext&& context, + const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, + std::shared_ptr* result) override; + ndk::ScopedAStatus createOutputStream( + const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, + StreamContext&& context, + const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& + offloadInfo, + std::shared_ptr* result) override; + + private: + ChildInterface mTelephony; +}; + +} // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h b/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h index 7b1d375117..ccfcdd9462 100644 --- a/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h +++ b/audio/aidl/default/include/core-impl/ModuleRemoteSubmix.h @@ -22,7 +22,7 @@ namespace aidl::android::hardware::audio::core { class ModuleRemoteSubmix : public Module { public: - explicit ModuleRemoteSubmix(Module::Type type) : Module(type) {} + ModuleRemoteSubmix() : Module(Type::R_SUBMIX) {} private: // IModule interfaces diff --git a/audio/aidl/default/include/core-impl/ModuleStub.h b/audio/aidl/default/include/core-impl/ModuleStub.h new file mode 100644 index 0000000000..59c343f4b7 --- /dev/null +++ b/audio/aidl/default/include/core-impl/ModuleStub.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023 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. + */ + +#pragma once + +#include "core-impl/Module.h" + +namespace aidl::android::hardware::audio::core { + +class ModuleStub final : public Module { + public: + ModuleStub() : Module(Type::STUB) {} + + protected: + ndk::ScopedAStatus getBluetooth(std::shared_ptr* _aidl_return) override; + ndk::ScopedAStatus getBluetoothA2dp(std::shared_ptr* _aidl_return) override; + ndk::ScopedAStatus getBluetoothLe(std::shared_ptr* _aidl_return) override; + + ndk::ScopedAStatus createInputStream( + const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, + StreamContext&& context, + const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, + std::shared_ptr* result) override; + ndk::ScopedAStatus createOutputStream( + const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, + StreamContext&& context, + const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& + offloadInfo, + std::shared_ptr* result) override; + + private: + ChildInterface mBluetooth; + ChildInterface mBluetoothA2dp; + ChildInterface mBluetoothLe; +}; + +} // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/include/core-impl/ModuleUsb.h b/audio/aidl/default/include/core-impl/ModuleUsb.h index ea7cc48214..e6b3e66e41 100644 --- a/audio/aidl/default/include/core-impl/ModuleUsb.h +++ b/audio/aidl/default/include/core-impl/ModuleUsb.h @@ -22,7 +22,7 @@ namespace aidl::android::hardware::audio::core { class ModuleUsb final : public ModuleAlsa { public: - explicit ModuleUsb(Module::Type type) : ModuleAlsa(type) {} + ModuleUsb() : ModuleAlsa(Type::USB) {} private: // IModule interfaces diff --git a/audio/aidl/default/main.cpp b/audio/aidl/default/main.cpp index 12c0c4b53e..93fb36607e 100644 --- a/audio/aidl/default/main.cpp +++ b/audio/aidl/default/main.cpp @@ -16,20 +16,21 @@ #include #include +#include #include +#include #include +#include #include #include #include #include "core-impl/Config.h" #include "core-impl/Module.h" -#include "core-impl/ModuleUsb.h" using aidl::android::hardware::audio::core::Config; using aidl::android::hardware::audio::core::Module; -using aidl::android::hardware::audio::core::ModuleUsb; int main() { // Random values are used in the implementation. @@ -52,18 +53,19 @@ int main() { CHECK_EQ(STATUS_OK, status); // Make modules - auto createModule = [](Module::Type type, const std::string& instance) { + auto createModule = [](Module::Type type) { auto module = Module::createInstance(type); ndk::SpAIBinder moduleBinder = module->asBinder(); - const std::string moduleName = std::string(Module::descriptor).append("/").append(instance); + std::stringstream moduleName; + moduleName << Module::descriptor << "/" << type; AIBinder_setMinSchedulerPolicy(moduleBinder.get(), SCHED_NORMAL, ANDROID_PRIORITY_AUDIO); - binder_status_t status = AServiceManager_addService(moduleBinder.get(), moduleName.c_str()); + binder_status_t status = + AServiceManager_addService(moduleBinder.get(), moduleName.str().c_str()); CHECK_EQ(STATUS_OK, status); return std::make_pair(module, moduleBinder); }; - auto modules = {createModule(Module::Type::DEFAULT, "default"), - createModule(Module::Type::R_SUBMIX, "r_submix"), - createModule(Module::Type::USB, "usb")}; + auto modules = {createModule(Module::Type::DEFAULT), createModule(Module::Type::R_SUBMIX), + createModule(Module::Type::USB), createModule(Module::Type::STUB)}; (void)modules; ABinderProcess_joinThreadPool(); diff --git a/audio/aidl/default/stub/ModuleStub.cpp b/audio/aidl/default/stub/ModuleStub.cpp new file mode 100644 index 0000000000..a60075221d --- /dev/null +++ b/audio/aidl/default/stub/ModuleStub.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2023 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. + */ + +#include + +#define LOG_TAG "AHAL_ModuleStub" +#include +#include + +#include "core-impl/Bluetooth.h" +#include "core-impl/ModuleStub.h" +#include "core-impl/StreamStub.h" + +using aidl::android::hardware::audio::common::SinkMetadata; +using aidl::android::hardware::audio::common::SourceMetadata; +using aidl::android::media::audio::common::AudioOffloadInfo; +using aidl::android::media::audio::common::AudioPort; +using aidl::android::media::audio::common::AudioPortConfig; +using aidl::android::media::audio::common::MicrophoneInfo; + +namespace aidl::android::hardware::audio::core { + +ndk::ScopedAStatus ModuleStub::getBluetooth(std::shared_ptr* _aidl_return) { + if (!mBluetooth) { + mBluetooth = ndk::SharedRefBase::make(); + } + *_aidl_return = mBluetooth.getPtr(); + LOG(DEBUG) << __func__ << ": returning instance of IBluetooth: " << _aidl_return->get(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus ModuleStub::getBluetoothA2dp(std::shared_ptr* _aidl_return) { + if (!mBluetoothA2dp) { + mBluetoothA2dp = ndk::SharedRefBase::make(); + } + *_aidl_return = mBluetoothA2dp.getPtr(); + LOG(DEBUG) << __func__ << ": returning instance of IBluetoothA2dp: " << _aidl_return->get(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus ModuleStub::getBluetoothLe(std::shared_ptr* _aidl_return) { + if (!mBluetoothLe) { + mBluetoothLe = ndk::SharedRefBase::make(); + } + *_aidl_return = mBluetoothLe.getPtr(); + LOG(DEBUG) << __func__ << ": returning instance of IBluetoothLe: " << _aidl_return->get(); + return ndk::ScopedAStatus::ok(); +} + +ndk::ScopedAStatus ModuleStub::createInputStream(const SinkMetadata& sinkMetadata, + StreamContext&& context, + const std::vector& microphones, + std::shared_ptr* result) { + return createStreamInstance(result, sinkMetadata, std::move(context), + microphones); +} + +ndk::ScopedAStatus ModuleStub::createOutputStream( + const SourceMetadata& sourceMetadata, StreamContext&& context, + const std::optional& offloadInfo, std::shared_ptr* result) { + return createStreamInstance(result, sourceMetadata, std::move(context), + offloadInfo); +} + +} // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/StreamStub.cpp b/audio/aidl/default/stub/StreamStub.cpp similarity index 100% rename from audio/aidl/default/StreamStub.cpp rename to audio/aidl/default/stub/StreamStub.cpp