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 static const std::string kForceDrainToDrainingName; 152 bool forceTransientBurst = false; 153 bool forceSynchronousDrain = false; 154 bool forceDrainToDraining = false; 155 }; 156 // ids of device ports created at runtime via 'connectExternalDevice'. 157 // Also stores a list of ids of mix ports with dynamic profiles that were populated from 158 // the connected port. This list can be empty, thus an int->int multimap can't be used. 159 using ConnectedDevicePorts = std::map<int32_t, std::set<int32_t>>; 160 // Maps port ids and port config ids to patch ids. 161 // Multimap because both ports and configs can be used by multiple patches. 162 using Patches = std::multimap<int32_t, int32_t>; 163 164 const Type mType; 165 std::unique_ptr<Configuration> mConfig; 166 ModuleDebug mDebug; 167 VendorDebug mVendorDebug; 168 ConnectedDevicePorts mConnectedDevicePorts; 169 Streams mStreams; 170 Patches mPatches; 171 bool mMicMute = false; 172 bool mMasterMute = false; 173 float mMasterVolume = 1.0f; 174 ChildInterface<sounddose::SoundDose> mSoundDose; 175 std::optional<bool> mIsMmapSupported; 176 177 protected: 178 // The following virtual functions are intended for vendor extension via inheritance. 179 180 virtual ndk::ScopedAStatus createInputStream( 181 StreamContext&& context, 182 const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, 183 const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, 184 std::shared_ptr<StreamIn>* result) = 0; 185 virtual ndk::ScopedAStatus createOutputStream( 186 StreamContext&& context, 187 const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, 188 const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& 189 offloadInfo, 190 std::shared_ptr<StreamOut>* result) = 0; 191 // If the module is unable to populate the connected device port correctly, the returned error 192 // code must correspond to the errors of `IModule.connectedExternalDevice` method. 193 virtual ndk::ScopedAStatus populateConnectedDevicePort( 194 ::aidl::android::media::audio::common::AudioPort* audioPort, int32_t nextPortId); 195 // If the module finds that the patch endpoints configurations are not matched, the returned 196 // error code must correspond to the errors of `IModule.setAudioPatch` method. 197 virtual ndk::ScopedAStatus checkAudioPatchEndpointsMatch( 198 const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources, 199 const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks); 200 virtual void onExternalDeviceConnectionChanged( 201 const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected); 202 virtual void onPrepareToDisconnectExternalDevice( 203 const ::aidl::android::media::audio::common::AudioPort& audioPort); 204 virtual ndk::ScopedAStatus onMasterMuteChanged(bool mute); 205 virtual ndk::ScopedAStatus onMasterVolumeChanged(float volume); 206 virtual std::vector<::aidl::android::media::audio::common::MicrophoneInfo> getMicrophoneInfos(); 207 virtual std::unique_ptr<Configuration> initializeConfig(); 208 virtual int32_t getNominalLatencyMs( 209 const ::aidl::android::media::audio::common::AudioPortConfig& portConfig); 210 virtual ndk::ScopedAStatus createMmapBuffer( 211 const ::aidl::android::hardware::audio::core::StreamContext& context, 212 ::aidl::android::hardware::audio::core::StreamDescriptor* desc); 213 214 // Utility and helper functions accessible to subclasses. calculateBufferSizeFrames(int32_t latencyMs,int32_t sampleRateHz)215 static int32_t calculateBufferSizeFrames(int32_t latencyMs, int32_t sampleRateHz) { 216 const int32_t rawSizeFrames = 217 aidl::android::hardware::audio::common::frameCountFromDurationMs(latencyMs, 218 sampleRateHz); 219 // Round up to nearest 16 frames since in the framework this is the size of a mixer burst. 220 const int32_t multipleOf16 = (rawSizeFrames + 15) & ~15; 221 if (sampleRateHz < 44100 || multipleOf16 <= 512) return multipleOf16; 222 // Larger buffers should use powers of 2. 223 int32_t powerOf2 = 1; 224 while (powerOf2 < multipleOf16) powerOf2 <<= 1; 225 return powerOf2; 226 } 227 228 ndk::ScopedAStatus bluetoothParametersUpdated(); 229 void cleanUpPatch(int32_t patchId); 230 ndk::ScopedAStatus createStreamContext( 231 int32_t in_portConfigId, int64_t in_bufferSizeFrames, 232 std::shared_ptr<IStreamCallback> asyncCallback, 233 std::shared_ptr<IStreamOutEventCallback> outEventCallback, 234 ::aidl::android::hardware::audio::core::StreamContext* out_context); 235 std::vector<::aidl::android::media::audio::common::AudioDevice> findConnectedDevices( 236 int32_t portConfigId); 237 std::set<int32_t> findConnectedPortConfigIds(int32_t portConfigId); 238 ndk::ScopedAStatus findPortIdForNewStream( 239 int32_t in_portConfigId, ::aidl::android::media::audio::common::AudioPort** port); 240 // Note: does not assign an ID to the config. 241 bool generateDefaultPortConfig(const ::aidl::android::media::audio::common::AudioPort& port, 242 ::aidl::android::media::audio::common::AudioPortConfig* config); 243 std::vector<AudioRoute*> getAudioRoutesForAudioPortImpl(int32_t portId); 244 Configuration& getConfig(); getConnectedDevicePorts()245 const ConnectedDevicePorts& getConnectedDevicePorts() const { return mConnectedDevicePorts; } 246 std::vector<::aidl::android::media::audio::common::AudioDevice> 247 getDevicesFromDevicePortConfigIds(const std::set<int32_t>& devicePortConfigIds); getMasterMute()248 bool getMasterMute() const { return mMasterMute; } getMasterVolume()249 bool getMasterVolume() const { return mMasterVolume; } getMicMute()250 bool getMicMute() const { return mMicMute; } getModuleDebug()251 const ModuleDebug& getModuleDebug() const { return mDebug; } getPatches()252 const Patches& getPatches() const { return mPatches; } 253 std::set<int32_t> getRoutableAudioPortIds(int32_t portId, 254 std::vector<AudioRoute*>* routes = nullptr); getStreams()255 const Streams& getStreams() const { return mStreams; } getType()256 Type getType() const { return mType; } 257 bool isMmapSupported(); 258 void populateConnectedProfiles(); 259 template <typename C> 260 std::set<int32_t> portIdsFromPortConfigIds(C portConfigIds); 261 void registerPatch(const AudioPatch& patch); 262 ndk::ScopedAStatus setAudioPortConfigImpl( 263 const ::aidl::android::media::audio::common::AudioPortConfig& in_requested, 264 const std::function<bool(const ::aidl::android::media::audio::common::AudioPort& port, 265 ::aidl::android::media::audio::common::AudioPortConfig* 266 config)>& fillPortConfig, 267 ::aidl::android::media::audio::common::AudioPortConfig* out_suggested, bool* applied); 268 ndk::ScopedAStatus updateStreamsConnectedState(const AudioPatch& oldPatch, 269 const AudioPatch& newPatch); 270 bool setAudioPortConfigGain( 271 const ::aidl::android::media::audio::common::AudioPort& port, 272 const ::aidl::android::media::audio::common::AudioGainConfig& gainRequested); 273 }; 274 275 std::ostream& operator<<(std::ostream& os, Module::Type t); 276 277 } // namespace aidl::android::hardware::audio::core 278