1 /*
2 **
3 ** Copyright 2010, 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_NDEBUG 0
20 #define LOG_TAG "AudioEffect"
21
22 #include <stdint.h>
23 #include <sys/types.h>
24 #include <limits.h>
25
26 #include <android/media/IAudioPolicyService.h>
27 #include <binder/IPCThreadState.h>
28 #include <media/AidlConversion.h>
29 #include <media/AudioEffect.h>
30 #include <media/PolicyAidlConversion.h>
31 #include <media/ShmemCompat.h>
32 #include <private/media/AudioEffectShared.h>
33 #include <utils/Log.h>
34
35 namespace android {
36 using aidl_utils::statusTFromBinderStatus;
37 using binder::Status;
38 using media::IAudioPolicyService;
39 using media::audio::common::AudioSource;
40 using media::audio::common::AudioUuid;
41
42 namespace {
43
44 // Copy from a raw pointer + size into a vector of bytes.
appendToBuffer(const void * data,size_t size,std::vector<uint8_t> * buffer)45 void appendToBuffer(const void* data,
46 size_t size,
47 std::vector<uint8_t>* buffer) {
48 const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
49 buffer->insert(buffer->end(), p, p + size);
50 }
51
52 } // namespace
53
54 // ---------------------------------------------------------------------------
55
AudioEffect(const android::content::AttributionSourceState & attributionSource)56 AudioEffect::AudioEffect(const android::content::AttributionSourceState& attributionSource)
57 : mClientAttributionSource(attributionSource)
58 {
59 }
60
set(const effect_uuid_t * type,const effect_uuid_t * uuid,int32_t priority,const wp<IAudioEffectCallback> & callback,audio_session_t sessionId,audio_io_handle_t io,const AudioDeviceTypeAddr & device,bool probe,bool notifyFramesProcessed)61 status_t AudioEffect::set(const effect_uuid_t *type,
62 const effect_uuid_t *uuid,
63 int32_t priority,
64 const wp<IAudioEffectCallback>& callback,
65 audio_session_t sessionId,
66 audio_io_handle_t io,
67 const AudioDeviceTypeAddr& device,
68 bool probe,
69 bool notifyFramesProcessed)
70 {
71 sp<media::IEffect> iEffect;
72 sp<IMemory> cblk;
73 int enabled;
74
75 ALOGV("set %p uuid: %p timeLow %08x", this, type, type ? type->timeLow : 0);
76
77 if (mIEffect != 0) {
78 ALOGW("Effect already in use");
79 return INVALID_OPERATION;
80 }
81
82 if (sessionId == AUDIO_SESSION_DEVICE && io != AUDIO_IO_HANDLE_NONE) {
83 ALOGW("IO handle should not be specified for device effect");
84 return BAD_VALUE;
85 }
86 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
87 if (audioFlinger == 0) {
88 ALOGE("set(): Could not get audioflinger");
89 return NO_INIT;
90 }
91
92 if (type == nullptr && uuid == nullptr) {
93 ALOGW("Must specify at least type or uuid");
94 return BAD_VALUE;
95 }
96 mProbe = probe;
97 mPriority = priority;
98 mSessionId = sessionId;
99 mCallback = callback;
100
101 memset(&mDescriptor, 0, sizeof(effect_descriptor_t));
102 mDescriptor.type = *(type != nullptr ? type : EFFECT_UUID_NULL);
103 mDescriptor.uuid = *(uuid != nullptr ? uuid : EFFECT_UUID_NULL);
104
105 // TODO b/182392769: use attribution source util
106 mIEffectClient = new EffectClient(this);
107 pid_t pid = IPCThreadState::self()->getCallingPid();
108 mClientAttributionSource.pid = VALUE_OR_RETURN_STATUS(legacy2aidl_pid_t_int32_t(pid));
109 pid_t uid = IPCThreadState::self()->getCallingUid();
110 mClientAttributionSource.uid = VALUE_OR_RETURN_STATUS(legacy2aidl_uid_t_int32_t(uid));
111
112 media::CreateEffectRequest request;
113 request.desc = VALUE_OR_RETURN_STATUS(
114 legacy2aidl_effect_descriptor_t_EffectDescriptor(mDescriptor));
115 request.client = mIEffectClient;
116 request.priority = priority;
117 request.output = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_io_handle_t_int32_t(io));
118 request.sessionId = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_session_t_int32_t(mSessionId));
119 request.device = VALUE_OR_RETURN_STATUS(legacy2aidl_AudioDeviceTypeAddress(device));
120 request.attributionSource = mClientAttributionSource;
121 request.probe = probe;
122 request.notifyFramesProcessed = notifyFramesProcessed;
123
124 media::CreateEffectResponse response;
125
126 mStatus = audioFlinger->createEffect(request, &response);
127
128 if (mStatus == OK) {
129 if (response.alreadyExists) {
130 mStatus = ALREADY_EXISTS;
131 }
132 mId = response.id;
133 enabled = response.enabled;
134 iEffect = response.effect;
135 mDescriptor = VALUE_OR_RETURN_STATUS(
136 aidl2legacy_EffectDescriptor_effect_descriptor_t(response.desc));
137 }
138
139 // In probe mode, we stop here and return the status: the IEffect interface to
140 // audio flinger will not be retained. initCheck() will return the creation status
141 // but all other APIs will return invalid operation.
142 if (probe || iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) {
143 char typeBuffer[64] = {}, uuidBuffer[64] = {};
144 guidToString(type, typeBuffer, sizeof(typeBuffer));
145 guidToString(uuid, uuidBuffer, sizeof(uuidBuffer));
146 ALOGE_IF(!probe, "set(): AudioFlinger could not create effect %s / %s, status: %d",
147 type != nullptr ? typeBuffer : "NULL",
148 uuid != nullptr ? uuidBuffer : "NULL",
149 mStatus);
150 if (!probe && iEffect == 0) {
151 mStatus = NO_INIT;
152 }
153 return mStatus;
154 }
155
156 mEnabled = (volatile int32_t)enabled;
157
158 if (media::SharedFileRegion shmem;
159 !iEffect->getCblk(&shmem).isOk()
160 || !convertSharedFileRegionToIMemory(shmem, &cblk)
161 || cblk == 0) {
162 mStatus = NO_INIT;
163 ALOGE("Could not get control block");
164 return mStatus;
165 }
166
167 mIEffect = iEffect;
168 mCblkMemory = cblk;
169 // TODO: Using unsecurePointer() has some associated security pitfalls
170 // (see declaration for details).
171 // Either document why it is safe in this case or address the
172 // issue (e.g. by copying).
173 mCblk = static_cast<effect_param_cblk_t*>(cblk->unsecurePointer());
174 int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
175 mCblk->buffer = (uint8_t *)mCblk + bufOffset;
176
177 IInterface::asBinder(iEffect)->linkToDeath(mIEffectClient);
178 ALOGV("set() %p OK effect: %s id: %d status %d enabled %d pid %d", this, mDescriptor.name, mId,
179 mStatus, mEnabled, mClientAttributionSource.pid);
180
181 if (!audio_is_global_session(mSessionId)) {
182 AudioSystem::acquireAudioSessionId(mSessionId, pid, uid);
183 }
184
185 return mStatus;
186 }
187
188 namespace {
189 class LegacyCallbackWrapper : public AudioEffect::IAudioEffectCallback {
190 public:
LegacyCallbackWrapper(AudioEffect::legacy_callback_t callback,void * user)191 LegacyCallbackWrapper(AudioEffect::legacy_callback_t callback, void* user):
192 mCallback(callback), mUser(user) {}
193 private:
onControlStatusChanged(bool isGranted)194 void onControlStatusChanged(bool isGranted) override {
195 mCallback(AudioEffect::EVENT_CONTROL_STATUS_CHANGED, mUser, &isGranted);
196 }
197
onEnableStatusChanged(bool isEnabled)198 void onEnableStatusChanged(bool isEnabled) override {
199 mCallback(AudioEffect::EVENT_ENABLE_STATUS_CHANGED, mUser, &isEnabled);
200 }
201
onParameterChanged(std::vector<uint8_t> param)202 void onParameterChanged(std::vector<uint8_t> param) override {
203 mCallback(AudioEffect::EVENT_PARAMETER_CHANGED, mUser, param.data());
204 }
205
onError(status_t errorCode)206 void onError(status_t errorCode) override {
207 mCallback(AudioEffect::EVENT_ERROR, mUser, &errorCode);
208 }
209
onFramesProcessed(int32_t framesProcessed)210 void onFramesProcessed(int32_t framesProcessed) override {
211 mCallback(AudioEffect::EVENT_FRAMES_PROCESSED, mUser, &framesProcessed);
212 }
213
214 const AudioEffect::legacy_callback_t mCallback;
215 void* const mUser;
216 };
217 } // namespace
218
set(const effect_uuid_t * type,const effect_uuid_t * uuid,int32_t priority,legacy_callback_t cbf,void * user,audio_session_t sessionId,audio_io_handle_t io,const AudioDeviceTypeAddr & device,bool probe,bool notifyFramesProcessed)219 status_t AudioEffect::set(const effect_uuid_t *type,
220 const effect_uuid_t *uuid,
221 int32_t priority,
222 legacy_callback_t cbf,
223 void* user,
224 audio_session_t sessionId,
225 audio_io_handle_t io,
226 const AudioDeviceTypeAddr& device,
227 bool probe,
228 bool notifyFramesProcessed)
229 {
230 if (cbf != nullptr) {
231 mLegacyWrapper = sp<LegacyCallbackWrapper>::make(cbf, user);
232 } else if (user != nullptr) {
233 LOG_ALWAYS_FATAL("%s: User provided without callback", __func__);
234 }
235 return set(type, uuid, priority, mLegacyWrapper, sessionId, io, device, probe,
236 notifyFramesProcessed);
237 }
set(const char * typeStr,const char * uuidStr,int32_t priority,const wp<IAudioEffectCallback> & callback,audio_session_t sessionId,audio_io_handle_t io,const AudioDeviceTypeAddr & device,bool probe,bool notifyFramesProcessed)238 status_t AudioEffect::set(const char *typeStr,
239 const char *uuidStr,
240 int32_t priority,
241 const wp<IAudioEffectCallback>& callback,
242 audio_session_t sessionId,
243 audio_io_handle_t io,
244 const AudioDeviceTypeAddr& device,
245 bool probe,
246 bool notifyFramesProcessed)
247 {
248 effect_uuid_t type;
249 effect_uuid_t *pType = nullptr;
250 effect_uuid_t uuid;
251 effect_uuid_t *pUuid = nullptr;
252
253 ALOGV("AudioEffect::set string\n - type: %s\n - uuid: %s",
254 typeStr ? typeStr : "nullptr", uuidStr ? uuidStr : "nullptr");
255
256 if (stringToGuid(typeStr, &type) == NO_ERROR) {
257 pType = &type;
258 }
259 if (stringToGuid(uuidStr, &uuid) == NO_ERROR) {
260 pUuid = &uuid;
261 }
262
263 return set(pType, pUuid, priority, callback, sessionId, io,
264 device, probe, notifyFramesProcessed);
265 }
266
set(const char * typeStr,const char * uuidStr,int32_t priority,legacy_callback_t cbf,void * user,audio_session_t sessionId,audio_io_handle_t io,const AudioDeviceTypeAddr & device,bool probe,bool notifyFramesProcessed)267 status_t AudioEffect::set(const char *typeStr,
268 const char *uuidStr,
269 int32_t priority,
270 legacy_callback_t cbf,
271 void* user,
272 audio_session_t sessionId,
273 audio_io_handle_t io,
274 const AudioDeviceTypeAddr& device,
275 bool probe,
276 bool notifyFramesProcessed)
277 {
278 if (cbf != nullptr) {
279 mLegacyWrapper = sp<LegacyCallbackWrapper>::make(cbf, user);
280 } else if (user != nullptr) {
281 LOG_ALWAYS_FATAL("%s: User provided without callback", __func__);
282 }
283 return set(typeStr, uuidStr, priority, mLegacyWrapper, sessionId, io, device, probe,
284 notifyFramesProcessed);
285 }
~AudioEffect()286 AudioEffect::~AudioEffect()
287 {
288 ALOGV("Destructor %p", this);
289
290 if (!mProbe && (mStatus == NO_ERROR || mStatus == ALREADY_EXISTS)) {
291 if (!audio_is_global_session(mSessionId)) {
292 AudioSystem::releaseAudioSessionId(mSessionId,
293 VALUE_OR_FATAL(aidl2legacy_int32_t_pid_t(mClientAttributionSource.pid)));
294 }
295 if (mIEffect != nullptr) {
296 mIEffect->disconnect();
297 IInterface::asBinder(mIEffect)->unlinkToDeath(mIEffectClient);
298 }
299 mIEffect.clear();
300 mCblkMemory.clear();
301 }
302 mIEffectClient.clear();
303 IPCThreadState::self()->flushCommands();
304 }
305
306
initCheck() const307 status_t AudioEffect::initCheck() const
308 {
309 return mStatus;
310 }
311
312 // -------------------------------------------------------------------------
313
descriptor() const314 effect_descriptor_t AudioEffect::descriptor() const
315 {
316 return mDescriptor;
317 }
318
getEnabled() const319 bool AudioEffect::getEnabled() const
320 {
321 return (mEnabled != 0);
322 }
323
setEnabled(bool enabled)324 status_t AudioEffect::setEnabled(bool enabled)
325 {
326 if (mProbe) {
327 return INVALID_OPERATION;
328 }
329 if (mStatus != NO_ERROR) {
330 return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
331 }
332
333 status_t status = NO_ERROR;
334 AutoMutex lock(mLock);
335 if (enabled != mEnabled) {
336 Status bs;
337
338 if (enabled) {
339 ALOGV("enable %p", this);
340 bs = mIEffect->enable(&status);
341 } else {
342 ALOGV("disable %p", this);
343 bs = mIEffect->disable(&status);
344 }
345 if (!bs.isOk()) {
346 status = statusTFromBinderStatus(bs);
347 }
348 if (status == NO_ERROR) {
349 mEnabled = enabled;
350 }
351 }
352 return status;
353 }
354
command(uint32_t cmdCode,uint32_t cmdSize,void * cmdData,uint32_t * replySize,void * replyData)355 status_t AudioEffect::command(uint32_t cmdCode,
356 uint32_t cmdSize,
357 void *cmdData,
358 uint32_t *replySize,
359 void *replyData)
360 {
361 if (mProbe) {
362 return INVALID_OPERATION;
363 }
364 if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
365 ALOGV("command() bad status %d", mStatus);
366 return mStatus;
367 }
368
369 std::unique_lock ul(mLock, std::defer_lock);
370 if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) {
371 ul.lock();
372 if (mEnabled == (cmdCode == EFFECT_CMD_ENABLE)) {
373 return NO_ERROR;
374 }
375 if (replySize == nullptr || *replySize != sizeof(status_t) || replyData == nullptr) {
376 return BAD_VALUE;
377 }
378 }
379
380 std::vector<uint8_t> data;
381 appendToBuffer(cmdData, cmdSize, &data);
382
383 status_t status;
384 std::vector<uint8_t> response;
385
386 Status bs = mIEffect->command(cmdCode, data, *replySize, &response, &status);
387 if (!bs.isOk()) {
388 status = statusTFromBinderStatus(bs);
389 }
390 if (status == NO_ERROR) {
391 memcpy(replyData, response.data(), response.size());
392 *replySize = response.size();
393 }
394
395 if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) {
396 if (status == NO_ERROR) {
397 status = *(status_t *)replyData;
398 }
399 if (status == NO_ERROR) {
400 mEnabled = (cmdCode == EFFECT_CMD_ENABLE);
401 }
402 }
403
404 return status;
405 }
406
setParameter(effect_param_t * param)407 status_t AudioEffect::setParameter(effect_param_t *param)
408 {
409 if (mProbe) {
410 return INVALID_OPERATION;
411 }
412 if (mStatus != NO_ERROR) {
413 return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
414 }
415
416 if (param == nullptr || param->psize == 0 || param->vsize == 0) {
417 return BAD_VALUE;
418 }
419
420 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
421
422 ALOGV("setParameter: param: %d, param2: %d", *(int *)param->data,
423 (param->psize == 8) ? *((int *)param->data + 1): -1);
424
425 std::vector<uint8_t> cmd;
426 appendToBuffer(param, sizeof(effect_param_t) + psize, &cmd);
427 std::vector<uint8_t> response;
428 status_t status;
429 Status bs = mIEffect->command(EFFECT_CMD_SET_PARAM,
430 cmd,
431 sizeof(int),
432 &response,
433 &status);
434 if (!bs.isOk()) {
435 status = statusTFromBinderStatus(bs);
436 return status;
437 }
438 assert(response.size() == sizeof(int));
439 memcpy(¶m->status, response.data(), response.size());
440 return status;
441 }
442
setParameterDeferred(effect_param_t * param)443 status_t AudioEffect::setParameterDeferred(effect_param_t *param)
444 {
445 if (mProbe) {
446 return INVALID_OPERATION;
447 }
448 if (mStatus != NO_ERROR) {
449 return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
450 }
451 if (param == nullptr || param->psize == 0 || param->vsize == 0) {
452 return BAD_VALUE;
453 }
454
455 Mutex::Autolock _l(mCblk->lock);
456
457 int psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
458 int size = ((sizeof(effect_param_t) + psize - 1) / sizeof(int) + 1) * sizeof(int);
459
460 if (mCblk->clientIndex + size > EFFECT_PARAM_BUFFER_SIZE) {
461 return NO_MEMORY;
462 }
463 int *p = (int *)(mCblk->buffer + mCblk->clientIndex);
464 *p++ = size;
465 memcpy(p, param, sizeof(effect_param_t) + psize);
466 mCblk->clientIndex += size;
467
468 return NO_ERROR;
469 }
470
setParameterCommit()471 status_t AudioEffect::setParameterCommit()
472 {
473 if (mProbe) {
474 return INVALID_OPERATION;
475 }
476 if (mStatus != NO_ERROR) {
477 return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
478 }
479
480 Mutex::Autolock _l(mCblk->lock);
481 if (mCblk->clientIndex == 0) {
482 return INVALID_OPERATION;
483 }
484 std::vector<uint8_t> cmd;
485 std::vector<uint8_t> response;
486 status_t status;
487 Status bs = mIEffect->command(EFFECT_CMD_SET_PARAM_COMMIT,
488 cmd,
489 0,
490 &response,
491 &status);
492 if (!bs.isOk()) {
493 status = statusTFromBinderStatus(bs);
494 }
495 return status;
496 }
497
getParameter(effect_param_t * param)498 status_t AudioEffect::getParameter(effect_param_t *param)
499 {
500 if (mProbe) {
501 return INVALID_OPERATION;
502 }
503 if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
504 return mStatus;
505 }
506 if (param == nullptr || param->psize == 0 || param->vsize == 0) {
507 return BAD_VALUE;
508 }
509
510 ALOGV("getParameter: param: %d, param2: %d", *(int *)param->data,
511 (param->psize == 8) ? *((int *)param->data + 1): -1);
512
513 uint32_t psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
514 param->vsize;
515
516 status_t status;
517 std::vector<uint8_t> cmd;
518 std::vector<uint8_t> response;
519 appendToBuffer(param, sizeof(effect_param_t) + param->psize, &cmd);
520
521 Status bs = mIEffect->command(EFFECT_CMD_GET_PARAM, cmd, psize, &response, &status);
522 if (!bs.isOk()) {
523 status = statusTFromBinderStatus(bs);
524 return status;
525 }
526 memcpy(param, response.data(), response.size());
527 return status;
528 }
529
getConfigs(audio_config_base_t * inputCfg,audio_config_base_t * outputCfg)530 status_t AudioEffect::getConfigs(
531 audio_config_base_t *inputCfg, audio_config_base_t *outputCfg)
532 {
533 if (mProbe) {
534 return INVALID_OPERATION;
535 }
536 if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
537 return mStatus;
538 }
539 if (inputCfg == NULL || outputCfg == NULL) {
540 return BAD_VALUE;
541 }
542 status_t status;
543 media::EffectConfig cfg;
544 Status bs = mIEffect->getConfig(&cfg, &status);
545 if (!bs.isOk()) {
546 status = statusTFromBinderStatus(bs);
547 ALOGW("%s received status %d from binder transaction", __func__, status);
548 return status;
549 }
550 if (status == NO_ERROR) {
551 *inputCfg = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioConfigBase_audio_config_base_t(
552 cfg.inputCfg, cfg.isOnInputStream));
553 *outputCfg = VALUE_OR_RETURN_STATUS(aidl2legacy_AudioConfigBase_audio_config_base_t(
554 cfg.outputCfg, cfg.isOnInputStream));
555 } else {
556 ALOGW("%s received status %d from the effect", __func__, status);
557 }
558 return status;
559 }
560
561 // -------------------------------------------------------------------------
562
binderDied()563 void AudioEffect::binderDied()
564 {
565 ALOGW("IEffect died");
566 mStatus = DEAD_OBJECT;
567 auto cb = mCallback.promote();
568 if (cb != nullptr) {
569 cb->onError(mStatus);
570 }
571 }
572
573 // -------------------------------------------------------------------------
574
controlStatusChanged(bool controlGranted)575 void AudioEffect::controlStatusChanged(bool controlGranted)
576 {
577 auto cb = mCallback.promote();
578 ALOGV("controlStatusChanged %p control %d callback %p", this, controlGranted, cb.get());
579 if (controlGranted) {
580 if (mStatus == ALREADY_EXISTS) {
581 mStatus = NO_ERROR;
582 }
583 } else {
584 if (mStatus == NO_ERROR) {
585 mStatus = ALREADY_EXISTS;
586 }
587 }
588 if (cb != nullptr) {
589 cb->onControlStatusChanged(controlGranted);
590 }
591 }
592
enableStatusChanged(bool enabled)593 void AudioEffect::enableStatusChanged(bool enabled)
594 {
595 auto cb = mCallback.promote();
596 ALOGV("enableStatusChanged %p enabled %d mCallback %p", this, enabled, cb.get());
597 if (mStatus == ALREADY_EXISTS) {
598 mEnabled = enabled;
599 if (cb != nullptr) {
600 cb->onEnableStatusChanged(enabled);
601 }
602 }
603 }
604
commandExecuted(int32_t cmdCode,const std::vector<uint8_t> & cmdData,const std::vector<uint8_t> & replyData)605 void AudioEffect::commandExecuted(int32_t cmdCode,
606 const std::vector<uint8_t>& cmdData,
607 const std::vector<uint8_t>& replyData)
608 {
609 if (cmdData.empty() || replyData.empty()) {
610 return;
611 }
612 auto cb = mCallback.promote();
613 if (cb != nullptr && cmdCode == EFFECT_CMD_SET_PARAM) {
614 std::vector<uint8_t> cmdDataCopy(cmdData);
615 effect_param_t* cmd = reinterpret_cast<effect_param_t *>(cmdDataCopy.data());
616 cmd->status = *reinterpret_cast<const int32_t *>(replyData.data());
617 cb->onParameterChanged(std::move(cmdDataCopy));
618 }
619 }
620
framesProcessed(int32_t frames)621 void AudioEffect::framesProcessed(int32_t frames)
622 {
623 auto cb = mCallback.promote();
624 if (cb != nullptr) {
625 cb->onFramesProcessed(frames);
626 }
627 }
628
629 // -------------------------------------------------------------------------
630
queryNumberEffects(uint32_t * numEffects)631 status_t AudioEffect::queryNumberEffects(uint32_t *numEffects)
632 {
633 if (numEffects == nullptr) {
634 return BAD_VALUE;
635 }
636 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
637 if (af == 0) return PERMISSION_DENIED;
638 return af->queryNumberEffects(numEffects);
639 }
640
queryEffect(uint32_t index,effect_descriptor_t * descriptor)641 status_t AudioEffect::queryEffect(uint32_t index, effect_descriptor_t *descriptor)
642 {
643 if (descriptor == nullptr) {
644 return BAD_VALUE;
645 }
646 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
647 if (af == 0) return PERMISSION_DENIED;
648 return af->queryEffect(index, descriptor);
649 }
650
getEffectDescriptor(const effect_uuid_t * uuid,const effect_uuid_t * type,uint32_t preferredTypeFlag,effect_descriptor_t * descriptor)651 status_t AudioEffect::getEffectDescriptor(const effect_uuid_t *uuid,
652 const effect_uuid_t *type,
653 uint32_t preferredTypeFlag,
654 effect_descriptor_t *descriptor)
655 {
656 if (uuid == nullptr || type == nullptr || descriptor == nullptr) {
657 return BAD_VALUE;
658 }
659 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
660 if (af == 0) return PERMISSION_DENIED;
661 return af->getEffectDescriptor(uuid, type, preferredTypeFlag, descriptor);
662 }
663
queryDefaultPreProcessing(audio_session_t audioSession,effect_descriptor_t * descriptors,uint32_t * count)664 status_t AudioEffect::queryDefaultPreProcessing(audio_session_t audioSession,
665 effect_descriptor_t *descriptors,
666 uint32_t *count)
667 {
668 if (descriptors == nullptr || count == nullptr) {
669 return BAD_VALUE;
670 }
671 const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
672 if (aps == 0) return PERMISSION_DENIED;
673
674 int32_t audioSessionAidl = VALUE_OR_RETURN_STATUS(
675 legacy2aidl_audio_session_t_int32_t(audioSession));
676 media::audio::common::Int countAidl;
677 countAidl.value = VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(*count));
678 std::vector<media::EffectDescriptor> retAidl;
679 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
680 aps->queryDefaultPreProcessing(audioSessionAidl, &countAidl, &retAidl)));
681 *count = VALUE_OR_RETURN_STATUS(convertIntegral<uint32_t>(countAidl.value));
682 RETURN_STATUS_IF_ERROR(convertRange(retAidl.begin(), retAidl.end(), descriptors,
683 aidl2legacy_EffectDescriptor_effect_descriptor_t));
684 return OK;
685 }
686
newEffectUniqueId(audio_unique_id_t * id)687 status_t AudioEffect::newEffectUniqueId(audio_unique_id_t* id)
688 {
689 if (id == nullptr) {
690 return BAD_VALUE;
691 }
692 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
693 if (af == 0) return PERMISSION_DENIED;
694 *id = af->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
695 return NO_ERROR;
696 }
697
addSourceDefaultEffect(const char * typeStr,const String16 & opPackageName,const char * uuidStr,int32_t priority,audio_source_t source,audio_unique_id_t * id)698 status_t AudioEffect::addSourceDefaultEffect(const char *typeStr,
699 const String16& opPackageName,
700 const char *uuidStr,
701 int32_t priority,
702 audio_source_t source,
703 audio_unique_id_t *id)
704 {
705 if ((typeStr == nullptr && uuidStr == nullptr) || id == nullptr) {
706 return BAD_VALUE;
707 }
708 const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
709 if (aps == 0) return PERMISSION_DENIED;
710
711 // Convert type & uuid from string to effect_uuid_t.
712 effect_uuid_t type;
713 if (typeStr != nullptr) {
714 status_t res = stringToGuid(typeStr, &type);
715 if (res != OK) return res;
716 } else {
717 type = *EFFECT_UUID_NULL;
718 }
719
720 effect_uuid_t uuid;
721 if (uuidStr != nullptr) {
722 status_t res = stringToGuid(uuidStr, &uuid);
723 if (res != OK) return res;
724 } else {
725 uuid = *EFFECT_UUID_NULL;
726 }
727
728 AudioUuid typeAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(type));
729 AudioUuid uuidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(uuid));
730 std::string opPackageNameAidl = VALUE_OR_RETURN_STATUS(
731 legacy2aidl_String16_string(opPackageName));
732 AudioSource sourceAidl = VALUE_OR_RETURN_STATUS(
733 legacy2aidl_audio_source_t_AudioSource(source));
734 int32_t retAidl;
735 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
736 aps->addSourceDefaultEffect(typeAidl, opPackageNameAidl, uuidAidl, priority, sourceAidl,
737 &retAidl)));
738 *id = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_unique_id_t(retAidl));
739 return OK;
740 }
741
addStreamDefaultEffect(const char * typeStr,const String16 & opPackageName,const char * uuidStr,int32_t priority,audio_usage_t usage,audio_unique_id_t * id)742 status_t AudioEffect::addStreamDefaultEffect(const char *typeStr,
743 const String16& opPackageName,
744 const char *uuidStr,
745 int32_t priority,
746 audio_usage_t usage,
747 audio_unique_id_t *id)
748 {
749 if ((typeStr == nullptr && uuidStr == nullptr) || id == nullptr) {
750 return BAD_VALUE;
751 }
752 const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
753 if (aps == 0) return PERMISSION_DENIED;
754
755 // Convert type & uuid from string to effect_uuid_t.
756 effect_uuid_t type;
757 if (typeStr != nullptr) {
758 status_t res = stringToGuid(typeStr, &type);
759 if (res != OK) return res;
760 } else {
761 type = *EFFECT_UUID_NULL;
762 }
763
764 effect_uuid_t uuid;
765 if (uuidStr != nullptr) {
766 status_t res = stringToGuid(uuidStr, &uuid);
767 if (res != OK) return res;
768 } else {
769 uuid = *EFFECT_UUID_NULL;
770 }
771
772 AudioUuid typeAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(type));
773 AudioUuid uuidAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_uuid_t_AudioUuid(uuid));
774 std::string opPackageNameAidl = VALUE_OR_RETURN_STATUS(
775 legacy2aidl_String16_string(opPackageName));
776 media::audio::common::AudioUsage usageAidl = VALUE_OR_RETURN_STATUS(
777 legacy2aidl_audio_usage_t_AudioUsage(usage));
778 int32_t retAidl;
779 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
780 aps->addStreamDefaultEffect(typeAidl, opPackageNameAidl, uuidAidl, priority, usageAidl,
781 &retAidl)));
782 *id = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_unique_id_t(retAidl));
783 return OK;
784 }
785
removeSourceDefaultEffect(audio_unique_id_t id)786 status_t AudioEffect::removeSourceDefaultEffect(audio_unique_id_t id)
787 {
788 const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
789 if (aps == 0) return PERMISSION_DENIED;
790
791 int32_t idAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_unique_id_t_int32_t(id));
792 return statusTFromBinderStatus(aps->removeSourceDefaultEffect(idAidl));
793 }
794
removeStreamDefaultEffect(audio_unique_id_t id)795 status_t AudioEffect::removeStreamDefaultEffect(audio_unique_id_t id)
796 {
797 const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
798 if (aps == 0) return PERMISSION_DENIED;
799
800 int32_t idAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_unique_id_t_int32_t(id));
801 return statusTFromBinderStatus(aps->removeStreamDefaultEffect(idAidl));
802 }
803
804 // -------------------------------------------------------------------------
805
stringToGuid(const char * str,effect_uuid_t * guid)806 status_t AudioEffect::stringToGuid(const char *str, effect_uuid_t *guid)
807 {
808 if (str == nullptr || guid == nullptr) {
809 return BAD_VALUE;
810 }
811
812 int tmp[10];
813
814 if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
815 tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
816 return BAD_VALUE;
817 }
818 guid->timeLow = (uint32_t)tmp[0];
819 guid->timeMid = (uint16_t)tmp[1];
820 guid->timeHiAndVersion = (uint16_t)tmp[2];
821 guid->clockSeq = (uint16_t)tmp[3];
822 guid->node[0] = (uint8_t)tmp[4];
823 guid->node[1] = (uint8_t)tmp[5];
824 guid->node[2] = (uint8_t)tmp[6];
825 guid->node[3] = (uint8_t)tmp[7];
826 guid->node[4] = (uint8_t)tmp[8];
827 guid->node[5] = (uint8_t)tmp[9];
828
829 return NO_ERROR;
830 }
831
guidToString(const effect_uuid_t * guid,char * str,size_t maxLen)832 status_t AudioEffect::guidToString(const effect_uuid_t *guid, char *str, size_t maxLen)
833 {
834 if (guid == nullptr || str == nullptr) {
835 return BAD_VALUE;
836 }
837
838 snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
839 guid->timeLow,
840 guid->timeMid,
841 guid->timeHiAndVersion,
842 guid->clockSeq,
843 guid->node[0],
844 guid->node[1],
845 guid->node[2],
846 guid->node[3],
847 guid->node[4],
848 guid->node[5]);
849
850 return NO_ERROR;
851 }
852
853
854 } // namespace android
855