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 "Configuration.h"
23 #include <utils/Log.h>
24 #include <audio_utils/primitives.h>
25 
26 #include "AudioFlinger.h"
27 #include <media/AudioParameter.h>
28 #include <media/DeviceDescriptorBase.h>
29 #include <media/PatchBuilder.h>
30 #include <mediautils/ServiceUtilities.h>
31 
32 // ----------------------------------------------------------------------------
33 
34 // Note: the following macro is used for extremely verbose logging message.  In
35 // order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
36 // 0; but one side effect of this is to turn all LOGV's as well.  Some messages
37 // are so verbose that we want to suppress them even when we have ALOG_ASSERT
38 // turned on.  Do not uncomment the #def below unless you really know what you
39 // are doing and want to see all of the extremely verbose messages.
40 //#define VERY_VERY_VERBOSE_LOGGING
41 #ifdef VERY_VERY_VERBOSE_LOGGING
42 #define ALOGVV ALOGV
43 #else
44 #define ALOGVV(a...) do { } while(0)
45 #endif
46 
47 namespace android {
48 
49 /* List connected audio ports and their attributes */
listAudioPorts(unsigned int * num_ports,struct audio_port * ports)50 status_t AudioFlinger::listAudioPorts(unsigned int *num_ports,
51                                 struct audio_port *ports)
52 {
53     Mutex::Autolock _l(mLock);
54     return mPatchPanel.listAudioPorts(num_ports, ports);
55 }
56 
57 /* Get supported attributes for a given audio port */
getAudioPort(struct audio_port * port)58 status_t AudioFlinger::getAudioPort(struct audio_port *port)
59 {
60     Mutex::Autolock _l(mLock);
61     return mPatchPanel.getAudioPort(port);
62 }
63 
64 /* Connect a patch between several source and sink ports */
createAudioPatch(const struct audio_patch * patch,audio_patch_handle_t * handle)65 status_t AudioFlinger::createAudioPatch(const struct audio_patch *patch,
66                                    audio_patch_handle_t *handle)
67 {
68     Mutex::Autolock _l(mLock);
69     return mPatchPanel.createAudioPatch(patch, handle);
70 }
71 
72 /* Disconnect a patch */
releaseAudioPatch(audio_patch_handle_t handle)73 status_t AudioFlinger::releaseAudioPatch(audio_patch_handle_t handle)
74 {
75     Mutex::Autolock _l(mLock);
76     return mPatchPanel.releaseAudioPatch(handle);
77 }
78 
79 /* List connected audio ports and they attributes */
listAudioPatches(unsigned int * num_patches,struct audio_patch * patches)80 status_t AudioFlinger::listAudioPatches(unsigned int *num_patches,
81                                   struct audio_patch *patches)
82 {
83     Mutex::Autolock _l(mLock);
84     return mPatchPanel.listAudioPatches(num_patches, patches);
85 }
86 
getLatencyMs_l(double * latencyMs) const87 status_t AudioFlinger::PatchPanel::SoftwarePatch::getLatencyMs_l(double *latencyMs) const
88 {
89     const auto& iter = mPatchPanel.mPatches.find(mPatchHandle);
90     if (iter != mPatchPanel.mPatches.end()) {
91         return iter->second.getLatencyMs(latencyMs);
92     } else {
93         return BAD_VALUE;
94     }
95 }
96 
97 /* List connected audio ports and their attributes */
listAudioPorts(unsigned int * num_ports __unused,struct audio_port * ports __unused)98 status_t AudioFlinger::PatchPanel::listAudioPorts(unsigned int *num_ports __unused,
99                                 struct audio_port *ports __unused)
100 {
101     ALOGV(__func__);
102     return NO_ERROR;
103 }
104 
105 /* Get supported attributes for a given audio port */
getAudioPort(struct audio_port * port __unused)106 status_t AudioFlinger::PatchPanel::getAudioPort(struct audio_port *port __unused)
107 {
108     ALOGV(__func__);
109     return NO_ERROR;
110 }
111 
112 /* Connect a patch between several source and sink ports */
createAudioPatch(const struct audio_patch * patch,audio_patch_handle_t * handle)113 status_t AudioFlinger::PatchPanel::createAudioPatch(const struct audio_patch *patch,
114                                    audio_patch_handle_t *handle)
115 {
116     if (handle == NULL || patch == NULL) {
117         return BAD_VALUE;
118     }
119     ALOGV("%s() num_sources %d num_sinks %d handle %d",
120             __func__, patch->num_sources, patch->num_sinks, *handle);
121     status_t status = NO_ERROR;
122     audio_patch_handle_t halHandle = AUDIO_PATCH_HANDLE_NONE;
123 
124     if (!audio_patch_is_valid(patch) || (patch->num_sinks == 0 && patch->num_sources != 2)) {
125         return BAD_VALUE;
126     }
127     // limit number of sources to 1 for now or 2 sources for special cross hw module case.
128     // only the audio policy manager can request a patch creation with 2 sources.
129     if (patch->num_sources > 2) {
130         return INVALID_OPERATION;
131     }
132 
133     if (*handle != AUDIO_PATCH_HANDLE_NONE) {
134         auto iter = mPatches.find(*handle);
135         if (iter != mPatches.end()) {
136             ALOGV("%s() removing patch handle %d", __func__, *handle);
137             Patch &removedPatch = iter->second;
138             // free resources owned by the removed patch if applicable
139             // 1) if a software patch is present, release the playback and capture threads and
140             // tracks created. This will also release the corresponding audio HAL patches
141             if (removedPatch.isSoftware()) {
142                 removedPatch.clearConnections(this);
143             }
144             // 2) if the new patch and old patch source or sink are devices from different
145             // hw modules,  clear the audio HAL patches now because they will not be updated
146             // by call to create_audio_patch() below which will happen on a different HW module
147             if (removedPatch.mHalHandle != AUDIO_PATCH_HANDLE_NONE) {
148                 audio_module_handle_t hwModule = AUDIO_MODULE_HANDLE_NONE;
149                 const struct audio_patch &oldPatch = removedPatch.mAudioPatch;
150                 if (oldPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE &&
151                         (patch->sources[0].type != AUDIO_PORT_TYPE_DEVICE ||
152                                 oldPatch.sources[0].ext.device.hw_module !=
153                                 patch->sources[0].ext.device.hw_module)) {
154                     hwModule = oldPatch.sources[0].ext.device.hw_module;
155                 } else if (patch->num_sinks == 0 ||
156                         (oldPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE &&
157                                 (patch->sinks[0].type != AUDIO_PORT_TYPE_DEVICE ||
158                                         oldPatch.sinks[0].ext.device.hw_module !=
159                                         patch->sinks[0].ext.device.hw_module))) {
160                     // Note on (patch->num_sinks == 0): this situation should not happen as
161                     // these special patches are only created by the policy manager but just
162                     // in case, systematically clear the HAL patch.
163                     // Note that removedPatch.mAudioPatch.num_sinks cannot be 0 here because
164                     // removedPatch.mHalHandle would be AUDIO_PATCH_HANDLE_NONE in this case.
165                     hwModule = oldPatch.sinks[0].ext.device.hw_module;
166                 }
167                 sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(hwModule);
168                 if (hwDevice != 0) {
169                     hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
170                 }
171             }
172             erasePatch(*handle);
173         }
174     }
175 
176     Patch newPatch{*patch};
177     audio_module_handle_t insertedModule = AUDIO_MODULE_HANDLE_NONE;
178 
179     switch (patch->sources[0].type) {
180         case AUDIO_PORT_TYPE_DEVICE: {
181             audio_module_handle_t srcModule = patch->sources[0].ext.device.hw_module;
182             AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(srcModule);
183             if (!audioHwDevice) {
184                 status = BAD_VALUE;
185                 goto exit;
186             }
187             for (unsigned int i = 0; i < patch->num_sinks; i++) {
188                 // support only one sink if connection to a mix or across HW modules
189                 if ((patch->sinks[i].type == AUDIO_PORT_TYPE_MIX ||
190                                 (patch->sinks[i].type == AUDIO_PORT_TYPE_DEVICE &&
191                                         patch->sinks[i].ext.device.hw_module != srcModule)) &&
192                         patch->num_sinks > 1) {
193                     ALOGW("%s() multiple sinks for mix or across modules not supported", __func__);
194                     status = INVALID_OPERATION;
195                     goto exit;
196                 }
197                 // reject connection to different sink types
198                 if (patch->sinks[i].type != patch->sinks[0].type) {
199                     ALOGW("%s() different sink types in same patch not supported", __func__);
200                     status = BAD_VALUE;
201                     goto exit;
202                 }
203             }
204 
205             // manage patches requiring a software bridge
206             // - special patch request with 2 sources (reuse one existing output mix) OR
207             // - Device to device AND
208             //    - source HW module != destination HW module OR
209             //    - audio HAL does not support audio patches creation
210             if ((patch->num_sources == 2) ||
211                 ((patch->sinks[0].type == AUDIO_PORT_TYPE_DEVICE) &&
212                  ((patch->sinks[0].ext.device.hw_module != srcModule) ||
213                   !audioHwDevice->supportsAudioPatches()))) {
214                 audio_devices_t outputDevice = patch->sinks[0].ext.device.type;
215                 String8 outputDeviceAddress = String8(patch->sinks[0].ext.device.address);
216                 if (patch->num_sources == 2) {
217                     if (patch->sources[1].type != AUDIO_PORT_TYPE_MIX ||
218                             (patch->num_sinks != 0 && patch->sinks[0].ext.device.hw_module !=
219                                     patch->sources[1].ext.mix.hw_module)) {
220                         ALOGW("%s() invalid source combination", __func__);
221                         status = INVALID_OPERATION;
222                         goto exit;
223                     }
224 
225                     sp<ThreadBase> thread =
226                             mAudioFlinger.checkPlaybackThread_l(patch->sources[1].ext.mix.handle);
227                     if (thread == 0) {
228                         ALOGW("%s() cannot get playback thread", __func__);
229                         status = INVALID_OPERATION;
230                         goto exit;
231                     }
232                     // existing playback thread is reused, so it is not closed when patch is cleared
233                     newPatch.mPlayback.setThread(
234                             reinterpret_cast<PlaybackThread*>(thread.get()), false /*closeThread*/);
235                 } else {
236                     audio_config_t config = AUDIO_CONFIG_INITIALIZER;
237                     audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
238                     audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
239                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
240                         config.sample_rate = patch->sinks[0].sample_rate;
241                     }
242                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
243                         config.channel_mask = patch->sinks[0].channel_mask;
244                     }
245                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
246                         config.format = patch->sinks[0].format;
247                     }
248                     if (patch->sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS) {
249                         flags = patch->sinks[0].flags.output;
250                     }
251                     sp<ThreadBase> thread = mAudioFlinger.openOutput_l(
252                                                             patch->sinks[0].ext.device.hw_module,
253                                                             &output,
254                                                             &config,
255                                                             outputDevice,
256                                                             outputDeviceAddress,
257                                                             flags);
258                     ALOGV("mAudioFlinger.openOutput_l() returned %p", thread.get());
259                     if (thread == 0) {
260                         status = NO_MEMORY;
261                         goto exit;
262                     }
263                     newPatch.mPlayback.setThread(reinterpret_cast<PlaybackThread*>(thread.get()));
264                 }
265                 audio_devices_t device = patch->sources[0].ext.device.type;
266                 String8 address = String8(patch->sources[0].ext.device.address);
267                 audio_config_t config = AUDIO_CONFIG_INITIALIZER;
268                 // open input stream with source device audio properties if provided or
269                 // default to peer output stream properties otherwise.
270                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
271                     config.sample_rate = patch->sources[0].sample_rate;
272                 } else {
273                     config.sample_rate = newPatch.mPlayback.thread()->sampleRate();
274                 }
275                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
276                     config.channel_mask = patch->sources[0].channel_mask;
277                 } else {
278                     config.channel_mask = audio_channel_in_mask_from_count(
279                             newPatch.mPlayback.thread()->channelCount());
280                 }
281                 if (patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FORMAT) {
282                     config.format = patch->sources[0].format;
283                 } else {
284                     config.format = newPatch.mPlayback.thread()->format();
285                 }
286                 audio_input_flags_t flags =
287                         patch->sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
288                         patch->sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
289                 audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
290                 sp<ThreadBase> thread = mAudioFlinger.openInput_l(srcModule,
291                                                                     &input,
292                                                                     &config,
293                                                                     device,
294                                                                     address,
295                                                                     AUDIO_SOURCE_MIC,
296                                                                     flags,
297                                                                     outputDevice,
298                                                                     outputDeviceAddress);
299                 ALOGV("mAudioFlinger.openInput_l() returned %p inChannelMask %08x",
300                       thread.get(), config.channel_mask);
301                 if (thread == 0) {
302                     status = NO_MEMORY;
303                     goto exit;
304                 }
305                 newPatch.mRecord.setThread(reinterpret_cast<RecordThread*>(thread.get()));
306                 status = newPatch.createConnections(this);
307                 if (status != NO_ERROR) {
308                     goto exit;
309                 }
310                 if (audioHwDevice->isInsert()) {
311                     insertedModule = audioHwDevice->handle();
312                 }
313             } else {
314                 if (patch->sinks[0].type == AUDIO_PORT_TYPE_MIX) {
315                     sp<ThreadBase> thread = mAudioFlinger.checkRecordThread_l(
316                                                               patch->sinks[0].ext.mix.handle);
317                     if (thread == 0) {
318                         thread = mAudioFlinger.checkMmapThread_l(patch->sinks[0].ext.mix.handle);
319                         if (thread == 0) {
320                             ALOGW("%s() bad capture I/O handle %d",
321                                     __func__, patch->sinks[0].ext.mix.handle);
322                             status = BAD_VALUE;
323                             goto exit;
324                         }
325                     }
326                     status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
327                     if (status == NO_ERROR) {
328                         newPatch.setThread(thread);
329                     }
330 
331                     // remove stale audio patch with same input as sink if any
332                     for (auto& iter : mPatches) {
333                         if (iter.second.mAudioPatch.sinks[0].ext.mix.handle == thread->id()) {
334                             erasePatch(iter.first);
335                             break;
336                         }
337                     }
338                 } else {
339                     sp<DeviceHalInterface> hwDevice = audioHwDevice->hwDevice();
340                     status = hwDevice->createAudioPatch(patch->num_sources,
341                                                         patch->sources,
342                                                         patch->num_sinks,
343                                                         patch->sinks,
344                                                         &halHandle);
345                     if (status == INVALID_OPERATION) goto exit;
346                 }
347             }
348         } break;
349         case AUDIO_PORT_TYPE_MIX: {
350             audio_module_handle_t srcModule =  patch->sources[0].ext.mix.hw_module;
351             ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(srcModule);
352             if (index < 0) {
353                 ALOGW("%s() bad src hw module %d", __func__, srcModule);
354                 status = BAD_VALUE;
355                 goto exit;
356             }
357             // limit to connections between devices and output streams
358             DeviceDescriptorBaseVector devices;
359             for (unsigned int i = 0; i < patch->num_sinks; i++) {
360                 if (patch->sinks[i].type != AUDIO_PORT_TYPE_DEVICE) {
361                     ALOGW("%s() invalid sink type %d for mix source",
362                             __func__, patch->sinks[i].type);
363                     status = BAD_VALUE;
364                     goto exit;
365                 }
366                 // limit to connections between sinks and sources on same HW module
367                 if (patch->sinks[i].ext.device.hw_module != srcModule) {
368                     status = BAD_VALUE;
369                     goto exit;
370                 }
371                 sp<DeviceDescriptorBase> device = new DeviceDescriptorBase(
372                         patch->sinks[i].ext.device.type);
373                 device->setAddress(patch->sinks[i].ext.device.address);
374                 device->applyAudioPortConfig(&patch->sinks[i]);
375                 devices.push_back(device);
376             }
377             sp<ThreadBase> thread =
378                             mAudioFlinger.checkPlaybackThread_l(patch->sources[0].ext.mix.handle);
379             if (thread == 0) {
380                 thread = mAudioFlinger.checkMmapThread_l(patch->sources[0].ext.mix.handle);
381                 if (thread == 0) {
382                     ALOGW("%s() bad playback I/O handle %d",
383                             __func__, patch->sources[0].ext.mix.handle);
384                     status = BAD_VALUE;
385                     goto exit;
386                 }
387             }
388             if (thread == mAudioFlinger.primaryPlaybackThread_l()) {
389                 mAudioFlinger.updateOutDevicesForRecordThreads_l(devices);
390             }
391 
392             status = thread->sendCreateAudioPatchConfigEvent(patch, &halHandle);
393             if (status == NO_ERROR) {
394                 newPatch.setThread(thread);
395             }
396 
397             // remove stale audio patch with same output as source if any
398             for (auto& iter : mPatches) {
399                 if (iter.second.mAudioPatch.sources[0].ext.mix.handle == thread->id()) {
400                     erasePatch(iter.first);
401                     break;
402                 }
403             }
404         } break;
405         default:
406             status = BAD_VALUE;
407             goto exit;
408     }
409 exit:
410     ALOGV("%s() status %d", __func__, status);
411     if (status == NO_ERROR) {
412         *handle = (audio_patch_handle_t) mAudioFlinger.nextUniqueId(AUDIO_UNIQUE_ID_USE_PATCH);
413         newPatch.mHalHandle = halHandle;
414         mAudioFlinger.mDeviceEffectManager.createAudioPatch(*handle, newPatch);
415         mPatches.insert(std::make_pair(*handle, std::move(newPatch)));
416         if (insertedModule != AUDIO_MODULE_HANDLE_NONE) {
417             addSoftwarePatchToInsertedModules(insertedModule, *handle);
418         }
419     } else {
420         newPatch.clearConnections(this);
421     }
422     return status;
423 }
424 
~Patch()425 AudioFlinger::PatchPanel::Patch::~Patch()
426 {
427     ALOGE_IF(isSoftware(), "Software patch connections leaked %d %d",
428             mRecord.handle(), mPlayback.handle());
429 }
430 
createConnections(PatchPanel * panel)431 status_t AudioFlinger::PatchPanel::Patch::createConnections(PatchPanel *panel)
432 {
433     // create patch from source device to record thread input
434     status_t status = panel->createAudioPatch(
435             PatchBuilder().addSource(mAudioPatch.sources[0]).
436                 addSink(mRecord.thread(), { .source = AUDIO_SOURCE_MIC }).patch(),
437             mRecord.handlePtr());
438     if (status != NO_ERROR) {
439         *mRecord.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
440         return status;
441     }
442 
443     // create patch from playback thread output to sink device
444     if (mAudioPatch.num_sinks != 0) {
445         status = panel->createAudioPatch(
446                 PatchBuilder().addSource(mPlayback.thread()).addSink(mAudioPatch.sinks[0]).patch(),
447                 mPlayback.handlePtr());
448         if (status != NO_ERROR) {
449             *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
450             return status;
451         }
452     } else {
453         *mPlayback.handlePtr() = AUDIO_PATCH_HANDLE_NONE;
454     }
455 
456     // create a special record track to capture from record thread
457     uint32_t channelCount = mPlayback.thread()->channelCount();
458     audio_channel_mask_t inChannelMask = audio_channel_in_mask_from_count(channelCount);
459     audio_channel_mask_t outChannelMask = mPlayback.thread()->channelMask();
460     uint32_t sampleRate = mPlayback.thread()->sampleRate();
461     audio_format_t format = mPlayback.thread()->format();
462 
463     audio_format_t inputFormat = mRecord.thread()->format();
464     if (!audio_is_linear_pcm(inputFormat)) {
465         // The playbackThread format will say PCM for IEC61937 packetized stream.
466         // Use recordThread format.
467         format = inputFormat;
468     }
469     audio_input_flags_t inputFlags = mAudioPatch.sources[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
470             mAudioPatch.sources[0].flags.input : AUDIO_INPUT_FLAG_NONE;
471     if (sampleRate == mRecord.thread()->sampleRate() &&
472             inChannelMask == mRecord.thread()->channelMask() &&
473             mRecord.thread()->fastTrackAvailable() &&
474             mRecord.thread()->hasFastCapture()) {
475         // Create a fast track if the record thread has fast capture to get better performance.
476         // Only enable fast mode when there is no resample needed.
477         inputFlags = (audio_input_flags_t) (inputFlags | AUDIO_INPUT_FLAG_FAST);
478     } else {
479         // Fast mode is not available in this case.
480         inputFlags = (audio_input_flags_t) (inputFlags & ~AUDIO_INPUT_FLAG_FAST);
481     }
482 
483     audio_output_flags_t outputFlags = mAudioPatch.sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
484             mAudioPatch.sinks[0].flags.output : AUDIO_OUTPUT_FLAG_NONE;
485     audio_stream_type_t streamType = AUDIO_STREAM_PATCH;
486     if (mAudioPatch.num_sources == 2 && mAudioPatch.sources[1].type == AUDIO_PORT_TYPE_MIX) {
487         // "reuse one existing output mix" case
488         streamType = mAudioPatch.sources[1].ext.mix.usecase.stream;
489     }
490     if (mPlayback.thread()->hasFastMixer()) {
491         // Create a fast track if the playback thread has fast mixer to get better performance.
492         // Note: we should have matching channel mask, sample rate, and format by the logic above.
493         outputFlags = (audio_output_flags_t) (outputFlags | AUDIO_OUTPUT_FLAG_FAST);
494     } else {
495         outputFlags = (audio_output_flags_t) (outputFlags & ~AUDIO_OUTPUT_FLAG_FAST);
496     }
497 
498     sp<RecordThread::PatchRecord> tempRecordTrack;
499     const bool usePassthruPatchRecord =
500             (inputFlags & AUDIO_INPUT_FLAG_DIRECT) && (outputFlags & AUDIO_OUTPUT_FLAG_DIRECT);
501     const size_t playbackFrameCount = mPlayback.thread()->frameCount();
502     const size_t recordFrameCount = mRecord.thread()->frameCount();
503     size_t frameCount = 0;
504     if (usePassthruPatchRecord) {
505         // PassthruPatchRecord producesBufferOnDemand, so use
506         // maximum of playback and record thread framecounts
507         frameCount = std::max(playbackFrameCount, recordFrameCount);
508         ALOGV("%s() playframeCount %zu recordFrameCount %zu frameCount %zu",
509             __func__, playbackFrameCount, recordFrameCount, frameCount);
510         tempRecordTrack = new RecordThread::PassthruPatchRecord(
511                                                  mRecord.thread().get(),
512                                                  sampleRate,
513                                                  inChannelMask,
514                                                  format,
515                                                  frameCount,
516                                                  inputFlags);
517     } else {
518         // use a pseudo LCM between input and output framecount
519         int playbackShift = __builtin_ctz(playbackFrameCount);
520         int shift = __builtin_ctz(recordFrameCount);
521         if (playbackShift < shift) {
522             shift = playbackShift;
523         }
524         frameCount = (playbackFrameCount * recordFrameCount) >> shift;
525         ALOGV("%s() playframeCount %zu recordFrameCount %zu frameCount %zu",
526             __func__, playbackFrameCount, recordFrameCount, frameCount);
527 
528         tempRecordTrack = new RecordThread::PatchRecord(
529                                                  mRecord.thread().get(),
530                                                  sampleRate,
531                                                  inChannelMask,
532                                                  format,
533                                                  frameCount,
534                                                  nullptr,
535                                                  (size_t)0 /* bufferSize */,
536                                                  inputFlags);
537     }
538     status = mRecord.checkTrack(tempRecordTrack.get());
539     if (status != NO_ERROR) {
540         return status;
541     }
542 
543     // create a special playback track to render to playback thread.
544     // this track is given the same buffer as the PatchRecord buffer
545     sp<PlaybackThread::PatchTrack> tempPatchTrack = new PlaybackThread::PatchTrack(
546                                            mPlayback.thread().get(),
547                                            streamType,
548                                            sampleRate,
549                                            outChannelMask,
550                                            format,
551                                            frameCount,
552                                            tempRecordTrack->buffer(),
553                                            tempRecordTrack->bufferSize(),
554                                            outputFlags);
555     status = mPlayback.checkTrack(tempPatchTrack.get());
556     if (status != NO_ERROR) {
557         return status;
558     }
559 
560     // tie playback and record tracks together
561     // In the case of PassthruPatchRecord no I/O activity happens on RecordThread,
562     // everything is driven from PlaybackThread. Thus AudioBufferProvider methods
563     // of PassthruPatchRecord can only be called if the corresponding PatchTrack
564     // is alive. There is no need to hold a reference, and there is no need
565     // to clear it. In fact, since playback stopping is asynchronous, there is
566     // no proper time when clearing could be done.
567     mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack, !usePassthruPatchRecord);
568     mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack, true /*holdReference*/);
569 
570     // start capture and playback
571     mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
572     mPlayback.track()->start();
573 
574     return status;
575 }
576 
clearConnections(PatchPanel * panel)577 void AudioFlinger::PatchPanel::Patch::clearConnections(PatchPanel *panel)
578 {
579     ALOGV("%s() mRecord.handle %d mPlayback.handle %d",
580             __func__, mRecord.handle(), mPlayback.handle());
581     mRecord.stopTrack();
582     mPlayback.stopTrack();
583     mRecord.clearTrackPeer(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle.
584     mRecord.closeConnections(panel);
585     mPlayback.closeConnections(panel);
586 }
587 
getLatencyMs(double * latencyMs) const588 status_t AudioFlinger::PatchPanel::Patch::getLatencyMs(double *latencyMs) const
589 {
590     if (!isSoftware()) return INVALID_OPERATION;
591 
592     auto recordTrack = mRecord.const_track();
593     if (recordTrack.get() == nullptr) return INVALID_OPERATION;
594 
595     auto playbackTrack = mPlayback.const_track();
596     if (playbackTrack.get() == nullptr) return INVALID_OPERATION;
597 
598     // Latency information for tracks may be called without obtaining
599     // the underlying thread lock.
600     //
601     // We use record server latency + playback track latency (generally smaller than the
602     // reverse due to internal biases).
603     //
604     // TODO: is this stable enough? Consider a PatchTrack synchronized version of this.
605 
606     // For PCM tracks get server latency.
607     if (audio_is_linear_pcm(recordTrack->format())) {
608         double recordServerLatencyMs, playbackTrackLatencyMs;
609         if (recordTrack->getServerLatencyMs(&recordServerLatencyMs) == OK
610                 && playbackTrack->getTrackLatencyMs(&playbackTrackLatencyMs) == OK) {
611             *latencyMs = recordServerLatencyMs + playbackTrackLatencyMs;
612             return OK;
613         }
614     }
615 
616     // See if kernel latencies are available.
617     // If so, do a frame diff and time difference computation to estimate
618     // the total patch latency. This requires that frame counts are reported by the
619     // HAL are matched properly in the case of record overruns and playback underruns.
620     ThreadBase::TrackBase::FrameTime recordFT{}, playFT{};
621     recordTrack->getKernelFrameTime(&recordFT);
622     playbackTrack->getKernelFrameTime(&playFT);
623     if (recordFT.timeNs > 0 && playFT.timeNs > 0) {
624         const int64_t frameDiff = recordFT.frames - playFT.frames;
625         const int64_t timeDiffNs = recordFT.timeNs - playFT.timeNs;
626 
627         // It is possible that the patch track and patch record have a large time disparity because
628         // one thread runs but another is stopped.  We arbitrarily choose the maximum timestamp
629         // time difference based on how often we expect the timestamps to update in normal operation
630         // (typical should be no more than 50 ms).
631         //
632         // If the timestamps aren't sampled close enough, the patch latency is not
633         // considered valid.
634         //
635         // TODO: change this based on more experiments.
636         constexpr int64_t maxValidTimeDiffNs = 200 * NANOS_PER_MILLISECOND;
637         if (std::abs(timeDiffNs) < maxValidTimeDiffNs) {
638             *latencyMs = frameDiff * 1e3 / recordTrack->sampleRate()
639                    - timeDiffNs * 1e-6;
640             return OK;
641         }
642     }
643 
644     return INVALID_OPERATION;
645 }
646 
dump(audio_patch_handle_t myHandle) const647 String8 AudioFlinger::PatchPanel::Patch::dump(audio_patch_handle_t myHandle) const
648 {
649     // TODO: Consider table dump form for patches, just like tracks.
650     String8 result = String8::format("Patch %d: %s (thread %p => thread %p)",
651             myHandle, isSoftware() ? "Software bridge between" : "No software bridge",
652             mRecord.const_thread().get(), mPlayback.const_thread().get());
653 
654     bool hasSinkDevice =
655             mAudioPatch.num_sinks > 0 && mAudioPatch.sinks[0].type == AUDIO_PORT_TYPE_DEVICE;
656     bool hasSourceDevice =
657             mAudioPatch.num_sources > 0 && mAudioPatch.sources[0].type == AUDIO_PORT_TYPE_DEVICE;
658     result.appendFormat(" thread %p %s (%d) first device type %08x", mThread.unsafe_get(),
659             hasSinkDevice ? "num sinks" :
660                 (hasSourceDevice ? "num sources" : "no devices"),
661             hasSinkDevice ? mAudioPatch.num_sinks :
662                 (hasSourceDevice ? mAudioPatch.num_sources : 0),
663             hasSinkDevice ? mAudioPatch.sinks[0].ext.device.type :
664                 (hasSourceDevice ? mAudioPatch.sources[0].ext.device.type : 0));
665 
666     // add latency if it exists
667     double latencyMs;
668     if (getLatencyMs(&latencyMs) == OK) {
669         result.appendFormat("  latency: %.2lf ms", latencyMs);
670     }
671     return result;
672 }
673 
674 /* Disconnect a patch */
releaseAudioPatch(audio_patch_handle_t handle)675 status_t AudioFlinger::PatchPanel::releaseAudioPatch(audio_patch_handle_t handle)
676 {
677     ALOGV("%s handle %d", __func__, handle);
678     status_t status = NO_ERROR;
679 
680     auto iter = mPatches.find(handle);
681     if (iter == mPatches.end()) {
682         return BAD_VALUE;
683     }
684     Patch &removedPatch = iter->second;
685     const struct audio_patch &patch = removedPatch.mAudioPatch;
686 
687     const struct audio_port_config &src = patch.sources[0];
688     switch (src.type) {
689         case AUDIO_PORT_TYPE_DEVICE: {
690             sp<DeviceHalInterface> hwDevice = findHwDeviceByModule(src.ext.device.hw_module);
691             if (hwDevice == 0) {
692                 ALOGW("%s() bad src hw module %d", __func__, src.ext.device.hw_module);
693                 status = BAD_VALUE;
694                 break;
695             }
696 
697             if (removedPatch.isSoftware()) {
698                 removedPatch.clearConnections(this);
699                 break;
700             }
701 
702             if (patch.sinks[0].type == AUDIO_PORT_TYPE_MIX) {
703                 audio_io_handle_t ioHandle = patch.sinks[0].ext.mix.handle;
704                 sp<ThreadBase> thread = mAudioFlinger.checkRecordThread_l(ioHandle);
705                 if (thread == 0) {
706                     thread = mAudioFlinger.checkMmapThread_l(ioHandle);
707                     if (thread == 0) {
708                         ALOGW("%s() bad capture I/O handle %d", __func__, ioHandle);
709                         status = BAD_VALUE;
710                         break;
711                     }
712                 }
713                 status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
714             } else {
715                 status = hwDevice->releaseAudioPatch(removedPatch.mHalHandle);
716             }
717         } break;
718         case AUDIO_PORT_TYPE_MIX: {
719             if (findHwDeviceByModule(src.ext.mix.hw_module) == 0) {
720                 ALOGW("%s() bad src hw module %d", __func__, src.ext.mix.hw_module);
721                 status = BAD_VALUE;
722                 break;
723             }
724             audio_io_handle_t ioHandle = src.ext.mix.handle;
725             sp<ThreadBase> thread = mAudioFlinger.checkPlaybackThread_l(ioHandle);
726             if (thread == 0) {
727                 thread = mAudioFlinger.checkMmapThread_l(ioHandle);
728                 if (thread == 0) {
729                     ALOGW("%s() bad playback I/O handle %d", __func__, ioHandle);
730                     status = BAD_VALUE;
731                     break;
732                 }
733             }
734             status = thread->sendReleaseAudioPatchConfigEvent(removedPatch.mHalHandle);
735         } break;
736         default:
737             status = BAD_VALUE;
738     }
739 
740     erasePatch(handle);
741     return status;
742 }
743 
erasePatch(audio_patch_handle_t handle)744 void AudioFlinger::PatchPanel::erasePatch(audio_patch_handle_t handle) {
745     mPatches.erase(handle);
746     removeSoftwarePatchFromInsertedModules(handle);
747     mAudioFlinger.mDeviceEffectManager.releaseAudioPatch(handle);
748 }
749 
750 /* List connected audio ports and they attributes */
listAudioPatches(unsigned int * num_patches __unused,struct audio_patch * patches __unused)751 status_t AudioFlinger::PatchPanel::listAudioPatches(unsigned int *num_patches __unused,
752                                   struct audio_patch *patches __unused)
753 {
754     ALOGV(__func__);
755     return NO_ERROR;
756 }
757 
getDownstreamSoftwarePatches(audio_io_handle_t stream,std::vector<AudioFlinger::PatchPanel::SoftwarePatch> * patches) const758 status_t AudioFlinger::PatchPanel::getDownstreamSoftwarePatches(
759         audio_io_handle_t stream,
760         std::vector<AudioFlinger::PatchPanel::SoftwarePatch> *patches) const
761 {
762     for (const auto& module : mInsertedModules) {
763         if (module.second.streams.count(stream)) {
764             for (const auto& patchHandle : module.second.sw_patches) {
765                 const auto& patch_iter = mPatches.find(patchHandle);
766                 if (patch_iter != mPatches.end()) {
767                     const Patch &patch = patch_iter->second;
768                     patches->emplace_back(*this, patchHandle,
769                             patch.mPlayback.const_thread()->id(),
770                             patch.mRecord.const_thread()->id());
771                 } else {
772                     ALOGE("Stale patch handle in the cache: %d", patchHandle);
773                 }
774             }
775             return OK;
776         }
777     }
778     // The stream is not associated with any of inserted modules.
779     return BAD_VALUE;
780 }
781 
notifyStreamOpened(AudioHwDevice * audioHwDevice,audio_io_handle_t stream)782 void AudioFlinger::PatchPanel::notifyStreamOpened(
783         AudioHwDevice *audioHwDevice, audio_io_handle_t stream)
784 {
785     if (audioHwDevice->isInsert()) {
786         mInsertedModules[audioHwDevice->handle()].streams.insert(stream);
787     }
788 }
789 
notifyStreamClosed(audio_io_handle_t stream)790 void AudioFlinger::PatchPanel::notifyStreamClosed(audio_io_handle_t stream)
791 {
792     for (auto& module : mInsertedModules) {
793         module.second.streams.erase(stream);
794     }
795 }
796 
findAudioHwDeviceByModule(audio_module_handle_t module)797 AudioHwDevice* AudioFlinger::PatchPanel::findAudioHwDeviceByModule(audio_module_handle_t module)
798 {
799     if (module == AUDIO_MODULE_HANDLE_NONE) return nullptr;
800     ssize_t index = mAudioFlinger.mAudioHwDevs.indexOfKey(module);
801     if (index < 0) {
802         ALOGW("%s() bad hw module %d", __func__, module);
803         return nullptr;
804     }
805     return mAudioFlinger.mAudioHwDevs.valueAt(index);
806 }
807 
findHwDeviceByModule(audio_module_handle_t module)808 sp<DeviceHalInterface> AudioFlinger::PatchPanel::findHwDeviceByModule(audio_module_handle_t module)
809 {
810     AudioHwDevice *audioHwDevice = findAudioHwDeviceByModule(module);
811     return audioHwDevice ? audioHwDevice->hwDevice() : nullptr;
812 }
813 
addSoftwarePatchToInsertedModules(audio_module_handle_t module,audio_patch_handle_t handle)814 void AudioFlinger::PatchPanel::addSoftwarePatchToInsertedModules(
815         audio_module_handle_t module, audio_patch_handle_t handle)
816 {
817     mInsertedModules[module].sw_patches.insert(handle);
818 }
819 
removeSoftwarePatchFromInsertedModules(audio_patch_handle_t handle)820 void AudioFlinger::PatchPanel::removeSoftwarePatchFromInsertedModules(
821         audio_patch_handle_t handle)
822 {
823     for (auto& module : mInsertedModules) {
824         module.second.sw_patches.erase(handle);
825     }
826 }
827 
dump(int fd) const828 void AudioFlinger::PatchPanel::dump(int fd) const
829 {
830     String8 patchPanelDump;
831     const char *indent = "  ";
832 
833     bool headerPrinted = false;
834     for (const auto& iter : mPatches) {
835         if (!headerPrinted) {
836             patchPanelDump += "\nPatches:\n";
837             headerPrinted = true;
838         }
839         patchPanelDump.appendFormat("%s%s\n", indent, iter.second.dump(iter.first).string());
840     }
841 
842     headerPrinted = false;
843     for (const auto& module : mInsertedModules) {
844         if (!module.second.streams.empty() || !module.second.sw_patches.empty()) {
845             if (!headerPrinted) {
846                 patchPanelDump += "\nTracked inserted modules:\n";
847                 headerPrinted = true;
848             }
849             String8 moduleDump = String8::format("Module %d: I/O handles: ", module.first);
850             for (const auto& stream : module.second.streams) {
851                 moduleDump.appendFormat("%d ", stream);
852             }
853             moduleDump.append("; SW Patches: ");
854             for (const auto& patch : module.second.sw_patches) {
855                 moduleDump.appendFormat("%d ", patch);
856             }
857             patchPanelDump.appendFormat("%s%s\n", indent, moduleDump.string());
858         }
859     }
860 
861     if (!patchPanelDump.isEmpty()) {
862         write(fd, patchPanelDump.string(), patchPanelDump.size());
863     }
864 }
865 
866 } // namespace android
867