1*ec779b8eSAndroid Build Coastguard Worker /* 2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project 3*ec779b8eSAndroid Build Coastguard Worker * 4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*ec779b8eSAndroid Build Coastguard Worker * 8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*ec779b8eSAndroid Build Coastguard Worker * 10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License. 15*ec779b8eSAndroid Build Coastguard Worker */ 16*ec779b8eSAndroid Build Coastguard Worker 17*ec779b8eSAndroid Build Coastguard Worker #pragma once 18*ec779b8eSAndroid Build Coastguard Worker 19*ec779b8eSAndroid Build Coastguard Worker // The following includes are required because we have class definitions below 20*ec779b8eSAndroid Build Coastguard Worker // for EndPoint and Patch, which precludes using a forward declaration only. 21*ec779b8eSAndroid Build Coastguard Worker #include "IAfThread.h" // IAfThreadBase IAfMmapThread IAfPlaybackThread IAfRecordThread 22*ec779b8eSAndroid Build Coastguard Worker #include "IAfTrack.h" // IAfPatchRecord IAfPatchTrack 23*ec779b8eSAndroid Build Coastguard Worker 24*ec779b8eSAndroid Build Coastguard Worker #include <datapath/AudioHwDevice.h> 25*ec779b8eSAndroid Build Coastguard Worker #include <media/DeviceDescriptorBase.h> 26*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h> // ALOG used in this file 27*ec779b8eSAndroid Build Coastguard Worker #include <utils/RefBase.h> // avoid transitive dependency 28*ec779b8eSAndroid Build Coastguard Worker #include <utils/Thread.h> 29*ec779b8eSAndroid Build Coastguard Worker 30*ec779b8eSAndroid Build Coastguard Worker namespace android { 31*ec779b8eSAndroid Build Coastguard Worker 32*ec779b8eSAndroid Build Coastguard Worker class IAfPatchPanel; 33*ec779b8eSAndroid Build Coastguard Worker class PatchCommandThread; 34*ec779b8eSAndroid Build Coastguard Worker 35*ec779b8eSAndroid Build Coastguard Worker class SoftwarePatch { 36*ec779b8eSAndroid Build Coastguard Worker public: SoftwarePatch(const sp<const IAfPatchPanel> & patchPanel,audio_patch_handle_t patchHandle,audio_io_handle_t playbackThreadHandle,audio_io_handle_t recordThreadHandle)37*ec779b8eSAndroid Build Coastguard Worker SoftwarePatch( 38*ec779b8eSAndroid Build Coastguard Worker const sp<const IAfPatchPanel>& patchPanel, 39*ec779b8eSAndroid Build Coastguard Worker audio_patch_handle_t patchHandle, 40*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t playbackThreadHandle, 41*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t recordThreadHandle) 42*ec779b8eSAndroid Build Coastguard Worker : mPatchPanel(patchPanel), 43*ec779b8eSAndroid Build Coastguard Worker mPatchHandle(patchHandle), 44*ec779b8eSAndroid Build Coastguard Worker mPlaybackThreadHandle(playbackThreadHandle), 45*ec779b8eSAndroid Build Coastguard Worker mRecordThreadHandle(recordThreadHandle) {} 46*ec779b8eSAndroid Build Coastguard Worker SoftwarePatch(const SoftwarePatch&) = default; 47*ec779b8eSAndroid Build Coastguard Worker 48*ec779b8eSAndroid Build Coastguard Worker status_t getLatencyMs_l(double* latencyMs) const REQUIRES(audio_utils::AudioFlinger_Mutex); getPatchHandle()49*ec779b8eSAndroid Build Coastguard Worker audio_patch_handle_t getPatchHandle() const { return mPatchHandle; }; getPlaybackThreadHandle()50*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t getPlaybackThreadHandle() const { return mPlaybackThreadHandle; }; getRecordThreadHandle()51*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t getRecordThreadHandle() const { return mRecordThreadHandle; }; 52*ec779b8eSAndroid Build Coastguard Worker 53*ec779b8eSAndroid Build Coastguard Worker private: 54*ec779b8eSAndroid Build Coastguard Worker const sp<const IAfPatchPanel> mPatchPanel; 55*ec779b8eSAndroid Build Coastguard Worker const audio_patch_handle_t mPatchHandle; 56*ec779b8eSAndroid Build Coastguard Worker const audio_io_handle_t mPlaybackThreadHandle; 57*ec779b8eSAndroid Build Coastguard Worker const audio_io_handle_t mRecordThreadHandle; 58*ec779b8eSAndroid Build Coastguard Worker }; 59*ec779b8eSAndroid Build Coastguard Worker 60*ec779b8eSAndroid Build Coastguard Worker class IAfPatchPanelCallback : public virtual RefBase { 61*ec779b8eSAndroid Build Coastguard Worker public: 62*ec779b8eSAndroid Build Coastguard Worker virtual void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) REQUIRES(mutex()) = 0; 63*ec779b8eSAndroid Build Coastguard Worker virtual void closeThreadInternal_l(const sp<IAfRecordThread>& thread) REQUIRES(mutex()) = 0; 64*ec779b8eSAndroid Build Coastguard Worker virtual IAfPlaybackThread* primaryPlaybackThread_l() const REQUIRES(mutex()) = 0; 65*ec779b8eSAndroid Build Coastguard Worker virtual IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const 66*ec779b8eSAndroid Build Coastguard Worker REQUIRES(mutex()) = 0; 67*ec779b8eSAndroid Build Coastguard Worker virtual IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const 68*ec779b8eSAndroid Build Coastguard Worker REQUIRES(mutex()) = 0; 69*ec779b8eSAndroid Build Coastguard Worker virtual IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const REQUIRES(mutex()) = 0; 70*ec779b8eSAndroid Build Coastguard Worker virtual sp<IAfThreadBase> openInput_l(audio_module_handle_t module, 71*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t* input, 72*ec779b8eSAndroid Build Coastguard Worker audio_config_t* config, 73*ec779b8eSAndroid Build Coastguard Worker audio_devices_t device, 74*ec779b8eSAndroid Build Coastguard Worker const char* address, 75*ec779b8eSAndroid Build Coastguard Worker audio_source_t source, 76*ec779b8eSAndroid Build Coastguard Worker audio_input_flags_t flags, 77*ec779b8eSAndroid Build Coastguard Worker audio_devices_t outputDevice, 78*ec779b8eSAndroid Build Coastguard Worker const String8& outputDeviceAddress) REQUIRES(mutex()) = 0; 79*ec779b8eSAndroid Build Coastguard Worker virtual sp<IAfThreadBase> openOutput_l(audio_module_handle_t module, 80*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t* output, 81*ec779b8eSAndroid Build Coastguard Worker audio_config_t* halConfig, 82*ec779b8eSAndroid Build Coastguard Worker audio_config_base_t* mixerConfig, 83*ec779b8eSAndroid Build Coastguard Worker audio_devices_t deviceType, 84*ec779b8eSAndroid Build Coastguard Worker const String8& address, 85*ec779b8eSAndroid Build Coastguard Worker audio_output_flags_t* flags, 86*ec779b8eSAndroid Build Coastguard Worker audio_attributes_t attributes) REQUIRES(mutex()) = 0; 87*ec779b8eSAndroid Build Coastguard Worker virtual audio_utils::mutex& mutex() const 88*ec779b8eSAndroid Build Coastguard Worker RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0; 89*ec779b8eSAndroid Build Coastguard Worker virtual const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>& 90*ec779b8eSAndroid Build Coastguard Worker getAudioHwDevs_l() const REQUIRES(mutex()) = 0; 91*ec779b8eSAndroid Build Coastguard Worker virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0; 92*ec779b8eSAndroid Build Coastguard Worker virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0; 93*ec779b8eSAndroid Build Coastguard Worker virtual void updateDownStreamPatches_l( 94*ec779b8eSAndroid Build Coastguard Worker const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams) 95*ec779b8eSAndroid Build Coastguard Worker REQUIRES(mutex()) = 0; 96*ec779b8eSAndroid Build Coastguard Worker virtual void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices) 97*ec779b8eSAndroid Build Coastguard Worker REQUIRES(mutex()) = 0; 98*ec779b8eSAndroid Build Coastguard Worker }; 99*ec779b8eSAndroid Build Coastguard Worker 100*ec779b8eSAndroid Build Coastguard Worker class IAfPatchPanel : public virtual RefBase { 101*ec779b8eSAndroid Build Coastguard Worker public: 102*ec779b8eSAndroid Build Coastguard Worker static sp<IAfPatchPanel> create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback); 103*ec779b8eSAndroid Build Coastguard Worker 104*ec779b8eSAndroid Build Coastguard Worker // Extraction of inner Endpoint and Patch classes would require interfaces 105*ec779b8eSAndroid Build Coastguard Worker // (in the Endpoint case a templated interface) but that seems 106*ec779b8eSAndroid Build Coastguard Worker // excessive for now. We keep them as inner classes until extraction 107*ec779b8eSAndroid Build Coastguard Worker // is needed. 108*ec779b8eSAndroid Build Coastguard Worker template <typename ThreadType, typename TrackType> 109*ec779b8eSAndroid Build Coastguard Worker class Endpoint final { 110*ec779b8eSAndroid Build Coastguard Worker public: 111*ec779b8eSAndroid Build Coastguard Worker Endpoint() = default; 112*ec779b8eSAndroid Build Coastguard Worker Endpoint(const Endpoint&) = delete; 113*ec779b8eSAndroid Build Coastguard Worker Endpoint& operator=(const Endpoint& other) noexcept { 114*ec779b8eSAndroid Build Coastguard Worker mThread = other.mThread; 115*ec779b8eSAndroid Build Coastguard Worker mCloseThread = other.mCloseThread; 116*ec779b8eSAndroid Build Coastguard Worker mHandle = other.mHandle; 117*ec779b8eSAndroid Build Coastguard Worker mTrack = other.mTrack; 118*ec779b8eSAndroid Build Coastguard Worker return *this; 119*ec779b8eSAndroid Build Coastguard Worker } Endpoint(Endpoint && other)120*ec779b8eSAndroid Build Coastguard Worker Endpoint(Endpoint&& other) noexcept { swap(other); } 121*ec779b8eSAndroid Build Coastguard Worker Endpoint& operator=(Endpoint&& other) noexcept { 122*ec779b8eSAndroid Build Coastguard Worker swap(other); 123*ec779b8eSAndroid Build Coastguard Worker return *this; 124*ec779b8eSAndroid Build Coastguard Worker } ~Endpoint()125*ec779b8eSAndroid Build Coastguard Worker ~Endpoint() { 126*ec779b8eSAndroid Build Coastguard Worker ALOGE_IF( 127*ec779b8eSAndroid Build Coastguard Worker mHandle != AUDIO_PATCH_HANDLE_NONE, 128*ec779b8eSAndroid Build Coastguard Worker "A non empty Patch Endpoint leaked, handle %d", mHandle); 129*ec779b8eSAndroid Build Coastguard Worker } 130*ec779b8eSAndroid Build Coastguard Worker checkTrack(TrackType * trackOrNull)131*ec779b8eSAndroid Build Coastguard Worker status_t checkTrack(TrackType* trackOrNull) const { 132*ec779b8eSAndroid Build Coastguard Worker if (trackOrNull == nullptr) return NO_MEMORY; 133*ec779b8eSAndroid Build Coastguard Worker return trackOrNull->initCheck(); 134*ec779b8eSAndroid Build Coastguard Worker } handle()135*ec779b8eSAndroid Build Coastguard Worker audio_patch_handle_t handle() const { return mHandle; } thread()136*ec779b8eSAndroid Build Coastguard Worker sp<ThreadType> thread() const { return mThread; } track()137*ec779b8eSAndroid Build Coastguard Worker sp<TrackType> track() const { return mTrack; } const_thread()138*ec779b8eSAndroid Build Coastguard Worker sp<const ThreadType> const_thread() const { return mThread; } const_track()139*ec779b8eSAndroid Build Coastguard Worker sp<const TrackType> const_track() const { return mTrack; } 140*ec779b8eSAndroid Build Coastguard Worker closeConnections_l(const sp<IAfPatchPanel> & panel)141*ec779b8eSAndroid Build Coastguard Worker void closeConnections_l(const sp<IAfPatchPanel>& panel) 142*ec779b8eSAndroid Build Coastguard Worker REQUIRES(audio_utils::AudioFlinger_Mutex) 143*ec779b8eSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS // this is broken in clang 144*ec779b8eSAndroid Build Coastguard Worker { 145*ec779b8eSAndroid Build Coastguard Worker if (mHandle != AUDIO_PATCH_HANDLE_NONE) { 146*ec779b8eSAndroid Build Coastguard Worker panel->releaseAudioPatch_l(mHandle); 147*ec779b8eSAndroid Build Coastguard Worker mHandle = AUDIO_PATCH_HANDLE_NONE; 148*ec779b8eSAndroid Build Coastguard Worker } 149*ec779b8eSAndroid Build Coastguard Worker if (mThread != nullptr) { 150*ec779b8eSAndroid Build Coastguard Worker if (mTrack != nullptr) { 151*ec779b8eSAndroid Build Coastguard Worker mThread->deletePatchTrack(mTrack); 152*ec779b8eSAndroid Build Coastguard Worker } 153*ec779b8eSAndroid Build Coastguard Worker if (mCloseThread) { 154*ec779b8eSAndroid Build Coastguard Worker panel->closeThreadInternal_l(mThread); 155*ec779b8eSAndroid Build Coastguard Worker } 156*ec779b8eSAndroid Build Coastguard Worker } 157*ec779b8eSAndroid Build Coastguard Worker } handlePtr()158*ec779b8eSAndroid Build Coastguard Worker audio_patch_handle_t* handlePtr() { return &mHandle; } 159*ec779b8eSAndroid Build Coastguard Worker void setThread(const sp<ThreadType>& thread, bool closeThread = true) { 160*ec779b8eSAndroid Build Coastguard Worker mThread = thread; 161*ec779b8eSAndroid Build Coastguard Worker mCloseThread = closeThread; 162*ec779b8eSAndroid Build Coastguard Worker } 163*ec779b8eSAndroid Build Coastguard Worker template <typename T> setTrackAndPeer(const sp<TrackType> & track,const sp<T> & peer,bool holdReference)164*ec779b8eSAndroid Build Coastguard Worker void setTrackAndPeer(const sp<TrackType>& track, const sp<T>& peer, bool holdReference) { 165*ec779b8eSAndroid Build Coastguard Worker mTrack = track; 166*ec779b8eSAndroid Build Coastguard Worker mThread->addPatchTrack(mTrack); 167*ec779b8eSAndroid Build Coastguard Worker mTrack->setPeerProxy(peer, holdReference); 168*ec779b8eSAndroid Build Coastguard Worker mClearPeerProxy = holdReference; 169*ec779b8eSAndroid Build Coastguard Worker } clearTrackPeer()170*ec779b8eSAndroid Build Coastguard Worker void clearTrackPeer() { 171*ec779b8eSAndroid Build Coastguard Worker if (mClearPeerProxy && mTrack) mTrack->clearPeerProxy(); 172*ec779b8eSAndroid Build Coastguard Worker } stopTrack()173*ec779b8eSAndroid Build Coastguard Worker void stopTrack() { 174*ec779b8eSAndroid Build Coastguard Worker if (mTrack) mTrack->stop(); 175*ec779b8eSAndroid Build Coastguard Worker } 176*ec779b8eSAndroid Build Coastguard Worker swap(Endpoint & other)177*ec779b8eSAndroid Build Coastguard Worker void swap(Endpoint& other) noexcept { 178*ec779b8eSAndroid Build Coastguard Worker using std::swap; 179*ec779b8eSAndroid Build Coastguard Worker swap(mThread, other.mThread); 180*ec779b8eSAndroid Build Coastguard Worker swap(mCloseThread, other.mCloseThread); 181*ec779b8eSAndroid Build Coastguard Worker swap(mClearPeerProxy, other.mClearPeerProxy); 182*ec779b8eSAndroid Build Coastguard Worker swap(mHandle, other.mHandle); 183*ec779b8eSAndroid Build Coastguard Worker swap(mTrack, other.mTrack); 184*ec779b8eSAndroid Build Coastguard Worker } 185*ec779b8eSAndroid Build Coastguard Worker swap(Endpoint & a,Endpoint & b)186*ec779b8eSAndroid Build Coastguard Worker friend void swap(Endpoint& a, Endpoint& b) noexcept { a.swap(b); } 187*ec779b8eSAndroid Build Coastguard Worker 188*ec779b8eSAndroid Build Coastguard Worker private: 189*ec779b8eSAndroid Build Coastguard Worker sp<ThreadType> mThread; 190*ec779b8eSAndroid Build Coastguard Worker bool mCloseThread = true; 191*ec779b8eSAndroid Build Coastguard Worker bool mClearPeerProxy = true; 192*ec779b8eSAndroid Build Coastguard Worker audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE; 193*ec779b8eSAndroid Build Coastguard Worker sp<TrackType> mTrack; 194*ec779b8eSAndroid Build Coastguard Worker }; 195*ec779b8eSAndroid Build Coastguard Worker 196*ec779b8eSAndroid Build Coastguard Worker class Patch final { 197*ec779b8eSAndroid Build Coastguard Worker public: Patch(const struct audio_patch & patch,bool endpointPatch)198*ec779b8eSAndroid Build Coastguard Worker Patch(const struct audio_patch& patch, bool endpointPatch) 199*ec779b8eSAndroid Build Coastguard Worker : mAudioPatch(patch), mIsEndpointPatch(endpointPatch) {} 200*ec779b8eSAndroid Build Coastguard Worker Patch() = default; 201*ec779b8eSAndroid Build Coastguard Worker ~Patch(); Patch(const Patch & other)202*ec779b8eSAndroid Build Coastguard Worker Patch(const Patch& other) noexcept { 203*ec779b8eSAndroid Build Coastguard Worker mAudioPatch = other.mAudioPatch; 204*ec779b8eSAndroid Build Coastguard Worker mHalHandle = other.mHalHandle; 205*ec779b8eSAndroid Build Coastguard Worker mPlayback = other.mPlayback; 206*ec779b8eSAndroid Build Coastguard Worker mRecord = other.mRecord; 207*ec779b8eSAndroid Build Coastguard Worker mThread = other.mThread; 208*ec779b8eSAndroid Build Coastguard Worker mIsEndpointPatch = other.mIsEndpointPatch; 209*ec779b8eSAndroid Build Coastguard Worker } Patch(Patch && other)210*ec779b8eSAndroid Build Coastguard Worker Patch(Patch&& other) noexcept { swap(other); } 211*ec779b8eSAndroid Build Coastguard Worker Patch& operator=(Patch&& other) noexcept { 212*ec779b8eSAndroid Build Coastguard Worker swap(other); 213*ec779b8eSAndroid Build Coastguard Worker return *this; 214*ec779b8eSAndroid Build Coastguard Worker } 215*ec779b8eSAndroid Build Coastguard Worker swap(Patch & other)216*ec779b8eSAndroid Build Coastguard Worker void swap(Patch& other) noexcept { 217*ec779b8eSAndroid Build Coastguard Worker using std::swap; 218*ec779b8eSAndroid Build Coastguard Worker swap(mAudioPatch, other.mAudioPatch); 219*ec779b8eSAndroid Build Coastguard Worker swap(mHalHandle, other.mHalHandle); 220*ec779b8eSAndroid Build Coastguard Worker swap(mPlayback, other.mPlayback); 221*ec779b8eSAndroid Build Coastguard Worker swap(mRecord, other.mRecord); 222*ec779b8eSAndroid Build Coastguard Worker swap(mThread, other.mThread); 223*ec779b8eSAndroid Build Coastguard Worker swap(mIsEndpointPatch, other.mIsEndpointPatch); 224*ec779b8eSAndroid Build Coastguard Worker } 225*ec779b8eSAndroid Build Coastguard Worker swap(Patch & a,Patch & b)226*ec779b8eSAndroid Build Coastguard Worker friend void swap(Patch& a, Patch& b) noexcept { a.swap(b); } 227*ec779b8eSAndroid Build Coastguard Worker 228*ec779b8eSAndroid Build Coastguard Worker status_t createConnections_l(const sp<IAfPatchPanel>& panel) 229*ec779b8eSAndroid Build Coastguard Worker REQUIRES(audio_utils::AudioFlinger_Mutex); 230*ec779b8eSAndroid Build Coastguard Worker void clearConnections_l(const sp<IAfPatchPanel>& panel) 231*ec779b8eSAndroid Build Coastguard Worker REQUIRES(audio_utils::AudioFlinger_Mutex); isSoftware()232*ec779b8eSAndroid Build Coastguard Worker bool isSoftware() const { 233*ec779b8eSAndroid Build Coastguard Worker return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE || 234*ec779b8eSAndroid Build Coastguard Worker mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE; 235*ec779b8eSAndroid Build Coastguard Worker } 236*ec779b8eSAndroid Build Coastguard Worker setThread(const sp<IAfThreadBase> & thread)237*ec779b8eSAndroid Build Coastguard Worker void setThread(const sp<IAfThreadBase>& thread) { mThread = thread; } thread()238*ec779b8eSAndroid Build Coastguard Worker wp<IAfThreadBase> thread() const { return mThread; } 239*ec779b8eSAndroid Build Coastguard Worker 240*ec779b8eSAndroid Build Coastguard Worker // returns the latency of the patch (from record to playback). 241*ec779b8eSAndroid Build Coastguard Worker status_t getLatencyMs(double* latencyMs) const; 242*ec779b8eSAndroid Build Coastguard Worker 243*ec779b8eSAndroid Build Coastguard Worker String8 dump(audio_patch_handle_t myHandle) const; 244*ec779b8eSAndroid Build Coastguard Worker 245*ec779b8eSAndroid Build Coastguard Worker // Note that audio_patch::id is only unique within a HAL module 246*ec779b8eSAndroid Build Coastguard Worker struct audio_patch mAudioPatch; 247*ec779b8eSAndroid Build Coastguard Worker // handle for audio HAL patch handle present only when the audio HAL version is >= 3.0 248*ec779b8eSAndroid Build Coastguard Worker audio_patch_handle_t mHalHandle = AUDIO_PATCH_HANDLE_NONE; 249*ec779b8eSAndroid Build Coastguard Worker // below members are used by a software audio patch connecting a source device from a 250*ec779b8eSAndroid Build Coastguard Worker // given audio HW module to a sink device on an other audio HW module. 251*ec779b8eSAndroid Build Coastguard Worker // the objects are created by createConnections() and released by clearConnections() 252*ec779b8eSAndroid Build Coastguard Worker // playback thread is created if no existing playback thread can be used 253*ec779b8eSAndroid Build Coastguard Worker // connects playback thread output to sink device 254*ec779b8eSAndroid Build Coastguard Worker Endpoint<IAfPlaybackThread, IAfPatchTrack> mPlayback; 255*ec779b8eSAndroid Build Coastguard Worker // connects source device to record thread input 256*ec779b8eSAndroid Build Coastguard Worker Endpoint<IAfRecordThread, IAfPatchRecord> mRecord; 257*ec779b8eSAndroid Build Coastguard Worker 258*ec779b8eSAndroid Build Coastguard Worker wp<IAfThreadBase> mThread; 259*ec779b8eSAndroid Build Coastguard Worker bool mIsEndpointPatch; 260*ec779b8eSAndroid Build Coastguard Worker }; 261*ec779b8eSAndroid Build Coastguard Worker 262*ec779b8eSAndroid Build Coastguard Worker /* List connected audio ports and their attributes */ 263*ec779b8eSAndroid Build Coastguard Worker virtual status_t listAudioPorts_l(unsigned int* num_ports, struct audio_port* ports) 264*ec779b8eSAndroid Build Coastguard Worker REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; 265*ec779b8eSAndroid Build Coastguard Worker 266*ec779b8eSAndroid Build Coastguard Worker /* Get supported attributes for a given audio port */ 267*ec779b8eSAndroid Build Coastguard Worker virtual status_t getAudioPort_l(struct audio_port_v7* port) 268*ec779b8eSAndroid Build Coastguard Worker REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; 269*ec779b8eSAndroid Build Coastguard Worker 270*ec779b8eSAndroid Build Coastguard Worker /* Create a patch between several source and sink ports */ 271*ec779b8eSAndroid Build Coastguard Worker virtual status_t createAudioPatch_l( 272*ec779b8eSAndroid Build Coastguard Worker const struct audio_patch* patch, 273*ec779b8eSAndroid Build Coastguard Worker audio_patch_handle_t* handle, 274*ec779b8eSAndroid Build Coastguard Worker bool endpointPatch = false) 275*ec779b8eSAndroid Build Coastguard Worker REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; 276*ec779b8eSAndroid Build Coastguard Worker 277*ec779b8eSAndroid Build Coastguard Worker /* Release a patch */ 278*ec779b8eSAndroid Build Coastguard Worker virtual status_t releaseAudioPatch_l(audio_patch_handle_t handle) 279*ec779b8eSAndroid Build Coastguard Worker REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; 280*ec779b8eSAndroid Build Coastguard Worker 281*ec779b8eSAndroid Build Coastguard Worker /* List connected audio devices and they attributes */ 282*ec779b8eSAndroid Build Coastguard Worker virtual status_t listAudioPatches_l(unsigned int* num_patches, struct audio_patch* patches) 283*ec779b8eSAndroid Build Coastguard Worker REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; 284*ec779b8eSAndroid Build Coastguard Worker 285*ec779b8eSAndroid Build Coastguard Worker // Retrieves all currently estrablished software patches for a stream 286*ec779b8eSAndroid Build Coastguard Worker // opened on an intermediate module. 287*ec779b8eSAndroid Build Coastguard Worker virtual status_t getDownstreamSoftwarePatches( 288*ec779b8eSAndroid Build Coastguard Worker audio_io_handle_t stream, std::vector<SoftwarePatch>* patches) const = 0; 289*ec779b8eSAndroid Build Coastguard Worker 290*ec779b8eSAndroid Build Coastguard Worker // Notifies patch panel about all opened and closed streams. 291*ec779b8eSAndroid Build Coastguard Worker virtual void notifyStreamOpened( 292*ec779b8eSAndroid Build Coastguard Worker AudioHwDevice* audioHwDevice, audio_io_handle_t stream, struct audio_patch* patch) = 0; 293*ec779b8eSAndroid Build Coastguard Worker 294*ec779b8eSAndroid Build Coastguard Worker virtual void notifyStreamClosed(audio_io_handle_t stream) = 0; 295*ec779b8eSAndroid Build Coastguard Worker 296*ec779b8eSAndroid Build Coastguard Worker virtual void dump(int fd) const = 0; 297*ec779b8eSAndroid Build Coastguard Worker 298*ec779b8eSAndroid Build Coastguard Worker virtual const std::map<audio_patch_handle_t, Patch>& patches_l() const 299*ec779b8eSAndroid Build Coastguard Worker REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; 300*ec779b8eSAndroid Build Coastguard Worker 301*ec779b8eSAndroid Build Coastguard Worker virtual status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const 302*ec779b8eSAndroid Build Coastguard Worker REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; 303*ec779b8eSAndroid Build Coastguard Worker 304*ec779b8eSAndroid Build Coastguard Worker virtual void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const 305*ec779b8eSAndroid Build Coastguard Worker REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; 306*ec779b8eSAndroid Build Coastguard Worker 307*ec779b8eSAndroid Build Coastguard Worker /** 308*ec779b8eSAndroid Build Coastguard Worker * Get the attributes of the mix port when connecting to the given device port. 309*ec779b8eSAndroid Build Coastguard Worker */ 310*ec779b8eSAndroid Build Coastguard Worker virtual status_t getAudioMixPort_l( 311*ec779b8eSAndroid Build Coastguard Worker const struct audio_port_v7* devicePort, 312*ec779b8eSAndroid Build Coastguard Worker struct audio_port_v7* mixPort) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0; 313*ec779b8eSAndroid Build Coastguard Worker }; 314*ec779b8eSAndroid Build Coastguard Worker 315*ec779b8eSAndroid Build Coastguard Worker } // namespace android 316