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