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 binder_status_t dump(int fd, const char** args, uint32_t numArgs) override; 65 66 ndk::ScopedAStatus setModuleDebug( 67 const ::aidl::android::hardware::audio::core::ModuleDebug& in_debug) override; 68 ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override; 69 ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override; 70 ndk::ScopedAStatus getBluetoothA2dp(std::shared_ptr<IBluetoothA2dp>* _aidl_return) override; 71 ndk::ScopedAStatus getBluetoothLe(std::shared_ptr<IBluetoothLe>* _aidl_return) override; 72 ndk::ScopedAStatus connectExternalDevice( 73 const ::aidl::android::media::audio::common::AudioPort& in_templateIdAndAdditionalData, 74 ::aidl::android::media::audio::common::AudioPort* _aidl_return) override; 75 ndk::ScopedAStatus disconnectExternalDevice(int32_t in_portId) override; 76 ndk::ScopedAStatus prepareToDisconnectExternalDevice(int32_t in_portId) override; 77 ndk::ScopedAStatus getAudioPatches(std::vector<AudioPatch>* _aidl_return) override; 78 ndk::ScopedAStatus getAudioPort( 79 int32_t in_portId, 80 ::aidl::android::media::audio::common::AudioPort* _aidl_return) override; 81 ndk::ScopedAStatus getAudioPortConfigs( 82 std::vector<::aidl::android::media::audio::common::AudioPortConfig>* _aidl_return) 83 override; 84 ndk::ScopedAStatus getAudioPorts( 85 std::vector<::aidl::android::media::audio::common::AudioPort>* _aidl_return) override; 86 ndk::ScopedAStatus getAudioRoutes(std::vector<AudioRoute>* _aidl_return) override; 87 ndk::ScopedAStatus getAudioRoutesForAudioPort( 88 int32_t in_portId, 89 std::vector<::aidl::android::hardware::audio::core::AudioRoute>* _aidl_return) override; 90 ndk::ScopedAStatus openInputStream( 91 const ::aidl::android::hardware::audio::core::IModule::OpenInputStreamArguments& 92 in_args, 93 ::aidl::android::hardware::audio::core::IModule::OpenInputStreamReturn* _aidl_return) 94 override; 95 ndk::ScopedAStatus openOutputStream( 96 const ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamArguments& 97 in_args, 98 ::aidl::android::hardware::audio::core::IModule::OpenOutputStreamReturn* _aidl_return) 99 override; 100 ndk::ScopedAStatus getSupportedPlaybackRateFactors( 101 SupportedPlaybackRateFactors* _aidl_return) override; 102 ndk::ScopedAStatus setAudioPatch(const AudioPatch& in_requested, 103 AudioPatch* _aidl_return) override; 104 ndk::ScopedAStatus setAudioPortConfig( 105 const ::aidl::android::media::audio::common::AudioPortConfig& in_requested, 106 ::aidl::android::media::audio::common::AudioPortConfig* out_suggested, 107 bool* _aidl_return) override; 108 ndk::ScopedAStatus resetAudioPatch(int32_t in_patchId) override; 109 ndk::ScopedAStatus resetAudioPortConfig(int32_t in_portConfigId) override; 110 ndk::ScopedAStatus getMasterMute(bool* _aidl_return) override; 111 ndk::ScopedAStatus setMasterMute(bool in_mute) override; 112 ndk::ScopedAStatus getMasterVolume(float* _aidl_return) override; 113 ndk::ScopedAStatus setMasterVolume(float in_volume) override; 114 ndk::ScopedAStatus getMicMute(bool* _aidl_return) override; 115 ndk::ScopedAStatus setMicMute(bool in_mute) override; 116 ndk::ScopedAStatus getMicrophones( 117 std::vector<::aidl::android::media::audio::common::MicrophoneInfo>* _aidl_return) 118 override; 119 ndk::ScopedAStatus updateAudioMode( 120 ::aidl::android::media::audio::common::AudioMode in_mode) override; 121 ndk::ScopedAStatus updateScreenRotation( 122 ::aidl::android::hardware::audio::core::IModule::ScreenRotation in_rotation) override; 123 ndk::ScopedAStatus updateScreenState(bool in_isTurnedOn) override; 124 ndk::ScopedAStatus getSoundDose(std::shared_ptr<sounddose::ISoundDose>* _aidl_return) override; 125 ndk::ScopedAStatus generateHwAvSyncId(int32_t* _aidl_return) override; 126 ndk::ScopedAStatus getVendorParameters(const std::vector<std::string>& in_ids, 127 std::vector<VendorParameter>* _aidl_return) override; 128 ndk::ScopedAStatus setVendorParameters(const std::vector<VendorParameter>& in_parameters, 129 bool in_async) override; 130 ndk::ScopedAStatus addDeviceEffect( 131 int32_t in_portConfigId, 132 const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) 133 override; 134 ndk::ScopedAStatus removeDeviceEffect( 135 int32_t in_portConfigId, 136 const std::shared_ptr<::aidl::android::hardware::audio::effect::IEffect>& in_effect) 137 override; 138 ndk::ScopedAStatus getMmapPolicyInfos( 139 ::aidl::android::media::audio::common::AudioMMapPolicyType mmapPolicyType, 140 std::vector<::aidl::android::media::audio::common::AudioMMapPolicyInfo>* _aidl_return) 141 override; 142 ndk::ScopedAStatus supportsVariableLatency(bool* _aidl_return) override; 143 ndk::ScopedAStatus getAAudioMixerBurstCount(int32_t* _aidl_return) override; 144 ndk::ScopedAStatus getAAudioHardwareBurstMinUsec(int32_t* _aidl_return) override; 145 146 // The maximum stream buffer size is 1 GiB = 2 ** 30 bytes; 147 static constexpr int32_t kMaximumStreamBufferSizeBytes = 1 << 30; 148 149 private: 150 struct VendorDebug { 151 static const std::string kForceTransientBurstName; 152 static const std::string kForceSynchronousDrainName; 153 bool forceTransientBurst = false; 154 bool forceSynchronousDrain = 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 static const std::string kClipTransitionSupportName; 165 const Type mType; 166 std::unique_ptr<Configuration> mConfig; 167 ModuleDebug mDebug; 168 VendorDebug mVendorDebug; 169 ConnectedDevicePorts mConnectedDevicePorts; 170 Streams mStreams; 171 Patches mPatches; 172 bool mMicMute = false; 173 bool mMasterMute = false; 174 float mMasterVolume = 1.0f; 175 ChildInterface<sounddose::SoundDose> mSoundDose; 176 std::optional<bool> mIsMmapSupported; 177 178 protected: 179 // The following virtual functions are intended for vendor extension via inheritance. 180 181 virtual ndk::ScopedAStatus createInputStream( 182 StreamContext&& context, 183 const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata, 184 const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones, 185 std::shared_ptr<StreamIn>* result) = 0; 186 virtual ndk::ScopedAStatus createOutputStream( 187 StreamContext&& context, 188 const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata, 189 const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>& 190 offloadInfo, 191 std::shared_ptr<StreamOut>* result) = 0; 192 // If the module is unable to populate the connected device port correctly, the returned error 193 // code must correspond to the errors of `IModule.connectedExternalDevice` method. 194 virtual ndk::ScopedAStatus populateConnectedDevicePort( 195 ::aidl::android::media::audio::common::AudioPort* audioPort, int32_t nextPortId); 196 // If the module finds that the patch endpoints configurations are not matched, the returned 197 // error code must correspond to the errors of `IModule.setAudioPatch` method. 198 virtual ndk::ScopedAStatus checkAudioPatchEndpointsMatch( 199 const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources, 200 const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks); 201 virtual void onExternalDeviceConnectionChanged( 202 const ::aidl::android::media::audio::common::AudioPort& audioPort, bool connected); 203 virtual void onPrepareToDisconnectExternalDevice( 204 const ::aidl::android::media::audio::common::AudioPort& audioPort); 205 virtual ndk::ScopedAStatus onMasterMuteChanged(bool mute); 206 virtual ndk::ScopedAStatus onMasterVolumeChanged(float volume); 207 virtual std::vector<::aidl::android::media::audio::common::MicrophoneInfo> getMicrophoneInfos(); 208 virtual std::unique_ptr<Configuration> initializeConfig(); 209 virtual int32_t getNominalLatencyMs( 210 const ::aidl::android::media::audio::common::AudioPortConfig& portConfig); 211 virtual ndk::ScopedAStatus calculateBufferSizeFrames( 212 const ::aidl::android::media::audio::common::AudioFormatDescription &format, 213 int32_t latencyMs, int32_t sampleRateHz, int32_t *bufferSizeFrames); 214 virtual ndk::ScopedAStatus createMmapBuffer( 215 const ::aidl::android::media::audio::common::AudioPortConfig& portConfig, 216 int32_t bufferSizeFrames, int32_t frameSizeBytes, MmapBufferDescriptor* desc); 217 218 // Utility and helper functions accessible to subclasses. calculateBufferSizeFramesForPcm(int32_t latencyMs,int32_t sampleRateHz)219 static int32_t calculateBufferSizeFramesForPcm(int32_t latencyMs, int32_t sampleRateHz) { 220 const int32_t rawSizeFrames = 221 aidl::android::hardware::audio::common::frameCountFromDurationMs(latencyMs, 222 sampleRateHz); 223 // Round up to nearest 16 frames since in the framework this is the size of a mixer burst. 224 const int32_t multipleOf16 = (rawSizeFrames + 15) & ~15; 225 if (sampleRateHz < 44100 || multipleOf16 <= 512) return multipleOf16; 226 // Larger buffers should use powers of 2. 227 int32_t powerOf2 = 1; 228 while (powerOf2 < multipleOf16) powerOf2 <<= 1; 229 return powerOf2; 230 } 231 232 ndk::ScopedAStatus bluetoothParametersUpdated(); 233 void cleanUpPatch(int32_t patchId); 234 ndk::ScopedAStatus createStreamContext( 235 int32_t in_portConfigId, int64_t in_bufferSizeFrames, 236 std::shared_ptr<IStreamCallback> asyncCallback, 237 std::shared_ptr<IStreamOutEventCallback> outEventCallback, 238 ::aidl::android::hardware::audio::core::StreamContext* out_context); 239 std::vector<::aidl::android::media::audio::common::AudioDevice> findConnectedDevices( 240 int32_t portConfigId); 241 std::set<int32_t> findConnectedPortConfigIds(int32_t portConfigId); 242 ndk::ScopedAStatus findPortIdForNewStream( 243 int32_t in_portConfigId, ::aidl::android::media::audio::common::AudioPort** port); 244 // Note: does not assign an ID to the config. 245 bool generateDefaultPortConfig(const ::aidl::android::media::audio::common::AudioPort& port, 246 ::aidl::android::media::audio::common::AudioPortConfig* config); 247 std::vector<AudioRoute*> getAudioRoutesForAudioPortImpl(int32_t portId); 248 Configuration& getConfig(); getConnectedDevicePorts()249 const ConnectedDevicePorts& getConnectedDevicePorts() const { return mConnectedDevicePorts; } 250 std::vector<::aidl::android::media::audio::common::AudioDevice> 251 getDevicesFromDevicePortConfigIds(const std::set<int32_t>& devicePortConfigIds); getMasterMute()252 bool getMasterMute() const { return mMasterMute; } getMasterVolume()253 bool getMasterVolume() const { return mMasterVolume; } getMicMute()254 bool getMicMute() const { return mMicMute; } getModuleDebug()255 const ModuleDebug& getModuleDebug() const { return mDebug; } getPatches()256 const Patches& getPatches() const { return mPatches; } 257 std::set<int32_t> getRoutableAudioPortIds(int32_t portId, 258 std::vector<AudioRoute*>* routes = nullptr); getStreams()259 const Streams& getStreams() const { return mStreams; } getType()260 Type getType() const { return mType; } 261 bool isMmapSupported(); 262 void populateConnectedProfiles(); 263 template <typename C> 264 std::set<int32_t> portIdsFromPortConfigIds(C portConfigIds); 265 void registerPatch(const AudioPatch& patch); 266 ndk::ScopedAStatus setAudioPortConfigImpl( 267 const ::aidl::android::media::audio::common::AudioPortConfig& in_requested, 268 const std::function<bool(const ::aidl::android::media::audio::common::AudioPort& port, 269 ::aidl::android::media::audio::common::AudioPortConfig* 270 config)>& fillPortConfig, 271 ::aidl::android::media::audio::common::AudioPortConfig* out_suggested, bool* applied); 272 ndk::ScopedAStatus updateStreamsConnectedState(const AudioPatch& oldPatch, 273 const AudioPatch& newPatch); 274 bool setAudioPortConfigGain( 275 const ::aidl::android::media::audio::common::AudioPort& port, 276 const ::aidl::android::media::audio::common::AudioGainConfig& gainRequested); 277 }; 278 279 std::ostream& operator<<(std::ostream& os, Module::Type t); 280 281 } // namespace aidl::android::hardware::audio::core 282