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