1 /*
2 **
3 ** Copyright 2012, 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"
20 //#define LOG_NDEBUG 0
21
22 #include <algorithm>
23
24 #include "Configuration.h"
25 #include <utils/Log.h>
26 #include <system/audio_effects/effect_aec.h>
27 #include <system/audio_effects/effect_downmix.h>
28 #include <system/audio_effects/effect_dynamicsprocessing.h>
29 #include <system/audio_effects/effect_hapticgenerator.h>
30 #include <system/audio_effects/effect_ns.h>
31 #include <system/audio_effects/effect_spatializer.h>
32 #include <system/audio_effects/effect_visualizer.h>
33 #include <audio_utils/channels.h>
34 #include <audio_utils/primitives.h>
35 #include <media/AudioCommonTypes.h>
36 #include <media/AudioContainers.h>
37 #include <media/AudioEffect.h>
38 #include <media/AudioDeviceTypeAddr.h>
39 #include <media/ShmemCompat.h>
40 #include <media/audiohal/EffectHalInterface.h>
41 #include <media/audiohal/EffectsFactoryHalInterface.h>
42 #include <mediautils/MethodStatistics.h>
43 #include <mediautils/ServiceUtilities.h>
44 #include <mediautils/TimeCheck.h>
45
46 #include "AudioFlinger.h"
47
48 // ----------------------------------------------------------------------------
49
50 // Note: the following macro is used for extremely verbose logging message. In
51 // order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to
52 // 0; but one side effect of this is to turn all LOGV's as well. Some messages
53 // are so verbose that we want to suppress them even when we have ALOG_ASSERT
54 // turned on. Do not uncomment the #def below unless you really know what you
55 // are doing and want to see all of the extremely verbose messages.
56 //#define VERY_VERY_VERBOSE_LOGGING
57 #ifdef VERY_VERY_VERBOSE_LOGGING
58 #define ALOGVV ALOGV
59 #else
60 #define ALOGVV(a...) do { } while(0)
61 #endif
62
63 #define DEFAULT_OUTPUT_SAMPLE_RATE 48000
64
65 namespace android {
66
67 using aidl_utils::statusTFromBinderStatus;
68 using binder::Status;
69
70 namespace {
71
72 // Append a POD value into a vector of bytes.
73 template<typename T>
appendToBuffer(const T & value,std::vector<uint8_t> * buffer)74 void appendToBuffer(const T& value, std::vector<uint8_t>* buffer) {
75 const uint8_t* ar(reinterpret_cast<const uint8_t*>(&value));
76 buffer->insert(buffer->end(), ar, ar + sizeof(T));
77 }
78
79 // Write a POD value into a vector of bytes (clears the previous buffer
80 // content).
81 template<typename T>
writeToBuffer(const T & value,std::vector<uint8_t> * buffer)82 void writeToBuffer(const T& value, std::vector<uint8_t>* buffer) {
83 buffer->clear();
84 appendToBuffer(value, buffer);
85 }
86
87 } // namespace
88
89 // ----------------------------------------------------------------------------
90 // EffectBase implementation
91 // ----------------------------------------------------------------------------
92
93 #undef LOG_TAG
94 #define LOG_TAG "AudioFlinger::EffectBase"
95
EffectBase(const sp<AudioFlinger::EffectCallbackInterface> & callback,effect_descriptor_t * desc,int id,audio_session_t sessionId,bool pinned)96 AudioFlinger::EffectBase::EffectBase(const sp<AudioFlinger::EffectCallbackInterface>& callback,
97 effect_descriptor_t *desc,
98 int id,
99 audio_session_t sessionId,
100 bool pinned)
101 : mPinned(pinned),
102 mCallback(callback), mId(id), mSessionId(sessionId),
103 mDescriptor(*desc)
104 {
105 }
106
107 // must be called with EffectModule::mLock held
setEnabled_l(bool enabled)108 status_t AudioFlinger::EffectBase::setEnabled_l(bool enabled)
109 {
110
111 ALOGV("setEnabled %p enabled %d", this, enabled);
112
113 if (enabled != isEnabled()) {
114 switch (mState) {
115 // going from disabled to enabled
116 case IDLE:
117 mState = STARTING;
118 break;
119 case STOPPED:
120 mState = RESTART;
121 break;
122 case STOPPING:
123 mState = ACTIVE;
124 break;
125
126 // going from enabled to disabled
127 case RESTART:
128 mState = STOPPED;
129 break;
130 case STARTING:
131 mState = IDLE;
132 break;
133 case ACTIVE:
134 mState = STOPPING;
135 break;
136 case DESTROYED:
137 return NO_ERROR; // simply ignore as we are being destroyed
138 }
139 for (size_t i = 1; i < mHandles.size(); i++) {
140 EffectHandle *h = mHandles[i];
141 if (h != NULL && !h->disconnected()) {
142 h->setEnabled(enabled);
143 }
144 }
145 }
146 return NO_ERROR;
147 }
148
setEnabled(bool enabled,bool fromHandle)149 status_t AudioFlinger::EffectBase::setEnabled(bool enabled, bool fromHandle)
150 {
151 status_t status;
152 {
153 Mutex::Autolock _l(mLock);
154 status = setEnabled_l(enabled);
155 }
156 if (fromHandle) {
157 if (enabled) {
158 if (status != NO_ERROR) {
159 getCallback()->checkSuspendOnEffectEnabled(this, false, false /*threadLocked*/);
160 } else {
161 getCallback()->onEffectEnable(this);
162 }
163 } else {
164 getCallback()->onEffectDisable(this);
165 }
166 }
167 return status;
168 }
169
isEnabled() const170 bool AudioFlinger::EffectBase::isEnabled() const
171 {
172 switch (mState) {
173 case RESTART:
174 case STARTING:
175 case ACTIVE:
176 return true;
177 case IDLE:
178 case STOPPING:
179 case STOPPED:
180 case DESTROYED:
181 default:
182 return false;
183 }
184 }
185
setSuspended(bool suspended)186 void AudioFlinger::EffectBase::setSuspended(bool suspended)
187 {
188 Mutex::Autolock _l(mLock);
189 mSuspended = suspended;
190 }
191
suspended() const192 bool AudioFlinger::EffectBase::suspended() const
193 {
194 Mutex::Autolock _l(mLock);
195 return mSuspended;
196 }
197
addHandle(EffectHandle * handle)198 status_t AudioFlinger::EffectBase::addHandle(EffectHandle *handle)
199 {
200 status_t status;
201
202 Mutex::Autolock _l(mLock);
203 int priority = handle->priority();
204 size_t size = mHandles.size();
205 EffectHandle *controlHandle = NULL;
206 size_t i;
207 for (i = 0; i < size; i++) {
208 EffectHandle *h = mHandles[i];
209 if (h == NULL || h->disconnected()) {
210 continue;
211 }
212 // first non destroyed handle is considered in control
213 if (controlHandle == NULL) {
214 controlHandle = h;
215 }
216 if (h->priority() <= priority) {
217 break;
218 }
219 }
220 // if inserted in first place, move effect control from previous owner to this handle
221 if (i == 0) {
222 bool enabled = false;
223 if (controlHandle != NULL) {
224 enabled = controlHandle->enabled();
225 controlHandle->setControl(false/*hasControl*/, true /*signal*/, enabled /*enabled*/);
226 }
227 handle->setControl(true /*hasControl*/, false /*signal*/, enabled /*enabled*/);
228 status = NO_ERROR;
229 } else {
230 status = ALREADY_EXISTS;
231 }
232 ALOGV("addHandle() %p added handle %p in position %zu", this, handle, i);
233 mHandles.insertAt(handle, i);
234 return status;
235 }
236
updatePolicyState()237 status_t AudioFlinger::EffectBase::updatePolicyState()
238 {
239 status_t status = NO_ERROR;
240 bool doRegister = false;
241 bool registered = false;
242 bool doEnable = false;
243 bool enabled = false;
244 audio_io_handle_t io = AUDIO_IO_HANDLE_NONE;
245 product_strategy_t strategy = PRODUCT_STRATEGY_NONE;
246
247 {
248 Mutex::Autolock _l(mLock);
249
250 if ((isInternal_l() && !mPolicyRegistered)
251 || !getCallback()->isAudioPolicyReady()) {
252 return NO_ERROR;
253 }
254
255 // register effect when first handle is attached and unregister when last handle is removed
256 if (mPolicyRegistered != mHandles.size() > 0) {
257 doRegister = true;
258 mPolicyRegistered = mHandles.size() > 0;
259 if (mPolicyRegistered) {
260 const auto callback = getCallback();
261 io = callback->io();
262 strategy = callback->strategy();
263 }
264 }
265 // enable effect when registered according to enable state requested by controlling handle
266 if (mHandles.size() > 0) {
267 EffectHandle *handle = controlHandle_l();
268 if (handle != nullptr && mPolicyEnabled != handle->enabled()) {
269 doEnable = true;
270 mPolicyEnabled = handle->enabled();
271 }
272 }
273 registered = mPolicyRegistered;
274 enabled = mPolicyEnabled;
275 // The simultaneous release of two EffectHandles with the same EffectModule
276 // may cause us to call this method at the same time.
277 // This may deadlock under some circumstances (b/180941720). Avoid this.
278 if (!doRegister && !(registered && doEnable)) {
279 return NO_ERROR;
280 }
281 mPolicyLock.lock();
282 }
283 ALOGV("%s name %s id %d session %d doRegister %d registered %d doEnable %d enabled %d",
284 __func__, mDescriptor.name, mId, mSessionId, doRegister, registered, doEnable, enabled);
285 if (doRegister) {
286 if (registered) {
287 status = AudioSystem::registerEffect(
288 &mDescriptor,
289 io,
290 strategy,
291 mSessionId,
292 mId);
293 } else {
294 status = AudioSystem::unregisterEffect(mId);
295 }
296 }
297 if (registered && doEnable) {
298 status = AudioSystem::setEffectEnabled(mId, enabled);
299 }
300 mPolicyLock.unlock();
301
302 return status;
303 }
304
305
removeHandle(EffectHandle * handle)306 ssize_t AudioFlinger::EffectBase::removeHandle(EffectHandle *handle)
307 {
308 Mutex::Autolock _l(mLock);
309 return removeHandle_l(handle);
310 }
311
removeHandle_l(EffectHandle * handle)312 ssize_t AudioFlinger::EffectBase::removeHandle_l(EffectHandle *handle)
313 {
314 size_t size = mHandles.size();
315 size_t i;
316 for (i = 0; i < size; i++) {
317 if (mHandles[i] == handle) {
318 break;
319 }
320 }
321 if (i == size) {
322 ALOGW("%s %p handle not found %p", __FUNCTION__, this, handle);
323 return BAD_VALUE;
324 }
325 ALOGV("removeHandle_l() %p removed handle %p in position %zu", this, handle, i);
326
327 mHandles.removeAt(i);
328 // if removed from first place, move effect control from this handle to next in line
329 if (i == 0) {
330 EffectHandle *h = controlHandle_l();
331 if (h != NULL) {
332 h->setControl(true /*hasControl*/, true /*signal*/ , handle->enabled() /*enabled*/);
333 }
334 }
335
336 // Prevent calls to process() and other functions on effect interface from now on.
337 // The effect engine will be released by the destructor when the last strong reference on
338 // this object is released which can happen after next process is called.
339 if (mHandles.size() == 0 && !mPinned) {
340 mState = DESTROYED;
341 }
342
343 return mHandles.size();
344 }
345
346 // must be called with EffectModule::mLock held
controlHandle_l()347 AudioFlinger::EffectHandle *AudioFlinger::EffectBase::controlHandle_l()
348 {
349 // the first valid handle in the list has control over the module
350 for (size_t i = 0; i < mHandles.size(); i++) {
351 EffectHandle *h = mHandles[i];
352 if (h != NULL && !h->disconnected()) {
353 return h;
354 }
355 }
356
357 return NULL;
358 }
359
360 // unsafe method called when the effect parent thread has been destroyed
disconnectHandle(EffectHandle * handle,bool unpinIfLast)361 ssize_t AudioFlinger::EffectBase::disconnectHandle(EffectHandle *handle, bool unpinIfLast)
362 {
363 const auto callback = getCallback();
364 ALOGV("disconnect() %p handle %p", this, handle);
365 if (callback->disconnectEffectHandle(handle, unpinIfLast)) {
366 return mHandles.size();
367 }
368
369 Mutex::Autolock _l(mLock);
370 ssize_t numHandles = removeHandle_l(handle);
371 if ((numHandles == 0) && (!mPinned || unpinIfLast)) {
372 mLock.unlock();
373 callback->updateOrphanEffectChains(this);
374 mLock.lock();
375 }
376 return numHandles;
377 }
378
purgeHandles()379 bool AudioFlinger::EffectBase::purgeHandles()
380 {
381 bool enabled = false;
382 Mutex::Autolock _l(mLock);
383 EffectHandle *handle = controlHandle_l();
384 if (handle != NULL) {
385 enabled = handle->enabled();
386 }
387 mHandles.clear();
388 return enabled;
389 }
390
checkSuspendOnEffectEnabled(bool enabled,bool threadLocked)391 void AudioFlinger::EffectBase::checkSuspendOnEffectEnabled(bool enabled, bool threadLocked) {
392 getCallback()->checkSuspendOnEffectEnabled(this, enabled, threadLocked);
393 }
394
effectFlagsToString(uint32_t flags)395 static String8 effectFlagsToString(uint32_t flags) {
396 String8 s;
397
398 s.append("conn. mode: ");
399 switch (flags & EFFECT_FLAG_TYPE_MASK) {
400 case EFFECT_FLAG_TYPE_INSERT: s.append("insert"); break;
401 case EFFECT_FLAG_TYPE_AUXILIARY: s.append("auxiliary"); break;
402 case EFFECT_FLAG_TYPE_REPLACE: s.append("replace"); break;
403 case EFFECT_FLAG_TYPE_PRE_PROC: s.append("preproc"); break;
404 case EFFECT_FLAG_TYPE_POST_PROC: s.append("postproc"); break;
405 default: s.append("unknown/reserved"); break;
406 }
407 s.append(", ");
408
409 s.append("insert pref: ");
410 switch (flags & EFFECT_FLAG_INSERT_MASK) {
411 case EFFECT_FLAG_INSERT_ANY: s.append("any"); break;
412 case EFFECT_FLAG_INSERT_FIRST: s.append("first"); break;
413 case EFFECT_FLAG_INSERT_LAST: s.append("last"); break;
414 case EFFECT_FLAG_INSERT_EXCLUSIVE: s.append("exclusive"); break;
415 default: s.append("unknown/reserved"); break;
416 }
417 s.append(", ");
418
419 s.append("volume mgmt: ");
420 switch (flags & EFFECT_FLAG_VOLUME_MASK) {
421 case EFFECT_FLAG_VOLUME_NONE: s.append("none"); break;
422 case EFFECT_FLAG_VOLUME_CTRL: s.append("implements control"); break;
423 case EFFECT_FLAG_VOLUME_IND: s.append("requires indication"); break;
424 case EFFECT_FLAG_VOLUME_MONITOR: s.append("monitors volume"); break;
425 default: s.append("unknown/reserved"); break;
426 }
427 s.append(", ");
428
429 uint32_t devind = flags & EFFECT_FLAG_DEVICE_MASK;
430 if (devind) {
431 s.append("device indication: ");
432 switch (devind) {
433 case EFFECT_FLAG_DEVICE_IND: s.append("requires updates"); break;
434 default: s.append("unknown/reserved"); break;
435 }
436 s.append(", ");
437 }
438
439 s.append("input mode: ");
440 switch (flags & EFFECT_FLAG_INPUT_MASK) {
441 case EFFECT_FLAG_INPUT_DIRECT: s.append("direct"); break;
442 case EFFECT_FLAG_INPUT_PROVIDER: s.append("provider"); break;
443 case EFFECT_FLAG_INPUT_BOTH: s.append("direct+provider"); break;
444 default: s.append("not set"); break;
445 }
446 s.append(", ");
447
448 s.append("output mode: ");
449 switch (flags & EFFECT_FLAG_OUTPUT_MASK) {
450 case EFFECT_FLAG_OUTPUT_DIRECT: s.append("direct"); break;
451 case EFFECT_FLAG_OUTPUT_PROVIDER: s.append("provider"); break;
452 case EFFECT_FLAG_OUTPUT_BOTH: s.append("direct+provider"); break;
453 default: s.append("not set"); break;
454 }
455 s.append(", ");
456
457 uint32_t accel = flags & EFFECT_FLAG_HW_ACC_MASK;
458 if (accel) {
459 s.append("hardware acceleration: ");
460 switch (accel) {
461 case EFFECT_FLAG_HW_ACC_SIMPLE: s.append("non-tunneled"); break;
462 case EFFECT_FLAG_HW_ACC_TUNNEL: s.append("tunneled"); break;
463 default: s.append("unknown/reserved"); break;
464 }
465 s.append(", ");
466 }
467
468 uint32_t modeind = flags & EFFECT_FLAG_AUDIO_MODE_MASK;
469 if (modeind) {
470 s.append("mode indication: ");
471 switch (modeind) {
472 case EFFECT_FLAG_AUDIO_MODE_IND: s.append("required"); break;
473 default: s.append("unknown/reserved"); break;
474 }
475 s.append(", ");
476 }
477
478 uint32_t srcind = flags & EFFECT_FLAG_AUDIO_SOURCE_MASK;
479 if (srcind) {
480 s.append("source indication: ");
481 switch (srcind) {
482 case EFFECT_FLAG_AUDIO_SOURCE_IND: s.append("required"); break;
483 default: s.append("unknown/reserved"); break;
484 }
485 s.append(", ");
486 }
487
488 if (flags & EFFECT_FLAG_OFFLOAD_MASK) {
489 s.append("offloadable, ");
490 }
491
492 int len = s.length();
493 if (s.length() > 2) {
494 (void) s.lockBuffer(len);
495 s.unlockBuffer(len - 2);
496 }
497 return s;
498 }
499
dump(int fd,const Vector<String16> & args __unused)500 void AudioFlinger::EffectBase::dump(int fd, const Vector<String16>& args __unused)
501 {
502 String8 result;
503
504 result.appendFormat("\tEffect ID %d:\n", mId);
505
506 bool locked = AudioFlinger::dumpTryLock(mLock);
507 // failed to lock - AudioFlinger is probably deadlocked
508 if (!locked) {
509 result.append("\t\tCould not lock Fx mutex:\n");
510 }
511
512 result.append("\t\tSession State Registered Enabled Suspended:\n");
513 result.appendFormat("\t\t%05d %03d %s %s %s\n",
514 mSessionId, mState, mPolicyRegistered ? "y" : "n",
515 mPolicyEnabled ? "y" : "n", mSuspended ? "y" : "n");
516
517 result.append("\t\tDescriptor:\n");
518 char uuidStr[64];
519 AudioEffect::guidToString(&mDescriptor.uuid, uuidStr, sizeof(uuidStr));
520 result.appendFormat("\t\t- UUID: %s\n", uuidStr);
521 AudioEffect::guidToString(&mDescriptor.type, uuidStr, sizeof(uuidStr));
522 result.appendFormat("\t\t- TYPE: %s\n", uuidStr);
523 result.appendFormat("\t\t- apiVersion: %08X\n\t\t- flags: %08X (%s)\n",
524 mDescriptor.apiVersion,
525 mDescriptor.flags,
526 effectFlagsToString(mDescriptor.flags).string());
527 result.appendFormat("\t\t- name: %s\n",
528 mDescriptor.name);
529
530 result.appendFormat("\t\t- implementor: %s\n",
531 mDescriptor.implementor);
532
533 result.appendFormat("\t\t%zu Clients:\n", mHandles.size());
534 result.append("\t\t\t Pid Priority Ctrl Locked client server\n");
535 char buffer[256];
536 for (size_t i = 0; i < mHandles.size(); ++i) {
537 EffectHandle *handle = mHandles[i];
538 if (handle != NULL && !handle->disconnected()) {
539 handle->dumpToBuffer(buffer, sizeof(buffer));
540 result.append(buffer);
541 }
542 }
543 if (locked) {
544 mLock.unlock();
545 }
546
547 write(fd, result.string(), result.length());
548 }
549
550 // ----------------------------------------------------------------------------
551 // EffectModule implementation
552 // ----------------------------------------------------------------------------
553
554 #undef LOG_TAG
555 #define LOG_TAG "AudioFlinger::EffectModule"
556
EffectModule(const sp<AudioFlinger::EffectCallbackInterface> & callback,effect_descriptor_t * desc,int id,audio_session_t sessionId,bool pinned,audio_port_handle_t deviceId)557 AudioFlinger::EffectModule::EffectModule(const sp<AudioFlinger::EffectCallbackInterface>& callback,
558 effect_descriptor_t *desc,
559 int id,
560 audio_session_t sessionId,
561 bool pinned,
562 audio_port_handle_t deviceId)
563 : EffectBase(callback, desc, id, sessionId, pinned),
564 // clear mConfig to ensure consistent initial value of buffer framecount
565 // in case buffers are associated by setInBuffer() or setOutBuffer()
566 // prior to configure().
567 mConfig{{}, {}},
568 mStatus(NO_INIT),
569 mMaxDisableWaitCnt(1), // set by configure(), should be >= 1
570 mDisableWaitCnt(0), // set by process() and updateState()
571 mOffloaded(false),
572 mAddedToHal(false)
573 #ifdef FLOAT_EFFECT_CHAIN
574 , mSupportsFloat(false)
575 #endif
576 {
577 ALOGV("Constructor %p pinned %d", this, pinned);
578 int lStatus;
579
580 // create effect engine from effect factory
581 mStatus = callback->createEffectHal(
582 &desc->uuid, sessionId, deviceId, &mEffectInterface);
583 if (mStatus != NO_ERROR) {
584 return;
585 }
586 lStatus = init();
587 if (lStatus < 0) {
588 mStatus = lStatus;
589 goto Error;
590 }
591
592 setOffloaded(callback->isOffload(), callback->io());
593 ALOGV("Constructor success name %s, Interface %p", mDescriptor.name, mEffectInterface.get());
594
595 return;
596 Error:
597 mEffectInterface.clear();
598 ALOGV("Constructor Error %d", mStatus);
599 }
600
~EffectModule()601 AudioFlinger::EffectModule::~EffectModule()
602 {
603 ALOGV("Destructor %p", this);
604 if (mEffectInterface != 0) {
605 char uuidStr[64];
606 AudioEffect::guidToString(&mDescriptor.uuid, uuidStr, sizeof(uuidStr));
607 ALOGW("EffectModule %p destructor called with unreleased interface, effect %s",
608 this, uuidStr);
609 release_l();
610 }
611
612 }
613
updateState()614 bool AudioFlinger::EffectModule::updateState() {
615 Mutex::Autolock _l(mLock);
616
617 bool started = false;
618 switch (mState) {
619 case RESTART:
620 reset_l();
621 FALLTHROUGH_INTENDED;
622
623 case STARTING:
624 // clear auxiliary effect input buffer for next accumulation
625 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
626 memset(mConfig.inputCfg.buffer.raw,
627 0,
628 mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
629 }
630 if (start_l() == NO_ERROR) {
631 mState = ACTIVE;
632 started = true;
633 } else {
634 mState = IDLE;
635 }
636 break;
637 case STOPPING:
638 // volume control for offload and direct threads must take effect immediately.
639 if (stop_l() == NO_ERROR
640 && !(isVolumeControl() && isOffloadedOrDirect())) {
641 mDisableWaitCnt = mMaxDisableWaitCnt;
642 } else {
643 mDisableWaitCnt = 1; // will cause immediate transition to IDLE
644 }
645 mState = STOPPED;
646 break;
647 case STOPPED:
648 // mDisableWaitCnt is forced to 1 by process() when the engine indicates the end of the
649 // turn off sequence.
650 if (--mDisableWaitCnt == 0) {
651 reset_l();
652 mState = IDLE;
653 }
654 break;
655 case ACTIVE:
656 for (size_t i = 0; i < mHandles.size(); i++) {
657 if (!mHandles[i]->disconnected()) {
658 mHandles[i]->framesProcessed(mConfig.inputCfg.buffer.frameCount);
659 }
660 }
661 break;
662 default: //IDLE , ACTIVE, DESTROYED
663 break;
664 }
665
666 return started;
667 }
668
process()669 void AudioFlinger::EffectModule::process()
670 {
671 Mutex::Autolock _l(mLock);
672
673 if (mState == DESTROYED || mEffectInterface == 0 || mInBuffer == 0 || mOutBuffer == 0) {
674 return;
675 }
676
677 const uint32_t inChannelCount =
678 audio_channel_count_from_out_mask(mConfig.inputCfg.channels);
679 const uint32_t outChannelCount =
680 audio_channel_count_from_out_mask(mConfig.outputCfg.channels);
681 const bool auxType =
682 (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY;
683
684 // safeInputOutputSampleCount is 0 if the channel count between input and output
685 // buffers do not match. This prevents automatic accumulation or copying between the
686 // input and output effect buffers without an intermediary effect process.
687 // TODO: consider implementing channel conversion.
688 const size_t safeInputOutputSampleCount =
689 mInChannelCountRequested != mOutChannelCountRequested ? 0
690 : mOutChannelCountRequested * std::min(
691 mConfig.inputCfg.buffer.frameCount,
692 mConfig.outputCfg.buffer.frameCount);
693 const auto accumulateInputToOutput = [this, safeInputOutputSampleCount]() {
694 #ifdef FLOAT_EFFECT_CHAIN
695 accumulate_float(
696 mConfig.outputCfg.buffer.f32,
697 mConfig.inputCfg.buffer.f32,
698 safeInputOutputSampleCount);
699 #else
700 accumulate_i16(
701 mConfig.outputCfg.buffer.s16,
702 mConfig.inputCfg.buffer.s16,
703 safeInputOutputSampleCount);
704 #endif
705 };
706 const auto copyInputToOutput = [this, safeInputOutputSampleCount]() {
707 #ifdef FLOAT_EFFECT_CHAIN
708 memcpy(
709 mConfig.outputCfg.buffer.f32,
710 mConfig.inputCfg.buffer.f32,
711 safeInputOutputSampleCount * sizeof(*mConfig.outputCfg.buffer.f32));
712
713 #else
714 memcpy(
715 mConfig.outputCfg.buffer.s16,
716 mConfig.inputCfg.buffer.s16,
717 safeInputOutputSampleCount * sizeof(*mConfig.outputCfg.buffer.s16));
718 #endif
719 };
720
721 if (isProcessEnabled()) {
722 int ret;
723 if (isProcessImplemented()) {
724 if (auxType) {
725 // We overwrite the aux input buffer here and clear after processing.
726 // aux input is always mono.
727 #ifdef FLOAT_EFFECT_CHAIN
728 if (mSupportsFloat) {
729 #ifndef FLOAT_AUX
730 // Do in-place float conversion for auxiliary effect input buffer.
731 static_assert(sizeof(float) <= sizeof(int32_t),
732 "in-place conversion requires sizeof(float) <= sizeof(int32_t)");
733
734 memcpy_to_float_from_q4_27(
735 mConfig.inputCfg.buffer.f32,
736 mConfig.inputCfg.buffer.s32,
737 mConfig.inputCfg.buffer.frameCount);
738 #endif // !FLOAT_AUX
739 } else
740 #endif // FLOAT_EFFECT_CHAIN
741 {
742 #ifdef FLOAT_AUX
743 memcpy_to_i16_from_float(
744 mConfig.inputCfg.buffer.s16,
745 mConfig.inputCfg.buffer.f32,
746 mConfig.inputCfg.buffer.frameCount);
747 #else
748 memcpy_to_i16_from_q4_27(
749 mConfig.inputCfg.buffer.s16,
750 mConfig.inputCfg.buffer.s32,
751 mConfig.inputCfg.buffer.frameCount);
752 #endif
753 }
754 }
755 #ifdef FLOAT_EFFECT_CHAIN
756 sp<EffectBufferHalInterface> inBuffer = mInBuffer;
757 sp<EffectBufferHalInterface> outBuffer = mOutBuffer;
758
759 if (!auxType && mInChannelCountRequested != inChannelCount) {
760 adjust_channels(
761 inBuffer->audioBuffer()->f32, mInChannelCountRequested,
762 mInConversionBuffer->audioBuffer()->f32, inChannelCount,
763 sizeof(float),
764 sizeof(float)
765 * mInChannelCountRequested * mConfig.inputCfg.buffer.frameCount);
766 inBuffer = mInConversionBuffer;
767 }
768 if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE
769 && mOutChannelCountRequested != outChannelCount) {
770 adjust_selected_channels(
771 outBuffer->audioBuffer()->f32, mOutChannelCountRequested,
772 mOutConversionBuffer->audioBuffer()->f32, outChannelCount,
773 sizeof(float),
774 sizeof(float)
775 * mOutChannelCountRequested * mConfig.outputCfg.buffer.frameCount);
776 outBuffer = mOutConversionBuffer;
777 }
778 if (!mSupportsFloat) { // convert input to int16_t as effect doesn't support float.
779 if (!auxType) {
780 if (mInConversionBuffer == nullptr) {
781 ALOGW("%s: mInConversionBuffer is null, bypassing", __func__);
782 goto data_bypass;
783 }
784 memcpy_to_i16_from_float(
785 mInConversionBuffer->audioBuffer()->s16,
786 inBuffer->audioBuffer()->f32,
787 inChannelCount * mConfig.inputCfg.buffer.frameCount);
788 inBuffer = mInConversionBuffer;
789 }
790 if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
791 if (mOutConversionBuffer == nullptr) {
792 ALOGW("%s: mOutConversionBuffer is null, bypassing", __func__);
793 goto data_bypass;
794 }
795 memcpy_to_i16_from_float(
796 mOutConversionBuffer->audioBuffer()->s16,
797 outBuffer->audioBuffer()->f32,
798 outChannelCount * mConfig.outputCfg.buffer.frameCount);
799 outBuffer = mOutConversionBuffer;
800 }
801 }
802 #endif
803 ret = mEffectInterface->process();
804 #ifdef FLOAT_EFFECT_CHAIN
805 if (!mSupportsFloat) { // convert output int16_t back to float.
806 sp<EffectBufferHalInterface> target =
807 mOutChannelCountRequested != outChannelCount
808 ? mOutConversionBuffer : mOutBuffer;
809
810 memcpy_to_float_from_i16(
811 target->audioBuffer()->f32,
812 mOutConversionBuffer->audioBuffer()->s16,
813 outChannelCount * mConfig.outputCfg.buffer.frameCount);
814 }
815 if (mOutChannelCountRequested != outChannelCount) {
816 adjust_selected_channels(mOutConversionBuffer->audioBuffer()->f32, outChannelCount,
817 mOutBuffer->audioBuffer()->f32, mOutChannelCountRequested,
818 sizeof(float),
819 sizeof(float) * outChannelCount * mConfig.outputCfg.buffer.frameCount);
820 }
821 #endif
822 } else {
823 #ifdef FLOAT_EFFECT_CHAIN
824 data_bypass:
825 #endif
826 if (!auxType /* aux effects do not require data bypass */
827 && mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
828 if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
829 accumulateInputToOutput();
830 } else {
831 copyInputToOutput();
832 }
833 }
834 ret = -ENODATA;
835 }
836
837 // force transition to IDLE state when engine is ready
838 if (mState == STOPPED && ret == -ENODATA) {
839 mDisableWaitCnt = 1;
840 }
841
842 // clear auxiliary effect input buffer for next accumulation
843 if (auxType) {
844 #ifdef FLOAT_AUX
845 const size_t size =
846 mConfig.inputCfg.buffer.frameCount * inChannelCount * sizeof(float);
847 #else
848 const size_t size =
849 mConfig.inputCfg.buffer.frameCount * inChannelCount * sizeof(int32_t);
850 #endif
851 memset(mConfig.inputCfg.buffer.raw, 0, size);
852 }
853 } else if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT &&
854 // mInBuffer->audioBuffer()->raw != mOutBuffer->audioBuffer()->raw
855 mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
856 // If an insert effect is idle and input buffer is different from output buffer,
857 // accumulate input onto output
858 if (getCallback()->activeTrackCnt() != 0) {
859 // similar handling with data_bypass above.
860 if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
861 accumulateInputToOutput();
862 } else { // EFFECT_BUFFER_ACCESS_WRITE
863 copyInputToOutput();
864 }
865 }
866 }
867 }
868
reset_l()869 void AudioFlinger::EffectModule::reset_l()
870 {
871 if (mStatus != NO_ERROR || mEffectInterface == 0) {
872 return;
873 }
874 mEffectInterface->command(EFFECT_CMD_RESET, 0, NULL, 0, NULL);
875 }
876
configure()877 status_t AudioFlinger::EffectModule::configure()
878 {
879 ALOGVV("configure() started");
880 status_t status;
881 uint32_t size;
882 audio_channel_mask_t channelMask;
883 sp<EffectCallbackInterface> callback;
884
885 if (mEffectInterface == 0) {
886 status = NO_INIT;
887 goto exit;
888 }
889
890 // TODO: handle configuration of effects replacing track process
891 // TODO: handle configuration of input (record) SW effects above the HAL,
892 // similar to output EFFECT_FLAG_TYPE_INSERT/REPLACE,
893 // in which case input channel masks should be used here.
894 callback = getCallback();
895 channelMask = callback->inChannelMask(mId);
896 mConfig.inputCfg.channels = channelMask;
897 mConfig.outputCfg.channels = callback->outChannelMask();
898
899 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
900 if (mConfig.inputCfg.channels != AUDIO_CHANNEL_OUT_MONO) {
901 mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO;
902 ALOGV("Overriding auxiliary effect input channels %#x as MONO",
903 mConfig.inputCfg.channels);
904 }
905 #ifndef MULTICHANNEL_EFFECT_CHAIN
906 if (mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) {
907 mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
908 ALOGV("Overriding auxiliary effect output channels %#x as STEREO",
909 mConfig.outputCfg.channels);
910 }
911 #endif
912 } else {
913 #ifndef MULTICHANNEL_EFFECT_CHAIN
914 // TODO: Update this logic when multichannel effects are implemented.
915 // For offloaded tracks consider mono output as stereo for proper effect initialization
916 if (channelMask == AUDIO_CHANNEL_OUT_MONO) {
917 mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
918 mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
919 ALOGV("Overriding effect input and output as STEREO");
920 }
921 #endif
922 }
923 if (isHapticGenerator()) {
924 audio_channel_mask_t hapticChannelMask = callback->hapticChannelMask();
925 mConfig.inputCfg.channels |= hapticChannelMask;
926 mConfig.outputCfg.channels |= hapticChannelMask;
927 }
928 mInChannelCountRequested =
929 audio_channel_count_from_out_mask(mConfig.inputCfg.channels);
930 mOutChannelCountRequested =
931 audio_channel_count_from_out_mask(mConfig.outputCfg.channels);
932
933 mConfig.inputCfg.format = EFFECT_BUFFER_FORMAT;
934 mConfig.outputCfg.format = EFFECT_BUFFER_FORMAT;
935
936 // Don't use sample rate for thread if effect isn't offloadable.
937 if (callback->isOffloadOrDirect() && !isOffloaded()) {
938 mConfig.inputCfg.samplingRate = DEFAULT_OUTPUT_SAMPLE_RATE;
939 ALOGV("Overriding effect input as 48kHz");
940 } else {
941 mConfig.inputCfg.samplingRate = callback->sampleRate();
942 }
943 mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate;
944 mConfig.inputCfg.bufferProvider.cookie = NULL;
945 mConfig.inputCfg.bufferProvider.getBuffer = NULL;
946 mConfig.inputCfg.bufferProvider.releaseBuffer = NULL;
947 mConfig.outputCfg.bufferProvider.cookie = NULL;
948 mConfig.outputCfg.bufferProvider.getBuffer = NULL;
949 mConfig.outputCfg.bufferProvider.releaseBuffer = NULL;
950 mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ;
951 // Insert effect:
952 // - in global sessions (e.g AUDIO_SESSION_OUTPUT_MIX),
953 // always overwrites output buffer: input buffer == output buffer
954 // - in other sessions:
955 // last effect in the chain accumulates in output buffer: input buffer != output buffer
956 // other effect: overwrites output buffer: input buffer == output buffer
957 // Auxiliary effect:
958 // accumulates in output buffer: input buffer != output buffer
959 // Therefore: accumulate <=> input buffer != output buffer
960 mConfig.outputCfg.accessMode = requiredEffectBufferAccessMode();
961 mConfig.inputCfg.mask = EFFECT_CONFIG_ALL;
962 mConfig.outputCfg.mask = EFFECT_CONFIG_ALL;
963 mConfig.inputCfg.buffer.frameCount = callback->frameCount();
964 mConfig.outputCfg.buffer.frameCount = mConfig.inputCfg.buffer.frameCount;
965
966 ALOGV("configure() %p chain %p buffer %p framecount %zu",
967 this, callback->chain().promote().get(),
968 mConfig.inputCfg.buffer.raw, mConfig.inputCfg.buffer.frameCount);
969
970 status_t cmdStatus;
971 size = sizeof(int);
972 status = mEffectInterface->command(EFFECT_CMD_SET_CONFIG,
973 sizeof(mConfig),
974 &mConfig,
975 &size,
976 &cmdStatus);
977 if (status == NO_ERROR) {
978 status = cmdStatus;
979 }
980
981 #ifdef MULTICHANNEL_EFFECT_CHAIN
982 if (status != NO_ERROR &&
983 callback->isOutput() &&
984 (mConfig.inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO
985 || mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO)) {
986 // Older effects may require exact STEREO position mask.
987 if (mConfig.inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO
988 && (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_AUXILIARY) {
989 ALOGV("Overriding effect input channels %#x as STEREO", mConfig.inputCfg.channels);
990 mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
991 }
992 if (mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) {
993 ALOGV("Overriding effect output channels %#x as STEREO", mConfig.outputCfg.channels);
994 mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
995 }
996 size = sizeof(int);
997 status = mEffectInterface->command(EFFECT_CMD_SET_CONFIG,
998 sizeof(mConfig),
999 &mConfig,
1000 &size,
1001 &cmdStatus);
1002 if (status == NO_ERROR) {
1003 status = cmdStatus;
1004 }
1005 }
1006 #endif
1007
1008 #ifdef FLOAT_EFFECT_CHAIN
1009 if (status == NO_ERROR) {
1010 mSupportsFloat = true;
1011 }
1012
1013 if (status != NO_ERROR) {
1014 ALOGV("EFFECT_CMD_SET_CONFIG failed with float format, retry with int16_t.");
1015 mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1016 mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
1017 size = sizeof(int);
1018 status = mEffectInterface->command(EFFECT_CMD_SET_CONFIG,
1019 sizeof(mConfig),
1020 &mConfig,
1021 &size,
1022 &cmdStatus);
1023 if (status == NO_ERROR) {
1024 status = cmdStatus;
1025 }
1026 if (status == NO_ERROR) {
1027 mSupportsFloat = false;
1028 ALOGVV("config worked with 16 bit");
1029 } else {
1030 ALOGE("%s failed %d with int16_t (as well as float)", __func__, status);
1031 }
1032 }
1033 #endif
1034
1035 if (status == NO_ERROR) {
1036 // Establish Buffer strategy
1037 setInBuffer(mInBuffer);
1038 setOutBuffer(mOutBuffer);
1039
1040 // Update visualizer latency
1041 if (memcmp(&mDescriptor.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) {
1042 uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
1043 effect_param_t *p = (effect_param_t *)buf32;
1044
1045 p->psize = sizeof(uint32_t);
1046 p->vsize = sizeof(uint32_t);
1047 size = sizeof(int);
1048 *(int32_t *)p->data = VISUALIZER_PARAM_LATENCY;
1049
1050 uint32_t latency = callback->latency();
1051
1052 *((int32_t *)p->data + 1)= latency;
1053 mEffectInterface->command(EFFECT_CMD_SET_PARAM,
1054 sizeof(effect_param_t) + 8,
1055 &buf32,
1056 &size,
1057 &cmdStatus);
1058 }
1059 }
1060
1061 // mConfig.outputCfg.buffer.frameCount cannot be zero.
1062 mMaxDisableWaitCnt = (uint32_t)std::max(
1063 (uint64_t)1, // mMaxDisableWaitCnt must be greater than zero.
1064 (uint64_t)MAX_DISABLE_TIME_MS * mConfig.outputCfg.samplingRate
1065 / ((uint64_t)1000 * mConfig.outputCfg.buffer.frameCount));
1066
1067 exit:
1068 // TODO: consider clearing mConfig on error.
1069 mStatus = status;
1070 ALOGVV("configure ended");
1071 return status;
1072 }
1073
init()1074 status_t AudioFlinger::EffectModule::init()
1075 {
1076 Mutex::Autolock _l(mLock);
1077 if (mEffectInterface == 0) {
1078 return NO_INIT;
1079 }
1080 status_t cmdStatus;
1081 uint32_t size = sizeof(status_t);
1082 status_t status = mEffectInterface->command(EFFECT_CMD_INIT,
1083 0,
1084 NULL,
1085 &size,
1086 &cmdStatus);
1087 if (status == 0) {
1088 status = cmdStatus;
1089 }
1090 return status;
1091 }
1092
addEffectToHal_l()1093 void AudioFlinger::EffectModule::addEffectToHal_l()
1094 {
1095 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
1096 (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
1097 if (mAddedToHal) {
1098 return;
1099 }
1100
1101 (void)getCallback()->addEffectToHal(mEffectInterface);
1102 mAddedToHal = true;
1103 }
1104 }
1105
1106 // start() must be called with PlaybackThread::mLock or EffectChain::mLock held
start()1107 status_t AudioFlinger::EffectModule::start()
1108 {
1109 status_t status;
1110 {
1111 Mutex::Autolock _l(mLock);
1112 status = start_l();
1113 }
1114 if (status == NO_ERROR) {
1115 getCallback()->resetVolume();
1116 }
1117 return status;
1118 }
1119
start_l()1120 status_t AudioFlinger::EffectModule::start_l()
1121 {
1122 if (mEffectInterface == 0) {
1123 return NO_INIT;
1124 }
1125 if (mStatus != NO_ERROR) {
1126 return mStatus;
1127 }
1128 status_t cmdStatus;
1129 uint32_t size = sizeof(status_t);
1130 status_t status = mEffectInterface->command(EFFECT_CMD_ENABLE,
1131 0,
1132 NULL,
1133 &size,
1134 &cmdStatus);
1135 if (status == 0) {
1136 status = cmdStatus;
1137 }
1138 if (status == 0) {
1139 addEffectToHal_l();
1140 }
1141 return status;
1142 }
1143
stop()1144 status_t AudioFlinger::EffectModule::stop()
1145 {
1146 Mutex::Autolock _l(mLock);
1147 return stop_l();
1148 }
1149
stop_l()1150 status_t AudioFlinger::EffectModule::stop_l()
1151 {
1152 if (mEffectInterface == 0) {
1153 return NO_INIT;
1154 }
1155 if (mStatus != NO_ERROR) {
1156 return mStatus;
1157 }
1158 status_t cmdStatus = NO_ERROR;
1159 uint32_t size = sizeof(status_t);
1160
1161 if (isVolumeControl() && isOffloadedOrDirect()) {
1162 // We have the EffectChain and EffectModule lock, permit a reentrant call to setVolume:
1163 // resetVolume_l --> setVolume_l --> EffectModule::setVolume
1164 mSetVolumeReentrantTid = gettid();
1165 getCallback()->resetVolume();
1166 mSetVolumeReentrantTid = INVALID_PID;
1167 }
1168
1169 status_t status = mEffectInterface->command(EFFECT_CMD_DISABLE,
1170 0,
1171 NULL,
1172 &size,
1173 &cmdStatus);
1174 if (status == NO_ERROR) {
1175 status = cmdStatus;
1176 }
1177 if (status == NO_ERROR) {
1178 status = removeEffectFromHal_l();
1179 }
1180 return status;
1181 }
1182
1183 // must be called with EffectChain::mLock held
release_l()1184 void AudioFlinger::EffectModule::release_l()
1185 {
1186 if (mEffectInterface != 0) {
1187 removeEffectFromHal_l();
1188 // release effect engine
1189 mEffectInterface->close();
1190 mEffectInterface.clear();
1191 }
1192 }
1193
removeEffectFromHal_l()1194 status_t AudioFlinger::EffectModule::removeEffectFromHal_l()
1195 {
1196 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
1197 (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
1198 if (!mAddedToHal) {
1199 return NO_ERROR;
1200 }
1201
1202 getCallback()->removeEffectFromHal(mEffectInterface);
1203 mAddedToHal = false;
1204 }
1205 return NO_ERROR;
1206 }
1207
1208 // round up delta valid if value and divisor are positive.
1209 template <typename T>
roundUpDelta(const T & value,const T & divisor)1210 static T roundUpDelta(const T &value, const T &divisor) {
1211 T remainder = value % divisor;
1212 return remainder == 0 ? 0 : divisor - remainder;
1213 }
1214
command(int32_t cmdCode,const std::vector<uint8_t> & cmdData,int32_t maxReplySize,std::vector<uint8_t> * reply)1215 status_t AudioFlinger::EffectModule::command(int32_t cmdCode,
1216 const std::vector<uint8_t>& cmdData,
1217 int32_t maxReplySize,
1218 std::vector<uint8_t>* reply)
1219 {
1220 Mutex::Autolock _l(mLock);
1221 ALOGVV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface.get());
1222
1223 if (mState == DESTROYED || mEffectInterface == 0) {
1224 return NO_INIT;
1225 }
1226 if (mStatus != NO_ERROR) {
1227 return mStatus;
1228 }
1229 if (maxReplySize < 0 || maxReplySize > EFFECT_PARAM_SIZE_MAX) {
1230 return -EINVAL;
1231 }
1232 size_t cmdSize = cmdData.size();
1233 const effect_param_t* param = cmdSize >= sizeof(effect_param_t)
1234 ? reinterpret_cast<const effect_param_t*>(cmdData.data())
1235 : nullptr;
1236 if (cmdCode == EFFECT_CMD_GET_PARAM &&
1237 (param == nullptr || param->psize > cmdSize - sizeof(effect_param_t))) {
1238 android_errorWriteLog(0x534e4554, "32438594");
1239 android_errorWriteLog(0x534e4554, "33003822");
1240 return -EINVAL;
1241 }
1242 if (cmdCode == EFFECT_CMD_GET_PARAM &&
1243 (maxReplySize < sizeof(effect_param_t) ||
1244 param->psize > maxReplySize - sizeof(effect_param_t))) {
1245 android_errorWriteLog(0x534e4554, "29251553");
1246 return -EINVAL;
1247 }
1248 if (cmdCode == EFFECT_CMD_GET_PARAM &&
1249 (sizeof(effect_param_t) > maxReplySize
1250 || param->psize > maxReplySize - sizeof(effect_param_t)
1251 || param->vsize > maxReplySize - sizeof(effect_param_t)
1252 - param->psize
1253 || roundUpDelta(param->psize, (uint32_t) sizeof(int)) >
1254 maxReplySize
1255 - sizeof(effect_param_t)
1256 - param->psize
1257 - param->vsize)) {
1258 ALOGV("\tLVM_ERROR : EFFECT_CMD_GET_PARAM: reply size inconsistent");
1259 android_errorWriteLog(0x534e4554, "32705438");
1260 return -EINVAL;
1261 }
1262 if ((cmdCode == EFFECT_CMD_SET_PARAM
1263 || cmdCode == EFFECT_CMD_SET_PARAM_DEFERRED)
1264 && // DEFERRED not generally used
1265 (param == nullptr
1266 || param->psize > cmdSize - sizeof(effect_param_t)
1267 || param->vsize > cmdSize - sizeof(effect_param_t)
1268 - param->psize
1269 || roundUpDelta(param->psize,
1270 (uint32_t) sizeof(int)) >
1271 cmdSize
1272 - sizeof(effect_param_t)
1273 - param->psize
1274 - param->vsize)) {
1275 android_errorWriteLog(0x534e4554, "30204301");
1276 return -EINVAL;
1277 }
1278 uint32_t replySize = maxReplySize;
1279 reply->resize(replySize);
1280 status_t status = mEffectInterface->command(cmdCode,
1281 cmdSize,
1282 const_cast<uint8_t*>(cmdData.data()),
1283 &replySize,
1284 reply->data());
1285 reply->resize(status == NO_ERROR ? replySize : 0);
1286 if (cmdCode != EFFECT_CMD_GET_PARAM && status == NO_ERROR) {
1287 for (size_t i = 1; i < mHandles.size(); i++) {
1288 EffectHandle *h = mHandles[i];
1289 if (h != NULL && !h->disconnected()) {
1290 h->commandExecuted(cmdCode, cmdData, *reply);
1291 }
1292 }
1293 }
1294 return status;
1295 }
1296
isProcessEnabled() const1297 bool AudioFlinger::EffectModule::isProcessEnabled() const
1298 {
1299 if (mStatus != NO_ERROR) {
1300 return false;
1301 }
1302
1303 switch (mState) {
1304 case RESTART:
1305 case ACTIVE:
1306 case STOPPING:
1307 case STOPPED:
1308 return true;
1309 case IDLE:
1310 case STARTING:
1311 case DESTROYED:
1312 default:
1313 return false;
1314 }
1315 }
1316
isOffloadedOrDirect() const1317 bool AudioFlinger::EffectModule::isOffloadedOrDirect() const
1318 {
1319 return getCallback()->isOffloadOrDirect();
1320 }
1321
isVolumeControlEnabled() const1322 bool AudioFlinger::EffectModule::isVolumeControlEnabled() const
1323 {
1324 return (isVolumeControl() && (isOffloadedOrDirect() ? isEnabled() : isProcessEnabled()));
1325 }
1326
setInBuffer(const sp<EffectBufferHalInterface> & buffer)1327 void AudioFlinger::EffectModule::setInBuffer(const sp<EffectBufferHalInterface>& buffer) {
1328 ALOGVV("setInBuffer %p",(&buffer));
1329
1330 // mConfig.inputCfg.buffer.frameCount may be zero if configure() is not called yet.
1331 if (buffer != 0) {
1332 mConfig.inputCfg.buffer.raw = buffer->audioBuffer()->raw;
1333 buffer->setFrameCount(mConfig.inputCfg.buffer.frameCount);
1334 } else {
1335 mConfig.inputCfg.buffer.raw = NULL;
1336 }
1337 mInBuffer = buffer;
1338 mEffectInterface->setInBuffer(buffer);
1339
1340 #ifdef FLOAT_EFFECT_CHAIN
1341 // aux effects do in place conversion to float - we don't allocate mInConversionBuffer.
1342 // Theoretically insert effects can also do in-place conversions (destroying
1343 // the original buffer) when the output buffer is identical to the input buffer,
1344 // but we don't optimize for it here.
1345 const bool auxType = (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY;
1346 const uint32_t inChannelCount =
1347 audio_channel_count_from_out_mask(mConfig.inputCfg.channels);
1348 const bool formatMismatch = !mSupportsFloat || mInChannelCountRequested != inChannelCount;
1349 if (!auxType && formatMismatch && mInBuffer != nullptr) {
1350 // we need to translate - create hidl shared buffer and intercept
1351 const size_t inFrameCount = mConfig.inputCfg.buffer.frameCount;
1352 // Use FCC_2 in case mInChannelCountRequested is mono and the effect is stereo.
1353 const uint32_t inChannels = std::max((uint32_t)FCC_2, mInChannelCountRequested);
1354 const size_t size = inChannels * inFrameCount * std::max(sizeof(int16_t), sizeof(float));
1355
1356 ALOGV("%s: setInBuffer updating for inChannels:%d inFrameCount:%zu total size:%zu",
1357 __func__, inChannels, inFrameCount, size);
1358
1359 if (size > 0 && (mInConversionBuffer == nullptr
1360 || size > mInConversionBuffer->getSize())) {
1361 mInConversionBuffer.clear();
1362 ALOGV("%s: allocating mInConversionBuffer %zu", __func__, size);
1363 (void)getCallback()->allocateHalBuffer(size, &mInConversionBuffer);
1364 }
1365 if (mInConversionBuffer != nullptr) {
1366 mInConversionBuffer->setFrameCount(inFrameCount);
1367 mEffectInterface->setInBuffer(mInConversionBuffer);
1368 } else if (size > 0) {
1369 ALOGE("%s cannot create mInConversionBuffer", __func__);
1370 }
1371 }
1372 #endif
1373 }
1374
setOutBuffer(const sp<EffectBufferHalInterface> & buffer)1375 void AudioFlinger::EffectModule::setOutBuffer(const sp<EffectBufferHalInterface>& buffer) {
1376 ALOGVV("setOutBuffer %p",(&buffer));
1377
1378 // mConfig.outputCfg.buffer.frameCount may be zero if configure() is not called yet.
1379 if (buffer != 0) {
1380 mConfig.outputCfg.buffer.raw = buffer->audioBuffer()->raw;
1381 buffer->setFrameCount(mConfig.outputCfg.buffer.frameCount);
1382 } else {
1383 mConfig.outputCfg.buffer.raw = NULL;
1384 }
1385 mOutBuffer = buffer;
1386 mEffectInterface->setOutBuffer(buffer);
1387
1388 #ifdef FLOAT_EFFECT_CHAIN
1389 // Note: Any effect that does not accumulate does not need mOutConversionBuffer and
1390 // can do in-place conversion from int16_t to float. We don't optimize here.
1391 const uint32_t outChannelCount =
1392 audio_channel_count_from_out_mask(mConfig.outputCfg.channels);
1393 const bool formatMismatch = !mSupportsFloat || mOutChannelCountRequested != outChannelCount;
1394 if (formatMismatch && mOutBuffer != nullptr) {
1395 const size_t outFrameCount = mConfig.outputCfg.buffer.frameCount;
1396 // Use FCC_2 in case mOutChannelCountRequested is mono and the effect is stereo.
1397 const uint32_t outChannels = std::max((uint32_t)FCC_2, mOutChannelCountRequested);
1398 const size_t size = outChannels * outFrameCount * std::max(sizeof(int16_t), sizeof(float));
1399
1400 ALOGV("%s: setOutBuffer updating for outChannels:%d outFrameCount:%zu total size:%zu",
1401 __func__, outChannels, outFrameCount, size);
1402
1403 if (size > 0 && (mOutConversionBuffer == nullptr
1404 || size > mOutConversionBuffer->getSize())) {
1405 mOutConversionBuffer.clear();
1406 ALOGV("%s: allocating mOutConversionBuffer %zu", __func__, size);
1407 (void)getCallback()->allocateHalBuffer(size, &mOutConversionBuffer);
1408 }
1409 if (mOutConversionBuffer != nullptr) {
1410 mOutConversionBuffer->setFrameCount(outFrameCount);
1411 mEffectInterface->setOutBuffer(mOutConversionBuffer);
1412 } else if (size > 0) {
1413 ALOGE("%s cannot create mOutConversionBuffer", __func__);
1414 }
1415 }
1416 #endif
1417 }
1418
setVolume(uint32_t * left,uint32_t * right,bool controller)1419 status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller)
1420 {
1421 AutoLockReentrant _l(mLock, mSetVolumeReentrantTid);
1422 if (mStatus != NO_ERROR) {
1423 return mStatus;
1424 }
1425 status_t status = NO_ERROR;
1426 // Send volume indication if EFFECT_FLAG_VOLUME_IND is set and read back altered volume
1427 // if controller flag is set (Note that controller == TRUE => EFFECT_FLAG_VOLUME_CTRL set)
1428 if (isProcessEnabled() &&
1429 ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL ||
1430 (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND ||
1431 (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_MONITOR)) {
1432 uint32_t volume[2];
1433 uint32_t *pVolume = NULL;
1434 uint32_t size = sizeof(volume);
1435 volume[0] = *left;
1436 volume[1] = *right;
1437 if (controller) {
1438 pVolume = volume;
1439 }
1440 status = mEffectInterface->command(EFFECT_CMD_SET_VOLUME,
1441 size,
1442 volume,
1443 &size,
1444 pVolume);
1445 if (controller && status == NO_ERROR && size == sizeof(volume)) {
1446 *left = volume[0];
1447 *right = volume[1];
1448 }
1449 }
1450 return status;
1451 }
1452
setVolumeForOutput_l(uint32_t left,uint32_t right)1453 void AudioFlinger::EffectChain::setVolumeForOutput_l(uint32_t left, uint32_t right)
1454 {
1455 // for offload or direct thread, if the effect chain has non-offloadable
1456 // effect and any effect module within the chain has volume control, then
1457 // volume control is delegated to effect, otherwise, set volume to hal.
1458 if (mEffectCallback->isOffloadOrDirect() &&
1459 !(isNonOffloadableEnabled_l() && hasVolumeControlEnabled_l())) {
1460 float vol_l = (float)left / (1 << 24);
1461 float vol_r = (float)right / (1 << 24);
1462 mEffectCallback->setVolumeForOutput(vol_l, vol_r);
1463 }
1464 }
1465
sendSetAudioDevicesCommand(const AudioDeviceTypeAddrVector & devices,uint32_t cmdCode)1466 status_t AudioFlinger::EffectModule::sendSetAudioDevicesCommand(
1467 const AudioDeviceTypeAddrVector &devices, uint32_t cmdCode)
1468 {
1469 audio_devices_t deviceType = deviceTypesToBitMask(getAudioDeviceTypes(devices));
1470 if (deviceType == AUDIO_DEVICE_NONE) {
1471 return NO_ERROR;
1472 }
1473
1474 Mutex::Autolock _l(mLock);
1475 if (mStatus != NO_ERROR) {
1476 return mStatus;
1477 }
1478 status_t status = NO_ERROR;
1479 if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) {
1480 status_t cmdStatus;
1481 uint32_t size = sizeof(status_t);
1482 // FIXME: use audio device types and addresses when the hal interface is ready.
1483 status = mEffectInterface->command(cmdCode,
1484 sizeof(uint32_t),
1485 &deviceType,
1486 &size,
1487 &cmdStatus);
1488 }
1489 return status;
1490 }
1491
setDevices(const AudioDeviceTypeAddrVector & devices)1492 status_t AudioFlinger::EffectModule::setDevices(const AudioDeviceTypeAddrVector &devices)
1493 {
1494 return sendSetAudioDevicesCommand(devices, EFFECT_CMD_SET_DEVICE);
1495 }
1496
setInputDevice(const AudioDeviceTypeAddr & device)1497 status_t AudioFlinger::EffectModule::setInputDevice(const AudioDeviceTypeAddr &device)
1498 {
1499 return sendSetAudioDevicesCommand({device}, EFFECT_CMD_SET_INPUT_DEVICE);
1500 }
1501
setMode(audio_mode_t mode)1502 status_t AudioFlinger::EffectModule::setMode(audio_mode_t mode)
1503 {
1504 Mutex::Autolock _l(mLock);
1505 if (mStatus != NO_ERROR) {
1506 return mStatus;
1507 }
1508 status_t status = NO_ERROR;
1509 if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_MODE_MASK) == EFFECT_FLAG_AUDIO_MODE_IND) {
1510 status_t cmdStatus;
1511 uint32_t size = sizeof(status_t);
1512 status = mEffectInterface->command(EFFECT_CMD_SET_AUDIO_MODE,
1513 sizeof(audio_mode_t),
1514 &mode,
1515 &size,
1516 &cmdStatus);
1517 if (status == NO_ERROR) {
1518 status = cmdStatus;
1519 }
1520 }
1521 return status;
1522 }
1523
setAudioSource(audio_source_t source)1524 status_t AudioFlinger::EffectModule::setAudioSource(audio_source_t source)
1525 {
1526 Mutex::Autolock _l(mLock);
1527 if (mStatus != NO_ERROR) {
1528 return mStatus;
1529 }
1530 status_t status = NO_ERROR;
1531 if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_SOURCE_MASK) == EFFECT_FLAG_AUDIO_SOURCE_IND) {
1532 uint32_t size = 0;
1533 status = mEffectInterface->command(EFFECT_CMD_SET_AUDIO_SOURCE,
1534 sizeof(audio_source_t),
1535 &source,
1536 &size,
1537 NULL);
1538 }
1539 return status;
1540 }
1541
setOffloaded(bool offloaded,audio_io_handle_t io)1542 status_t AudioFlinger::EffectModule::setOffloaded(bool offloaded, audio_io_handle_t io)
1543 {
1544 Mutex::Autolock _l(mLock);
1545 if (mStatus != NO_ERROR) {
1546 return mStatus;
1547 }
1548 status_t status = NO_ERROR;
1549 if ((mDescriptor.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) != 0) {
1550 status_t cmdStatus;
1551 uint32_t size = sizeof(status_t);
1552 effect_offload_param_t cmd;
1553
1554 cmd.isOffload = offloaded;
1555 cmd.ioHandle = io;
1556 status = mEffectInterface->command(EFFECT_CMD_OFFLOAD,
1557 sizeof(effect_offload_param_t),
1558 &cmd,
1559 &size,
1560 &cmdStatus);
1561 if (status == NO_ERROR) {
1562 status = cmdStatus;
1563 }
1564 mOffloaded = (status == NO_ERROR) ? offloaded : false;
1565 } else {
1566 if (offloaded) {
1567 status = INVALID_OPERATION;
1568 }
1569 mOffloaded = false;
1570 }
1571 ALOGV("setOffloaded() offloaded %d io %d status %d", offloaded, io, status);
1572 return status;
1573 }
1574
isOffloaded() const1575 bool AudioFlinger::EffectModule::isOffloaded() const
1576 {
1577 Mutex::Autolock _l(mLock);
1578 return mOffloaded;
1579 }
1580
1581 /*static*/
isHapticGenerator(const effect_uuid_t * type)1582 bool AudioFlinger::EffectModule::isHapticGenerator(const effect_uuid_t *type) {
1583 return memcmp(type, FX_IID_HAPTICGENERATOR, sizeof(effect_uuid_t)) == 0;
1584 }
1585
isHapticGenerator() const1586 bool AudioFlinger::EffectModule::isHapticGenerator() const {
1587 return isHapticGenerator(&mDescriptor.type);
1588 }
1589
setHapticIntensity(int id,int intensity)1590 status_t AudioFlinger::EffectModule::setHapticIntensity(int id, int intensity)
1591 {
1592 if (mStatus != NO_ERROR) {
1593 return mStatus;
1594 }
1595 if (!isHapticGenerator()) {
1596 ALOGW("Should not set haptic intensity for effects that are not HapticGenerator");
1597 return INVALID_OPERATION;
1598 }
1599
1600 std::vector<uint8_t> request(sizeof(effect_param_t) + 3 * sizeof(uint32_t));
1601 effect_param_t *param = (effect_param_t*) request.data();
1602 param->psize = sizeof(int32_t);
1603 param->vsize = sizeof(int32_t) * 2;
1604 *(int32_t*)param->data = HG_PARAM_HAPTIC_INTENSITY;
1605 *((int32_t*)param->data + 1) = id;
1606 *((int32_t*)param->data + 2) = intensity;
1607 std::vector<uint8_t> response;
1608 status_t status = command(EFFECT_CMD_SET_PARAM, request, sizeof(int32_t), &response);
1609 if (status == NO_ERROR) {
1610 LOG_ALWAYS_FATAL_IF(response.size() != 4);
1611 status = *reinterpret_cast<const status_t*>(response.data());
1612 }
1613 return status;
1614 }
1615
setVibratorInfo(const media::AudioVibratorInfo & vibratorInfo)1616 status_t AudioFlinger::EffectModule::setVibratorInfo(const media::AudioVibratorInfo& vibratorInfo)
1617 {
1618 if (mStatus != NO_ERROR) {
1619 return mStatus;
1620 }
1621 if (!isHapticGenerator()) {
1622 ALOGW("Should not set vibrator info for effects that are not HapticGenerator");
1623 return INVALID_OPERATION;
1624 }
1625
1626 const size_t paramCount = 3;
1627 std::vector<uint8_t> request(
1628 sizeof(effect_param_t) + sizeof(int32_t) + paramCount * sizeof(float));
1629 effect_param_t *param = (effect_param_t*) request.data();
1630 param->psize = sizeof(int32_t);
1631 param->vsize = paramCount * sizeof(float);
1632 *(int32_t*)param->data = HG_PARAM_VIBRATOR_INFO;
1633 float* vibratorInfoPtr = reinterpret_cast<float*>(param->data + sizeof(int32_t));
1634 vibratorInfoPtr[0] = vibratorInfo.resonantFrequency;
1635 vibratorInfoPtr[1] = vibratorInfo.qFactor;
1636 vibratorInfoPtr[2] = vibratorInfo.maxAmplitude;
1637 std::vector<uint8_t> response;
1638 status_t status = command(EFFECT_CMD_SET_PARAM, request, sizeof(int32_t), &response);
1639 if (status == NO_ERROR) {
1640 LOG_ALWAYS_FATAL_IF(response.size() != sizeof(status_t));
1641 status = *reinterpret_cast<const status_t*>(response.data());
1642 }
1643 return status;
1644 }
1645
dumpInOutBuffer(bool isInput,const sp<EffectBufferHalInterface> & buffer)1646 static std::string dumpInOutBuffer(bool isInput, const sp<EffectBufferHalInterface> &buffer) {
1647 std::stringstream ss;
1648
1649 if (buffer == nullptr) {
1650 return "nullptr"; // make different than below
1651 } else if (buffer->externalData() != nullptr) {
1652 ss << (isInput ? buffer->externalData() : buffer->audioBuffer()->raw)
1653 << " -> "
1654 << (isInput ? buffer->audioBuffer()->raw : buffer->externalData());
1655 } else {
1656 ss << buffer->audioBuffer()->raw;
1657 }
1658 return ss.str();
1659 }
1660
dump(int fd,const Vector<String16> & args)1661 void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
1662 {
1663 EffectBase::dump(fd, args);
1664
1665 String8 result;
1666 bool locked = AudioFlinger::dumpTryLock(mLock);
1667
1668 result.append("\t\tStatus Engine:\n");
1669 result.appendFormat("\t\t%03d %p\n",
1670 mStatus, mEffectInterface.get());
1671
1672 result.appendFormat("\t\t- data: %s\n", mSupportsFloat ? "float" : "int16");
1673
1674 result.append("\t\t- Input configuration:\n");
1675 result.append("\t\t\tBuffer Frames Smp rate Channels Format\n");
1676 result.appendFormat("\t\t\t%p %05zu %05d %08x %6d (%s)\n",
1677 mConfig.inputCfg.buffer.raw,
1678 mConfig.inputCfg.buffer.frameCount,
1679 mConfig.inputCfg.samplingRate,
1680 mConfig.inputCfg.channels,
1681 mConfig.inputCfg.format,
1682 formatToString((audio_format_t)mConfig.inputCfg.format).c_str());
1683
1684 result.append("\t\t- Output configuration:\n");
1685 result.append("\t\t\tBuffer Frames Smp rate Channels Format\n");
1686 result.appendFormat("\t\t\t%p %05zu %05d %08x %6d (%s)\n",
1687 mConfig.outputCfg.buffer.raw,
1688 mConfig.outputCfg.buffer.frameCount,
1689 mConfig.outputCfg.samplingRate,
1690 mConfig.outputCfg.channels,
1691 mConfig.outputCfg.format,
1692 formatToString((audio_format_t)mConfig.outputCfg.format).c_str());
1693
1694 #ifdef FLOAT_EFFECT_CHAIN
1695
1696 result.appendFormat("\t\t- HAL buffers:\n"
1697 "\t\t\tIn(%s) InConversion(%s) Out(%s) OutConversion(%s)\n",
1698 dumpInOutBuffer(true /* isInput */, mInBuffer).c_str(),
1699 dumpInOutBuffer(true /* isInput */, mInConversionBuffer).c_str(),
1700 dumpInOutBuffer(false /* isInput */, mOutBuffer).c_str(),
1701 dumpInOutBuffer(false /* isInput */, mOutConversionBuffer).c_str());
1702 #endif
1703
1704 write(fd, result.string(), result.length());
1705
1706 if (mEffectInterface != 0) {
1707 dprintf(fd, "\tEffect ID %d HAL dump:\n", mId);
1708 (void)mEffectInterface->dump(fd);
1709 }
1710
1711 if (locked) {
1712 mLock.unlock();
1713 }
1714 }
1715
1716 // ----------------------------------------------------------------------------
1717 // EffectHandle implementation
1718 // ----------------------------------------------------------------------------
1719
1720 #undef LOG_TAG
1721 #define LOG_TAG "AudioFlinger::EffectHandle"
1722
EffectHandle(const sp<EffectBase> & effect,const sp<AudioFlinger::Client> & client,const sp<media::IEffectClient> & effectClient,int32_t priority,bool notifyFramesProcessed)1723 AudioFlinger::EffectHandle::EffectHandle(const sp<EffectBase>& effect,
1724 const sp<AudioFlinger::Client>& client,
1725 const sp<media::IEffectClient>& effectClient,
1726 int32_t priority, bool notifyFramesProcessed)
1727 : BnEffect(),
1728 mEffect(effect), mEffectClient(effectClient), mClient(client), mCblk(NULL),
1729 mPriority(priority), mHasControl(false), mEnabled(false), mDisconnected(false),
1730 mNotifyFramesProcessed(notifyFramesProcessed)
1731 {
1732 ALOGV("constructor %p client %p", this, client.get());
1733 setMinSchedulerPolicy(SCHED_NORMAL, ANDROID_PRIORITY_AUDIO);
1734
1735 if (client == 0) {
1736 return;
1737 }
1738 int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
1739 mCblkMemory = client->heap()->allocate(EFFECT_PARAM_BUFFER_SIZE + bufOffset);
1740 if (mCblkMemory == 0 ||
1741 (mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->unsecurePointer())) == NULL) {
1742 ALOGE("not enough memory for Effect size=%zu", EFFECT_PARAM_BUFFER_SIZE +
1743 sizeof(effect_param_cblk_t));
1744 mCblkMemory.clear();
1745 return;
1746 }
1747 new(mCblk) effect_param_cblk_t();
1748 mBuffer = (uint8_t *)mCblk + bufOffset;
1749 }
1750
~EffectHandle()1751 AudioFlinger::EffectHandle::~EffectHandle()
1752 {
1753 ALOGV("Destructor %p", this);
1754 disconnect(false);
1755 }
1756
1757 // Creates an association between Binder code to name for IEffect.
1758 #define IEFFECT_BINDER_METHOD_MACRO_LIST \
1759 BINDER_METHOD_ENTRY(enable) \
1760 BINDER_METHOD_ENTRY(disable) \
1761 BINDER_METHOD_ENTRY(command) \
1762 BINDER_METHOD_ENTRY(disconnect) \
1763 BINDER_METHOD_ENTRY(getCblk) \
1764
1765 // singleton for Binder Method Statistics for IEffect
getIEffectStatistics()1766 mediautils::MethodStatistics<int>& getIEffectStatistics() {
1767 using Code = int;
1768
1769 #pragma push_macro("BINDER_METHOD_ENTRY")
1770 #undef BINDER_METHOD_ENTRY
1771 #define BINDER_METHOD_ENTRY(ENTRY) \
1772 {(Code)media::BnEffect::TRANSACTION_##ENTRY, #ENTRY},
1773
1774 static mediautils::MethodStatistics<Code> methodStatistics{
1775 IEFFECT_BINDER_METHOD_MACRO_LIST
1776 METHOD_STATISTICS_BINDER_CODE_NAMES(Code)
1777 };
1778 #pragma pop_macro("BINDER_METHOD_ENTRY")
1779
1780 return methodStatistics;
1781 }
1782
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)1783 status_t AudioFlinger::EffectHandle::onTransact(
1784 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
1785 const std::string methodName = getIEffectStatistics().getMethodForCode(code);
1786 mediautils::TimeCheck check(
1787 std::string("IEffect::").append(methodName),
1788 [code](bool timeout, float elapsedMs) {
1789 if (timeout) {
1790 ; // we don't timeout right now on the effect interface.
1791 } else {
1792 getIEffectStatistics().event(code, elapsedMs);
1793 }
1794 }, {} /* timeoutDuration */, {} /* secondChanceDuration */, false /* crashOnTimeout */);
1795 return BnEffect::onTransact(code, data, reply, flags);
1796 }
1797
initCheck()1798 status_t AudioFlinger::EffectHandle::initCheck()
1799 {
1800 return mClient == 0 || mCblkMemory != 0 ? OK : NO_MEMORY;
1801 }
1802
1803 #define RETURN(code) \
1804 *_aidl_return = (code); \
1805 return Status::ok();
1806
enable(int32_t * _aidl_return)1807 Status AudioFlinger::EffectHandle::enable(int32_t* _aidl_return)
1808 {
1809 AutoMutex _l(mLock);
1810 ALOGV("enable %p", this);
1811 sp<EffectBase> effect = mEffect.promote();
1812 if (effect == 0 || mDisconnected) {
1813 RETURN(DEAD_OBJECT);
1814 }
1815 if (!mHasControl) {
1816 RETURN(INVALID_OPERATION);
1817 }
1818
1819 if (mEnabled) {
1820 RETURN(NO_ERROR);
1821 }
1822
1823 mEnabled = true;
1824
1825 status_t status = effect->updatePolicyState();
1826 if (status != NO_ERROR) {
1827 mEnabled = false;
1828 RETURN(status);
1829 }
1830
1831 effect->checkSuspendOnEffectEnabled(true, false /*threadLocked*/);
1832
1833 // checkSuspendOnEffectEnabled() can suspend this same effect when enabled
1834 if (effect->suspended()) {
1835 RETURN(NO_ERROR);
1836 }
1837
1838 status = effect->setEnabled(true, true /*fromHandle*/);
1839 if (status != NO_ERROR) {
1840 mEnabled = false;
1841 }
1842 RETURN(status);
1843 }
1844
disable(int32_t * _aidl_return)1845 Status AudioFlinger::EffectHandle::disable(int32_t* _aidl_return)
1846 {
1847 ALOGV("disable %p", this);
1848 AutoMutex _l(mLock);
1849 sp<EffectBase> effect = mEffect.promote();
1850 if (effect == 0 || mDisconnected) {
1851 RETURN(DEAD_OBJECT);
1852 }
1853 if (!mHasControl) {
1854 RETURN(INVALID_OPERATION);
1855 }
1856
1857 if (!mEnabled) {
1858 RETURN(NO_ERROR);
1859 }
1860 mEnabled = false;
1861
1862 effect->updatePolicyState();
1863
1864 if (effect->suspended()) {
1865 RETURN(NO_ERROR);
1866 }
1867
1868 status_t status = effect->setEnabled(false, true /*fromHandle*/);
1869 RETURN(status);
1870 }
1871
disconnect()1872 Status AudioFlinger::EffectHandle::disconnect()
1873 {
1874 ALOGV("%s %p", __FUNCTION__, this);
1875 disconnect(true);
1876 return Status::ok();
1877 }
1878
disconnect(bool unpinIfLast)1879 void AudioFlinger::EffectHandle::disconnect(bool unpinIfLast)
1880 {
1881 AutoMutex _l(mLock);
1882 ALOGV("disconnect(%s) %p", unpinIfLast ? "true" : "false", this);
1883 if (mDisconnected) {
1884 if (unpinIfLast) {
1885 android_errorWriteLog(0x534e4554, "32707507");
1886 }
1887 return;
1888 }
1889 mDisconnected = true;
1890 {
1891 sp<EffectBase> effect = mEffect.promote();
1892 if (effect != 0) {
1893 if (effect->disconnectHandle(this, unpinIfLast) > 0) {
1894 ALOGW("%s Effect handle %p disconnected after thread destruction",
1895 __func__, this);
1896 }
1897 effect->updatePolicyState();
1898 }
1899 }
1900
1901 if (mClient != 0) {
1902 if (mCblk != NULL) {
1903 // unlike ~TrackBase(), mCblk is never a local new, so don't delete
1904 mCblk->~effect_param_cblk_t(); // destroy our shared-structure.
1905 }
1906 mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to
1907 // Client destructor must run with AudioFlinger client mutex locked
1908 Mutex::Autolock _l(mClient->audioFlinger()->mClientLock);
1909 mClient.clear();
1910 }
1911 }
1912
getCblk(media::SharedFileRegion * _aidl_return)1913 Status AudioFlinger::EffectHandle::getCblk(media::SharedFileRegion* _aidl_return) {
1914 LOG_ALWAYS_FATAL_IF(!convertIMemoryToSharedFileRegion(mCblkMemory, _aidl_return));
1915 return Status::ok();
1916 }
1917
command(int32_t cmdCode,const std::vector<uint8_t> & cmdData,int32_t maxResponseSize,std::vector<uint8_t> * response,int32_t * _aidl_return)1918 Status AudioFlinger::EffectHandle::command(int32_t cmdCode,
1919 const std::vector<uint8_t>& cmdData,
1920 int32_t maxResponseSize,
1921 std::vector<uint8_t>* response,
1922 int32_t* _aidl_return)
1923 {
1924 ALOGVV("command(), cmdCode: %d, mHasControl: %d, mEffect: %p",
1925 cmdCode, mHasControl, mEffect.unsafe_get());
1926
1927 // reject commands reserved for internal use by audio framework if coming from outside
1928 // of audioserver
1929 switch(cmdCode) {
1930 case EFFECT_CMD_ENABLE:
1931 case EFFECT_CMD_DISABLE:
1932 case EFFECT_CMD_SET_PARAM:
1933 case EFFECT_CMD_SET_PARAM_DEFERRED:
1934 case EFFECT_CMD_SET_PARAM_COMMIT:
1935 case EFFECT_CMD_GET_PARAM:
1936 break;
1937 default:
1938 if (cmdCode >= EFFECT_CMD_FIRST_PROPRIETARY) {
1939 break;
1940 }
1941 android_errorWriteLog(0x534e4554, "62019992");
1942 RETURN(BAD_VALUE);
1943 }
1944
1945 if (cmdCode == EFFECT_CMD_ENABLE) {
1946 if (maxResponseSize < sizeof(int)) {
1947 android_errorWriteLog(0x534e4554, "32095713");
1948 RETURN(BAD_VALUE);
1949 }
1950 writeToBuffer(NO_ERROR, response);
1951 return enable(_aidl_return);
1952 } else if (cmdCode == EFFECT_CMD_DISABLE) {
1953 if (maxResponseSize < sizeof(int)) {
1954 android_errorWriteLog(0x534e4554, "32095713");
1955 RETURN(BAD_VALUE);
1956 }
1957 writeToBuffer(NO_ERROR, response);
1958 return disable(_aidl_return);
1959 }
1960
1961 AutoMutex _l(mLock);
1962 sp<EffectBase> effect = mEffect.promote();
1963 if (effect == 0 || mDisconnected) {
1964 RETURN(DEAD_OBJECT);
1965 }
1966 // only get parameter command is permitted for applications not controlling the effect
1967 if (!mHasControl && cmdCode != EFFECT_CMD_GET_PARAM) {
1968 RETURN(INVALID_OPERATION);
1969 }
1970
1971 // handle commands that are not forwarded transparently to effect engine
1972 if (cmdCode == EFFECT_CMD_SET_PARAM_COMMIT) {
1973 if (mClient == 0) {
1974 RETURN(INVALID_OPERATION);
1975 }
1976
1977 if (maxResponseSize < sizeof(int)) {
1978 android_errorWriteLog(0x534e4554, "32095713");
1979 RETURN(BAD_VALUE);
1980 }
1981 writeToBuffer(NO_ERROR, response);
1982
1983 // No need to trylock() here as this function is executed in the binder thread serving a
1984 // particular client process: no risk to block the whole media server process or mixer
1985 // threads if we are stuck here
1986 Mutex::Autolock _l(mCblk->lock);
1987 // keep local copy of index in case of client corruption b/32220769
1988 const uint32_t clientIndex = mCblk->clientIndex;
1989 const uint32_t serverIndex = mCblk->serverIndex;
1990 if (clientIndex > EFFECT_PARAM_BUFFER_SIZE ||
1991 serverIndex > EFFECT_PARAM_BUFFER_SIZE) {
1992 mCblk->serverIndex = 0;
1993 mCblk->clientIndex = 0;
1994 RETURN(BAD_VALUE);
1995 }
1996 status_t status = NO_ERROR;
1997 std::vector<uint8_t> param;
1998 for (uint32_t index = serverIndex; index < clientIndex;) {
1999 int *p = (int *)(mBuffer + index);
2000 const int size = *p++;
2001 if (size < 0
2002 || size > EFFECT_PARAM_BUFFER_SIZE
2003 || ((uint8_t *)p + size) > mBuffer + clientIndex) {
2004 ALOGW("command(): invalid parameter block size");
2005 status = BAD_VALUE;
2006 break;
2007 }
2008
2009 std::copy(reinterpret_cast<const uint8_t*>(p),
2010 reinterpret_cast<const uint8_t*>(p) + size,
2011 std::back_inserter(param));
2012
2013 std::vector<uint8_t> replyBuffer;
2014 status_t ret = effect->command(EFFECT_CMD_SET_PARAM,
2015 param,
2016 sizeof(int),
2017 &replyBuffer);
2018 int reply = *reinterpret_cast<const int*>(replyBuffer.data());
2019
2020 // verify shared memory: server index shouldn't change; client index can't go back.
2021 if (serverIndex != mCblk->serverIndex
2022 || clientIndex > mCblk->clientIndex) {
2023 android_errorWriteLog(0x534e4554, "32220769");
2024 status = BAD_VALUE;
2025 break;
2026 }
2027
2028 // stop at first error encountered
2029 if (ret != NO_ERROR) {
2030 status = ret;
2031 writeToBuffer(reply, response);
2032 break;
2033 } else if (reply != NO_ERROR) {
2034 writeToBuffer(reply, response);
2035 break;
2036 }
2037 index += size;
2038 }
2039 mCblk->serverIndex = 0;
2040 mCblk->clientIndex = 0;
2041 RETURN(status);
2042 }
2043
2044 status_t status = effect->command(cmdCode,
2045 cmdData,
2046 maxResponseSize,
2047 response);
2048 RETURN(status);
2049 }
2050
setControl(bool hasControl,bool signal,bool enabled)2051 void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal, bool enabled)
2052 {
2053 ALOGV("setControl %p control %d", this, hasControl);
2054
2055 mHasControl = hasControl;
2056 mEnabled = enabled;
2057
2058 if (signal && mEffectClient != 0) {
2059 mEffectClient->controlStatusChanged(hasControl);
2060 }
2061 }
2062
commandExecuted(uint32_t cmdCode,const std::vector<uint8_t> & cmdData,const std::vector<uint8_t> & replyData)2063 void AudioFlinger::EffectHandle::commandExecuted(uint32_t cmdCode,
2064 const std::vector<uint8_t>& cmdData,
2065 const std::vector<uint8_t>& replyData)
2066 {
2067 if (mEffectClient != 0) {
2068 mEffectClient->commandExecuted(cmdCode, cmdData, replyData);
2069 }
2070 }
2071
2072
2073
setEnabled(bool enabled)2074 void AudioFlinger::EffectHandle::setEnabled(bool enabled)
2075 {
2076 if (mEffectClient != 0) {
2077 mEffectClient->enableStatusChanged(enabled);
2078 }
2079 }
2080
framesProcessed(int32_t frames) const2081 void AudioFlinger::EffectHandle::framesProcessed(int32_t frames) const
2082 {
2083 if (mEffectClient != 0 && mNotifyFramesProcessed) {
2084 mEffectClient->framesProcessed(frames);
2085 }
2086 }
2087
dumpToBuffer(char * buffer,size_t size)2088 void AudioFlinger::EffectHandle::dumpToBuffer(char* buffer, size_t size)
2089 {
2090 bool locked = mCblk != NULL && AudioFlinger::dumpTryLock(mCblk->lock);
2091
2092 snprintf(buffer, size, "\t\t\t%5d %5d %3s %3s %5u %5u\n",
2093 (mClient == 0) ? getpid() : mClient->pid(),
2094 mPriority,
2095 mHasControl ? "yes" : "no",
2096 locked ? "yes" : "no",
2097 mCblk ? mCblk->clientIndex : 0,
2098 mCblk ? mCblk->serverIndex : 0
2099 );
2100
2101 if (locked) {
2102 mCblk->lock.unlock();
2103 }
2104 }
2105
2106 #undef LOG_TAG
2107 #define LOG_TAG "AudioFlinger::EffectChain"
2108
EffectChain(const wp<ThreadBase> & thread,audio_session_t sessionId)2109 AudioFlinger::EffectChain::EffectChain(const wp<ThreadBase>& thread,
2110 audio_session_t sessionId)
2111 : mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0),
2112 mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
2113 mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX),
2114 mEffectCallback(new EffectCallback(wp<EffectChain>(this), thread))
2115 {
2116 sp<ThreadBase> p = thread.promote();
2117 if (p == nullptr) {
2118 return;
2119 }
2120 mStrategy = p->getStrategyForStream(AUDIO_STREAM_MUSIC);
2121 mMaxTailBuffers = ((kProcessTailDurationMs * p->sampleRate()) / 1000) /
2122 p->frameCount();
2123 }
2124
~EffectChain()2125 AudioFlinger::EffectChain::~EffectChain()
2126 {
2127 }
2128
2129 // getEffectFromDesc_l() must be called with ThreadBase::mLock held
getEffectFromDesc_l(effect_descriptor_t * descriptor)2130 sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l(
2131 effect_descriptor_t *descriptor)
2132 {
2133 size_t size = mEffects.size();
2134
2135 for (size_t i = 0; i < size; i++) {
2136 if (memcmp(&mEffects[i]->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) == 0) {
2137 return mEffects[i];
2138 }
2139 }
2140 return 0;
2141 }
2142
2143 // getEffectFromId_l() must be called with ThreadBase::mLock held
getEffectFromId_l(int id)2144 sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id)
2145 {
2146 size_t size = mEffects.size();
2147
2148 for (size_t i = 0; i < size; i++) {
2149 // by convention, return first effect if id provided is 0 (0 is never a valid id)
2150 if (id == 0 || mEffects[i]->id() == id) {
2151 return mEffects[i];
2152 }
2153 }
2154 return 0;
2155 }
2156
2157 // getEffectFromType_l() must be called with ThreadBase::mLock held
getEffectFromType_l(const effect_uuid_t * type)2158 sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l(
2159 const effect_uuid_t *type)
2160 {
2161 size_t size = mEffects.size();
2162
2163 for (size_t i = 0; i < size; i++) {
2164 if (memcmp(&mEffects[i]->desc().type, type, sizeof(effect_uuid_t)) == 0) {
2165 return mEffects[i];
2166 }
2167 }
2168 return 0;
2169 }
2170
getEffectIds()2171 std::vector<int> AudioFlinger::EffectChain::getEffectIds()
2172 {
2173 std::vector<int> ids;
2174 Mutex::Autolock _l(mLock);
2175 for (size_t i = 0; i < mEffects.size(); i++) {
2176 ids.push_back(mEffects[i]->id());
2177 }
2178 return ids;
2179 }
2180
clearInputBuffer()2181 void AudioFlinger::EffectChain::clearInputBuffer()
2182 {
2183 Mutex::Autolock _l(mLock);
2184 clearInputBuffer_l();
2185 }
2186
2187 // Must be called with EffectChain::mLock locked
clearInputBuffer_l()2188 void AudioFlinger::EffectChain::clearInputBuffer_l()
2189 {
2190 if (mInBuffer == NULL) {
2191 return;
2192 }
2193 const size_t frameSize = audio_bytes_per_sample(EFFECT_BUFFER_FORMAT)
2194 * mEffectCallback->inChannelCount(mEffects[0]->id());
2195
2196 memset(mInBuffer->audioBuffer()->raw, 0, mEffectCallback->frameCount() * frameSize);
2197 mInBuffer->commit();
2198 }
2199
2200 // Must be called with EffectChain::mLock locked
process_l()2201 void AudioFlinger::EffectChain::process_l()
2202 {
2203 // never process effects when:
2204 // - on an OFFLOAD thread
2205 // - no more tracks are on the session and the effect tail has been rendered
2206 bool doProcess = !mEffectCallback->isOffloadOrMmap();
2207 if (!audio_is_global_session(mSessionId)) {
2208 bool tracksOnSession = (trackCnt() != 0);
2209
2210 if (!tracksOnSession && mTailBufferCount == 0) {
2211 doProcess = false;
2212 }
2213
2214 if (activeTrackCnt() == 0) {
2215 // if no track is active and the effect tail has not been rendered,
2216 // the input buffer must be cleared here as the mixer process will not do it
2217 if (tracksOnSession || mTailBufferCount > 0) {
2218 clearInputBuffer_l();
2219 if (mTailBufferCount > 0) {
2220 mTailBufferCount--;
2221 }
2222 }
2223 }
2224 }
2225
2226 size_t size = mEffects.size();
2227 if (doProcess) {
2228 // Only the input and output buffers of the chain can be external,
2229 // and 'update' / 'commit' do nothing for allocated buffers, thus
2230 // it's not needed to consider any other buffers here.
2231 mInBuffer->update();
2232 if (mInBuffer->audioBuffer()->raw != mOutBuffer->audioBuffer()->raw) {
2233 mOutBuffer->update();
2234 }
2235 for (size_t i = 0; i < size; i++) {
2236 mEffects[i]->process();
2237 }
2238 mInBuffer->commit();
2239 if (mInBuffer->audioBuffer()->raw != mOutBuffer->audioBuffer()->raw) {
2240 mOutBuffer->commit();
2241 }
2242 }
2243 bool doResetVolume = false;
2244 for (size_t i = 0; i < size; i++) {
2245 doResetVolume = mEffects[i]->updateState() || doResetVolume;
2246 }
2247 if (doResetVolume) {
2248 resetVolume_l();
2249 }
2250 }
2251
2252 // createEffect_l() must be called with ThreadBase::mLock held
createEffect_l(sp<EffectModule> & effect,effect_descriptor_t * desc,int id,audio_session_t sessionId,bool pinned)2253 status_t AudioFlinger::EffectChain::createEffect_l(sp<EffectModule>& effect,
2254 effect_descriptor_t *desc,
2255 int id,
2256 audio_session_t sessionId,
2257 bool pinned)
2258 {
2259 Mutex::Autolock _l(mLock);
2260 effect = new EffectModule(mEffectCallback, desc, id, sessionId, pinned, AUDIO_PORT_HANDLE_NONE);
2261 status_t lStatus = effect->status();
2262 if (lStatus == NO_ERROR) {
2263 lStatus = addEffect_ll(effect);
2264 }
2265 if (lStatus != NO_ERROR) {
2266 effect.clear();
2267 }
2268 return lStatus;
2269 }
2270
2271 // addEffect_l() must be called with ThreadBase::mLock held
addEffect_l(const sp<EffectModule> & effect)2272 status_t AudioFlinger::EffectChain::addEffect_l(const sp<EffectModule>& effect)
2273 {
2274 Mutex::Autolock _l(mLock);
2275 return addEffect_ll(effect);
2276 }
2277 // addEffect_l() must be called with ThreadBase::mLock and EffectChain::mLock held
addEffect_ll(const sp<EffectModule> & effect)2278 status_t AudioFlinger::EffectChain::addEffect_ll(const sp<EffectModule>& effect)
2279 {
2280 effect->setCallback(mEffectCallback);
2281
2282 effect_descriptor_t desc = effect->desc();
2283 if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
2284 // Auxiliary effects are inserted at the beginning of mEffects vector as
2285 // they are processed first and accumulated in chain input buffer
2286 mEffects.insertAt(effect, 0);
2287
2288 // the input buffer for auxiliary effect contains mono samples in
2289 // 32 bit format. This is to avoid saturation in AudoMixer
2290 // accumulation stage. Saturation is done in EffectModule::process() before
2291 // calling the process in effect engine
2292 size_t numSamples = mEffectCallback->frameCount();
2293 sp<EffectBufferHalInterface> halBuffer;
2294 #ifdef FLOAT_EFFECT_CHAIN
2295 status_t result = mEffectCallback->allocateHalBuffer(
2296 numSamples * sizeof(float), &halBuffer);
2297 #else
2298 status_t result = mEffectCallback->allocateHalBuffer(
2299 numSamples * sizeof(int32_t), &halBuffer);
2300 #endif
2301 if (result != OK) return result;
2302
2303 effect->configure();
2304
2305 effect->setInBuffer(halBuffer);
2306 // auxiliary effects output samples to chain input buffer for further processing
2307 // by insert effects
2308 effect->setOutBuffer(mInBuffer);
2309 } else {
2310 ssize_t idx_insert = getInsertIndex(desc);
2311 if (idx_insert < 0) {
2312 return INVALID_OPERATION;
2313 }
2314
2315 size_t previousSize = mEffects.size();
2316 mEffects.insertAt(effect, idx_insert);
2317
2318 effect->configure();
2319
2320 // - By default:
2321 // All effects read samples from chain input buffer.
2322 // The last effect in the chain, writes samples to chain output buffer,
2323 // otherwise to chain input buffer
2324 // - In the OUTPUT_STAGE chain of a spatializer mixer thread:
2325 // The spatializer effect (first effect) reads samples from the input buffer
2326 // and writes samples to the output buffer.
2327 // All other effects read and writes samples to the output buffer
2328 if (mEffectCallback->isSpatializer()
2329 && mSessionId == AUDIO_SESSION_OUTPUT_STAGE) {
2330 effect->setOutBuffer(mOutBuffer);
2331 if (idx_insert == 0) {
2332 if (previousSize != 0) {
2333 mEffects[1]->configure();
2334 mEffects[1]->setInBuffer(mOutBuffer);
2335 mEffects[1]->updateAccessMode(); // reconfig if neeeded.
2336 }
2337 effect->setInBuffer(mInBuffer);
2338 } else {
2339 effect->setInBuffer(mOutBuffer);
2340 }
2341 } else {
2342 effect->setInBuffer(mInBuffer);
2343 if (idx_insert == previousSize) {
2344 if (idx_insert != 0) {
2345 mEffects[idx_insert-1]->configure();
2346 mEffects[idx_insert-1]->setOutBuffer(mInBuffer);
2347 mEffects[idx_insert - 1]->updateAccessMode(); // reconfig if neeeded.
2348 }
2349 effect->setOutBuffer(mOutBuffer);
2350 } else {
2351 effect->setOutBuffer(mInBuffer);
2352 }
2353 }
2354 ALOGV("%s effect %p, added in chain %p at rank %zu",
2355 __func__, effect.get(), this, idx_insert);
2356 }
2357 effect->configure();
2358
2359 return NO_ERROR;
2360 }
2361
getInsertIndex(const effect_descriptor_t & desc)2362 ssize_t AudioFlinger::EffectChain::getInsertIndex(const effect_descriptor_t& desc) {
2363 // Insert effects are inserted at the end of mEffects vector as they are processed
2364 // after track and auxiliary effects.
2365 // Insert effect order as a function of indicated preference:
2366 // if EFFECT_FLAG_INSERT_EXCLUSIVE, insert in first position or reject if
2367 // another effect is present
2368 // else if EFFECT_FLAG_INSERT_FIRST, insert in first position or after the
2369 // last effect claiming first position
2370 // else if EFFECT_FLAG_INSERT_LAST, insert in last position or before the
2371 // first effect claiming last position
2372 // else if EFFECT_FLAG_INSERT_ANY insert after first or before last
2373 // Reject insertion if an effect with EFFECT_FLAG_INSERT_EXCLUSIVE is
2374 // already present
2375 // Spatializer or Downmixer effects are inserted in first position because
2376 // they adapt the channel count for all other effects in the chain
2377 if ((memcmp(&desc.type, FX_IID_SPATIALIZER, sizeof(effect_uuid_t)) == 0)
2378 || (memcmp(&desc.type, EFFECT_UIID_DOWNMIX, sizeof(effect_uuid_t)) == 0)) {
2379 return 0;
2380 }
2381
2382 size_t size = mEffects.size();
2383 uint32_t insertPref = desc.flags & EFFECT_FLAG_INSERT_MASK;
2384 ssize_t idx_insert;
2385 ssize_t idx_insert_first = -1;
2386 ssize_t idx_insert_last = -1;
2387
2388 idx_insert = size;
2389 for (size_t i = 0; i < size; i++) {
2390 effect_descriptor_t d = mEffects[i]->desc();
2391 uint32_t iMode = d.flags & EFFECT_FLAG_TYPE_MASK;
2392 uint32_t iPref = d.flags & EFFECT_FLAG_INSERT_MASK;
2393 if (iMode == EFFECT_FLAG_TYPE_INSERT) {
2394 // check invalid effect chaining combinations
2395 if (insertPref == EFFECT_FLAG_INSERT_EXCLUSIVE ||
2396 iPref == EFFECT_FLAG_INSERT_EXCLUSIVE) {
2397 ALOGW("%s could not insert effect %s: exclusive conflict with %s",
2398 __func__, desc.name, d.name);
2399 return -1;
2400 }
2401 // remember position of first insert effect and by default
2402 // select this as insert position for new effect
2403 if (idx_insert == size) {
2404 idx_insert = i;
2405 }
2406 // remember position of last insert effect claiming
2407 // first position
2408 if (iPref == EFFECT_FLAG_INSERT_FIRST) {
2409 idx_insert_first = i;
2410 }
2411 // remember position of first insert effect claiming
2412 // last position
2413 if (iPref == EFFECT_FLAG_INSERT_LAST &&
2414 idx_insert_last == -1) {
2415 idx_insert_last = i;
2416 }
2417 }
2418 }
2419
2420 // modify idx_insert from first position if needed
2421 if (insertPref == EFFECT_FLAG_INSERT_LAST) {
2422 if (idx_insert_last != -1) {
2423 idx_insert = idx_insert_last;
2424 } else {
2425 idx_insert = size;
2426 }
2427 } else {
2428 if (idx_insert_first != -1) {
2429 idx_insert = idx_insert_first + 1;
2430 }
2431 }
2432 return idx_insert;
2433 }
2434
2435 // removeEffect_l() must be called with ThreadBase::mLock held
removeEffect_l(const sp<EffectModule> & effect,bool release)2436 size_t AudioFlinger::EffectChain::removeEffect_l(const sp<EffectModule>& effect,
2437 bool release)
2438 {
2439 Mutex::Autolock _l(mLock);
2440 size_t size = mEffects.size();
2441 uint32_t type = effect->desc().flags & EFFECT_FLAG_TYPE_MASK;
2442
2443 for (size_t i = 0; i < size; i++) {
2444 if (effect == mEffects[i]) {
2445 // calling stop here will remove pre-processing effect from the audio HAL.
2446 // This is safe as we hold the EffectChain mutex which guarantees that we are not in
2447 // the middle of a read from audio HAL
2448 if (mEffects[i]->state() == EffectModule::ACTIVE ||
2449 mEffects[i]->state() == EffectModule::STOPPING) {
2450 mEffects[i]->stop();
2451 }
2452 if (release) {
2453 mEffects[i]->release_l();
2454 }
2455
2456 if (type != EFFECT_FLAG_TYPE_AUXILIARY) {
2457 if (i == size - 1 && i != 0) {
2458 mEffects[i - 1]->configure();
2459 mEffects[i - 1]->setOutBuffer(mOutBuffer);
2460 mEffects[i - 1]->updateAccessMode(); // reconfig if neeeded.
2461 }
2462 }
2463 mEffects.removeAt(i);
2464
2465 // make sure the input buffer configuration for the new first effect in the chain
2466 // is updated if needed (can switch from HAL channel mask to mixer channel mask)
2467 if (i == 0 && size > 1) {
2468 mEffects[0]->configure();
2469 mEffects[0]->setInBuffer(mInBuffer);
2470 mEffects[0]->updateAccessMode(); // reconfig if neeeded.
2471 }
2472
2473 ALOGV("removeEffect_l() effect %p, removed from chain %p at rank %zu", effect.get(),
2474 this, i);
2475 break;
2476 }
2477 }
2478
2479 return mEffects.size();
2480 }
2481
2482 // setDevices_l() must be called with ThreadBase::mLock held
setDevices_l(const AudioDeviceTypeAddrVector & devices)2483 void AudioFlinger::EffectChain::setDevices_l(const AudioDeviceTypeAddrVector &devices)
2484 {
2485 size_t size = mEffects.size();
2486 for (size_t i = 0; i < size; i++) {
2487 mEffects[i]->setDevices(devices);
2488 }
2489 }
2490
2491 // setInputDevice_l() must be called with ThreadBase::mLock held
setInputDevice_l(const AudioDeviceTypeAddr & device)2492 void AudioFlinger::EffectChain::setInputDevice_l(const AudioDeviceTypeAddr &device)
2493 {
2494 size_t size = mEffects.size();
2495 for (size_t i = 0; i < size; i++) {
2496 mEffects[i]->setInputDevice(device);
2497 }
2498 }
2499
2500 // setMode_l() must be called with ThreadBase::mLock held
setMode_l(audio_mode_t mode)2501 void AudioFlinger::EffectChain::setMode_l(audio_mode_t mode)
2502 {
2503 size_t size = mEffects.size();
2504 for (size_t i = 0; i < size; i++) {
2505 mEffects[i]->setMode(mode);
2506 }
2507 }
2508
2509 // setAudioSource_l() must be called with ThreadBase::mLock held
setAudioSource_l(audio_source_t source)2510 void AudioFlinger::EffectChain::setAudioSource_l(audio_source_t source)
2511 {
2512 size_t size = mEffects.size();
2513 for (size_t i = 0; i < size; i++) {
2514 mEffects[i]->setAudioSource(source);
2515 }
2516 }
2517
hasVolumeControlEnabled_l() const2518 bool AudioFlinger::EffectChain::hasVolumeControlEnabled_l() const {
2519 for (const auto &effect : mEffects) {
2520 if (effect->isVolumeControlEnabled()) return true;
2521 }
2522 return false;
2523 }
2524
2525 // setVolume_l() must be called with ThreadBase::mLock or EffectChain::mLock held
setVolume_l(uint32_t * left,uint32_t * right,bool force)2526 bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right, bool force)
2527 {
2528 uint32_t newLeft = *left;
2529 uint32_t newRight = *right;
2530 bool hasControl = false;
2531 int ctrlIdx = -1;
2532 size_t size = mEffects.size();
2533
2534 // first update volume controller
2535 for (size_t i = size; i > 0; i--) {
2536 if (mEffects[i - 1]->isVolumeControlEnabled()) {
2537 ctrlIdx = i - 1;
2538 hasControl = true;
2539 break;
2540 }
2541 }
2542
2543 if (!force && ctrlIdx == mVolumeCtrlIdx &&
2544 *left == mLeftVolume && *right == mRightVolume) {
2545 if (hasControl) {
2546 *left = mNewLeftVolume;
2547 *right = mNewRightVolume;
2548 }
2549 return hasControl;
2550 }
2551
2552 mVolumeCtrlIdx = ctrlIdx;
2553 mLeftVolume = newLeft;
2554 mRightVolume = newRight;
2555
2556 // second get volume update from volume controller
2557 if (ctrlIdx >= 0) {
2558 mEffects[ctrlIdx]->setVolume(&newLeft, &newRight, true);
2559 mNewLeftVolume = newLeft;
2560 mNewRightVolume = newRight;
2561 }
2562 // then indicate volume to all other effects in chain.
2563 // Pass altered volume to effects before volume controller
2564 // and requested volume to effects after controller or with volume monitor flag
2565 uint32_t lVol = newLeft;
2566 uint32_t rVol = newRight;
2567
2568 for (size_t i = 0; i < size; i++) {
2569 if ((int)i == ctrlIdx) {
2570 continue;
2571 }
2572 // this also works for ctrlIdx == -1 when there is no volume controller
2573 if ((int)i > ctrlIdx) {
2574 lVol = *left;
2575 rVol = *right;
2576 }
2577 // Pass requested volume directly if this is volume monitor module
2578 if (mEffects[i]->isVolumeMonitor()) {
2579 mEffects[i]->setVolume(left, right, false);
2580 } else {
2581 mEffects[i]->setVolume(&lVol, &rVol, false);
2582 }
2583 }
2584 *left = newLeft;
2585 *right = newRight;
2586
2587 setVolumeForOutput_l(*left, *right);
2588
2589 return hasControl;
2590 }
2591
2592 // resetVolume_l() must be called with ThreadBase::mLock or EffectChain::mLock held
resetVolume_l()2593 void AudioFlinger::EffectChain::resetVolume_l()
2594 {
2595 if ((mLeftVolume != UINT_MAX) && (mRightVolume != UINT_MAX)) {
2596 uint32_t left = mLeftVolume;
2597 uint32_t right = mRightVolume;
2598 (void)setVolume_l(&left, &right, true);
2599 }
2600 }
2601
2602 // containsHapticGeneratingEffect_l must be called with ThreadBase::mLock or EffectChain::mLock held
containsHapticGeneratingEffect_l()2603 bool AudioFlinger::EffectChain::containsHapticGeneratingEffect_l()
2604 {
2605 for (size_t i = 0; i < mEffects.size(); ++i) {
2606 if (mEffects[i]->isHapticGenerator()) {
2607 return true;
2608 }
2609 }
2610 return false;
2611 }
2612
setHapticIntensity_l(int id,int intensity)2613 void AudioFlinger::EffectChain::setHapticIntensity_l(int id, int intensity)
2614 {
2615 Mutex::Autolock _l(mLock);
2616 for (size_t i = 0; i < mEffects.size(); ++i) {
2617 mEffects[i]->setHapticIntensity(id, intensity);
2618 }
2619 }
2620
syncHalEffectsState()2621 void AudioFlinger::EffectChain::syncHalEffectsState()
2622 {
2623 Mutex::Autolock _l(mLock);
2624 for (size_t i = 0; i < mEffects.size(); i++) {
2625 if (mEffects[i]->state() == EffectModule::ACTIVE ||
2626 mEffects[i]->state() == EffectModule::STOPPING) {
2627 mEffects[i]->addEffectToHal_l();
2628 }
2629 }
2630 }
2631
dump(int fd,const Vector<String16> & args)2632 void AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args)
2633 {
2634 String8 result;
2635
2636 const size_t numEffects = mEffects.size();
2637 result.appendFormat(" %zu effects for session %d\n", numEffects, mSessionId);
2638
2639 if (numEffects) {
2640 bool locked = AudioFlinger::dumpTryLock(mLock);
2641 // failed to lock - AudioFlinger is probably deadlocked
2642 if (!locked) {
2643 result.append("\tCould not lock mutex:\n");
2644 }
2645
2646 const std::string inBufferStr = dumpInOutBuffer(true /* isInput */, mInBuffer);
2647 const std::string outBufferStr = dumpInOutBuffer(false /* isInput */, mOutBuffer);
2648 result.appendFormat("\t%-*s%-*s Active tracks:\n",
2649 (int)inBufferStr.size(), "In buffer ",
2650 (int)outBufferStr.size(), "Out buffer ");
2651 result.appendFormat("\t%s %s %d\n",
2652 inBufferStr.c_str(), outBufferStr.c_str(), mActiveTrackCnt);
2653 write(fd, result.string(), result.size());
2654
2655 for (size_t i = 0; i < numEffects; ++i) {
2656 sp<EffectModule> effect = mEffects[i];
2657 if (effect != 0) {
2658 effect->dump(fd, args);
2659 }
2660 }
2661
2662 if (locked) {
2663 mLock.unlock();
2664 }
2665 } else {
2666 write(fd, result.string(), result.size());
2667 }
2668 }
2669
2670 // must be called with ThreadBase::mLock held
setEffectSuspended_l(const effect_uuid_t * type,bool suspend)2671 void AudioFlinger::EffectChain::setEffectSuspended_l(
2672 const effect_uuid_t *type, bool suspend)
2673 {
2674 sp<SuspendedEffectDesc> desc;
2675 // use effect type UUID timelow as key as there is no real risk of identical
2676 // timeLow fields among effect type UUIDs.
2677 ssize_t index = mSuspendedEffects.indexOfKey(type->timeLow);
2678 if (suspend) {
2679 if (index >= 0) {
2680 desc = mSuspendedEffects.valueAt(index);
2681 } else {
2682 desc = new SuspendedEffectDesc();
2683 desc->mType = *type;
2684 mSuspendedEffects.add(type->timeLow, desc);
2685 ALOGV("setEffectSuspended_l() add entry for %08x", type->timeLow);
2686 }
2687
2688 if (desc->mRefCount++ == 0) {
2689 sp<EffectModule> effect = getEffectIfEnabled(type);
2690 if (effect != 0) {
2691 desc->mEffect = effect;
2692 effect->setSuspended(true);
2693 effect->setEnabled(false, false /*fromHandle*/);
2694 }
2695 }
2696 } else {
2697 if (index < 0) {
2698 return;
2699 }
2700 desc = mSuspendedEffects.valueAt(index);
2701 if (desc->mRefCount <= 0) {
2702 ALOGW("setEffectSuspended_l() restore refcount should not be 0 %d", desc->mRefCount);
2703 desc->mRefCount = 0;
2704 return;
2705 }
2706 if (--desc->mRefCount == 0) {
2707 ALOGV("setEffectSuspended_l() remove entry for %08x", mSuspendedEffects.keyAt(index));
2708 if (desc->mEffect != 0) {
2709 sp<EffectModule> effect = desc->mEffect.promote();
2710 if (effect != 0) {
2711 effect->setSuspended(false);
2712 effect->lock();
2713 EffectHandle *handle = effect->controlHandle_l();
2714 if (handle != NULL && !handle->disconnected()) {
2715 effect->setEnabled_l(handle->enabled());
2716 }
2717 effect->unlock();
2718 }
2719 desc->mEffect.clear();
2720 }
2721 mSuspendedEffects.removeItemsAt(index);
2722 }
2723 }
2724 }
2725
2726 // must be called with ThreadBase::mLock held
setEffectSuspendedAll_l(bool suspend)2727 void AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend)
2728 {
2729 sp<SuspendedEffectDesc> desc;
2730
2731 ssize_t index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
2732 if (suspend) {
2733 if (index >= 0) {
2734 desc = mSuspendedEffects.valueAt(index);
2735 } else {
2736 desc = new SuspendedEffectDesc();
2737 mSuspendedEffects.add((int)kKeyForSuspendAll, desc);
2738 ALOGV("setEffectSuspendedAll_l() add entry for 0");
2739 }
2740 if (desc->mRefCount++ == 0) {
2741 Vector< sp<EffectModule> > effects;
2742 getSuspendEligibleEffects(effects);
2743 for (size_t i = 0; i < effects.size(); i++) {
2744 setEffectSuspended_l(&effects[i]->desc().type, true);
2745 }
2746 }
2747 } else {
2748 if (index < 0) {
2749 return;
2750 }
2751 desc = mSuspendedEffects.valueAt(index);
2752 if (desc->mRefCount <= 0) {
2753 ALOGW("setEffectSuspendedAll_l() restore refcount should not be 0 %d", desc->mRefCount);
2754 desc->mRefCount = 1;
2755 }
2756 if (--desc->mRefCount == 0) {
2757 Vector<const effect_uuid_t *> types;
2758 for (size_t i = 0; i < mSuspendedEffects.size(); i++) {
2759 if (mSuspendedEffects.keyAt(i) == (int)kKeyForSuspendAll) {
2760 continue;
2761 }
2762 types.add(&mSuspendedEffects.valueAt(i)->mType);
2763 }
2764 for (size_t i = 0; i < types.size(); i++) {
2765 setEffectSuspended_l(types[i], false);
2766 }
2767 ALOGV("setEffectSuspendedAll_l() remove entry for %08x",
2768 mSuspendedEffects.keyAt(index));
2769 mSuspendedEffects.removeItem((int)kKeyForSuspendAll);
2770 }
2771 }
2772 }
2773
2774
2775 // The volume effect is used for automated tests only
2776 #ifndef OPENSL_ES_H_
2777 static const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6,
2778 { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
2779 const effect_uuid_t * const SL_IID_VOLUME = &SL_IID_VOLUME_;
2780 #endif //OPENSL_ES_H_
2781
2782 /* static */
isEffectEligibleForBtNrecSuspend(const effect_uuid_t * type)2783 bool AudioFlinger::EffectChain::isEffectEligibleForBtNrecSuspend(const effect_uuid_t *type)
2784 {
2785 // Only NS and AEC are suspended when BtNRec is off
2786 if ((memcmp(type, FX_IID_AEC, sizeof(effect_uuid_t)) == 0) ||
2787 (memcmp(type, FX_IID_NS, sizeof(effect_uuid_t)) == 0)) {
2788 return true;
2789 }
2790 return false;
2791 }
2792
isEffectEligibleForSuspend(const effect_descriptor_t & desc)2793 bool AudioFlinger::EffectChain::isEffectEligibleForSuspend(const effect_descriptor_t& desc)
2794 {
2795 // auxiliary effects and visualizer are never suspended on output mix
2796 if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) &&
2797 (((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) ||
2798 (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) ||
2799 (memcmp(&desc.type, SL_IID_VOLUME, sizeof(effect_uuid_t)) == 0) ||
2800 (memcmp(&desc.type, SL_IID_DYNAMICSPROCESSING, sizeof(effect_uuid_t)) == 0))) {
2801 return false;
2802 }
2803 return true;
2804 }
2805
getSuspendEligibleEffects(Vector<sp<AudioFlinger::EffectModule>> & effects)2806 void AudioFlinger::EffectChain::getSuspendEligibleEffects(
2807 Vector< sp<AudioFlinger::EffectModule> > &effects)
2808 {
2809 effects.clear();
2810 for (size_t i = 0; i < mEffects.size(); i++) {
2811 if (isEffectEligibleForSuspend(mEffects[i]->desc())) {
2812 effects.add(mEffects[i]);
2813 }
2814 }
2815 }
2816
getEffectIfEnabled(const effect_uuid_t * type)2817 sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled(
2818 const effect_uuid_t *type)
2819 {
2820 sp<EffectModule> effect = getEffectFromType_l(type);
2821 return effect != 0 && effect->isEnabled() ? effect : 0;
2822 }
2823
checkSuspendOnEffectEnabled(const sp<EffectModule> & effect,bool enabled)2824 void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
2825 bool enabled)
2826 {
2827 ssize_t index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
2828 if (enabled) {
2829 if (index < 0) {
2830 // if the effect is not suspend check if all effects are suspended
2831 index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll);
2832 if (index < 0) {
2833 return;
2834 }
2835 if (!isEffectEligibleForSuspend(effect->desc())) {
2836 return;
2837 }
2838 setEffectSuspended_l(&effect->desc().type, enabled);
2839 index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow);
2840 if (index < 0) {
2841 ALOGW("checkSuspendOnEffectEnabled() Fx should be suspended here!");
2842 return;
2843 }
2844 }
2845 ALOGV("checkSuspendOnEffectEnabled() enable suspending fx %08x",
2846 effect->desc().type.timeLow);
2847 sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
2848 // if effect is requested to suspended but was not yet enabled, suspend it now.
2849 if (desc->mEffect == 0) {
2850 desc->mEffect = effect;
2851 effect->setEnabled(false, false /*fromHandle*/);
2852 effect->setSuspended(true);
2853 }
2854 } else {
2855 if (index < 0) {
2856 return;
2857 }
2858 ALOGV("checkSuspendOnEffectEnabled() disable restoring fx %08x",
2859 effect->desc().type.timeLow);
2860 sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index);
2861 desc->mEffect.clear();
2862 effect->setSuspended(false);
2863 }
2864 }
2865
isNonOffloadableEnabled()2866 bool AudioFlinger::EffectChain::isNonOffloadableEnabled()
2867 {
2868 Mutex::Autolock _l(mLock);
2869 return isNonOffloadableEnabled_l();
2870 }
2871
isNonOffloadableEnabled_l()2872 bool AudioFlinger::EffectChain::isNonOffloadableEnabled_l()
2873 {
2874 size_t size = mEffects.size();
2875 for (size_t i = 0; i < size; i++) {
2876 if (mEffects[i]->isEnabled() && !mEffects[i]->isOffloadable()) {
2877 return true;
2878 }
2879 }
2880 return false;
2881 }
2882
setThread(const sp<ThreadBase> & thread)2883 void AudioFlinger::EffectChain::setThread(const sp<ThreadBase>& thread)
2884 {
2885 Mutex::Autolock _l(mLock);
2886 mEffectCallback->setThread(thread);
2887 }
2888
checkOutputFlagCompatibility(audio_output_flags_t * flags) const2889 void AudioFlinger::EffectChain::checkOutputFlagCompatibility(audio_output_flags_t *flags) const
2890 {
2891 if ((*flags & AUDIO_OUTPUT_FLAG_RAW) != 0 && !isRawCompatible()) {
2892 *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_RAW);
2893 }
2894 if ((*flags & AUDIO_OUTPUT_FLAG_FAST) != 0 && !isFastCompatible()) {
2895 *flags = (audio_output_flags_t)(*flags & ~AUDIO_OUTPUT_FLAG_FAST);
2896 }
2897 }
2898
checkInputFlagCompatibility(audio_input_flags_t * flags) const2899 void AudioFlinger::EffectChain::checkInputFlagCompatibility(audio_input_flags_t *flags) const
2900 {
2901 if ((*flags & AUDIO_INPUT_FLAG_RAW) != 0 && !isRawCompatible()) {
2902 *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_RAW);
2903 }
2904 if ((*flags & AUDIO_INPUT_FLAG_FAST) != 0 && !isFastCompatible()) {
2905 *flags = (audio_input_flags_t)(*flags & ~AUDIO_INPUT_FLAG_FAST);
2906 }
2907 }
2908
isRawCompatible() const2909 bool AudioFlinger::EffectChain::isRawCompatible() const
2910 {
2911 Mutex::Autolock _l(mLock);
2912 for (const auto &effect : mEffects) {
2913 if (effect->isProcessImplemented()) {
2914 return false;
2915 }
2916 }
2917 // Allow effects without processing.
2918 return true;
2919 }
2920
isFastCompatible() const2921 bool AudioFlinger::EffectChain::isFastCompatible() const
2922 {
2923 Mutex::Autolock _l(mLock);
2924 for (const auto &effect : mEffects) {
2925 if (effect->isProcessImplemented()
2926 && effect->isImplementationSoftware()) {
2927 return false;
2928 }
2929 }
2930 // Allow effects without processing or hw accelerated effects.
2931 return true;
2932 }
2933
2934 // isCompatibleWithThread_l() must be called with thread->mLock held
isCompatibleWithThread_l(const sp<ThreadBase> & thread) const2935 bool AudioFlinger::EffectChain::isCompatibleWithThread_l(const sp<ThreadBase>& thread) const
2936 {
2937 Mutex::Autolock _l(mLock);
2938 for (size_t i = 0; i < mEffects.size(); i++) {
2939 if (thread->checkEffectCompatibility_l(&(mEffects[i]->desc()), mSessionId) != NO_ERROR) {
2940 return false;
2941 }
2942 }
2943 return true;
2944 }
2945
2946 // EffectCallbackInterface implementation
createEffectHal(const effect_uuid_t * pEffectUuid,int32_t sessionId,int32_t deviceId,sp<EffectHalInterface> * effect)2947 status_t AudioFlinger::EffectChain::EffectCallback::createEffectHal(
2948 const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
2949 sp<EffectHalInterface> *effect) {
2950 status_t status = NO_INIT;
2951 sp<EffectsFactoryHalInterface> effectsFactory = mAudioFlinger.getEffectsFactory();
2952 if (effectsFactory != 0) {
2953 status = effectsFactory->createEffect(pEffectUuid, sessionId, io(), deviceId, effect);
2954 }
2955 return status;
2956 }
2957
updateOrphanEffectChains(const sp<AudioFlinger::EffectBase> & effect)2958 bool AudioFlinger::EffectChain::EffectCallback::updateOrphanEffectChains(
2959 const sp<AudioFlinger::EffectBase>& effect) {
2960 // in EffectChain context, an EffectBase is always from an EffectModule so static cast is safe
2961 return mAudioFlinger.updateOrphanEffectChains(effect->asEffectModule());
2962 }
2963
allocateHalBuffer(size_t size,sp<EffectBufferHalInterface> * buffer)2964 status_t AudioFlinger::EffectChain::EffectCallback::allocateHalBuffer(
2965 size_t size, sp<EffectBufferHalInterface>* buffer) {
2966 return mAudioFlinger.mEffectsFactoryHal->allocateBuffer(size, buffer);
2967 }
2968
addEffectToHal(sp<EffectHalInterface> effect)2969 status_t AudioFlinger::EffectChain::EffectCallback::addEffectToHal(
2970 sp<EffectHalInterface> effect) {
2971 status_t result = NO_INIT;
2972 sp<ThreadBase> t = thread().promote();
2973 if (t == nullptr) {
2974 return result;
2975 }
2976 sp <StreamHalInterface> st = t->stream();
2977 if (st == nullptr) {
2978 return result;
2979 }
2980 result = st->addEffect(effect);
2981 ALOGE_IF(result != OK, "Error when adding effect: %d", result);
2982 return result;
2983 }
2984
removeEffectFromHal(sp<EffectHalInterface> effect)2985 status_t AudioFlinger::EffectChain::EffectCallback::removeEffectFromHal(
2986 sp<EffectHalInterface> effect) {
2987 status_t result = NO_INIT;
2988 sp<ThreadBase> t = thread().promote();
2989 if (t == nullptr) {
2990 return result;
2991 }
2992 sp <StreamHalInterface> st = t->stream();
2993 if (st == nullptr) {
2994 return result;
2995 }
2996 result = st->removeEffect(effect);
2997 ALOGE_IF(result != OK, "Error when removing effect: %d", result);
2998 return result;
2999 }
3000
io() const3001 audio_io_handle_t AudioFlinger::EffectChain::EffectCallback::io() const {
3002 sp<ThreadBase> t = thread().promote();
3003 if (t == nullptr) {
3004 return AUDIO_IO_HANDLE_NONE;
3005 }
3006 return t->id();
3007 }
3008
isOutput() const3009 bool AudioFlinger::EffectChain::EffectCallback::isOutput() const {
3010 sp<ThreadBase> t = thread().promote();
3011 if (t == nullptr) {
3012 return true;
3013 }
3014 return t->isOutput();
3015 }
3016
isOffload() const3017 bool AudioFlinger::EffectChain::EffectCallback::isOffload() const {
3018 return mThreadType == ThreadBase::OFFLOAD;
3019 }
3020
isOffloadOrDirect() const3021 bool AudioFlinger::EffectChain::EffectCallback::isOffloadOrDirect() const {
3022 return mThreadType == ThreadBase::OFFLOAD || mThreadType == ThreadBase::DIRECT;
3023 }
3024
isOffloadOrMmap() const3025 bool AudioFlinger::EffectChain::EffectCallback::isOffloadOrMmap() const {
3026 switch (mThreadType) {
3027 case ThreadBase::OFFLOAD:
3028 case ThreadBase::MMAP_PLAYBACK:
3029 case ThreadBase::MMAP_CAPTURE:
3030 return true;
3031 default:
3032 return false;
3033 }
3034 }
3035
isSpatializer() const3036 bool AudioFlinger::EffectChain::EffectCallback::isSpatializer() const {
3037 return mThreadType == ThreadBase::SPATIALIZER;
3038 }
3039
sampleRate() const3040 uint32_t AudioFlinger::EffectChain::EffectCallback::sampleRate() const {
3041 sp<ThreadBase> t = thread().promote();
3042 if (t == nullptr) {
3043 return 0;
3044 }
3045 return t->sampleRate();
3046 }
3047
inChannelMask(int id) const3048 audio_channel_mask_t AudioFlinger::EffectChain::EffectCallback::inChannelMask(int id) const {
3049 sp<ThreadBase> t = thread().promote();
3050 if (t == nullptr) {
3051 return AUDIO_CHANNEL_NONE;
3052 }
3053 sp<EffectChain> c = chain().promote();
3054 if (c == nullptr) {
3055 return AUDIO_CHANNEL_NONE;
3056 }
3057
3058 if (mThreadType == ThreadBase::SPATIALIZER) {
3059 if (c->sessionId() == AUDIO_SESSION_OUTPUT_STAGE) {
3060 if (c->isFirstEffect(id)) {
3061 return t->mixerChannelMask();
3062 } else {
3063 return t->channelMask();
3064 }
3065 } else if (!audio_is_global_session(c->sessionId())) {
3066 if ((t->hasAudioSession_l(c->sessionId()) & ThreadBase::SPATIALIZED_SESSION) != 0) {
3067 return t->mixerChannelMask();
3068 } else {
3069 return t->channelMask();
3070 }
3071 } else {
3072 return t->channelMask();
3073 }
3074 } else {
3075 return t->channelMask();
3076 }
3077 }
3078
inChannelCount(int id) const3079 uint32_t AudioFlinger::EffectChain::EffectCallback::inChannelCount(int id) const {
3080 return audio_channel_count_from_out_mask(inChannelMask(id));
3081 }
3082
outChannelMask() const3083 audio_channel_mask_t AudioFlinger::EffectChain::EffectCallback::outChannelMask() const {
3084 sp<ThreadBase> t = thread().promote();
3085 if (t == nullptr) {
3086 return AUDIO_CHANNEL_NONE;
3087 }
3088 sp<EffectChain> c = chain().promote();
3089 if (c == nullptr) {
3090 return AUDIO_CHANNEL_NONE;
3091 }
3092
3093 if (mThreadType == ThreadBase::SPATIALIZER) {
3094 if (!audio_is_global_session(c->sessionId())) {
3095 if ((t->hasAudioSession_l(c->sessionId()) & ThreadBase::SPATIALIZED_SESSION) != 0) {
3096 return t->mixerChannelMask();
3097 } else {
3098 return t->channelMask();
3099 }
3100 } else {
3101 return t->channelMask();
3102 }
3103 } else {
3104 return t->channelMask();
3105 }
3106 }
3107
outChannelCount() const3108 uint32_t AudioFlinger::EffectChain::EffectCallback::outChannelCount() const {
3109 return audio_channel_count_from_out_mask(outChannelMask());
3110 }
3111
hapticChannelMask() const3112 audio_channel_mask_t AudioFlinger::EffectChain::EffectCallback::hapticChannelMask() const {
3113 sp<ThreadBase> t = thread().promote();
3114 if (t == nullptr) {
3115 return AUDIO_CHANNEL_NONE;
3116 }
3117 return t->hapticChannelMask();
3118 }
3119
frameCount() const3120 size_t AudioFlinger::EffectChain::EffectCallback::frameCount() const {
3121 sp<ThreadBase> t = thread().promote();
3122 if (t == nullptr) {
3123 return 0;
3124 }
3125 return t->frameCount();
3126 }
3127
latency() const3128 uint32_t AudioFlinger::EffectChain::EffectCallback::latency() const {
3129 sp<ThreadBase> t = thread().promote();
3130 if (t == nullptr) {
3131 return 0;
3132 }
3133 return t->latency_l();
3134 }
3135
setVolumeForOutput(float left,float right) const3136 void AudioFlinger::EffectChain::EffectCallback::setVolumeForOutput(float left, float right) const {
3137 sp<ThreadBase> t = thread().promote();
3138 if (t == nullptr) {
3139 return;
3140 }
3141 t->setVolumeForOutput_l(left, right);
3142 }
3143
checkSuspendOnEffectEnabled(const sp<EffectBase> & effect,bool enabled,bool threadLocked)3144 void AudioFlinger::EffectChain::EffectCallback::checkSuspendOnEffectEnabled(
3145 const sp<EffectBase>& effect, bool enabled, bool threadLocked) {
3146 sp<ThreadBase> t = thread().promote();
3147 if (t == nullptr) {
3148 return;
3149 }
3150 t->checkSuspendOnEffectEnabled(enabled, effect->sessionId(), threadLocked);
3151
3152 sp<EffectChain> c = chain().promote();
3153 if (c == nullptr) {
3154 return;
3155 }
3156 // in EffectChain context, an EffectBase is always from an EffectModule so static cast is safe
3157 c->checkSuspendOnEffectEnabled(effect->asEffectModule(), enabled);
3158 }
3159
onEffectEnable(const sp<EffectBase> & effect)3160 void AudioFlinger::EffectChain::EffectCallback::onEffectEnable(const sp<EffectBase>& effect) {
3161 sp<ThreadBase> t = thread().promote();
3162 if (t == nullptr) {
3163 return;
3164 }
3165 // in EffectChain context, an EffectBase is always from an EffectModule so static cast is safe
3166 t->onEffectEnable(effect->asEffectModule());
3167 }
3168
onEffectDisable(const sp<EffectBase> & effect)3169 void AudioFlinger::EffectChain::EffectCallback::onEffectDisable(const sp<EffectBase>& effect) {
3170 checkSuspendOnEffectEnabled(effect, false, false /*threadLocked*/);
3171
3172 sp<ThreadBase> t = thread().promote();
3173 if (t == nullptr) {
3174 return;
3175 }
3176 t->onEffectDisable();
3177 }
3178
disconnectEffectHandle(EffectHandle * handle,bool unpinIfLast)3179 bool AudioFlinger::EffectChain::EffectCallback::disconnectEffectHandle(EffectHandle *handle,
3180 bool unpinIfLast) {
3181 sp<ThreadBase> t = thread().promote();
3182 if (t == nullptr) {
3183 return false;
3184 }
3185 t->disconnectEffectHandle(handle, unpinIfLast);
3186 return true;
3187 }
3188
resetVolume()3189 void AudioFlinger::EffectChain::EffectCallback::resetVolume() {
3190 sp<EffectChain> c = chain().promote();
3191 if (c == nullptr) {
3192 return;
3193 }
3194 c->resetVolume_l();
3195
3196 }
3197
strategy() const3198 product_strategy_t AudioFlinger::EffectChain::EffectCallback::strategy() const {
3199 sp<EffectChain> c = chain().promote();
3200 if (c == nullptr) {
3201 return PRODUCT_STRATEGY_NONE;
3202 }
3203 return c->strategy();
3204 }
3205
activeTrackCnt() const3206 int32_t AudioFlinger::EffectChain::EffectCallback::activeTrackCnt() const {
3207 sp<EffectChain> c = chain().promote();
3208 if (c == nullptr) {
3209 return 0;
3210 }
3211 return c->activeTrackCnt();
3212 }
3213
3214
3215 #undef LOG_TAG
3216 #define LOG_TAG "AudioFlinger::DeviceEffectProxy"
3217
setEnabled(bool enabled,bool fromHandle)3218 status_t AudioFlinger::DeviceEffectProxy::setEnabled(bool enabled, bool fromHandle)
3219 {
3220 status_t status = EffectBase::setEnabled(enabled, fromHandle);
3221 Mutex::Autolock _l(mProxyLock);
3222 if (status == NO_ERROR) {
3223 for (auto& handle : mEffectHandles) {
3224 Status bs;
3225 if (enabled) {
3226 bs = handle.second->enable(&status);
3227 } else {
3228 bs = handle.second->disable(&status);
3229 }
3230 if (!bs.isOk()) {
3231 status = statusTFromBinderStatus(bs);
3232 }
3233 }
3234 }
3235 ALOGV("%s enable %d status %d", __func__, enabled, status);
3236 return status;
3237 }
3238
init(const std::map<audio_patch_handle_t,PatchPanel::Patch> & patches)3239 status_t AudioFlinger::DeviceEffectProxy::init(
3240 const std::map <audio_patch_handle_t, PatchPanel::Patch>& patches) {
3241 //For all audio patches
3242 //If src or sink device match
3243 //If the effect is HW accelerated
3244 // if no corresponding effect module
3245 // Create EffectModule: mHalEffect
3246 //Create and attach EffectHandle
3247 //If the effect is not HW accelerated and the patch sink or src is a mixer port
3248 // Create Effect on patch input or output thread on session -1
3249 //Add EffectHandle to EffectHandle map of Effect Proxy:
3250 ALOGV("%s device type %d address %s", __func__, mDevice.mType, mDevice.getAddress());
3251 status_t status = NO_ERROR;
3252 for (auto &patch : patches) {
3253 status = onCreatePatch(patch.first, patch.second);
3254 ALOGV("%s onCreatePatch status %d", __func__, status);
3255 if (status == BAD_VALUE) {
3256 return status;
3257 }
3258 }
3259 return status;
3260 }
3261
onCreatePatch(audio_patch_handle_t patchHandle,const AudioFlinger::PatchPanel::Patch & patch)3262 status_t AudioFlinger::DeviceEffectProxy::onCreatePatch(
3263 audio_patch_handle_t patchHandle, const AudioFlinger::PatchPanel::Patch& patch) {
3264 status_t status = NAME_NOT_FOUND;
3265 sp<EffectHandle> handle;
3266 // only consider source[0] as this is the only "true" source of a patch
3267 status = checkPort(patch, &patch.mAudioPatch.sources[0], &handle);
3268 ALOGV("%s source checkPort status %d", __func__, status);
3269 for (uint32_t i = 0; i < patch.mAudioPatch.num_sinks && status == NAME_NOT_FOUND; i++) {
3270 status = checkPort(patch, &patch.mAudioPatch.sinks[i], &handle);
3271 ALOGV("%s sink %d checkPort status %d", __func__, i, status);
3272 }
3273 if (status == NO_ERROR || status == ALREADY_EXISTS) {
3274 Mutex::Autolock _l(mProxyLock);
3275 mEffectHandles.emplace(patchHandle, handle);
3276 }
3277 ALOGW_IF(status == BAD_VALUE,
3278 "%s cannot attach effect %s on patch %d", __func__, mDescriptor.name, patchHandle);
3279
3280 return status;
3281 }
3282
checkPort(const PatchPanel::Patch & patch,const struct audio_port_config * port,sp<EffectHandle> * handle)3283 status_t AudioFlinger::DeviceEffectProxy::checkPort(const PatchPanel::Patch& patch,
3284 const struct audio_port_config *port, sp <EffectHandle> *handle) {
3285
3286 ALOGV("%s type %d device type %d address %s device ID %d patch.isSoftware() %d",
3287 __func__, port->type, port->ext.device.type,
3288 port->ext.device.address, port->id, patch.isSoftware());
3289 if (port->type != AUDIO_PORT_TYPE_DEVICE || port->ext.device.type != mDevice.mType
3290 || port->ext.device.address != mDevice.address()) {
3291 return NAME_NOT_FOUND;
3292 }
3293 status_t status = NAME_NOT_FOUND;
3294
3295 if (mDescriptor.flags & EFFECT_FLAG_HW_ACC_TUNNEL) {
3296 Mutex::Autolock _l(mProxyLock);
3297 mDevicePort = *port;
3298 mHalEffect = new EffectModule(mMyCallback,
3299 const_cast<effect_descriptor_t *>(&mDescriptor),
3300 mMyCallback->newEffectId(), AUDIO_SESSION_DEVICE,
3301 false /* pinned */, port->id);
3302 if (audio_is_input_device(mDevice.mType)) {
3303 mHalEffect->setInputDevice(mDevice);
3304 } else {
3305 mHalEffect->setDevices({mDevice});
3306 }
3307 mHalEffect->configure();
3308
3309 *handle = new EffectHandle(mHalEffect, nullptr, nullptr, 0 /*priority*/,
3310 mNotifyFramesProcessed);
3311 status = (*handle)->initCheck();
3312 if (status == OK) {
3313 status = mHalEffect->addHandle((*handle).get());
3314 } else {
3315 mHalEffect.clear();
3316 mDevicePort.id = AUDIO_PORT_HANDLE_NONE;
3317 }
3318 } else if (patch.isSoftware() || patch.thread().promote() != nullptr) {
3319 sp <ThreadBase> thread;
3320 if (audio_port_config_has_input_direction(port)) {
3321 if (patch.isSoftware()) {
3322 thread = patch.mRecord.thread();
3323 } else {
3324 thread = patch.thread().promote();
3325 }
3326 } else {
3327 if (patch.isSoftware()) {
3328 thread = patch.mPlayback.thread();
3329 } else {
3330 thread = patch.thread().promote();
3331 }
3332 }
3333 int enabled;
3334 *handle = thread->createEffect_l(nullptr, nullptr, 0, AUDIO_SESSION_DEVICE,
3335 const_cast<effect_descriptor_t *>(&mDescriptor),
3336 &enabled, &status, false, false /*probe*/,
3337 mNotifyFramesProcessed);
3338 ALOGV("%s thread->createEffect_l status %d", __func__, status);
3339 } else {
3340 status = BAD_VALUE;
3341 }
3342 if (status == NO_ERROR || status == ALREADY_EXISTS) {
3343 Status bs;
3344 if (isEnabled()) {
3345 bs = (*handle)->enable(&status);
3346 } else {
3347 bs = (*handle)->disable(&status);
3348 }
3349 if (!bs.isOk()) {
3350 status = statusTFromBinderStatus(bs);
3351 }
3352 }
3353 return status;
3354 }
3355
onReleasePatch(audio_patch_handle_t patchHandle)3356 void AudioFlinger::DeviceEffectProxy::onReleasePatch(audio_patch_handle_t patchHandle) {
3357 sp<EffectHandle> effect;
3358 {
3359 Mutex::Autolock _l(mProxyLock);
3360 if (mEffectHandles.find(patchHandle) != mEffectHandles.end()) {
3361 effect = mEffectHandles.at(patchHandle);
3362 mEffectHandles.erase(patchHandle);
3363 }
3364 }
3365 }
3366
3367
removeEffect(const sp<EffectModule> & effect)3368 size_t AudioFlinger::DeviceEffectProxy::removeEffect(const sp<EffectModule>& effect)
3369 {
3370 Mutex::Autolock _l(mProxyLock);
3371 if (effect == mHalEffect) {
3372 mHalEffect->release_l();
3373 mHalEffect.clear();
3374 mDevicePort.id = AUDIO_PORT_HANDLE_NONE;
3375 }
3376 return mHalEffect == nullptr ? 0 : 1;
3377 }
3378
addEffectToHal(sp<EffectHalInterface> effect)3379 status_t AudioFlinger::DeviceEffectProxy::addEffectToHal(
3380 sp<EffectHalInterface> effect) {
3381 if (mHalEffect == nullptr) {
3382 return NO_INIT;
3383 }
3384 return mManagerCallback->addEffectToHal(
3385 mDevicePort.id, mDevicePort.ext.device.hw_module, effect);
3386 }
3387
removeEffectFromHal(sp<EffectHalInterface> effect)3388 status_t AudioFlinger::DeviceEffectProxy::removeEffectFromHal(
3389 sp<EffectHalInterface> effect) {
3390 if (mHalEffect == nullptr) {
3391 return NO_INIT;
3392 }
3393 return mManagerCallback->removeEffectFromHal(
3394 mDevicePort.id, mDevicePort.ext.device.hw_module, effect);
3395 }
3396
isOutput() const3397 bool AudioFlinger::DeviceEffectProxy::isOutput() const {
3398 if (mDevicePort.id != AUDIO_PORT_HANDLE_NONE) {
3399 return mDevicePort.role == AUDIO_PORT_ROLE_SINK;
3400 }
3401 return true;
3402 }
3403
sampleRate() const3404 uint32_t AudioFlinger::DeviceEffectProxy::sampleRate() const {
3405 if (mDevicePort.id != AUDIO_PORT_HANDLE_NONE &&
3406 (mDevicePort.config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) != 0) {
3407 return mDevicePort.sample_rate;
3408 }
3409 return DEFAULT_OUTPUT_SAMPLE_RATE;
3410 }
3411
channelMask() const3412 audio_channel_mask_t AudioFlinger::DeviceEffectProxy::channelMask() const {
3413 if (mDevicePort.id != AUDIO_PORT_HANDLE_NONE &&
3414 (mDevicePort.config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) != 0) {
3415 return mDevicePort.channel_mask;
3416 }
3417 return AUDIO_CHANNEL_OUT_STEREO;
3418 }
3419
channelCount() const3420 uint32_t AudioFlinger::DeviceEffectProxy::channelCount() const {
3421 if (isOutput()) {
3422 return audio_channel_count_from_out_mask(channelMask());
3423 }
3424 return audio_channel_count_from_in_mask(channelMask());
3425 }
3426
dump(int fd,int spaces)3427 void AudioFlinger::DeviceEffectProxy::dump(int fd, int spaces) {
3428 const Vector<String16> args;
3429 EffectBase::dump(fd, args);
3430
3431 const bool locked = dumpTryLock(mProxyLock);
3432 if (!locked) {
3433 String8 result("DeviceEffectProxy may be deadlocked\n");
3434 write(fd, result.string(), result.size());
3435 }
3436
3437 String8 outStr;
3438 if (mHalEffect != nullptr) {
3439 outStr.appendFormat("%*sHAL Effect Id: %d\n", spaces, "", mHalEffect->id());
3440 } else {
3441 outStr.appendFormat("%*sNO HAL Effect\n", spaces, "");
3442 }
3443 write(fd, outStr.string(), outStr.size());
3444 outStr.clear();
3445
3446 outStr.appendFormat("%*sSub Effects:\n", spaces, "");
3447 write(fd, outStr.string(), outStr.size());
3448 outStr.clear();
3449
3450 for (const auto& iter : mEffectHandles) {
3451 outStr.appendFormat("%*sEffect for patch handle %d:\n", spaces + 2, "", iter.first);
3452 write(fd, outStr.string(), outStr.size());
3453 outStr.clear();
3454 sp<EffectBase> effect = iter.second->effect().promote();
3455 if (effect != nullptr) {
3456 effect->dump(fd, args);
3457 }
3458 }
3459
3460 if (locked) {
3461 mLock.unlock();
3462 }
3463 }
3464
3465 #undef LOG_TAG
3466 #define LOG_TAG "AudioFlinger::DeviceEffectProxy::ProxyCallback"
3467
newEffectId()3468 int AudioFlinger::DeviceEffectProxy::ProxyCallback::newEffectId() {
3469 return mManagerCallback->newEffectId();
3470 }
3471
3472
disconnectEffectHandle(EffectHandle * handle,bool unpinIfLast)3473 bool AudioFlinger::DeviceEffectProxy::ProxyCallback::disconnectEffectHandle(
3474 EffectHandle *handle, bool unpinIfLast) {
3475 sp<EffectBase> effectBase = handle->effect().promote();
3476 if (effectBase == nullptr) {
3477 return false;
3478 }
3479
3480 sp<EffectModule> effect = effectBase->asEffectModule();
3481 if (effect == nullptr) {
3482 return false;
3483 }
3484
3485 // restore suspended effects if the disconnected handle was enabled and the last one.
3486 bool remove = (effect->removeHandle(handle) == 0) && (!effect->isPinned() || unpinIfLast);
3487 if (remove) {
3488 sp<DeviceEffectProxy> proxy = mProxy.promote();
3489 if (proxy != nullptr) {
3490 proxy->removeEffect(effect);
3491 }
3492 if (handle->enabled()) {
3493 effectBase->checkSuspendOnEffectEnabled(false, false /*threadLocked*/);
3494 }
3495 }
3496 return true;
3497 }
3498
createEffectHal(const effect_uuid_t * pEffectUuid,int32_t sessionId,int32_t deviceId,sp<EffectHalInterface> * effect)3499 status_t AudioFlinger::DeviceEffectProxy::ProxyCallback::createEffectHal(
3500 const effect_uuid_t *pEffectUuid, int32_t sessionId, int32_t deviceId,
3501 sp<EffectHalInterface> *effect) {
3502 return mManagerCallback->createEffectHal(pEffectUuid, sessionId, deviceId, effect);
3503 }
3504
addEffectToHal(sp<EffectHalInterface> effect)3505 status_t AudioFlinger::DeviceEffectProxy::ProxyCallback::addEffectToHal(
3506 sp<EffectHalInterface> effect) {
3507 sp<DeviceEffectProxy> proxy = mProxy.promote();
3508 if (proxy == nullptr) {
3509 return NO_INIT;
3510 }
3511 return proxy->addEffectToHal(effect);
3512 }
3513
removeEffectFromHal(sp<EffectHalInterface> effect)3514 status_t AudioFlinger::DeviceEffectProxy::ProxyCallback::removeEffectFromHal(
3515 sp<EffectHalInterface> effect) {
3516 sp<DeviceEffectProxy> proxy = mProxy.promote();
3517 if (proxy == nullptr) {
3518 return NO_INIT;
3519 }
3520 return proxy->removeEffectFromHal(effect);
3521 }
3522
isOutput() const3523 bool AudioFlinger::DeviceEffectProxy::ProxyCallback::isOutput() const {
3524 sp<DeviceEffectProxy> proxy = mProxy.promote();
3525 if (proxy == nullptr) {
3526 return true;
3527 }
3528 return proxy->isOutput();
3529 }
3530
sampleRate() const3531 uint32_t AudioFlinger::DeviceEffectProxy::ProxyCallback::sampleRate() const {
3532 sp<DeviceEffectProxy> proxy = mProxy.promote();
3533 if (proxy == nullptr) {
3534 return DEFAULT_OUTPUT_SAMPLE_RATE;
3535 }
3536 return proxy->sampleRate();
3537 }
3538
inChannelMask(int id __unused) const3539 audio_channel_mask_t AudioFlinger::DeviceEffectProxy::ProxyCallback::inChannelMask(
3540 int id __unused) const {
3541 sp<DeviceEffectProxy> proxy = mProxy.promote();
3542 if (proxy == nullptr) {
3543 return AUDIO_CHANNEL_OUT_STEREO;
3544 }
3545 return proxy->channelMask();
3546 }
3547
inChannelCount(int id __unused) const3548 uint32_t AudioFlinger::DeviceEffectProxy::ProxyCallback::inChannelCount(int id __unused) const {
3549 sp<DeviceEffectProxy> proxy = mProxy.promote();
3550 if (proxy == nullptr) {
3551 return 2;
3552 }
3553 return proxy->channelCount();
3554 }
3555
outChannelMask() const3556 audio_channel_mask_t AudioFlinger::DeviceEffectProxy::ProxyCallback::outChannelMask() const {
3557 sp<DeviceEffectProxy> proxy = mProxy.promote();
3558 if (proxy == nullptr) {
3559 return AUDIO_CHANNEL_OUT_STEREO;
3560 }
3561 return proxy->channelMask();
3562 }
3563
outChannelCount() const3564 uint32_t AudioFlinger::DeviceEffectProxy::ProxyCallback::outChannelCount() const {
3565 sp<DeviceEffectProxy> proxy = mProxy.promote();
3566 if (proxy == nullptr) {
3567 return 2;
3568 }
3569 return proxy->channelCount();
3570 }
3571
onEffectEnable(const sp<EffectBase> & effectBase)3572 void AudioFlinger::DeviceEffectProxy::ProxyCallback::onEffectEnable(
3573 const sp<EffectBase>& effectBase) {
3574 sp<EffectModule> effect = effectBase->asEffectModule();
3575 if (effect == nullptr) {
3576 return;
3577 }
3578 effect->start();
3579 }
3580
onEffectDisable(const sp<EffectBase> & effectBase)3581 void AudioFlinger::DeviceEffectProxy::ProxyCallback::onEffectDisable(
3582 const sp<EffectBase>& effectBase) {
3583 sp<EffectModule> effect = effectBase->asEffectModule();
3584 if (effect == nullptr) {
3585 return;
3586 }
3587 effect->stop();
3588 }
3589
3590 } // namespace android
3591