• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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