1 /* 2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <functional> 20 #include <iostream> 21 #include <map> 22 #include <memory> 23 #include <optional> 24 #include <set> 25 26 #include <Utils.h> 27 #include <aidl/android/hardware/audio/core/BnModule.h> 28 29 #include "core-impl/ChildInterface.h" 30 #include "core-impl/Stream.h" 31 32 namespace aidl::android::hardware::audio::core { 33 34 class Module : public BnModule { 35 public: 36 struct Configuration { 37 std::vector<::aidl::android::media::audio::common::AudioPort> ports; 38 std::vector<::aidl::android::media::audio::common::AudioPortConfig> portConfigs; 39 std::vector<::aidl::android::media::audio::common::AudioPortConfig> initialConfigs; 40 // Port id -> List of profiles to use when the device port state is set to 'connected' 41 // in connection simulation mode. 42 std::map<int32_t, std::vector<::aidl::android::media::audio::common::AudioProfile>> 43 connectedProfiles; 44 std::vector<AudioRoute> routes; 45 std::vector<AudioPatch> patches; 46 int32_t nextPortId = 1; 47 int32_t nextPatchId = 1; 48 }; 49 enum Type : int { DEFAULT, R_SUBMIX, STUB, USB, BLUETOOTH }; 50 createInstance(Type type)51 static std::shared_ptr<Module> createInstance(Type type) { 52 return createInstance(type, std::make_unique<Configuration>()); 53 } 54 static std::shared_ptr<Module> createInstance(Type type, 55 std::unique_ptr<Configuration>&& config); 56 static std::optional<Type> typeFromString(const std::string& type); 57 58 Module(Type type, std::unique_ptr<Configuration>&& config); 59 60 protected: 61 // The vendor extension done via inheritance can override interface methods and augment 62 // a call to the base implementation. 63 64 ndk::ScopedAStatus setModuleDebug( 65 const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override; 66 ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override; 67 ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override; 68 ndk::ScopedAStatus getBluetoothA2dp(std::shared_ptr<IBluetoothA2dp>* _aidl_return) override; 69 ndk::ScopedAStatus getBluetoothLe(std::shared_ptr<IBluetoothLe>* _aidl_return) override; 70 ndk::ScopedAStatus connectExternalDevice( 71 const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData, 72 ::aidl::android::media::audio::common::AudioPort* _aidl_return) override; 73 ndk::ScopedAStatus disconnectExternalDevice(int32_t in_portId) override; 74 ndk::ScopedAStatus prepareToDisconnectExternalDevice(int32_t in_portId) override; 75 ndk::ScopedAStatus getAudioPatches(std::vector<AudioPatch>* _aidl_return) override; 76 ndk::ScopedAStatus getAudioPort( 77 int32_t in_portId, 78 ::aidl::android::media::audio::common::AudioPort* _aidl_return) override; 79 ndk::ScopedAStatus getAudioPortConfigs( 80 std::vector<::aidl::android::media::audio::common::AudioPortConfig>* _aidl_return) 81 override; 82 ndk::ScopedAStatus getAudioPorts( 83 std::vector<::aidl::android::media::audio::common::AudioPort>* _aidl_return) override; 84 ndk::ScopedAStatus getAudioRoutes(std::vector<AudioRoute>* _aidl_return) override; 85 ndk::ScopedAStatus getAudioRoutesForAudioPort( 86 int32_t in_portId, 87 std::vector<::aidl::android::hardware::audio::core::AudioRoute>* _aidl_return) override; 88 ndk::ScopedAStatus openInputStream( 89 const ::aidl::android::hardware::audio::core::IModule::OpenInputStreamArguments& 90 in_args, 91 ::aidl::android::hardware::audio::core::IModule::OpenInputStreamReturn* _aidl_return) 92 override; 93 ndk::ScopedAStatus openOutputStream( 94 const ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments& 95 in_args, 96 ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn* _aidl_return) 97 override; 98 ndk::ScopedAStatus getSupportedPlaybackRateFactors( 99 SupportedPlaybackRateFactors* _aidl_return) override; 100 ndk::ScopedAStatus setAudioPatch(const AudioPatch& in_requested, 101 AudioPatch* _aidl_return) override; 102 ndk::ScopedAStatus setAudioPortConfig( 103 const ::aidl::android::media::audio::common::AudioPortConfig& in_requested, 104 ::aidl::android::media::audio::common::AudioPortConfig* out_suggested, 105 bool* _aidl_return) override; 106 ndk::ScopedAStatus resetAudioPatch(int32_t in_patchId) override; 107 ndk::ScopedAStatus resetAudioPortConfig(int32_t in_portConfigId) override; 108 ndk::ScopedAStatus getMasterMute(bool* _aidl_return) override; 109 ndk::ScopedAStatus setMasterMute(bool in_mute) override; 110 ndk::ScopedAStatus getMasterVolume(float* _aidl_return) override; 111 ndk::ScopedAStatus setMasterVolume(float in_volume) override; 112 ndk::ScopedAStatus getMicMute(bool* _aidl_return) override; 113 ndk::ScopedAStatus setMicMute(bool in_mute) override; 114 ndk::ScopedAStatus getMicrophones( 115 std::vector<::aidl::android::media::audio::common::MicrophoneInfo>* _aidl_return) 116 override; 117 ndk::ScopedAStatus updateAudioMode( 118 ::aidl::android::media::audio::common::AudioMode in_mode) override; 119 ndk::ScopedAStatus updateScreenRotation( 120 ::aidl::android::hardware::audio::core::IModule::ScreenRotation in_rotation) override; 121 ndk::ScopedAStatus updateScreenState(bool in_isTurnedOn) override; 122 ndk::ScopedAStatus getSoundDose(std::shared_ptr<sounddose::ISoundDose>* _aidl_return) override; 123 ndk::ScopedAStatus generateHwAvSyncId(int32_t* _aidl_return) override; 124 ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_ids, 125 std::vector<VendorParameter>* _aidl_return) override; 126 ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters, 127 bool in_async) override; 128 ndk::ScopedAStatus addDeviceEffect( 129 int32_t in_portConfigId, 130 const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) 131 override; 132 ndk::ScopedAStatus removeDeviceEffect( 133 int32_t in_portConfigId, 134 const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) 135 override; 136 ndk::ScopedAStatus getMmapPolicyInfos( 137 ::aidl::android::media::audio::common::AudioMMapPolicyType mmapPolicyType, 138 std::vector<::aidl::android::media::audio::common::AudioMMapPolicyInfo>* _aidl_return) 139 override; 140 ndk::ScopedAStatus supportsVariableLatency(bool* _aidl_return) override; 141 ndk::ScopedAStatus getAAudioMixerBurstCount(int32_t* _aidl_return) override; 142 ndk::ScopedAStatus getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) override; 143 144 // The maximum stream buffer size is 1 GiB = 2 ** 30 bytes; 145 static constexpr int32_t kMaximumStreamBufferSizeBytes = 1 << 30; 146 147 private: 148 struct VendorDebug { 149 static const std::string kForceTransientBurstName; 150 static const std::string kForceSynchronousDrainName; 151 bool forceTransientBurst = false; 152 bool forceSynchronousDrain = false; 153 }; 154 // ids of device ports created at runtime via 'connectExternalDevice'. 155 // Also stores a list of ids of mix ports with dynamic profiles that were populated from 156 // the connected port. This list can be empty, thus an int->int multimap can't be used. 157 using ConnectedDevicePorts = std::map<int32_t, std::set<int32_t>>; 158 // Maps port ids and port config ids to patch ids. 159 // Multimap because both ports and configs can be used by multiple patches. 160 using Patches = std::multimap<int32_t, int32_t>; 161 162 const Type mType; 163 std::unique_ptr<Configuration> mConfig; 164 ModuleDebug mDebug; 165 VendorDebug mVendorDebug; 166 ConnectedDevicePorts mConnectedDevicePorts; 167 Streams mStreams; 168 Patches mPatches; 169 bool mMicMute = false; 170 bool mMasterMute = false; 171 float mMasterVolume = 1.0f; 172 ChildInterface<sounddose::SoundDose> mSoundDose; 173 std::optional<bool> mIsMmapSupported; 174 175 protected: 176 // The following virtual functions are intended for vendor extension via inheritance. 177 178 virtual ndk::ScopedAStatus createInputStream( 179 StreamContext&& context, 180 const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, 181 const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, 182 std::shared_ptr<StreamIn>* result) = 0; 183 virtual ndk::ScopedAStatus createOutputStream( 184 StreamContext&& context, 185 const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, 186 const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& 187 offloadInfo, 188 std::shared_ptr<StreamOut>* result) = 0; 189 // If the module is unable to populate the connected device port correctly, the returned error 190 // code must correspond to the errors of `IModule.connectedExternalDevice` method. 191 virtual ndk::ScopedAStatus populateConnectedDevicePort( 192 ::aidl::android::media::audio::common::AudioPort* audioPort, int32_t nextPortId); 193 // If the module finds that the patch endpoints configurations are not matched, the returned 194 // error code must correspond to the errors of `IModule.setAudioPatch` method. 195 virtual ndk::ScopedAStatus checkAudioPatchEndpointsMatch( 196 const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources, 197 const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks); 198 virtual void onExternalDeviceConnectionChanged( 199 const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected); 200 virtual void onPrepareToDisconnectExternalDevice( 201 const ::aidl::android::media::audio::common::AudioPort& audioPort); 202 virtual ndk::ScopedAStatus onMasterMuteChanged(bool mute); 203 virtual ndk::ScopedAStatus onMasterVolumeChanged(float volume); 204 virtual std::vector<::aidl::android::media::audio::common::MicrophoneInfo> getMicrophoneInfos(); 205 virtual std::unique_ptr<Configuration> initializeConfig(); 206 virtual int32_t getNominalLatencyMs( 207 const ::aidl::android::media::audio::common::AudioPortConfig& portConfig); 208 209 // Utility and helper functions accessible to subclasses. calculateBufferSizeFrames(int32_t latencyMs,int32_t sampleRateHz)210 static int32_t calculateBufferSizeFrames(int32_t latencyMs, int32_t sampleRateHz) { 211 const int32_t rawSizeFrames = 212 aidl::android::hardware::audio::common::frameCountFromDurationMs(latencyMs, 213 sampleRateHz); 214 // Round up to nearest 16 frames since in the framework this is the size of a mixer burst. 215 const int32_t multipleOf16 = (rawSizeFrames + 15) & ~15; 216 if (sampleRateHz < 44100 || multipleOf16 <= 512) return multipleOf16; 217 // Larger buffers should use powers of 2. 218 int32_t powerOf2 = 1; 219 while (powerOf2 < multipleOf16) powerOf2 <<= 1; 220 return powerOf2; 221 } 222 223 ndk::ScopedAStatus bluetoothParametersUpdated(); 224 void cleanUpPatch(int32_t patchId); 225 ndk::ScopedAStatus createStreamContext( 226 int32_t in_portConfigId, int64_t in_bufferSizeFrames, 227 std::shared_ptr<IStreamCallback> asyncCallback, 228 std::shared_ptr<IStreamOutEventCallback> outEventCallback, 229 ::aidl::android::hardware::audio::core::StreamContext* out_context); 230 std::vector<::aidl::android::media::audio::common::AudioDevice> findConnectedDevices( 231 int32_t portConfigId); 232 std::set<int32_t> findConnectedPortConfigIds(int32_t portConfigId); 233 ndk::ScopedAStatus findPortIdForNewStream( 234 int32_t in_portConfigId, ::aidl::android::media::audio::common::AudioPort** port); 235 // Note: does not assign an ID to the config. 236 bool generateDefaultPortConfig(const ::aidl::android::media::audio::common::AudioPort& port, 237 ::aidl::android::media::audio::common::AudioPortConfig* config); 238 std::vector<AudioRoute*> getAudioRoutesForAudioPortImpl(int32_t portId); 239 Configuration& getConfig(); getConnectedDevicePorts()240 const ConnectedDevicePorts& getConnectedDevicePorts() const { return mConnectedDevicePorts; } getMasterMute()241 bool getMasterMute() const { return mMasterMute; } getMasterVolume()242 bool getMasterVolume() const { return mMasterVolume; } getMicMute()243 bool getMicMute() const { return mMicMute; } getModuleDebug()244 const ModuleDebug& getModuleDebug() const { return mDebug; } getPatches()245 const Patches& getPatches() const { return mPatches; } 246 std::set<int32_t> getRoutableAudioPortIds(int32_t portId, 247 std::vector<AudioRoute*>* routes = nullptr); getStreams()248 const Streams& getStreams() const { return mStreams; } getType()249 Type getType() const { return mType; } 250 bool isMmapSupported(); 251 void populateConnectedProfiles(); 252 template <typename C> 253 std::set<int32_t> portIdsFromPortConfigIds(C portConfigIds); 254 void registerPatch(const AudioPatch& patch); 255 ndk::ScopedAStatus setAudioPortConfigImpl( 256 const ::aidl::android::media::audio::common::AudioPortConfig& in_requested, 257 const std::function<bool(const ::aidl::android::media::audio::common::AudioPort& port, 258 ::aidl::android::media::audio::common::AudioPortConfig* 259 config)>& fillPortConfig, 260 ::aidl::android::media::audio::common::AudioPortConfig* out_suggested, bool* applied); 261 ndk::ScopedAStatus updateStreamsConnectedState(const AudioPatch& oldPatch, 262 const AudioPatch& newPatch); 263 }; 264 265 std::ostream& operator<<(std::ostream& os, Module::Type t); 266 267 } // namespace aidl::android::hardware::audio::core 268