xref: /aosp_15_r20/frameworks/av/services/audioflinger/PatchPanel.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2 **
3 ** Copyright 2014, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 
19 #define LOG_TAG "AudioFlinger::PatchPanel"
20 //#define LOG_NDEBUG 0
21 
22 #include "PatchPanel.h"
23 #include "PatchCommandThread.h"
24 
25 #include <audio_utils/primitives.h>
26 #include <media/AudioParameter.h>
27 #include <media/AudioValidator.h>
28 #include <media/DeviceDescriptorBase.h>
29 #include <media/PatchBuilder.h>
30 #include <mediautils/ServiceUtilities.h>
31 #include <utils/Log.h>
32 
33 // ----------------------------------------------------------------------------
34 
35 // Note: the following macro is used for extremely verbose logging message.  In
36 // order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
37 // 0; but one side effect of this is to turn all LOGV's as well.  Some messages
38 // are so verbose that we want to suppress them even when we have ALOG_ASSERT
39 // turned on.  Do not uncomment the #def below unless you really know what you
40 // are doing and want to see all of the extremely verbose messages.
41 //#define VERY_VERY_VERBOSE_LOGGING
42 #ifdef VERY_VERY_VERBOSE_LOGGING
43 #define ALOGVV ALOGV
44 #else
45 #define ALOGVV(a...) do { } while(0)
46 #endif
47 
48 namespace android {
49 
50 /* static */
create(const sp<IAfPatchPanelCallback> & afPatchPanelCallback)51 sp<IAfPatchPanel> IAfPatchPanel::create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback) {
52     return sp<PatchPanel>::make(afPatchPanelCallback);
53 }
54 
getLatencyMs_l(double * latencyMs) const55 status_t SoftwarePatch::getLatencyMs_l(double* latencyMs) const {
56     return mPatchPanel->getLatencyMs_l(mPatchHandle, latencyMs);
57 }
58 
getLatencyMs_l(audio_patch_handle_t patchHandle,double * latencyMs) const59 status_t PatchPanel::getLatencyMs_l(
60         audio_patch_handle_t patchHandle, double* latencyMs) const
61 {
62     const auto& iter = mPatches.find(patchHandle);
63     if (iter != mPatches.end()) {
64         return iter->second.getLatencyMs(latencyMs);
65     } else {
66         return BAD_VALUE;
67     }
68 }
69 
closeThreadInternal_l(const sp<IAfThreadBase> & thread) const70 void PatchPanel::closeThreadInternal_l(const sp<IAfThreadBase>& thread) const
71 {
72     if (const auto recordThread = thread->asIAfRecordThread();
73             recordThread) {
74         mAfPatchPanelCallback->closeThreadInternal_l(recordThread);
75     } else if (const auto playbackThread = thread->asIAfPlaybackThread();
76             playbackThread) {
77         mAfPatchPanelCallback->closeThreadInternal_l(playbackThread);
78     } else {
79         LOG_ALWAYS_FATAL("%s: Endpoints only accept IAfPlayback and IAfRecord threads, "
80                 "invalid thread, id: %d  type: %d",
81                 __func__, thread->id(), thread->type());
82     }
83 }
84 
85 /* List connected audio ports and their attributes */
listAudioPorts_l(unsigned int *,struct audio_port * ports __unused)86 status_t PatchPanel::listAudioPorts_l(unsigned int* /* num_ports */,
87                                 struct audio_port *ports __unused)
88 {
89     ALOGV(__func__);
90     return NO_ERROR;
91 }
92 
93 /* Get supported attributes for a given audio port */
getAudioPort_l(struct audio_port_v7 * port)94 status_t PatchPanel::getAudioPort_l(struct audio_port_v7* port)
95 {
96     if (port->type != AUDIO_PORT_TYPE_DEVICE) {
97         // Only query the HAL when the port is a device.
98         // TODO: implement getAudioPort for mix.
99         return INVALID_OPERATION;
100     }
101     AudioHwDevice* hwDevice = findAudioHwDeviceByModule_l(port->ext.device.hw_module);
102     if (hwDevice == nullptr) {
103         ALOGW("%s cannot find hw module %d", __func__, port->ext.device.hw_module);
104         return BAD_VALUE;
105     }
106     if (!hwDevice->supportsAudioPatches()) {
107         return INVALID_OPERATION;
108     }
109     return hwDevice->getAudioPort(port);
110 }
111 
112 /* Connect a patch between several source and sink ports */
createAudioPatch_l(const struct audio_patch * patch,audio_patch_handle_t * handle,bool endpointPatch)113 status_t PatchPanel::createAudioPatch_l(const struct audio_patch* patch,
114                                    audio_patch_handle_t *handle,
115                                    bool endpointPatch)
116  //unlocks AudioFlinger::mLock when calling IAfThreadBase::sendCreateAudioPatchConfigEvent
117  //to avoid deadlocks if the thread loop needs to acquire AudioFlinger::mLock
118  //before processing the create patch request.
119  NO_THREAD_SAFETY_ANALYSIS
120 {
121     if (handle == NULL || patch == NULL) {
122         return BAD_VALUE;
123     }
124     ALOGV("%s() num_sources %d num_sinks %d handle %d",
125             __func__, patch->num_sources, patch->num_sinks, *handle);
126     status_t status = NO_ERROR;
127     audio_patch_handle_t halHandle = AUDIO_PATCH_HANDLE_NONE;
128 
129     if (!audio_patch_is_valid(patch) || (patch->num_sinks == 0 && patch->num_sources != 2)) {
130         return BAD_VALUE;
131     }
132     // limit number of sources to 1 for now or 2 sources for special cross hw module case.
133     // only the audio policy manager can request a patch creation with 2 sources.
134     if (patch->num_sources > 2) {
135         return INVALID_OPERATION;
136     }
137     bool reuseExistingHalPatch = false;
138     audio_patch_handle_t oldhandle = AUDIO_PATCH_HANDLE_NONE;
139     if (*handle != AUDIO_PATCH_HANDLE_NONE) {
140         auto iter = mPatches.find(*handle);
141         if (iter != mPatches.end()) {
142             ALOGV("%s() removing patch handle %d", __func__, *handle);
143             Patch &removedPatch = iter->second;
144             // free resources owned by the removed patch if applicable
145             // 1) if a software patch is present, release the playback and capture threads and
146             // tracks created. This will also release the corresponding audio HAL patches
147             if (removedPatch.isSoftware()) {
148                 removedPatch.clearConnections_l(this);
149             }
150             // 2) if the new patch and old patch source or sink are devices from different
151             // hw modules,  clear the audio HAL patches now because they will not be updated
152             // by call to create_audio_patch() below which will happen on a different HW module
153             if (removedPatch.mHalHandle != AUDIO_PATCH_HANDLE_NONE) {
154                 audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE;
155                 const struct audio_patch &oldPatch = removedPatch.mAudioPatch;
156                 oldhandle = *handle;
157                 if (oldPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE &&
158                         (patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE ||
159                                 oldPatch.sources[0].ext.device.hw_module !=
160                                 patch->sources[0].ext.device.hw_module)) {
161                     hwModule = oldPatch.sources[0].ext.device.hw_module;
162                 } else if (patch->num_sinks == 0 ||
163                         (oldPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE &&
164                                 (patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE ||
165                                         oldPatch.sinks[0].ext.device.hw_module !=
166                                         patch->sinks[0].ext.device.hw_module))) {
167                     // Note on (patch->num_sinks == 0): this situation should not happen as
168                     // these special patches are only created by the policy manager but just
169                     // in case, systematically clear the HAL patch.
170                     // Note that removedPatch.mAudioPatch.num_sinks cannot be 0 here because
171                     // removedPatch.mHalHandle would be AUDIO_PATCH_HANDLE_NONE in this case.
172                     hwModule = oldPatch.sinks[0].ext.device.hw_module;
173                 }
174                 sp<DeviceHalInterface> hwDevice = findHwDeviceByModule_l(hwModule);
175                 if (hwDevice != 0) {
176                     hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
177                 }
178                 halHandle = removedPatch.mHalHandle;
179                 // Prevent to remove/add device effect when mix / device did not change, and
180                 // hal patch has not been released
181                 // Note that no patch leak at hal layer as halHandle is reused.
182                 reuseExistingHalPatch = (hwDevice == 0) && patchesHaveSameRoute(*patch, oldPatch);
183             }
184             erasePatch(*handle, reuseExistingHalPatch);
185         }
186     }
187 
188     Patch newPatch{*patch, endpointPatch};
189     audio_module_handle_t insertedModule = AUDIO_MODULE_HANDLE_NONE;
190 
191     switch (patch->sources[0].type) {
192         case AUDIO_PORT_TYPE_DEVICE: {
193             audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module;
194             AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule_l(srcModule);
195             if (!audioHwDevice) {
196                 status = BAD_VALUE;
197                 goto exit;
198             }
199             for (unsigned int i = 0; i < patch->num_sinks; i++) {
200                 // support only one sink if connection to a mix or across HW modules
201                 if ((patch->sinks[i].type == AUDIO_PORT_TYPE_MIX ||
202                                 (patch->sinks[i].type == AUDIO_PORT_TYPE_DEVICE &&
203                                         patch->sinks[i].ext.device.hw_module != srcModule)) &&
204                         patch->num_sinks > 1) {
205                     ALOGW("%s() multiple sinks for mix or across modules not supported", __func__);
206                     status = INVALID_OPERATION;
207                     goto exit;
208                 }
209                 // reject connection to different sink types
210                 if (patch->sinks[i].type != patch->sinks[0].type) {
211                     ALOGW("%s() different sink types in same patch not supported", __func__);
212                     status = BAD_VALUE;
213                     goto exit;
214                 }
215             }
216 
217             // manage patches requiring a software bridge
218             // - special patch request with 2 sources (reuse one existing output mix) OR
219             // - Device to device AND
220             //    - source HW module != destination HW module OR
221             //    - audio HAL does not support audio patches creation
222             if ((patch->num_sources == 2) ||
223                 ((patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
224                  ((patch->sinks[0].ext.device.hw_module != srcModule) ||
225                   !audioHwDevice->supportsAudioPatches()))) {
226                 audio_devices_t outputDevice = patch->sinks[0].ext.device.type;
227                 String8 outputDeviceAddress = String8(patch->sinks[0].ext.device.address);
228                 if (patch->num_sources == 2) {
229                     if (patch->sources[1].type != AUDIO_PORT_TYPE_MIX ||
230                             (patch->num_sinks != 0 && patch->sinks[0].ext.device.hw_module !=
231                                     patch->sources[1].ext.mix.hw_module)) {
232                         ALOGW("%s() invalid source combination", __func__);
233                         status = INVALID_OPERATION;
234                         goto exit;
235                     }
236                     const sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(
237                             patch->sources[1].ext.mix.handle);
238                     if (thread == 0) {
239                         ALOGW("%s() cannot get playback thread", __func__);
240                         status = INVALID_OPERATION;
241                         goto exit;
242                     }
243                     // existing playback thread is reused, so it is not closed when patch is cleared
244                     newPatch.mPlayback.setThread(
245                             thread->asIAfPlaybackThread().get(), false /*closeThread*/);
246                 } else {
247                     audio_config_t config = AUDIO_CONFIG_INITIALIZER;
248                     audio_config_base_t mixerConfig = AUDIO_CONFIG_BASE_INITIALIZER;
249                     audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
250                     audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
251                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
252                         config.sample_rate = patch->sinks[0].sample_rate;
253                     }
254                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
255                         config.channel_mask = patch->sinks[0].channel_mask;
256                     }
257                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
258                         config.format = patch->sinks[0].format;
259                     }
260                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS) {
261                         flags = patch->sinks[0].flags.output;
262                     }
263                     audio_attributes_t attributes = AUDIO_ATTRIBUTES_INITIALIZER;
264                     const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openOutput_l(
265                                                             patch->sinks[0].ext.device.hw_module,
266                                                             &output,
267                                                             &config,
268                                                             &mixerConfig,
269                                                             outputDevice,
270                                                             outputDeviceAddress,
271                                                             &flags,
272                                                             attributes);
273                     ALOGV("mAfPatchPanelCallback->openOutput_l() returned %p", thread.get());
274                     if (thread == 0) {
275                         status = NO_MEMORY;
276                         goto exit;
277                     }
278                     newPatch.mPlayback.setThread(thread->asIAfPlaybackThread().get());
279                 }
280                 audio_devices_t device = patch->sources[0].ext.device.type;
281                 String8 address = String8(patch->sources[0].ext.device.address);
282                 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
283                 // open input stream with source device audio properties if provided or
284                 // default to peer output stream properties otherwise.
285                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
286                     config.sample_rate = patch->sources[0].sample_rate;
287                 } else {
288                     config.sample_rate = newPatch.mPlayback.thread()->sampleRate();
289                 }
290                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
291                     config.channel_mask = patch->sources[0].channel_mask;
292                 } else {
293                     config.channel_mask = audio_channel_in_mask_from_count(
294                             newPatch.mPlayback.thread()->channelCount());
295                 }
296                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
297                     config.format = patch->sources[0].format;
298                 } else {
299                     config.format = newPatch.mPlayback.thread()->format();
300                 }
301                 audio_input_flags_t flags =
302                         patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
303                         patch->sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
304                 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
305                 audio_source_t source = AUDIO_SOURCE_MIC;
306                 // For telephony patches, propagate voice communication use case to record side
307                 if (patch->num_sources == 2
308                         && patch->sources[1].ext.mix.usecase.stream
309                                 == AUDIO_STREAM_VOICE_CALL) {
310                     source = AUDIO_SOURCE_VOICE_COMMUNICATION;
311                 }
312                 const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openInput_l(srcModule,
313                                                                     &input,
314                                                                     &config,
315                                                                     device,
316                                                                     address,
317                                                                     source,
318                                                                     flags,
319                                                                     outputDevice,
320                                                                     outputDeviceAddress);
321                 ALOGV("mAfPatchPanelCallback->openInput_l() returned %p inChannelMask %08x",
322                       thread.get(), config.channel_mask);
323                 if (thread == 0) {
324                     status = NO_MEMORY;
325                     goto exit;
326                 }
327                 newPatch.mRecord.setThread(thread->asIAfRecordThread().get());
328                 status = newPatch.createConnections_l(this);
329                 if (status != NO_ERROR) {
330                     goto exit;
331                 }
332                 if (audioHwDevice->isInsert()) {
333                     insertedModule = audioHwDevice->handle();
334                 }
335             } else {
336                 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
337                     sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(
338                                                               patch->sinks[0].ext.mix.handle);
339                     if (thread == 0) {
340                         thread = mAfPatchPanelCallback->checkMmapThread_l(
341                                 patch->sinks[0].ext.mix.handle);
342                         if (thread == 0) {
343                             ALOGW("%s() bad capture I/O handle %d",
344                                     __func__, patch->sinks[0].ext.mix.handle);
345                             status = BAD_VALUE;
346                             goto exit;
347                         }
348                     }
349                     mAfPatchPanelCallback->mutex().unlock();
350                     status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
351                     mAfPatchPanelCallback->mutex().lock();
352                     if (status == NO_ERROR) {
353                         newPatch.setThread(thread);
354                     }
355                     // remove stale audio patch with same input as sink if any
356                     for (auto& iter : mPatches) {
357                         if (iter.second.mAudioPatch.sinks[0].ext.mix.handle == thread->id()) {
358                             erasePatch(iter.first);
359                             break;
360                         }
361                     }
362                 } else {
363                     sp<DeviceHalInterface> hwDevice = audioHwDevice->hwDevice();
364                     status = hwDevice->createAudioPatch(patch->num_sources,
365                                                         patch->sources,
366                                                         patch->num_sinks,
367                                                         patch->sinks,
368                                                         &halHandle);
369                     if (status == INVALID_OPERATION) goto exit;
370                 }
371             }
372         } break;
373         case AUDIO_PORT_TYPE_MIX: {
374             audio_module_handle_t srcModule =  patch->sources[0].ext.mix.hw_module;
375             ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(srcModule);
376             if (index < 0) {
377                 ALOGW("%s() bad src hw module %d", __func__, srcModule);
378                 status = BAD_VALUE;
379                 goto exit;
380             }
381             // limit to connections between devices and output streams
382             DeviceDescriptorBaseVector devices;
383             for (unsigned int i = 0; i < patch->num_sinks; i++) {
384                 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
385                     ALOGW("%s() invalid sink type %d for mix source",
386                             __func__, patch->sinks[i].type);
387                     status = BAD_VALUE;
388                     goto exit;
389                 }
390                 // limit to connections between sinks and sources on same HW module
391                 if (patch->sinks[i].ext.device.hw_module != srcModule) {
392                     status = BAD_VALUE;
393                     goto exit;
394                 }
395                 sp<DeviceDescriptorBase> device = new DeviceDescriptorBase(
396                         patch->sinks[i].ext.device.type);
397                 device->setAddress(patch->sinks[i].ext.device.address);
398                 device->applyAudioPortConfig(&patch->sinks[i]);
399                 devices.push_back(device);
400             }
401             sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(
402                     patch->sources[0].ext.mix.handle);
403             if (thread == 0) {
404                 thread = mAfPatchPanelCallback->checkMmapThread_l(
405                         patch->sources[0].ext.mix.handle);
406                 if (thread == 0) {
407                     ALOGW("%s() bad playback I/O handle %d",
408                             __func__, patch->sources[0].ext.mix.handle);
409                     status = BAD_VALUE;
410                     goto exit;
411                 }
412             }
413             if (thread == mAfPatchPanelCallback->primaryPlaybackThread_l()) {
414                 mAfPatchPanelCallback->updateOutDevicesForRecordThreads_l(devices);
415             }
416 
417             // For endpoint patches, we do not need to re-evaluate the device effect state
418             // if the same HAL patch is reused (see calls to mAfPatchPanelCallback below)
419             if (endpointPatch) {
420                 for (auto& p : mPatches) {
421                     // end point patches are skipped so we do not compare against this patch
422                     if (!p.second.mIsEndpointPatch && patchesHaveSameRoute(
423                             newPatch.mAudioPatch, p.second.mAudioPatch)) {
424                         ALOGV("%s() Sw Bridge endpoint reusing halHandle=%d", __func__,
425                               p.second.mHalHandle);
426                         halHandle = p.second.mHalHandle;
427                         reuseExistingHalPatch = true;
428                         break;
429                     }
430                 }
431             }
432             mAfPatchPanelCallback->mutex().unlock();
433 
434             status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
435             mAfPatchPanelCallback->mutex().lock();
436             if (status == NO_ERROR) {
437                 newPatch.setThread(thread);
438             }
439 
440             // remove stale audio patch with same output as source if any
441             // Prevent to remove endpoint patches (involved in a SwBridge)
442             // Prevent to remove AudioPatch used to route an output involved in an endpoint.
443             if (!endpointPatch) {
444                 for (auto& iter : mPatches) {
445                     if (iter.second.mAudioPatch.sources[0].ext.mix.handle == thread->id() &&
446                             !iter.second.mIsEndpointPatch) {
447                         erasePatch(iter.first);
448                         break;
449                     }
450                 }
451             }
452         } break;
453         default:
454             status = BAD_VALUE;
455             goto exit;
456     }
457 exit:
458     ALOGV("%s() status %d", __func__, status);
459     if (status == NO_ERROR) {
460         *handle = static_cast<audio_patch_handle_t>(
461                 mAfPatchPanelCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH));
462         newPatch.mHalHandle = halHandle;
463         // Skip device effect:
464         //  -for sw bridge as effect are likely held by endpoint patches
465         //  -for endpoint reusing a HalPatch handle
466         if (!(newPatch.isSoftware()
467                 || (endpointPatch && reuseExistingHalPatch))) {
468             if (reuseExistingHalPatch) {
469                 mAfPatchPanelCallback->getPatchCommandThread()->updateAudioPatch(
470                         oldhandle, *handle, newPatch);
471             } else {
472                  mAfPatchPanelCallback->getPatchCommandThread()->createAudioPatch(
473                         *handle, newPatch);
474             }
475         }
476         if (insertedModule != AUDIO_MODULE_HANDLE_NONE) {
477             addSoftwarePatchToInsertedModules_l(insertedModule, *handle, &newPatch.mAudioPatch);
478         }
479         mPatches.insert(std::make_pair(*handle, std::move(newPatch)));
480     } else {
481         newPatch.clearConnections_l(this);
482     }
483     return status;
484 }
485 
getAudioMixPort_l(const audio_port_v7 * devicePort,audio_port_v7 * mixPort)486 status_t PatchPanel::getAudioMixPort_l(const audio_port_v7 *devicePort,
487                                        audio_port_v7 *mixPort) {
488     if (devicePort->type != AUDIO_PORT_TYPE_DEVICE) {
489         ALOGE("%s the type of given device port is not DEVICE", __func__);
490         return INVALID_OPERATION;
491     }
492     if (mixPort->type != AUDIO_PORT_TYPE_MIX) {
493         ALOGE("%s the type of given mix port is not MIX", __func__);
494         return INVALID_OPERATION;
495     }
496     AudioHwDevice* hwDevice = findAudioHwDeviceByModule_l(devicePort->ext.device.hw_module);
497     if (hwDevice == nullptr) {
498         ALOGW("%s cannot find hw module %d", __func__, devicePort->ext.device.hw_module);
499         return BAD_VALUE;
500     }
501     return hwDevice->getAudioMixPort(devicePort, mixPort);
502 }
503 
~Patch()504 PatchPanel::Patch::~Patch()
505 {
506     ALOGE_IF(isSoftware(), "Software patch connections leaked %d %d",
507             mRecord.handle(), mPlayback.handle());
508 }
509 
createConnections_l(const sp<IAfPatchPanel> & panel)510 status_t PatchPanel::Patch::createConnections_l(const sp<IAfPatchPanel>& panel)
511 {
512     // create patch from source device to record thread input
513     status_t status = panel->createAudioPatch_l(
514             PatchBuilder().addSource(mAudioPatch.sources[0]).
515                 addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(),
516             mRecord.handlePtr(),
517             true /*endpointPatch*/);
518     if (status != NO_ERROR) {
519         *mRecord.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
520         return status;
521     }
522 
523     // create patch from playback thread output to sink device
524     if (mAudioPatch.num_sinks != 0) {
525         status = panel->createAudioPatch_l(
526                 PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(),
527                 mPlayback.handlePtr(),
528                 true /*endpointPatch*/);
529         if (status != NO_ERROR) {
530             *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
531             return status;
532         }
533     } else {
534         *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
535     }
536 
537     // create a special record track to capture from record thread
538     uint32_t channelCount = mPlayback.thread()->channelCount();
539     audio_channel_mask_t inChannelMask = audio_channel_in_mask_from_count(channelCount);
540     audio_channel_mask_t outChannelMask = mPlayback.thread()->channelMask();
541     uint32_t sampleRate = mPlayback.thread()->sampleRate();
542     audio_format_t format = mPlayback.thread()->format();
543 
544     audio_format_t inputFormat = mRecord.thread()->format();
545     if (!audio_is_linear_pcm(inputFormat)) {
546         // The playbackThread format will say PCM for IEC61937 packetized stream.
547         // Use recordThread format.
548         format = inputFormat;
549     }
550     audio_input_flags_t inputFlags = mAudioPatch.sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
551             mAudioPatch.sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
552     if (sampleRate == mRecord.thread()->sampleRate() &&
553             inChannelMask == mRecord.thread()->channelMask() &&
554             mRecord.thread()->fastTrackAvailable() &&
555             mRecord.thread()->hasFastCapture()) {
556         // Create a fast track if the record thread has fast capture to get better performance.
557         // Only enable fast mode when there is no resample needed.
558         inputFlags = (audio_input_flags_t) (inputFlags | AUDIO_INPUT_FLAG_FAST);
559     } else {
560         // Fast mode is not available in this case.
561         inputFlags = (audio_input_flags_t) (inputFlags & ~AUDIO_INPUT_FLAG_FAST);
562     }
563 
564     audio_output_flags_t outputFlags = mAudioPatch.sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
565             mAudioPatch.sinks[0].flags.output : AUDIO_OUTPUT_FLAG_NONE;
566     audio_stream_type_t streamType = AUDIO_STREAM_PATCH;
567     audio_source_t source = AUDIO_SOURCE_DEFAULT;
568     if (mAudioPatch.num_sources == 2 && mAudioPatch.sources[1].type == AUDIO_PORT_TYPE_MIX) {
569         // "reuse one existing output mix" case
570         streamType = mAudioPatch.sources[1].ext.mix.usecase.stream;
571         // For telephony patches, propagate voice communication use case to record side
572         if (streamType == AUDIO_STREAM_VOICE_CALL) {
573             source = AUDIO_SOURCE_VOICE_COMMUNICATION;
574         }
575     }
576     if (mPlayback.thread()->hasFastMixer()) {
577         // Create a fast track if the playback thread has fast mixer to get better performance.
578         // Note: we should have matching channel mask, sample rate, and format by the logic above.
579         outputFlags = (audio_output_flags_t) (outputFlags | AUDIO_OUTPUT_FLAG_FAST);
580     } else {
581         outputFlags = (audio_output_flags_t) (outputFlags & ~AUDIO_OUTPUT_FLAG_FAST);
582     }
583 
584     sp<IAfPatchRecord> tempRecordTrack;
585     const bool usePassthruPatchRecord =
586             (inputFlags & AUDIO_INPUT_FLAG_DIRECT) && (outputFlags & AUDIO_OUTPUT_FLAG_DIRECT);
587     const size_t playbackFrameCount = mPlayback.thread()->frameCount();
588     const size_t recordFrameCount = mRecord.thread()->frameCount();
589     size_t frameCount = 0;
590     if (usePassthruPatchRecord) {
591         // PassthruPatchRecord producesBufferOnDemand, so use
592         // maximum of playback and record thread framecounts
593         frameCount = std::max(playbackFrameCount, recordFrameCount);
594         ALOGV("%s() playframeCount %zu recordFrameCount %zu frameCount %zu",
595             __func__, playbackFrameCount, recordFrameCount, frameCount);
596         tempRecordTrack = IAfPatchRecord::createPassThru(
597                                                  mRecord.thread().get(),
598                                                  sampleRate,
599                                                  inChannelMask,
600                                                  format,
601                                                  frameCount,
602                                                  inputFlags,
603                                                  source);
604     } else {
605         // use a pseudo LCM between input and output framecount
606         int playbackShift = __builtin_ctz(playbackFrameCount);
607         int shift = __builtin_ctz(recordFrameCount);
608         if (playbackShift < shift) {
609             shift = playbackShift;
610         }
611         frameCount = (playbackFrameCount * recordFrameCount) >> shift;
612         ALOGV("%s() playframeCount %zu recordFrameCount %zu frameCount %zu",
613             __func__, playbackFrameCount, recordFrameCount, frameCount);
614 
615         tempRecordTrack = IAfPatchRecord::create(
616                                                  mRecord.thread().get(),
617                                                  sampleRate,
618                                                  inChannelMask,
619                                                  format,
620                                                  frameCount,
621                                                  nullptr,
622                                                  (size_t)0 /* bufferSize */,
623                                                  inputFlags,
624                                                  {} /* timeout */,
625                                                  source);
626     }
627     status = mRecord.checkTrack(tempRecordTrack.get());
628     if (status != NO_ERROR) {
629         return status;
630     }
631 
632     // create a special playback track to render to playback thread.
633     // this track is given the same buffer as the PatchRecord buffer
634 
635     // Default behaviour is to start as soon as possible to have the lowest possible latency even if
636     // it might glitch.
637     // Disable this behavior for FM Tuner source if no fast capture/mixer available.
638     const bool isFmBridge = mAudioPatch.sources[0].ext.device.type == AUDIO_DEVICE_IN_FM_TUNER;
639     const size_t frameCountToBeReady = isFmBridge && !usePassthruPatchRecord ? frameCount / 4 : 1;
640     sp<IAfPatchTrack> tempPatchTrack = IAfPatchTrack::create(
641                                            mPlayback.thread().get(),
642                                            streamType,
643                                            sampleRate,
644                                            outChannelMask,
645                                            format,
646                                            frameCount,
647                                            tempRecordTrack->buffer(),
648                                            tempRecordTrack->bufferSize(),
649                                            outputFlags,
650                                            {} /*timeout*/,
651                                            frameCountToBeReady,
652                                            1.0f /*speed*/,
653                                            1.0f /*volume*/,
654                                            false /*muted*/);
655     status = mPlayback.checkTrack(tempPatchTrack.get());
656     if (status != NO_ERROR) {
657         return status;
658     }
659 
660     // tie playback and record tracks together
661     // In the case of PassthruPatchRecord no I/O activity happens on RecordThread,
662     // everything is driven from PlaybackThread. Thus AudioBufferProvider methods
663     // of PassthruPatchRecord can only be called if the corresponding PatchTrack
664     // is alive. There is no need to hold a reference, and there is no need
665     // to clear it. In fact, since playback stopping is asynchronous, there is
666     // no proper time when clearing could be done.
667     mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack, !usePassthruPatchRecord);
668     mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack, true /*holdReference*/);
669 
670     // start capture and playback
671     mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
672     mPlayback.track()->start();
673 
674     return status;
675 }
676 
clearConnections_l(const sp<IAfPatchPanel> & panel)677 void PatchPanel::Patch::clearConnections_l(const sp<IAfPatchPanel>& panel)
678 {
679     ALOGV("%s() mRecord.handle %d mPlayback.handle %d",
680             __func__, mRecord.handle(), mPlayback.handle());
681     mRecord.stopTrack();
682     mPlayback.stopTrack();
683     mRecord.clearTrackPeer(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle.
684     mRecord.closeConnections_l(panel);
685     mPlayback.closeConnections_l(panel);
686 }
687 
getLatencyMs(double * latencyMs) const688 status_t PatchPanel::Patch::getLatencyMs(double* latencyMs) const
689 {
690     if (!isSoftware()) return INVALID_OPERATION;
691 
692     auto recordTrack = mRecord.const_track();
693     if (recordTrack.get() == nullptr) return INVALID_OPERATION;
694 
695     auto playbackTrack = mPlayback.const_track();
696     if (playbackTrack.get() == nullptr) return INVALID_OPERATION;
697 
698     // Latency information for tracks may be called without obtaining
699     // the underlying thread lock.
700     //
701     // We use record server latency + playback track latency (generally smaller than the
702     // reverse due to internal biases).
703     //
704     // TODO: is this stable enough? Consider a PatchTrack synchronized version of this.
705 
706     // For PCM tracks get server latency.
707     if (audio_is_linear_pcm(recordTrack->format())) {
708         double recordServerLatencyMs, playbackTrackLatencyMs;
709         if (recordTrack->getServerLatencyMs(&recordServerLatencyMs) == OK
710                 && playbackTrack->getTrackLatencyMs(&playbackTrackLatencyMs) == OK) {
711             *latencyMs = recordServerLatencyMs + playbackTrackLatencyMs;
712             return OK;
713         }
714     }
715 
716     // See if kernel latencies are available.
717     // If so, do a frame diff and time difference computation to estimate
718     // the total patch latency. This requires that frame counts are reported by the
719     // HAL are matched properly in the case of record overruns and playback underruns.
720     IAfTrack::FrameTime recordFT{}, playFT{};
721     recordTrack->getKernelFrameTime(&recordFT);
722     playbackTrack->getKernelFrameTime(&playFT);
723     if (recordFT.timeNs > 0 && playFT.timeNs > 0) {
724         const int64_t frameDiff = recordFT.frames - playFT.frames;
725         const int64_t timeDiffNs = recordFT.timeNs - playFT.timeNs;
726 
727         // It is possible that the patch track and patch record have a large time disparity because
728         // one thread runs but another is stopped.  We arbitrarily choose the maximum timestamp
729         // time difference based on how often we expect the timestamps to update in normal operation
730         // (typical should be no more than 50 ms).
731         //
732         // If the timestamps aren't sampled close enough, the patch latency is not
733         // considered valid.
734         //
735         // TODO: change this based on more experiments.
736         constexpr int64_t maxValidTimeDiffNs = 200 * NANOS_PER_MILLISECOND;
737         if (std::abs(timeDiffNs) < maxValidTimeDiffNs) {
738             *latencyMs = frameDiff * 1e3 / recordTrack->sampleRate()
739                    - timeDiffNs * 1e-6;
740             return OK;
741         }
742     }
743 
744     return INVALID_OPERATION;
745 }
746 
dump(audio_patch_handle_t myHandle) const747 String8 PatchPanel::Patch::dump(audio_patch_handle_t myHandle) const
748 {
749     // TODO: Consider table dump form for patches, just like tracks.
750     String8 result = String8::format("Patch %d: %s (thread %p => thread %p)",
751             myHandle, isSoftware() ? "Software bridge between" : "No software bridge",
752             mRecord.const_thread().get(), mPlayback.const_thread().get());
753 
754     bool hasSinkDevice =
755             mAudioPatch.num_sinks > 0 && mAudioPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE;
756     bool hasSourceDevice =
757             mAudioPatch.num_sources > 0 && mAudioPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE;
758     result.appendFormat(" thread %p %s (%d) first device type %08x", mThread.unsafe_get(),
759             hasSinkDevice ? "num sinks" :
760                 (hasSourceDevice ? "num sources" : "no devices"),
761             hasSinkDevice ? mAudioPatch.num_sinks :
762                 (hasSourceDevice ? mAudioPatch.num_sources : 0),
763             hasSinkDevice ? mAudioPatch.sinks[0].ext.device.type :
764                 (hasSourceDevice ? mAudioPatch.sources[0].ext.device.type : 0));
765 
766     // add latency if it exists
767     double latencyMs;
768     if (getLatencyMs(&latencyMs) == OK) {
769         result.appendFormat("  latency: %.2lf ms", latencyMs);
770     }
771     return result;
772 }
773 
774 /* Disconnect a patch */
releaseAudioPatch_l(audio_patch_handle_t handle)775 status_t PatchPanel::releaseAudioPatch_l(audio_patch_handle_t handle)
776  //unlocks AudioFlinger::mLock when calling IAfThreadBase::sendReleaseAudioPatchConfigEvent
777  //to avoid deadlocks if the thread loop needs to acquire AudioFlinger::mLock
778  //before processing the release patch request.
779  NO_THREAD_SAFETY_ANALYSIS
780  {
781     ALOGV("%s handle %d", __func__, handle);
782     status_t status = NO_ERROR;
783     bool doReleasePatch = true;
784 
785     auto iter = mPatches.find(handle);
786     if (iter == mPatches.end()) {
787         return BAD_VALUE;
788     }
789     Patch &removedPatch = iter->second;
790     const bool isSwBridge = removedPatch.isSoftware();
791     const struct audio_patch &patch = removedPatch.mAudioPatch;
792 
793     const struct audio_port_config &src = patch.sources[0];
794     switch (src.type) {
795         case AUDIO_PORT_TYPE_DEVICE: {
796             sp<DeviceHalInterface> hwDevice = findHwDeviceByModule_l(src.ext.device.hw_module);
797             if (hwDevice == 0) {
798                 ALOGW("%s() bad src hw module %d", __func__, src.ext.device.hw_module);
799                 status = BAD_VALUE;
800                 break;
801             }
802 
803             if (removedPatch.isSoftware()) {
804                 removedPatch.clearConnections_l(this);
805                 break;
806             }
807 
808             if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) {
809                 audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle;
810                 sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(ioHandle);
811                 if (thread == 0) {
812                     thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle);
813                     if (thread == 0) {
814                         ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle);
815                         status = BAD_VALUE;
816                         break;
817                     }
818                 }
819                 mAfPatchPanelCallback->mutex().unlock();
820                 status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
821                 mAfPatchPanelCallback->mutex().lock();
822             } else {
823                 status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
824             }
825         } break;
826         case AUDIO_PORT_TYPE_MIX: {
827             if (findHwDeviceByModule_l(src.ext.mix.hw_module) == 0) {
828                 ALOGW("%s() bad src hw module %d", __func__, src.ext.mix.hw_module);
829                 status = BAD_VALUE;
830                 break;
831             }
832             audio_io_handle_t ioHandle = src.ext.mix.handle;
833             sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(ioHandle);
834             if (thread == 0) {
835                 thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle);
836                 if (thread == 0) {
837                     ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle);
838                     status = BAD_VALUE;
839                     break;
840                 }
841             }
842             // Check whether the removed patch Hal Handle is used in another non-Endpoint patch.
843             // Since this is a non-Endpoint patch, the removed patch is not considered (it is
844             // removed later from mPatches).
845             if (removedPatch.mIsEndpointPatch) {
846                 for (auto& p: mPatches) {
847                     if (!p.second.mIsEndpointPatch
848                             && p.second.mHalHandle == removedPatch.mHalHandle) {
849                         ALOGV("%s() Sw Bridge endpoint used existing halHandle=%d, do not release",
850                               __func__,  p.second.mHalHandle);
851                         doReleasePatch = false;
852                         break;
853                     }
854                 }
855             }
856             if (doReleasePatch) {
857                 mAfPatchPanelCallback->mutex().unlock();
858                 status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
859                 mAfPatchPanelCallback->mutex().lock();
860             }
861         } break;
862         default:
863             status = BAD_VALUE;
864     }
865 
866     erasePatch(handle, /* reuseExistingHalPatch= */ !doReleasePatch || isSwBridge);
867     return status;
868 }
869 
erasePatch(audio_patch_handle_t handle,bool reuseExistingHalPatch)870 void PatchPanel::erasePatch(audio_patch_handle_t handle, bool reuseExistingHalPatch) {
871     mPatches.erase(handle);
872     removeSoftwarePatchFromInsertedModules(handle);
873     if (!reuseExistingHalPatch) {
874         mAfPatchPanelCallback->getPatchCommandThread()->releaseAudioPatch(handle);
875     }
876 }
877 
878 /* List connected audio ports and they attributes */
listAudioPatches_l(unsigned int *,struct audio_patch * patches __unused)879 status_t PatchPanel::listAudioPatches_l(unsigned int* /* num_patches */,
880                                   struct audio_patch *patches __unused)
881 {
882     ALOGV(__func__);
883     return NO_ERROR;
884 }
885 
getDownstreamSoftwarePatches(audio_io_handle_t stream,std::vector<SoftwarePatch> * patches) const886 status_t PatchPanel::getDownstreamSoftwarePatches(
887         audio_io_handle_t stream,
888         std::vector<SoftwarePatch>* patches) const
889 {
890     for (const auto& module : mInsertedModules) {
891         if (module.second.streams.count(stream)) {
892             for (const auto& patchHandle : module.second.sw_patches) {
893                 const auto& patch_iter = mPatches.find(patchHandle);
894                 if (patch_iter != mPatches.end()) {
895                     const Patch &patch = patch_iter->second;
896                     patches->emplace_back(sp<const IAfPatchPanel>::fromExisting(this),
897                             patchHandle,
898                             patch.mPlayback.const_thread()->id(),
899                             patch.mRecord.const_thread()->id());
900                 } else {
901                     ALOGE("Stale patch handle in the cache: %d", patchHandle);
902                 }
903             }
904             return OK;
905         }
906     }
907     // The stream is not associated with any of inserted modules.
908     return BAD_VALUE;
909 }
910 
notifyStreamOpened(AudioHwDevice * audioHwDevice,audio_io_handle_t stream,struct audio_patch * patch)911 void PatchPanel::notifyStreamOpened(
912         AudioHwDevice *audioHwDevice, audio_io_handle_t stream, struct audio_patch *patch)
913 {
914     if (audioHwDevice->isInsert()) {
915         mInsertedModules[audioHwDevice->handle()].streams.insert(stream);
916         if (patch != nullptr) {
917             std::vector <SoftwarePatch> swPatches;
918             getDownstreamSoftwarePatches(stream, &swPatches);
919             if (swPatches.size() > 0) {
920                 auto iter = mPatches.find(swPatches[0].getPatchHandle());
921                 if (iter != mPatches.end()) {
922                     *patch = iter->second.mAudioPatch;
923                 }
924             }
925         }
926     }
927 }
928 
notifyStreamClosed(audio_io_handle_t stream)929 void PatchPanel::notifyStreamClosed(audio_io_handle_t stream)
930 {
931     for (auto& module : mInsertedModules) {
932         module.second.streams.erase(stream);
933     }
934 }
935 
findAudioHwDeviceByModule_l(audio_module_handle_t module)936 AudioHwDevice* PatchPanel::findAudioHwDeviceByModule_l(audio_module_handle_t module)
937 {
938     if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr;
939     ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(module);
940     if (index < 0) {
941         ALOGW("%s() bad hw module %d", __func__, module);
942         return nullptr;
943     }
944     return mAfPatchPanelCallback->getAudioHwDevs_l().valueAt(index);
945 }
946 
findHwDeviceByModule_l(audio_module_handle_t module)947 sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule_l(audio_module_handle_t module)
948 {
949     AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule_l(module);
950     return audioHwDevice ? audioHwDevice->hwDevice() : nullptr;
951 }
952 
addSoftwarePatchToInsertedModules_l(audio_module_handle_t module,audio_patch_handle_t handle,const struct audio_patch * patch)953 void PatchPanel::addSoftwarePatchToInsertedModules_l(
954         audio_module_handle_t module, audio_patch_handle_t handle,
955         const struct audio_patch *patch)
956 {
957     mInsertedModules[module].sw_patches.insert(handle);
958     if (!mInsertedModules[module].streams.empty()) {
959         mAfPatchPanelCallback->updateDownStreamPatches_l(patch, mInsertedModules[module].streams);
960     }
961 }
962 
removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle)963 void PatchPanel::removeSoftwarePatchFromInsertedModules(
964         audio_patch_handle_t handle)
965 {
966     for (auto& module : mInsertedModules) {
967         module.second.sw_patches.erase(handle);
968     }
969 }
970 
dump(int fd) const971 void PatchPanel::dump(int fd) const
972 {
973     String8 patchPanelDump;
974     const char *indent = "  ";
975 
976     bool headerPrinted = false;
977     for (const auto& iter : mPatches) {
978         if (!headerPrinted) {
979             patchPanelDump += "\nPatches:\n";
980             headerPrinted = true;
981         }
982         patchPanelDump.appendFormat("%s%s\n", indent, iter.second.dump(iter.first).c_str());
983     }
984 
985     headerPrinted = false;
986     for (const auto& module : mInsertedModules) {
987         if (!module.second.streams.empty() || !module.second.sw_patches.empty()) {
988             if (!headerPrinted) {
989                 patchPanelDump += "\nTracked inserted modules:\n";
990                 headerPrinted = true;
991             }
992             String8 moduleDump = String8::format("Module %d: I/O handles: ", module.first);
993             for (const auto& stream : module.second.streams) {
994                 moduleDump.appendFormat("%d ", stream);
995             }
996             moduleDump.append("; SW Patches: ");
997             for (const auto& patch : module.second.sw_patches) {
998                 moduleDump.appendFormat("%d ", patch);
999             }
1000             patchPanelDump.appendFormat("%s%s\n", indent, moduleDump.c_str());
1001         }
1002     }
1003 
1004     if (!patchPanelDump.empty()) {
1005         write(fd, patchPanelDump.c_str(), patchPanelDump.size());
1006     }
1007 }
1008 
1009 } // namespace android
1010