xref: /aosp_15_r20/frameworks/av/services/audioflinger/IAfPatchPanel.h (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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