• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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 <atomic>
20 #include <memory>
21 #include <mutex>
22 #include <string_view>
23 
24 #include <aidl/android/hardware/audio/common/AudioOffloadMetadata.h>
25 #include <aidl/android/hardware/audio/core/BpStreamCommon.h>
26 #include <aidl/android/hardware/audio/core/BpStreamIn.h>
27 #include <aidl/android/hardware/audio/core/BpStreamOut.h>
28 #include <aidl/android/hardware/audio/core/MmapBufferDescriptor.h>
29 #include <aidl/android/media/audio/IHalAdapterVendorExtension.h>
30 #include <fmq/AidlMessageQueue.h>
31 #include <media/audiohal/EffectHalInterface.h>
32 #include <media/audiohal/StreamHalInterface.h>
33 #include <media/AidlConversionUtil.h>
34 #include <media/AudioParameter.h>
35 
36 #include "ConversionHelperAidl.h"
37 #include "StreamPowerLog.h"
38 
39 using ::aidl::android::hardware::audio::common::AudioOffloadMetadata;
40 using ::aidl::android::hardware::audio::core::MmapBufferDescriptor;
41 
42 namespace android {
43 
44 class StreamContextAidl {
45   public:
46     typedef AidlMessageQueue<::aidl::android::hardware::audio::core::StreamDescriptor::Command,
47           ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> CommandMQ;
48     typedef AidlMessageQueue<::aidl::android::hardware::audio::core::StreamDescriptor::Reply,
49             ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> ReplyMQ;
50     typedef AidlMessageQueue<int8_t,
51             ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> DataMQ;
52 
StreamContextAidl(::aidl::android::hardware::audio::core::StreamDescriptor & descriptor,bool isAsynchronous)53     StreamContextAidl(
54             ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor,
55             bool isAsynchronous)
56         : mFrameSizeBytes(descriptor.frameSizeBytes),
57           mCommandMQ(new CommandMQ(descriptor.command)),
58           mReplyMQ(new ReplyMQ(descriptor.reply)),
59           mBufferSizeFrames(descriptor.bufferSizeFrames),
60           mDataMQ(maybeCreateDataMQ(descriptor)),
61           mIsAsynchronous(isAsynchronous),
62           mIsMmapped(isMmapped(descriptor)),
63           mMmapBufferDescriptor(maybeGetMmapBuffer(descriptor)) {}
StreamContextAidl(StreamContextAidl && other)64     StreamContextAidl(StreamContextAidl&& other) :
65             mFrameSizeBytes(other.mFrameSizeBytes),
66             mCommandMQ(std::move(other.mCommandMQ)),
67             mReplyMQ(std::move(other.mReplyMQ)),
68             mBufferSizeFrames(other.mBufferSizeFrames),
69             mDataMQ(std::move(other.mDataMQ)),
70             mIsAsynchronous(other.mIsAsynchronous),
71             mIsMmapped(other.mIsMmapped),
72             mMmapBufferDescriptor(std::move(other.mMmapBufferDescriptor)) {}
73     StreamContextAidl& operator=(StreamContextAidl&& other) {
74         mFrameSizeBytes = other.mFrameSizeBytes;
75         mCommandMQ = std::move(other.mCommandMQ);
76         mReplyMQ = std::move(other.mReplyMQ);
77         mBufferSizeFrames = other.mBufferSizeFrames;
78         mDataMQ = std::move(other.mDataMQ);
79         mIsAsynchronous = other.mIsAsynchronous;
80         mIsMmapped = other.mIsMmapped;
81         mMmapBufferDescriptor = std::move(other.mMmapBufferDescriptor);
82         return *this;
83     }
isValid()84     bool isValid() const {
85         return mFrameSizeBytes != 0 &&
86                 mCommandMQ != nullptr && mCommandMQ->isValid() &&
87                 mReplyMQ != nullptr && mReplyMQ->isValid() &&
88                 (mDataMQ == nullptr || (
89                         mDataMQ->isValid() &&
90                         mDataMQ->getQuantumCount() * mDataMQ->getQuantumSize() >=
91                         mFrameSizeBytes * mBufferSizeFrames)) &&
92                 (!mIsMmapped || mMmapBufferDescriptor.sharedMemory.fd.get() >= 0);
93     }
getBufferSizeBytes()94     size_t getBufferSizeBytes() const { return mFrameSizeBytes * mBufferSizeFrames; }
getBufferSizeFrames()95     size_t getBufferSizeFrames() const { return mBufferSizeFrames; }
getCommandMQ()96     CommandMQ* getCommandMQ() const { return mCommandMQ.get(); }
getDataMQ()97     DataMQ* getDataMQ() const { return mDataMQ.get(); }
getFrameSizeBytes()98     size_t getFrameSizeBytes() const { return mFrameSizeBytes; }
getReplyMQ()99     ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); }
isAsynchronous()100     bool isAsynchronous() const { return mIsAsynchronous; }
isMmapped()101     bool isMmapped() const { return mIsMmapped; }
getMmapBufferDescriptor()102     const MmapBufferDescriptor& getMmapBufferDescriptor() const { return mMmapBufferDescriptor; }
103 
104   private:
maybeCreateDataMQ(const::aidl::android::hardware::audio::core::StreamDescriptor & descriptor)105     static std::unique_ptr<DataMQ> maybeCreateDataMQ(
106             const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor) {
107         using Tag = ::aidl::android::hardware::audio::core::StreamDescriptor::AudioBuffer::Tag;
108         if (descriptor.audio.getTag() == Tag::fmq) {
109             return std::make_unique<DataMQ>(descriptor.audio.get<Tag::fmq>());
110         }
111         return nullptr;
112     }
isMmapped(const::aidl::android::hardware::audio::core::StreamDescriptor & descriptor)113     static bool isMmapped(
114             const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor) {
115         using Tag = ::aidl::android::hardware::audio::core::StreamDescriptor::AudioBuffer::Tag;
116         return descriptor.audio.getTag() == Tag::mmap;
117     }
maybeGetMmapBuffer(::aidl::android::hardware::audio::core::StreamDescriptor & descriptor)118     static MmapBufferDescriptor maybeGetMmapBuffer(
119             ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor) {
120         using Tag = ::aidl::android::hardware::audio::core::StreamDescriptor::AudioBuffer::Tag;
121         if (descriptor.audio.getTag() == Tag::mmap) {
122             return std::move(descriptor.audio.get<Tag::mmap>());
123         }
124         return {};
125     }
126 
127     size_t mFrameSizeBytes;
128     std::unique_ptr<CommandMQ> mCommandMQ;
129     std::unique_ptr<ReplyMQ> mReplyMQ;
130     size_t mBufferSizeFrames;
131     std::unique_ptr<DataMQ> mDataMQ;
132     bool mIsAsynchronous;
133     bool mIsMmapped;
134     MmapBufferDescriptor mMmapBufferDescriptor;
135 };
136 
137 class StreamHalAidl : public virtual StreamHalInterface, public ConversionHelperAidl {
138   public:
139     // Return size of input/output buffer in bytes for this stream - eg. 4800.
140     status_t getBufferSize(size_t *size) override;
141 
142     // Return the base configuration of the stream:
143     //   - channel mask;
144     //   - format - e.g. AUDIO_FORMAT_PCM_16_BIT;
145     //   - sampling rate in Hz - eg. 44100.
146     status_t getAudioProperties(audio_config_base_t *configBase) override;
147 
148     // Set audio stream parameters.
149     status_t setParameters(const String8& kvPairs) override;
150 
151     // Get audio stream parameters.
152     status_t getParameters(const String8& keys, String8 *values) override;
153 
154     // Return the frame size (number of bytes per sample) of a stream.
155     status_t getFrameSize(size_t *size) override;
156 
157     // Add or remove the effect on the stream.
158     status_t addEffect(sp<EffectHalInterface> effect) override;
159     status_t removeEffect(sp<EffectHalInterface> effect) override;
160 
161     // Put the audio hardware input/output into standby mode.
162     status_t standby() override;
163 
164     status_t dump(int fd, const Vector<String16>& args) override;
165 
166     // Start a stream operating in mmap mode.
167     status_t start() override;
168 
169     // Stop a stream operating in mmap mode.
170     status_t stop() override;
171 
172     // Retrieve information on the data buffer in mmap mode.
173     status_t createMmapBuffer(int32_t minSizeFrames,
174             struct audio_mmap_buffer_info *info) override;
175 
176     // Get current read/write position in the mmap buffer
177     status_t getMmapPosition(struct audio_mmap_position *position) override;
178 
179     // Set the priority of the thread that interacts with the HAL
180     // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
181     status_t setHalThreadPriority(int priority) override;
182 
183     status_t legacyCreateAudioPatch(const struct audio_port_config& port,
184             std::optional<audio_source_t> source,
185             audio_devices_t type) override;
186 
187     status_t legacyReleaseAudioPatch() override;
188 
189   protected:
190     // For tests.
191     friend class sp<StreamHalAidl>;
192 
193     template<class T>
194     static std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> getStreamCommon(
195             const std::shared_ptr<T>& stream);
196 
197     // Subclasses can not be constructed directly by clients.
198     StreamHalAidl(std::string_view className,
199             bool isInput,
200             const audio_config& config,
201             int32_t nominalLatency,
202             StreamContextAidl&& context,
203             const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon>& stream,
204             const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension>& vext);
205 
206     ~StreamHalAidl() override;
207 
208     status_t getLatency(uint32_t *latency);
209 
210     status_t getObservablePosition(int64_t *frames, int64_t *timestamp);
211 
212     status_t getHardwarePosition(int64_t *frames, int64_t *timestamp);
213 
214     status_t getXruns(int32_t *frames);
215 
216     status_t transfer(void *buffer, size_t bytes, size_t *transferred);
217 
218     status_t pause(
219             ::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr);
220 
221     status_t resume(
222             ::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr);
223 
224     status_t drain(bool earlyNotify,
225             ::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr);
226 
227     status_t flush(
228             ::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr);
229 
230     status_t exit();
231 
232     const bool mIsInput;
233     const audio_config_base_t mConfig;
234     const StreamContextAidl mContext;
235 
236   private:
configToBase(const audio_config & config)237     static audio_config_base_t configToBase(const audio_config& config) {
238         audio_config_base_t result = AUDIO_CONFIG_BASE_INITIALIZER;
239         result.sample_rate = config.sample_rate;
240         result.channel_mask = config.channel_mask;
241         result.format = config.format;
242         return result;
243     }
getState()244     ::aidl::android::hardware::audio::core::StreamDescriptor::State getState() {
245         std::lock_guard l(mLock);
246         return mLastReply.state;
247     }
248     status_t sendCommand(
249             const ::aidl::android::hardware::audio::core::StreamDescriptor::Command &command,
250             ::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr,
251             bool safeFromNonWorkerThread = false);
252     status_t updateCountersIfNeeded(
253             ::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr);
254 
255     const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> mStream;
256     const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension> mVendorExt;
257     std::mutex mLock;
258     ::aidl::android::hardware::audio::core::StreamDescriptor::Reply mLastReply GUARDED_BY(mLock);
259     // mStreamPowerLog is used for audio signal power logging.
260     StreamPowerLog mStreamPowerLog;
261     std::atomic<pid_t> mWorkerTid = -1;
262 };
263 
264 class CallbackBroker;
265 
266 class StreamOutHalAidl : public StreamOutHalInterface, public StreamHalAidl {
267   public:
268     // Extract the output stream parameters and set by AIDL APIs.
269     status_t setParameters(const String8& kvPairs) override;
270 
271     // Return the audio hardware driver estimated latency in milliseconds.
272     status_t getLatency(uint32_t *latency) override;
273 
274     // Use this method in situations where audio mixing is done in the hardware.
275     status_t setVolume(float left, float right) override;
276 
277     // Selects the audio presentation (if available).
278     status_t selectPresentation(int presentationId, int programId) override;
279 
280     // Write audio buffer to driver.
281     status_t write(const void *buffer, size_t bytes, size_t *written) override;
282 
283     // Return the number of audio frames written by the audio dsp to DAC since
284     // the output has exited standby.
285     status_t getRenderPosition(uint32_t *dspFrames) override;
286 
287     // Get the local time at which the next write to the audio driver will be presented.
288     status_t getNextWriteTimestamp(int64_t *timestamp) override;
289 
290     // Set the callback for notifying completion of non-blocking write and drain.
291     status_t setCallback(wp<StreamOutHalInterfaceCallback> callback) override;
292 
293     // Returns whether pause and resume operations are supported.
294     status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume) override;
295 
296     // Notifies to the audio driver to resume playback following a pause.
297     status_t pause() override;
298 
299     // Notifies to the audio driver to resume playback following a pause.
300     status_t resume() override;
301 
302     // Returns whether drain operation is supported.
303     status_t supportsDrain(bool *supportsDrain) override;
304 
305     // Requests notification when data buffered by the driver/hardware has been played.
306     status_t drain(bool earlyNotify) override;
307 
308     // Notifies to the audio driver to flush the queued data.
309     status_t flush() override;
310 
311     // Return a recent count of the number of audio frames presented to an external observer.
312     status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) override;
313 
314     // Called when the metadata of the stream's source has been changed.
315     status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override;
316 
317     // Returns the Dual Mono mode presentation setting.
318     status_t getDualMonoMode(audio_dual_mono_mode_t* mode) override;
319 
320     // Sets the Dual Mono mode presentation on the output device.
321     status_t setDualMonoMode(audio_dual_mono_mode_t mode) override;
322 
323     // Returns the Audio Description Mix level in dB.
324     status_t getAudioDescriptionMixLevel(float* leveldB) override;
325 
326     // Sets the Audio Description Mix level in dB.
327     status_t setAudioDescriptionMixLevel(float leveldB) override;
328 
329     // Retrieves current playback rate parameters.
330     status_t getPlaybackRateParameters(audio_playback_rate_t* playbackRate) override;
331 
332     // Sets the playback rate parameters that control playback behavior.
333     status_t setPlaybackRateParameters(const audio_playback_rate_t& playbackRate) override;
334 
335     status_t setEventCallback(const sp<StreamOutHalInterfaceEventCallback>& callback) override;
336 
337     status_t setLatencyMode(audio_latency_mode_t mode) override;
338     status_t getRecommendedLatencyModes(std::vector<audio_latency_mode_t> *modes) override;
339     status_t setLatencyModeCallback(
340             const sp<StreamOutHalInterfaceLatencyModeCallback>& callback) override;
341 
342     status_t exit() override;
343 
344   private:
345     friend class sp<StreamOutHalAidl>;
346 
347     static ConversionResult<::aidl::android::hardware::audio::common::SourceMetadata>
348     legacy2aidl_SourceMetadata(const StreamOutHalInterface::SourceMetadata& legacy);
349 
350     const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut> mStream;
351     const wp<CallbackBroker> mCallbackBroker;
352 
353     AudioOffloadMetadata mOffloadMetadata;
354 
355     // Can not be constructed directly by clients.
356     StreamOutHalAidl(
357             const audio_config& config, StreamContextAidl&& context, int32_t nominalLatency,
358             const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut>& stream,
359             const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension>& vext,
360             const sp<CallbackBroker>& callbackBroker);
361 
362     ~StreamOutHalAidl() override;
363 
364     // Filter and update the offload metadata. The parameters which are related to the offload
365     // metadata will be removed after filtering.
366     status_t filterAndUpdateOffloadMetadata(AudioParameter &parameters);
367 };
368 
369 class MicrophoneInfoProvider;
370 
371 class StreamInHalAidl : public StreamInHalInterface, public StreamHalAidl {
372   public:
373     // Set the input gain for the audio driver.
374     status_t setGain(float gain) override;
375 
376     // Read audio buffer in from driver.
377     status_t read(void *buffer, size_t bytes, size_t *read) override;
378 
379     // Return the amount of input frames lost in the audio driver.
380     status_t getInputFramesLost(uint32_t *framesLost) override;
381 
382     // Return a recent count of the number of audio frames received and
383     // the clock time associated with that frame count.
384     status_t getCapturePosition(int64_t *frames, int64_t *time) override;
385 
386     // Get active microphones
387     status_t getActiveMicrophones(std::vector<media::MicrophoneInfoFw> *microphones) override;
388 
389     // Set microphone direction (for processing)
390     status_t setPreferredMicrophoneDirection(
391                             audio_microphone_direction_t direction) override;
392 
393     // Set microphone zoom (for processing)
394     status_t setPreferredMicrophoneFieldDimension(float zoom) override;
395 
396     // Called when the metadata of the stream's sink has been changed.
397     status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override;
398 
399   private:
400     friend class sp<StreamInHalAidl>;
401 
402     static ConversionResult<::aidl::android::hardware::audio::common::SinkMetadata>
403     legacy2aidl_SinkMetadata(const StreamInHalInterface::SinkMetadata& legacy);
404 
405     const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn> mStream;
406     const wp<MicrophoneInfoProvider> mMicInfoProvider;
407 
408     // Can not be constructed directly by clients.
409     StreamInHalAidl(
410             const audio_config& config, StreamContextAidl&& context, int32_t nominalLatency,
411             const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn>& stream,
412             const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension>& vext,
413             const sp<MicrophoneInfoProvider>& micInfoProvider);
414 
415     ~StreamInHalAidl() override = default;
416 };
417 
418 } // namespace android
419