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(&param->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