diff --git a/audio/aidl/default/include/core-impl/Module.h b/audio/aidl/default/include/core-impl/Module.h index 83ecfaa8c6..e8b3d899c3 100644 --- a/audio/aidl/default/include/core-impl/Module.h +++ b/audio/aidl/default/include/core-impl/Module.h @@ -39,33 +39,9 @@ class Module : public BnModule { static StreamIn::CreateInstance getStreamInCreator(Type type); static StreamOut::CreateInstance getStreamOutCreator(Type type); - private: - struct VendorDebug { - static const std::string kForceTransientBurstName; - static const std::string kForceSynchronousDrainName; - 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; } - }; + protected: + // The vendor extension done via inheritance can override interface methods and augment + // a call to the base implementation. ndk::ScopedAStatus setModuleDebug( const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override; @@ -146,29 +122,46 @@ class Module : public BnModule { ndk::ScopedAStatus getAAudioMixerBurstCount(int32_t* _aidl_return) override; ndk::ScopedAStatus getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) override; - void cleanUpPatch(int32_t patchId); - ndk::ScopedAStatus createStreamContext( - int32_t in_portConfigId, int64_t in_bufferSizeFrames, - std::shared_ptr asyncCallback, - std::shared_ptr outEventCallback, - ::aidl::android::hardware::audio::core::StreamContext* out_context); - std::vector<::aidl::android::media::audio::common::AudioDevice> findConnectedDevices( - int32_t portConfigId); - std::set findConnectedPortConfigIds(int32_t portConfigId); - ndk::ScopedAStatus findPortIdForNewStream( - int32_t in_portConfigId, ::aidl::android::media::audio::common::AudioPort** port); - internal::Configuration& getConfig(); - template - std::set portIdsFromPortConfigIds(C portConfigIds); - void registerPatch(const AudioPatch& patch); - void updateStreamsConnectedState(const AudioPatch& oldPatch, const AudioPatch& newPatch); - bool isMmapSupported(); - // This value is used for all AudioPatches. static constexpr int32_t kMinimumStreamBufferSizeFrames = 256; // The maximum stream buffer size is 1 GiB = 2 ** 30 bytes; static constexpr int32_t kMaximumStreamBufferSizeBytes = 1 << 30; + private: + struct VendorDebug { + static const std::string kForceTransientBurstName; + static const std::string kForceSynchronousDrainName; + 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. + using ConnectedDevicePorts = std::map>; + // Maps port ids and port config ids to patch ids. + // Multimap because both ports and configs can be used by multiple patches. + using Patches = std::multimap; + const Type mType; std::unique_ptr mConfig; ModuleDebug mDebug; @@ -177,19 +170,18 @@ class Module : public BnModule { ChildInterface mBluetooth; ChildInterface mBluetoothA2dp; ChildInterface mBluetoothLe; - // ids of device ports created at runtime via 'connectExternalDevice'. - // Also stores ids of mix ports with dynamic profiles which got populated from the connected - // port. - std::map> mConnectedDevicePorts; + ConnectedDevicePorts mConnectedDevicePorts; Streams mStreams; - // Maps port ids and port config ids to patch ids. - // Multimap because both ports and configs can be used by multiple patches. - std::multimap mPatches; + Patches mPatches; bool mMicMute = false; + bool mMasterMute = false; + float mMasterVolume = 1.0f; ChildInterface mSoundDose; std::optional mIsMmapSupported; protected: + // The following virtual functions are intended for vendor extension via inheritance. + // 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( @@ -204,8 +196,30 @@ class Module : public BnModule { virtual ndk::ScopedAStatus onMasterMuteChanged(bool mute); virtual ndk::ScopedAStatus onMasterVolumeChanged(float volume); - bool mMasterMute = false; - float mMasterVolume = 1.0f; + // Utility and helper functions accessible to subclasses. + void cleanUpPatch(int32_t patchId); + ndk::ScopedAStatus createStreamContext( + int32_t in_portConfigId, int64_t in_bufferSizeFrames, + std::shared_ptr asyncCallback, + std::shared_ptr outEventCallback, + ::aidl::android::hardware::audio::core::StreamContext* out_context); + std::vector<::aidl::android::media::audio::common::AudioDevice> findConnectedDevices( + int32_t portConfigId); + std::set findConnectedPortConfigIds(int32_t portConfigId); + ndk::ScopedAStatus findPortIdForNewStream( + int32_t in_portConfigId, ::aidl::android::media::audio::common::AudioPort** port); + internal::Configuration& getConfig(); + const ConnectedDevicePorts& getConnectedDevicePorts() const { return mConnectedDevicePorts; } + bool getMasterMute() const { return mMasterMute; } + bool getMasterVolume() const { return mMasterVolume; } + bool getMicMute() const { return mMicMute; } + const Patches& getPatches() const { return mPatches; } + const Streams& getStreams() const { return mStreams; } + bool isMmapSupported(); + template + std::set portIdsFromPortConfigIds(C portConfigIds); + void registerPatch(const AudioPatch& patch); + void updateStreamsConnectedState(const AudioPatch& oldPatch, const AudioPatch& newPatch); }; } // namespace aidl::android::hardware::audio::core diff --git a/audio/aidl/default/usb/ModuleUsb.cpp b/audio/aidl/default/usb/ModuleUsb.cpp index ecdbd5cb77..627f854dac 100644 --- a/audio/aidl/default/usb/ModuleUsb.cpp +++ b/audio/aidl/default/usb/ModuleUsb.cpp @@ -175,8 +175,8 @@ void ModuleUsb::onExternalDeviceConnectionChanged( return; } const int card = address.get()[0]; - usb::UsbAlsaMixerControl::getInstance().setDeviceConnectionState(card, mMasterMute, - mMasterVolume, connected); + usb::UsbAlsaMixerControl::getInstance().setDeviceConnectionState(card, getMasterMute(), + getMasterVolume(), connected); } ndk::ScopedAStatus ModuleUsb::onMasterMuteChanged(bool mute) {