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 ¶meters); 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