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