• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                     const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openOutput_l(
264                                                             patch->sinks[0].ext.device.hw_module,
265                                                             &output,
266                                                             &config,
267                                                             &mixerConfig,
268                                                             outputDevice,
269                                                             outputDeviceAddress,
270                                                             flags);
271                     ALOGV("mAfPatchPanelCallback->openOutput_l() returned %p", thread.get());
272                     if (thread == 0) {
273                         status = NO_MEMORY;
274                         goto exit;
275                     }
276                     newPatch.mPlayback.setThread(thread->asIAfPlaybackThread().get());
277                 }
278                 audio_devices_t device = patch->sources[0].ext.device.type;
279                 String8 address = String8(patch->sources[0].ext.device.address);
280                 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
281                 // open input stream with source device audio properties if provided or
282                 // default to peer output stream properties otherwise.
283                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
284                     config.sample_rate = patch->sources[0].sample_rate;
285                 } else {
286                     config.sample_rate = newPatch.mPlayback.thread()->sampleRate();
287                 }
288                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
289                     config.channel_mask = patch->sources[0].channel_mask;
290                 } else {
291                     config.channel_mask = audio_channel_in_mask_from_count(
292                             newPatch.mPlayback.thread()->channelCount());
293                 }
294                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
295                     config.format = patch->sources[0].format;
296                 } else {
297                     config.format = newPatch.mPlayback.thread()->format();
298                 }
299                 audio_input_flags_t flags =
300                         patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
301                         patch->sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
302                 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
303                 audio_source_t source = AUDIO_SOURCE_MIC;
304                 // For telephony patches, propagate voice communication use case to record side
305                 if (patch->num_sources == 2
306                         && patch->sources[1].ext.mix.usecase.stream
307                                 == AUDIO_STREAM_VOICE_CALL) {
308                     source = AUDIO_SOURCE_VOICE_COMMUNICATION;
309                 }
310                 const sp<IAfThreadBase> thread = mAfPatchPanelCallback->openInput_l(srcModule,
311                                                                     &input,
312                                                                     &config,
313                                                                     device,
314                                                                     address,
315                                                                     source,
316                                                                     flags,
317                                                                     outputDevice,
318                                                                     outputDeviceAddress);
319                 ALOGV("mAfPatchPanelCallback->openInput_l() returned %p inChannelMask %08x",
320                       thread.get(), config.channel_mask);
321                 if (thread == 0) {
322                     status = NO_MEMORY;
323                     goto exit;
324                 }
325                 newPatch.mRecord.setThread(thread->asIAfRecordThread().get());
326                 status = newPatch.createConnections_l(this);
327                 if (status != NO_ERROR) {
328                     goto exit;
329                 }
330                 if (audioHwDevice->isInsert()) {
331                     insertedModule = audioHwDevice->handle();
332                 }
333             } else {
334                 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
335                     sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(
336                                                               patch->sinks[0].ext.mix.handle);
337                     if (thread == 0) {
338                         thread = mAfPatchPanelCallback->checkMmapThread_l(
339                                 patch->sinks[0].ext.mix.handle);
340                         if (thread == 0) {
341                             ALOGW("%s() bad capture I/O handle %d",
342                                     __func__, patch->sinks[0].ext.mix.handle);
343                             status = BAD_VALUE;
344                             goto exit;
345                         }
346                     }
347                     mAfPatchPanelCallback->mutex().unlock();
348                     status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
349                     mAfPatchPanelCallback->mutex().lock();
350                     if (status == NO_ERROR) {
351                         newPatch.setThread(thread);
352                     }
353                     // remove stale audio patch with same input as sink if any
354                     for (auto& iter : mPatches) {
355                         if (iter.second.mAudioPatch.sinks[0].ext.mix.handle == thread->id()) {
356                             erasePatch(iter.first);
357                             break;
358                         }
359                     }
360                 } else {
361                     sp<DeviceHalInterface> hwDevice = audioHwDevice->hwDevice();
362                     status = hwDevice->createAudioPatch(patch->num_sources,
363                                                         patch->sources,
364                                                         patch->num_sinks,
365                                                         patch->sinks,
366                                                         &halHandle);
367                     if (status == INVALID_OPERATION) goto exit;
368                 }
369             }
370         } break;
371         case AUDIO_PORT_TYPE_MIX: {
372             audio_module_handle_t srcModule =  patch->sources[0].ext.mix.hw_module;
373             ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(srcModule);
374             if (index < 0) {
375                 ALOGW("%s() bad src hw module %d", __func__, srcModule);
376                 status = BAD_VALUE;
377                 goto exit;
378             }
379             // limit to connections between devices and output streams
380             DeviceDescriptorBaseVector devices;
381             for (unsigned int i = 0; i < patch->num_sinks; i++) {
382                 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
383                     ALOGW("%s() invalid sink type %d for mix source",
384                             __func__, patch->sinks[i].type);
385                     status = BAD_VALUE;
386                     goto exit;
387                 }
388                 // limit to connections between sinks and sources on same HW module
389                 if (patch->sinks[i].ext.device.hw_module != srcModule) {
390                     status = BAD_VALUE;
391                     goto exit;
392                 }
393                 sp<DeviceDescriptorBase> device = new DeviceDescriptorBase(
394                         patch->sinks[i].ext.device.type);
395                 device->setAddress(patch->sinks[i].ext.device.address);
396                 device->applyAudioPortConfig(&patch->sinks[i]);
397                 devices.push_back(device);
398             }
399             sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(
400                     patch->sources[0].ext.mix.handle);
401             if (thread == 0) {
402                 thread = mAfPatchPanelCallback->checkMmapThread_l(
403                         patch->sources[0].ext.mix.handle);
404                 if (thread == 0) {
405                     ALOGW("%s() bad playback I/O handle %d",
406                             __func__, patch->sources[0].ext.mix.handle);
407                     status = BAD_VALUE;
408                     goto exit;
409                 }
410             }
411             if (thread == mAfPatchPanelCallback->primaryPlaybackThread_l()) {
412                 mAfPatchPanelCallback->updateOutDevicesForRecordThreads_l(devices);
413             }
414 
415             // For endpoint patches, we do not need to re-evaluate the device effect state
416             // if the same HAL patch is reused (see calls to mAfPatchPanelCallback below)
417             if (endpointPatch) {
418                 for (auto& p : mPatches) {
419                     // end point patches are skipped so we do not compare against this patch
420                     if (!p.second.mIsEndpointPatch && patchesHaveSameRoute(
421                             newPatch.mAudioPatch, p.second.mAudioPatch)) {
422                         ALOGV("%s() Sw Bridge endpoint reusing halHandle=%d", __func__,
423                               p.second.mHalHandle);
424                         halHandle = p.second.mHalHandle;
425                         reuseExistingHalPatch = true;
426                         break;
427                     }
428                 }
429             }
430             mAfPatchPanelCallback->mutex().unlock();
431 
432             status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
433             mAfPatchPanelCallback->mutex().lock();
434             if (status == NO_ERROR) {
435                 newPatch.setThread(thread);
436             }
437 
438             // remove stale audio patch with same output as source if any
439             // Prevent to remove endpoint patches (involved in a SwBridge)
440             // Prevent to remove AudioPatch used to route an output involved in an endpoint.
441             if (!endpointPatch) {
442                 for (auto& iter : mPatches) {
443                     if (iter.second.mAudioPatch.sources[0].ext.mix.handle == thread->id() &&
444                             !iter.second.mIsEndpointPatch) {
445                         erasePatch(iter.first);
446                         break;
447                     }
448                 }
449             }
450         } break;
451         default:
452             status = BAD_VALUE;
453             goto exit;
454     }
455 exit:
456     ALOGV("%s() status %d", __func__, status);
457     if (status == NO_ERROR) {
458         *handle = static_cast<audio_patch_handle_t>(
459                 mAfPatchPanelCallback->nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH));
460         newPatch.mHalHandle = halHandle;
461         // Skip device effect:
462         //  -for sw bridge as effect are likely held by endpoint patches
463         //  -for endpoint reusing a HalPatch handle
464         if (!(newPatch.isSoftware()
465                 || (endpointPatch && reuseExistingHalPatch))) {
466             if (reuseExistingHalPatch) {
467                 mAfPatchPanelCallback->getPatchCommandThread()->updateAudioPatch(
468                         oldhandle, *handle, newPatch);
469             } else {
470                  mAfPatchPanelCallback->getPatchCommandThread()->createAudioPatch(
471                         *handle, newPatch);
472             }
473         }
474         if (insertedModule != AUDIO_MODULE_HANDLE_NONE) {
475             addSoftwarePatchToInsertedModules_l(insertedModule, *handle, &newPatch.mAudioPatch);
476         }
477         mPatches.insert(std::make_pair(*handle, std::move(newPatch)));
478     } else {
479         newPatch.clearConnections_l(this);
480     }
481     return status;
482 }
483 
getAudioMixPort_l(const audio_port_v7 * devicePort,audio_port_v7 * mixPort)484 status_t PatchPanel::getAudioMixPort_l(const audio_port_v7 *devicePort,
485                                        audio_port_v7 *mixPort) {
486     if (devicePort->type != AUDIO_PORT_TYPE_DEVICE) {
487         ALOGE("%s the type of given device port is not DEVICE", __func__);
488         return INVALID_OPERATION;
489     }
490     if (mixPort->type != AUDIO_PORT_TYPE_MIX) {
491         ALOGE("%s the type of given mix port is not MIX", __func__);
492         return INVALID_OPERATION;
493     }
494     AudioHwDevice* hwDevice = findAudioHwDeviceByModule_l(devicePort->ext.device.hw_module);
495     if (hwDevice == nullptr) {
496         ALOGW("%s cannot find hw module %d", __func__, devicePort->ext.device.hw_module);
497         return BAD_VALUE;
498     }
499     return hwDevice->getAudioMixPort(devicePort, mixPort);
500 }
501 
~Patch()502 PatchPanel::Patch::~Patch()
503 {
504     ALOGE_IF(isSoftware(), "Software patch connections leaked %d %d",
505             mRecord.handle(), mPlayback.handle());
506 }
507 
createConnections_l(const sp<IAfPatchPanel> & panel)508 status_t PatchPanel::Patch::createConnections_l(const sp<IAfPatchPanel>& panel)
509 {
510     // create patch from source device to record thread input
511     status_t status = panel->createAudioPatch_l(
512             PatchBuilder().addSource(mAudioPatch.sources[0]).
513                 addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(),
514             mRecord.handlePtr(),
515             true /*endpointPatch*/);
516     if (status != NO_ERROR) {
517         *mRecord.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
518         return status;
519     }
520 
521     // create patch from playback thread output to sink device
522     if (mAudioPatch.num_sinks != 0) {
523         status = panel->createAudioPatch_l(
524                 PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(),
525                 mPlayback.handlePtr(),
526                 true /*endpointPatch*/);
527         if (status != NO_ERROR) {
528             *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
529             return status;
530         }
531     } else {
532         *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
533     }
534 
535     // create a special record track to capture from record thread
536     uint32_t channelCount = mPlayback.thread()->channelCount();
537     audio_channel_mask_t inChannelMask = audio_channel_in_mask_from_count(channelCount);
538     audio_channel_mask_t outChannelMask = mPlayback.thread()->channelMask();
539     uint32_t sampleRate = mPlayback.thread()->sampleRate();
540     audio_format_t format = mPlayback.thread()->format();
541 
542     audio_format_t inputFormat = mRecord.thread()->format();
543     if (!audio_is_linear_pcm(inputFormat)) {
544         // The playbackThread format will say PCM for IEC61937 packetized stream.
545         // Use recordThread format.
546         format = inputFormat;
547     }
548     audio_input_flags_t inputFlags = mAudioPatch.sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
549             mAudioPatch.sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
550     if (sampleRate == mRecord.thread()->sampleRate() &&
551             inChannelMask == mRecord.thread()->channelMask() &&
552             mRecord.thread()->fastTrackAvailable() &&
553             mRecord.thread()->hasFastCapture()) {
554         // Create a fast track if the record thread has fast capture to get better performance.
555         // Only enable fast mode when there is no resample needed.
556         inputFlags = (audio_input_flags_t) (inputFlags | AUDIO_INPUT_FLAG_FAST);
557     } else {
558         // Fast mode is not available in this case.
559         inputFlags = (audio_input_flags_t) (inputFlags & ~AUDIO_INPUT_FLAG_FAST);
560     }
561 
562     audio_output_flags_t outputFlags = mAudioPatch.sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
563             mAudioPatch.sinks[0].flags.output : AUDIO_OUTPUT_FLAG_NONE;
564     audio_stream_type_t streamType = AUDIO_STREAM_PATCH;
565     audio_source_t source = AUDIO_SOURCE_DEFAULT;
566     if (mAudioPatch.num_sources == 2 && mAudioPatch.sources[1].type == AUDIO_PORT_TYPE_MIX) {
567         // "reuse one existing output mix" case
568         streamType = mAudioPatch.sources[1].ext.mix.usecase.stream;
569         // For telephony patches, propagate voice communication use case to record side
570         if (streamType == AUDIO_STREAM_VOICE_CALL) {
571             source = AUDIO_SOURCE_VOICE_COMMUNICATION;
572         }
573     }
574     if (mPlayback.thread()->hasFastMixer()) {
575         // Create a fast track if the playback thread has fast mixer to get better performance.
576         // Note: we should have matching channel mask, sample rate, and format by the logic above.
577         outputFlags = (audio_output_flags_t) (outputFlags | AUDIO_OUTPUT_FLAG_FAST);
578     } else {
579         outputFlags = (audio_output_flags_t) (outputFlags & ~AUDIO_OUTPUT_FLAG_FAST);
580     }
581 
582     sp<IAfPatchRecord> tempRecordTrack;
583     const bool usePassthruPatchRecord =
584             (inputFlags & AUDIO_INPUT_FLAG_DIRECT) && (outputFlags & AUDIO_OUTPUT_FLAG_DIRECT);
585     const size_t playbackFrameCount = mPlayback.thread()->frameCount();
586     const size_t recordFrameCount = mRecord.thread()->frameCount();
587     size_t frameCount = 0;
588     if (usePassthruPatchRecord) {
589         // PassthruPatchRecord producesBufferOnDemand, so use
590         // maximum of playback and record thread framecounts
591         frameCount = std::max(playbackFrameCount, recordFrameCount);
592         ALOGV("%s() playframeCount %zu recordFrameCount %zu frameCount %zu",
593             __func__, playbackFrameCount, recordFrameCount, frameCount);
594         tempRecordTrack = IAfPatchRecord::createPassThru(
595                                                  mRecord.thread().get(),
596                                                  sampleRate,
597                                                  inChannelMask,
598                                                  format,
599                                                  frameCount,
600                                                  inputFlags,
601                                                  source);
602     } else {
603         // use a pseudo LCM between input and output framecount
604         int playbackShift = __builtin_ctz(playbackFrameCount);
605         int shift = __builtin_ctz(recordFrameCount);
606         if (playbackShift < shift) {
607             shift = playbackShift;
608         }
609         frameCount = (playbackFrameCount * recordFrameCount) >> shift;
610         ALOGV("%s() playframeCount %zu recordFrameCount %zu frameCount %zu",
611             __func__, playbackFrameCount, recordFrameCount, frameCount);
612 
613         tempRecordTrack = IAfPatchRecord::create(
614                                                  mRecord.thread().get(),
615                                                  sampleRate,
616                                                  inChannelMask,
617                                                  format,
618                                                  frameCount,
619                                                  nullptr,
620                                                  (size_t)0 /* bufferSize */,
621                                                  inputFlags,
622                                                  {} /* timeout */,
623                                                  source);
624     }
625     status = mRecord.checkTrack(tempRecordTrack.get());
626     if (status != NO_ERROR) {
627         return status;
628     }
629 
630     // create a special playback track to render to playback thread.
631     // this track is given the same buffer as the PatchRecord buffer
632 
633     // Default behaviour is to start as soon as possible to have the lowest possible latency even if
634     // it might glitch.
635     // Disable this behavior for FM Tuner source if no fast capture/mixer available.
636     const bool isFmBridge = mAudioPatch.sources[0].ext.device.type == AUDIO_DEVICE_IN_FM_TUNER;
637     const size_t frameCountToBeReady = isFmBridge && !usePassthruPatchRecord ? frameCount / 4 : 1;
638     sp<IAfPatchTrack> tempPatchTrack = IAfPatchTrack::create(
639                                            mPlayback.thread().get(),
640                                            streamType,
641                                            sampleRate,
642                                            outChannelMask,
643                                            format,
644                                            frameCount,
645                                            tempRecordTrack->buffer(),
646                                            tempRecordTrack->bufferSize(),
647                                            outputFlags,
648                                            {} /*timeout*/,
649                                            frameCountToBeReady,
650                                            1.0f);
651     status = mPlayback.checkTrack(tempPatchTrack.get());
652     if (status != NO_ERROR) {
653         return status;
654     }
655 
656     // tie playback and record tracks together
657     // In the case of PassthruPatchRecord no I/O activity happens on RecordThread,
658     // everything is driven from PlaybackThread. Thus AudioBufferProvider methods
659     // of PassthruPatchRecord can only be called if the corresponding PatchTrack
660     // is alive. There is no need to hold a reference, and there is no need
661     // to clear it. In fact, since playback stopping is asynchronous, there is
662     // no proper time when clearing could be done.
663     mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack, !usePassthruPatchRecord);
664     mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack, true /*holdReference*/);
665 
666     // start capture and playback
667     mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
668     mPlayback.track()->start();
669 
670     return status;
671 }
672 
clearConnections_l(const sp<IAfPatchPanel> & panel)673 void PatchPanel::Patch::clearConnections_l(const sp<IAfPatchPanel>& panel)
674 {
675     ALOGV("%s() mRecord.handle %d mPlayback.handle %d",
676             __func__, mRecord.handle(), mPlayback.handle());
677     mRecord.stopTrack();
678     mPlayback.stopTrack();
679     mRecord.clearTrackPeer(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle.
680     mRecord.closeConnections_l(panel);
681     mPlayback.closeConnections_l(panel);
682 }
683 
getLatencyMs(double * latencyMs) const684 status_t PatchPanel::Patch::getLatencyMs(double* latencyMs) const
685 {
686     if (!isSoftware()) return INVALID_OPERATION;
687 
688     auto recordTrack = mRecord.const_track();
689     if (recordTrack.get() == nullptr) return INVALID_OPERATION;
690 
691     auto playbackTrack = mPlayback.const_track();
692     if (playbackTrack.get() == nullptr) return INVALID_OPERATION;
693 
694     // Latency information for tracks may be called without obtaining
695     // the underlying thread lock.
696     //
697     // We use record server latency + playback track latency (generally smaller than the
698     // reverse due to internal biases).
699     //
700     // TODO: is this stable enough? Consider a PatchTrack synchronized version of this.
701 
702     // For PCM tracks get server latency.
703     if (audio_is_linear_pcm(recordTrack->format())) {
704         double recordServerLatencyMs, playbackTrackLatencyMs;
705         if (recordTrack->getServerLatencyMs(&recordServerLatencyMs) == OK
706                 && playbackTrack->getTrackLatencyMs(&playbackTrackLatencyMs) == OK) {
707             *latencyMs = recordServerLatencyMs + playbackTrackLatencyMs;
708             return OK;
709         }
710     }
711 
712     // See if kernel latencies are available.
713     // If so, do a frame diff and time difference computation to estimate
714     // the total patch latency. This requires that frame counts are reported by the
715     // HAL are matched properly in the case of record overruns and playback underruns.
716     IAfTrack::FrameTime recordFT{}, playFT{};
717     recordTrack->getKernelFrameTime(&recordFT);
718     playbackTrack->getKernelFrameTime(&playFT);
719     if (recordFT.timeNs > 0 && playFT.timeNs > 0) {
720         const int64_t frameDiff = recordFT.frames - playFT.frames;
721         const int64_t timeDiffNs = recordFT.timeNs - playFT.timeNs;
722 
723         // It is possible that the patch track and patch record have a large time disparity because
724         // one thread runs but another is stopped.  We arbitrarily choose the maximum timestamp
725         // time difference based on how often we expect the timestamps to update in normal operation
726         // (typical should be no more than 50 ms).
727         //
728         // If the timestamps aren't sampled close enough, the patch latency is not
729         // considered valid.
730         //
731         // TODO: change this based on more experiments.
732         constexpr int64_t maxValidTimeDiffNs = 200 * NANOS_PER_MILLISECOND;
733         if (std::abs(timeDiffNs) < maxValidTimeDiffNs) {
734             *latencyMs = frameDiff * 1e3 / recordTrack->sampleRate()
735                    - timeDiffNs * 1e-6;
736             return OK;
737         }
738     }
739 
740     return INVALID_OPERATION;
741 }
742 
dump(audio_patch_handle_t myHandle) const743 String8 PatchPanel::Patch::dump(audio_patch_handle_t myHandle) const
744 {
745     // TODO: Consider table dump form for patches, just like tracks.
746     String8 result = String8::format("Patch %d: %s (thread %p => thread %p)",
747             myHandle, isSoftware() ? "Software bridge between" : "No software bridge",
748             mRecord.const_thread().get(), mPlayback.const_thread().get());
749 
750     bool hasSinkDevice =
751             mAudioPatch.num_sinks > 0 && mAudioPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE;
752     bool hasSourceDevice =
753             mAudioPatch.num_sources > 0 && mAudioPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE;
754     result.appendFormat(" thread %p %s (%d) first device type %08x", mThread.unsafe_get(),
755             hasSinkDevice ? "num sinks" :
756                 (hasSourceDevice ? "num sources" : "no devices"),
757             hasSinkDevice ? mAudioPatch.num_sinks :
758                 (hasSourceDevice ? mAudioPatch.num_sources : 0),
759             hasSinkDevice ? mAudioPatch.sinks[0].ext.device.type :
760                 (hasSourceDevice ? mAudioPatch.sources[0].ext.device.type : 0));
761 
762     // add latency if it exists
763     double latencyMs;
764     if (getLatencyMs(&latencyMs) == OK) {
765         result.appendFormat("  latency: %.2lf ms", latencyMs);
766     }
767     return result;
768 }
769 
770 /* Disconnect a patch */
releaseAudioPatch_l(audio_patch_handle_t handle)771 status_t PatchPanel::releaseAudioPatch_l(audio_patch_handle_t handle)
772  //unlocks AudioFlinger::mLock when calling IAfThreadBase::sendReleaseAudioPatchConfigEvent
773  //to avoid deadlocks if the thread loop needs to acquire AudioFlinger::mLock
774  //before processing the release patch request.
775  NO_THREAD_SAFETY_ANALYSIS
776  {
777     ALOGV("%s handle %d", __func__, handle);
778     status_t status = NO_ERROR;
779     bool doReleasePatch = true;
780 
781     auto iter = mPatches.find(handle);
782     if (iter == mPatches.end()) {
783         return BAD_VALUE;
784     }
785     Patch &removedPatch = iter->second;
786     const bool isSwBridge = removedPatch.isSoftware();
787     const struct audio_patch &patch = removedPatch.mAudioPatch;
788 
789     const struct audio_port_config &src = patch.sources[0];
790     switch (src.type) {
791         case AUDIO_PORT_TYPE_DEVICE: {
792             sp<DeviceHalInterface> hwDevice = findHwDeviceByModule_l(src.ext.device.hw_module);
793             if (hwDevice == 0) {
794                 ALOGW("%s() bad src hw module %d", __func__, src.ext.device.hw_module);
795                 status = BAD_VALUE;
796                 break;
797             }
798 
799             if (removedPatch.isSoftware()) {
800                 removedPatch.clearConnections_l(this);
801                 break;
802             }
803 
804             if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) {
805                 audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle;
806                 sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkRecordThread_l(ioHandle);
807                 if (thread == 0) {
808                     thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle);
809                     if (thread == 0) {
810                         ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle);
811                         status = BAD_VALUE;
812                         break;
813                     }
814                 }
815                 mAfPatchPanelCallback->mutex().unlock();
816                 status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
817                 mAfPatchPanelCallback->mutex().lock();
818             } else {
819                 status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
820             }
821         } break;
822         case AUDIO_PORT_TYPE_MIX: {
823             if (findHwDeviceByModule_l(src.ext.mix.hw_module) == 0) {
824                 ALOGW("%s() bad src hw module %d", __func__, src.ext.mix.hw_module);
825                 status = BAD_VALUE;
826                 break;
827             }
828             audio_io_handle_t ioHandle = src.ext.mix.handle;
829             sp<IAfThreadBase> thread = mAfPatchPanelCallback->checkPlaybackThread_l(ioHandle);
830             if (thread == 0) {
831                 thread = mAfPatchPanelCallback->checkMmapThread_l(ioHandle);
832                 if (thread == 0) {
833                     ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle);
834                     status = BAD_VALUE;
835                     break;
836                 }
837             }
838             // Check whether the removed patch Hal Handle is used in another non-Endpoint patch.
839             // Since this is a non-Endpoint patch, the removed patch is not considered (it is
840             // removed later from mPatches).
841             if (removedPatch.mIsEndpointPatch) {
842                 for (auto& p: mPatches) {
843                     if (!p.second.mIsEndpointPatch
844                             && p.second.mHalHandle == removedPatch.mHalHandle) {
845                         ALOGV("%s() Sw Bridge endpoint used existing halHandle=%d, do not release",
846                               __func__,  p.second.mHalHandle);
847                         doReleasePatch = false;
848                         break;
849                     }
850                 }
851             }
852             if (doReleasePatch) {
853                 mAfPatchPanelCallback->mutex().unlock();
854                 status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
855                 mAfPatchPanelCallback->mutex().lock();
856             }
857         } break;
858         default:
859             status = BAD_VALUE;
860     }
861 
862     erasePatch(handle, /* reuseExistingHalPatch= */ !doReleasePatch || isSwBridge);
863     return status;
864 }
865 
erasePatch(audio_patch_handle_t handle,bool reuseExistingHalPatch)866 void PatchPanel::erasePatch(audio_patch_handle_t handle, bool reuseExistingHalPatch) {
867     mPatches.erase(handle);
868     removeSoftwarePatchFromInsertedModules(handle);
869     if (!reuseExistingHalPatch) {
870         mAfPatchPanelCallback->getPatchCommandThread()->releaseAudioPatch(handle);
871     }
872 }
873 
874 /* List connected audio ports and they attributes */
listAudioPatches_l(unsigned int *,struct audio_patch * patches __unused)875 status_t PatchPanel::listAudioPatches_l(unsigned int* /* num_patches */,
876                                   struct audio_patch *patches __unused)
877 {
878     ALOGV(__func__);
879     return NO_ERROR;
880 }
881 
getDownstreamSoftwarePatches(audio_io_handle_t stream,std::vector<SoftwarePatch> * patches) const882 status_t PatchPanel::getDownstreamSoftwarePatches(
883         audio_io_handle_t stream,
884         std::vector<SoftwarePatch>* patches) const
885 {
886     for (const auto& module : mInsertedModules) {
887         if (module.second.streams.count(stream)) {
888             for (const auto& patchHandle : module.second.sw_patches) {
889                 const auto& patch_iter = mPatches.find(patchHandle);
890                 if (patch_iter != mPatches.end()) {
891                     const Patch &patch = patch_iter->second;
892                     patches->emplace_back(sp<const IAfPatchPanel>::fromExisting(this),
893                             patchHandle,
894                             patch.mPlayback.const_thread()->id(),
895                             patch.mRecord.const_thread()->id());
896                 } else {
897                     ALOGE("Stale patch handle in the cache: %d", patchHandle);
898                 }
899             }
900             return OK;
901         }
902     }
903     // The stream is not associated with any of inserted modules.
904     return BAD_VALUE;
905 }
906 
notifyStreamOpened(AudioHwDevice * audioHwDevice,audio_io_handle_t stream,struct audio_patch * patch)907 void PatchPanel::notifyStreamOpened(
908         AudioHwDevice *audioHwDevice, audio_io_handle_t stream, struct audio_patch *patch)
909 {
910     if (audioHwDevice->isInsert()) {
911         mInsertedModules[audioHwDevice->handle()].streams.insert(stream);
912         if (patch != nullptr) {
913             std::vector <SoftwarePatch> swPatches;
914             getDownstreamSoftwarePatches(stream, &swPatches);
915             if (swPatches.size() > 0) {
916                 auto iter = mPatches.find(swPatches[0].getPatchHandle());
917                 if (iter != mPatches.end()) {
918                     *patch = iter->second.mAudioPatch;
919                 }
920             }
921         }
922     }
923 }
924 
notifyStreamClosed(audio_io_handle_t stream)925 void PatchPanel::notifyStreamClosed(audio_io_handle_t stream)
926 {
927     for (auto& module : mInsertedModules) {
928         module.second.streams.erase(stream);
929     }
930 }
931 
findAudioHwDeviceByModule_l(audio_module_handle_t module)932 AudioHwDevice* PatchPanel::findAudioHwDeviceByModule_l(audio_module_handle_t module)
933 {
934     if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr;
935     ssize_t index = mAfPatchPanelCallback->getAudioHwDevs_l().indexOfKey(module);
936     if (index < 0) {
937         ALOGW("%s() bad hw module %d", __func__, module);
938         return nullptr;
939     }
940     return mAfPatchPanelCallback->getAudioHwDevs_l().valueAt(index);
941 }
942 
findHwDeviceByModule_l(audio_module_handle_t module)943 sp<DeviceHalInterface> PatchPanel::findHwDeviceByModule_l(audio_module_handle_t module)
944 {
945     AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule_l(module);
946     return audioHwDevice ? audioHwDevice->hwDevice() : nullptr;
947 }
948 
addSoftwarePatchToInsertedModules_l(audio_module_handle_t module,audio_patch_handle_t handle,const struct audio_patch * patch)949 void PatchPanel::addSoftwarePatchToInsertedModules_l(
950         audio_module_handle_t module, audio_patch_handle_t handle,
951         const struct audio_patch *patch)
952 {
953     mInsertedModules[module].sw_patches.insert(handle);
954     if (!mInsertedModules[module].streams.empty()) {
955         mAfPatchPanelCallback->updateDownStreamPatches_l(patch, mInsertedModules[module].streams);
956     }
957 }
958 
removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle)959 void PatchPanel::removeSoftwarePatchFromInsertedModules(
960         audio_patch_handle_t handle)
961 {
962     for (auto& module : mInsertedModules) {
963         module.second.sw_patches.erase(handle);
964     }
965 }
966 
dump(int fd) const967 void PatchPanel::dump(int fd) const
968 {
969     String8 patchPanelDump;
970     const char *indent = "  ";
971 
972     bool headerPrinted = false;
973     for (const auto& iter : mPatches) {
974         if (!headerPrinted) {
975             patchPanelDump += "\nPatches:\n";
976             headerPrinted = true;
977         }
978         patchPanelDump.appendFormat("%s%s\n", indent, iter.second.dump(iter.first).c_str());
979     }
980 
981     headerPrinted = false;
982     for (const auto& module : mInsertedModules) {
983         if (!module.second.streams.empty() || !module.second.sw_patches.empty()) {
984             if (!headerPrinted) {
985                 patchPanelDump += "\nTracked inserted modules:\n";
986                 headerPrinted = true;
987             }
988             String8 moduleDump = String8::format("Module %d: I/O handles: ", module.first);
989             for (const auto& stream : module.second.streams) {
990                 moduleDump.appendFormat("%d ", stream);
991             }
992             moduleDump.append("; SW Patches: ");
993             for (const auto& patch : module.second.sw_patches) {
994                 moduleDump.appendFormat("%d ", patch);
995             }
996             patchPanelDump.appendFormat("%s%s\n", indent, moduleDump.c_str());
997         }
998     }
999 
1000     if (!patchPanelDump.empty()) {
1001         write(fd, patchPanelDump.c_str(), patchPanelDump.size());
1002     }
1003 }
1004 
1005 } // namespace android
1006