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 #include <mediautils/Synchronization.h> 36 37 #include "ConversionHelperAidl.h" 38 #include "StreamPowerLog.h" 39 40 namespace android { 41 42 class StreamContextAidl { 43 public: 44 typedef AidlMessageQueue<::aidl::android::hardware::audio::core::StreamDescriptor::Command, 45 ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> CommandMQ; 46 typedef AidlMessageQueue<::aidl::android::hardware::audio::core::StreamDescriptor::Reply, 47 ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> ReplyMQ; 48 typedef AidlMessageQueue<int8_t, 49 ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> DataMQ; 50 StreamContextAidl(::aidl::android::hardware::audio::core::StreamDescriptor & descriptor,bool isAsynchronous,int ioHandle,bool hasClipTransitionSupport)51 StreamContextAidl(::aidl::android::hardware::audio::core::StreamDescriptor& descriptor, 52 bool isAsynchronous, int ioHandle, bool hasClipTransitionSupport) 53 : mFrameSizeBytes(descriptor.frameSizeBytes), 54 mCommandMQ(new CommandMQ(descriptor.command)), 55 mReplyMQ(new ReplyMQ(descriptor.reply)), 56 mBufferSizeFrames(descriptor.bufferSizeFrames), 57 mDataMQ(maybeCreateDataMQ(descriptor)), 58 mIsAsynchronous(isAsynchronous), 59 mIsMmapped(isMmapped(descriptor)), 60 mMmapBufferDescriptor(maybeGetMmapBuffer(descriptor)), 61 mIoHandle(ioHandle), 62 mHasClipTransitionSupport(hasClipTransitionSupport) {} 63 StreamContextAidl(StreamContextAidl&&) = default; 64 StreamContextAidl& operator=(StreamContextAidl&&) = default; isValid()65 bool isValid() const { 66 return mFrameSizeBytes != 0 && 67 mCommandMQ != nullptr && mCommandMQ->isValid() && 68 mReplyMQ != nullptr && mReplyMQ->isValid() && 69 (mDataMQ == nullptr || ( 70 mDataMQ->isValid() && 71 mDataMQ->getQuantumCount() * mDataMQ->getQuantumSize() >= 72 mFrameSizeBytes * mBufferSizeFrames)) && 73 (!mIsMmapped || mMmapBufferDescriptor.sharedMemory.fd.get() >= 0); 74 } getBufferSizeBytes()75 size_t getBufferSizeBytes() const { return mFrameSizeBytes * mBufferSizeFrames; } getBufferSizeFrames()76 size_t getBufferSizeFrames() const { return mBufferSizeFrames; } getBufferDurationMs(int32_t sampleRate)77 size_t getBufferDurationMs(int32_t sampleRate) const { 78 auto bufferSize = mIsMmapped ? getMmapBurstSize() : mBufferSizeFrames; 79 return sampleRate != 0 ? bufferSize * MILLIS_PER_SECOND / sampleRate : 0; 80 } getCommandMQ()81 CommandMQ* getCommandMQ() const { return mCommandMQ.get(); } getDataMQ()82 DataMQ* getDataMQ() const { return mDataMQ.get(); } getFrameSizeBytes()83 size_t getFrameSizeBytes() const { return mFrameSizeBytes; } getReplyMQ()84 ReplyMQ* getReplyMQ() const { return mReplyMQ.get(); } isAsynchronous()85 bool isAsynchronous() const { return mIsAsynchronous; } isMmapped()86 bool isMmapped() const { return mIsMmapped; } 87 const ::aidl::android::hardware::audio::core::MmapBufferDescriptor& getMmapBufferDescriptor()88 getMmapBufferDescriptor() const { return mMmapBufferDescriptor; } getMmapBurstSize()89 size_t getMmapBurstSize() const { return mMmapBufferDescriptor.burstSizeFrames; } getIoHandle()90 int getIoHandle() const { return mIoHandle; } hasClipTransitionSupport()91 bool hasClipTransitionSupport() const { return mHasClipTransitionSupport; } updateMmapBufferDescriptor(::aidl::android::hardware::audio::core::MmapBufferDescriptor && desc)92 void updateMmapBufferDescriptor( 93 ::aidl::android::hardware::audio::core::MmapBufferDescriptor&& desc) { 94 mMmapBufferDescriptor = std::move(desc); } 95 96 private: maybeCreateDataMQ(const::aidl::android::hardware::audio::core::StreamDescriptor & descriptor)97 static std::unique_ptr<DataMQ> maybeCreateDataMQ( 98 const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor) { 99 using Tag = ::aidl::android::hardware::audio::core::StreamDescriptor::AudioBuffer::Tag; 100 if (descriptor.audio.getTag() == Tag::fmq) { 101 return std::make_unique<DataMQ>(descriptor.audio.get<Tag::fmq>()); 102 } 103 return nullptr; 104 } isMmapped(const::aidl::android::hardware::audio::core::StreamDescriptor & descriptor)105 static bool isMmapped( 106 const ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor) { 107 using Tag = ::aidl::android::hardware::audio::core::StreamDescriptor::AudioBuffer::Tag; 108 return descriptor.audio.getTag() == Tag::mmap; 109 } maybeGetMmapBuffer(::aidl::android::hardware::audio::core::StreamDescriptor & descriptor)110 static ::aidl::android::hardware::audio::core::MmapBufferDescriptor maybeGetMmapBuffer( 111 ::aidl::android::hardware::audio::core::StreamDescriptor& descriptor) { 112 using Tag = ::aidl::android::hardware::audio::core::StreamDescriptor::AudioBuffer::Tag; 113 if (descriptor.audio.getTag() == Tag::mmap) { 114 return std::move(descriptor.audio.get<Tag::mmap>()); 115 } 116 return {}; 117 } 118 119 size_t mFrameSizeBytes; 120 std::unique_ptr<CommandMQ> mCommandMQ; 121 std::unique_ptr<ReplyMQ> mReplyMQ; 122 size_t mBufferSizeFrames; 123 std::unique_ptr<DataMQ> mDataMQ; 124 bool mIsAsynchronous; 125 bool mIsMmapped; 126 ::aidl::android::hardware::audio::core::MmapBufferDescriptor mMmapBufferDescriptor; 127 int mIoHandle; 128 bool mHasClipTransitionSupport; 129 }; 130 131 class StreamHalAidl : public virtual StreamHalInterface, public ConversionHelperAidl { 132 public: 133 // Return size of input/output buffer in bytes for this stream - eg. 4800. 134 status_t getBufferSize(size_t *size) override; 135 136 // Return the base configuration of the stream: 137 // - channel mask; 138 // - format - e.g. AUDIO_FORMAT_PCM_16_BIT; 139 // - sampling rate in Hz - eg. 44100. 140 status_t getAudioProperties(audio_config_base_t *configBase) override; 141 142 // Set audio stream parameters. 143 status_t setParameters(const String8& kvPairs) override; 144 145 // Get audio stream parameters. 146 status_t getParameters(const String8& keys, String8 *values) override; 147 148 // Return the frame size (number of bytes per sample) of a stream. 149 status_t getFrameSize(size_t *size) override; 150 151 // Add or remove the effect on the stream. 152 status_t addEffect(sp<EffectHalInterface> effect) override; 153 status_t removeEffect(sp<EffectHalInterface> effect) override; 154 155 // Put the audio hardware input/output into standby mode. 156 status_t standby() override; 157 158 status_t dump(int fd, const Vector<String16>& args) override; 159 160 // Start a stream operating in mmap mode. 161 status_t start() override; 162 163 // Stop a stream operating in mmap mode. 164 status_t stop() override; 165 166 // Retrieve information on the data buffer in mmap mode. 167 status_t createMmapBuffer(int32_t minSizeFrames, 168 struct audio_mmap_buffer_info *info) override; 169 170 // Get current read/write position in the mmap buffer 171 status_t getMmapPosition(struct audio_mmap_position *position) override; 172 173 // Set the priority of the thread that interacts with the HAL 174 // (must match the priority of the audioflinger's thread that calls 'read' / 'write') 175 status_t setHalThreadPriority(int priority) override; 176 177 status_t legacyCreateAudioPatch(const struct audio_port_config& port, 178 std::optional<audio_source_t> source, 179 audio_devices_t type) override; 180 181 status_t legacyReleaseAudioPatch() override; 182 183 protected: 184 // For tests. 185 friend class sp<StreamHalAidl>; 186 187 struct FrameCounters { 188 int64_t framesAtFlushOrDrain; 189 int64_t framesAtStandby; 190 }; 191 struct StatePositions { 192 FrameCounters observable; 193 FrameCounters hardware; 194 enum DrainState : int32_t { NONE, ALL, EN /*early notify*/, EN_RECEIVED }; 195 DrainState drainState; 196 }; 197 198 template<class T> 199 static std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon> getStreamCommon( 200 const std::shared_ptr<T>& stream); 201 202 // Subclasses can not be constructed directly by clients. 203 StreamHalAidl(std::string_view className, 204 bool isInput, 205 const audio_config& config, 206 int32_t nominalLatency, 207 StreamContextAidl&& context, 208 const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamCommon>& stream, 209 const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension>& vext); 210 211 ~StreamHalAidl() override; 212 getState()213 ::aidl::android::hardware::audio::core::StreamDescriptor::State getState() { 214 std::lock_guard l(mLock); 215 return mLastReply.state; 216 } 217 isInDrainedState(const::aidl::android::hardware::audio::core::StreamDescriptor::State state)218 bool isInDrainedState( 219 const ::aidl::android::hardware::audio::core::StreamDescriptor::State state) { 220 if (state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::IDLE || 221 state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::STANDBY) { 222 // drain equivalent states 223 return true; 224 } 225 return false; 226 } 227 isInPlayOrRecordState(const::aidl::android::hardware::audio::core::StreamDescriptor::State state)228 bool isInPlayOrRecordState( 229 const ::aidl::android::hardware::audio::core::StreamDescriptor::State state) { 230 if (state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::ACTIVE || 231 state == 232 ::aidl::android::hardware::audio::core::StreamDescriptor::State::TRANSFERRING || 233 state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::DRAINING) { 234 // play or record equivalent states 235 return true; 236 } 237 return false; 238 } 239 isInPausedState(const::aidl::android::hardware::audio::core::StreamDescriptor::State & state)240 bool isInPausedState( 241 const ::aidl::android::hardware::audio::core::StreamDescriptor::State& state) { 242 if (state == ::aidl::android::hardware::audio::core::StreamDescriptor::State::PAUSED || 243 state == 244 ::aidl::android::hardware::audio::core::StreamDescriptor::State::DRAIN_PAUSED || 245 state == ::aidl::android::hardware::audio::core::StreamDescriptor::State:: 246 TRANSFER_PAUSED) { 247 // pause equivalent states 248 return true; 249 } 250 return false; 251 } 252 253 status_t getLatency(uint32_t *latency); 254 255 // Always returns non-negative values. 256 status_t getObservablePosition(int64_t* frames, int64_t* timestamp, 257 StatePositions* statePositions = nullptr); 258 259 // Always returns non-negative values. 260 status_t getHardwarePosition(int64_t *frames, int64_t *timestamp); 261 262 // Always returns non-negative values. 263 status_t getXruns(int32_t *frames); 264 265 status_t transfer(void *buffer, size_t bytes, size_t *transferred); 266 267 status_t pause( 268 ::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr); 269 270 status_t resume( 271 ::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr); 272 273 status_t drain(bool earlyNotify, 274 ::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr); 275 276 status_t flush( 277 ::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr); 278 279 status_t exit(); 280 281 template <typename T, typename Callable, typename... Args> serializeCall(const std::shared_ptr<T> & obj,Callable && func,Args &&...args)282 auto serializeCall(const std::shared_ptr<T>& obj, Callable&& func, Args&&... args) 283 EXCLUDES(mCallLock) { 284 std::lock_guard lock(mCallLock); 285 return std::invoke(std::forward<Callable&&>(func), 286 std::forward<const std::shared_ptr<T>&>(obj), 287 std::forward<Args&&>(args)...); 288 } 289 290 void onAsyncTransferReady(); 291 void onAsyncDrainReady(); 292 void onAsyncError(); 293 294 const bool mIsInput; 295 const audio_config_base_t mConfig; 296 StreamContextAidl mContext; 297 // This lock is used to make sending of a command and receiving a reply an atomic 298 // operation. Otherwise, when two threads are trying to send a command, they may both advance to 299 // reading of the reply once the HAL has consumed the command from the MQ, and that creates a 300 // race condition between them. 301 // 302 // Note that only access to command and reply MQs needs to be protected because the data MQ is 303 // only accessed by the I/O thread. Also, there is no need to protect lookup operations on the 304 // queues as they are thread-safe, only send/receive operation must be protected. 305 std::mutex mCommandReplyLock; 306 307 private: configToBase(const audio_config & config)308 static audio_config_base_t configToBase(const audio_config& config) { 309 audio_config_base_t result = AUDIO_CONFIG_BASE_INITIALIZER; 310 result.sample_rate = config.sample_rate; 311 result.channel_mask = config.channel_mask; 312 result.format = config.format; 313 return result; 314 } 315 // Note: Since `sendCommand` takes mLock while holding mCommandReplyLock, never call 316 // it with `mLock` being held. 317 status_t sendCommand( 318 const ::aidl::android::hardware::audio::core::StreamDescriptor::Command& command, 319 ::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr, 320 bool safeFromNonWorkerThread = false, 321 StatePositions* statePositions = nullptr); 322 status_t updateCountersIfNeeded( 323 ::aidl::android::hardware::audio::core::StreamDescriptor::Reply* reply = nullptr, 324 StatePositions* statePositions = nullptr); 325 326 /* 327 * This lock is exclusively intended to serialize binder calls to remote 328 * IStream[Common|Out|In] objects in Audio HAL. Thereby, preventing any race conditions in Audio 329 * HAL. The only exception for above is when calling the IStream[Common|Out|In]::dump API. 330 * Please note that lock doesn't prevent access to IStream[Common|Out|In] class fields. That 331 * explains why there is no 'GUARDED_BY' annotations. 332 */ 333 std::mutex mCallLock; 334 335 using Stream = ::aidl::android::hardware::audio::core::IStreamCommon; 336 const std::shared_ptr<Stream> mStream; 337 const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension> mVendorExt; 338 const int64_t mLastReplyLifeTimeNs; 339 std::mutex mLock; 340 ::aidl::android::hardware::audio::core::StreamDescriptor::Reply mLastReply GUARDED_BY(mLock); 341 int64_t mLastReplyExpirationNs GUARDED_BY(mLock) = 0; 342 // Cached values of observable positions when the stream last entered certain state. 343 // Updated for output streams only. 344 StatePositions mStatePositions GUARDED_BY(mLock) = {}; 345 // mStreamPowerLog is used for audio signal power logging. 346 StreamPowerLog mStreamPowerLog; 347 std::atomic<pid_t> mWorkerTid = -1; 348 int32_t mAidlInterfaceVersion = -1; 349 bool mSupportsCreateMmapBuffer = false; 350 }; 351 352 class CallbackBroker; 353 354 class StreamOutHalAidl : public virtual StreamOutHalInterface, 355 public virtual StreamOutHalInterfaceCallback, 356 public StreamHalAidl { 357 public: 358 // Extract the output stream parameters and set by AIDL APIs. 359 status_t setParameters(const String8& kvPairs) override; 360 361 // Return the audio hardware driver estimated latency in milliseconds. 362 status_t getLatency(uint32_t *latency) override; 363 364 // Use this method in situations where audio mixing is done in the hardware. 365 status_t setVolume(float left, float right) override; 366 367 // Selects the audio presentation (if available). 368 status_t selectPresentation(int presentationId, int programId) override; 369 370 // Write audio buffer to driver. 371 status_t write(const void *buffer, size_t bytes, size_t *written) override; 372 373 // Return the number of audio frames written by the audio dsp to DAC since 374 // the output has exited standby. 375 status_t getRenderPosition(uint64_t *dspFrames) override; 376 377 // Set the callback for notifying completion of non-blocking write and drain. 378 status_t setCallback(wp<StreamOutHalInterfaceCallback> callback) override; 379 380 // Returns whether pause and resume operations are supported. 381 status_t supportsPauseAndResume(bool *supportsPause, bool *supportsResume) override; 382 383 // Notifies to the audio driver to resume playback following a pause. 384 status_t pause() override; 385 386 // Notifies to the audio driver to resume playback following a pause. 387 status_t resume() override; 388 389 // Returns whether drain operation is supported. 390 status_t supportsDrain(bool *supportsDrain) override; 391 392 // Requests notification when data buffered by the driver/hardware has been played. 393 status_t drain(bool earlyNotify) override; 394 395 // Notifies to the audio driver to flush (that is, drop) the queued data. Stream must 396 // already be paused before calling 'flush'. 397 status_t flush() override; 398 399 // Return a recent count of the number of audio frames presented to an external observer. 400 // This excludes frames which have been written but are still in the pipeline. See the 401 // table at the start of the 'StreamOutHalInterface' for the specification of the frame 402 // count behavior w.r.t. 'flush', 'drain' and 'standby' operations. 403 status_t getPresentationPosition(uint64_t *frames, struct timespec *timestamp) override; 404 405 // Notifies the HAL layer that the framework considers the current playback as completed. 406 status_t presentationComplete() override; 407 408 // Called when the metadata of the stream's source has been changed. 409 status_t updateSourceMetadata(const SourceMetadata& sourceMetadata) override; 410 411 // Returns the Dual Mono mode presentation setting. 412 status_t getDualMonoMode(audio_dual_mono_mode_t* mode) override; 413 414 // Sets the Dual Mono mode presentation on the output device. 415 status_t setDualMonoMode(audio_dual_mono_mode_t mode) override; 416 417 // Returns the Audio Description Mix level in dB. 418 status_t getAudioDescriptionMixLevel(float* leveldB) override; 419 420 // Sets the Audio Description Mix level in dB. 421 status_t setAudioDescriptionMixLevel(float leveldB) override; 422 423 // Retrieves current playback rate parameters. 424 status_t getPlaybackRateParameters(audio_playback_rate_t* playbackRate) override; 425 426 // Sets the playback rate parameters that control playback behavior. 427 status_t setPlaybackRateParameters(const audio_playback_rate_t& playbackRate) override; 428 429 status_t setEventCallback(const sp<StreamOutHalInterfaceEventCallback>& callback) override; 430 431 status_t setLatencyMode(audio_latency_mode_t mode) override; 432 status_t getRecommendedLatencyModes(std::vector<audio_latency_mode_t> *modes) override; 433 status_t setLatencyModeCallback( 434 const sp<StreamOutHalInterfaceLatencyModeCallback>& callback) override; 435 436 status_t exit() override; 437 438 // StreamOutHalInterfaceCallback 439 void onWriteReady() override; 440 void onDrainReady() override; 441 void onError(bool isHardError) override; 442 443 status_t dump(int fd, const Vector<String16>& args) override; 444 445 private: 446 friend class sp<StreamOutHalAidl>; 447 448 static ConversionResult<::aidl::android::hardware::audio::common::SourceMetadata> 449 legacy2aidl_SourceMetadata(const StreamOutHalInterface::SourceMetadata& legacy); 450 451 using Stream = ::aidl::android::hardware::audio::core::IStreamOut; 452 const std::shared_ptr<Stream> mStream; 453 const wp<CallbackBroker> mCallbackBroker; 454 mediautils::atomic_wp<StreamOutHalInterfaceCallback> mClientCallback; 455 456 ::aidl::android::hardware::audio::common::AudioOffloadMetadata mOffloadMetadata; 457 458 // Can not be constructed directly by clients. 459 StreamOutHalAidl( 460 const audio_config& config, StreamContextAidl&& context, int32_t nominalLatency, 461 const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamOut>& stream, 462 const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension>& vext, 463 const sp<CallbackBroker>& callbackBroker); 464 465 ~StreamOutHalAidl() override; 466 467 // Filter and update the offload metadata. The parameters which are related to the offload 468 // metadata will be removed after filtering. 469 status_t filterAndUpdateOffloadMetadata(AudioParameter ¶meters); 470 }; 471 472 class MicrophoneInfoProvider; 473 474 class StreamInHalAidl : public StreamInHalInterface, public StreamHalAidl { 475 public: 476 // Set the input gain for the audio driver. 477 status_t setGain(float gain) override; 478 479 // Read audio buffer in from driver. 480 status_t read(void *buffer, size_t bytes, size_t *read) override; 481 482 // Return the amount of input frames lost in the audio driver. 483 status_t getInputFramesLost(uint32_t *framesLost) override; 484 485 // Return a recent count of the number of audio frames received and 486 // the clock time associated with that frame count. 487 // The count must not reset to zero when a PCM input enters standby. 488 status_t getCapturePosition(int64_t *frames, int64_t *time) override; 489 490 // Get active microphones 491 status_t getActiveMicrophones(std::vector<media::MicrophoneInfoFw> *microphones) override; 492 493 // Set microphone direction (for processing) 494 status_t setPreferredMicrophoneDirection( 495 audio_microphone_direction_t direction) override; 496 497 // Set microphone zoom (for processing) 498 status_t setPreferredMicrophoneFieldDimension(float zoom) override; 499 500 // Called when the metadata of the stream's sink has been changed. 501 status_t updateSinkMetadata(const SinkMetadata& sinkMetadata) override; 502 503 status_t dump(int fd, const Vector<String16>& args) override; 504 505 private: 506 friend class sp<StreamInHalAidl>; 507 508 static ConversionResult<::aidl::android::hardware::audio::common::SinkMetadata> 509 legacy2aidl_SinkMetadata(const StreamInHalInterface::SinkMetadata& legacy); 510 511 using Stream = ::aidl::android::hardware::audio::core::IStreamIn; 512 const std::shared_ptr<Stream> mStream; 513 const wp<MicrophoneInfoProvider> mMicInfoProvider; 514 515 // Can not be constructed directly by clients. 516 StreamInHalAidl( 517 const audio_config& config, StreamContextAidl&& context, int32_t nominalLatency, 518 const std::shared_ptr<::aidl::android::hardware::audio::core::IStreamIn>& stream, 519 const std::shared_ptr<::aidl::android::media::audio::IHalAdapterVendorExtension>& vext, 520 const sp<MicrophoneInfoProvider>& micInfoProvider); 521 522 ~StreamInHalAidl() override = default; 523 }; 524 525 } // namespace android 526