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 <private/media/AudioEffectShared.h>
27 #include <media/AudioEffect.h>
28
29 #include <utils/Log.h>
30 #include <binder/IPCThreadState.h>
31
32
33
34 namespace android {
35
36 // ---------------------------------------------------------------------------
37
AudioEffect(const String16 & opPackageName)38 AudioEffect::AudioEffect(const String16& opPackageName)
39 : mOpPackageName(opPackageName)
40 {
41 }
42
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)43 status_t AudioEffect::set(const effect_uuid_t *type,
44 const effect_uuid_t *uuid,
45 int32_t priority,
46 effect_callback_t cbf,
47 void* user,
48 audio_session_t sessionId,
49 audio_io_handle_t io,
50 const AudioDeviceTypeAddr& device,
51 bool probe)
52 {
53 sp<IEffect> iEffect;
54 sp<IMemory> cblk;
55 int enabled;
56
57 ALOGV("set %p mUserData: %p uuid: %p timeLow %08x", this, user, type, type ? type->timeLow : 0);
58
59 if (mIEffect != 0) {
60 ALOGW("Effect already in use");
61 return INVALID_OPERATION;
62 }
63
64 if (sessionId == AUDIO_SESSION_DEVICE && io != AUDIO_IO_HANDLE_NONE) {
65 ALOGW("IO handle should not be specified for device effect");
66 return BAD_VALUE;
67 }
68 const sp<IAudioFlinger>& audioFlinger = AudioSystem::get_audio_flinger();
69 if (audioFlinger == 0) {
70 ALOGE("set(): Could not get audioflinger");
71 return NO_INIT;
72 }
73
74 if (type == NULL && uuid == NULL) {
75 ALOGW("Must specify at least type or uuid");
76 return BAD_VALUE;
77 }
78 mProbe = probe;
79 mPriority = priority;
80 mCbf = cbf;
81 mUserData = user;
82 mSessionId = sessionId;
83
84 memset(&mDescriptor, 0, sizeof(effect_descriptor_t));
85 mDescriptor.type = *(type != NULL ? type : EFFECT_UUID_NULL);
86 mDescriptor.uuid = *(uuid != NULL ? uuid : EFFECT_UUID_NULL);
87
88 mIEffectClient = new EffectClient(this);
89 mClientPid = IPCThreadState::self()->getCallingPid();
90 mClientUid = IPCThreadState::self()->getCallingUid();
91
92 iEffect = audioFlinger->createEffect((effect_descriptor_t *)&mDescriptor,
93 mIEffectClient, priority, io, mSessionId, device, mOpPackageName, mClientPid,
94 probe, &mStatus, &mId, &enabled);
95
96 // In probe mode, we stop here and return the status: the IEffect interface to
97 // audio flinger will not be retained. initCheck() will return the creation status
98 // but all other APIs will return invalid operation.
99 if (probe || iEffect == 0 || (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS)) {
100 char typeBuffer[64] = {}, uuidBuffer[64] = {};
101 guidToString(type, typeBuffer, sizeof(typeBuffer));
102 guidToString(uuid, uuidBuffer, sizeof(uuidBuffer));
103 ALOGE_IF(!probe, "set(): AudioFlinger could not create effect %s / %s, status: %d",
104 type != nullptr ? typeBuffer : "NULL",
105 uuid != nullptr ? uuidBuffer : "NULL",
106 mStatus);
107 if (!probe && iEffect == 0) {
108 mStatus = NO_INIT;
109 }
110 return mStatus;
111 }
112
113 mEnabled = (volatile int32_t)enabled;
114
115 cblk = iEffect->getCblk();
116 if (cblk == 0) {
117 mStatus = NO_INIT;
118 ALOGE("Could not get control block");
119 return mStatus;
120 }
121
122 mIEffect = iEffect;
123 mCblkMemory = cblk;
124 // TODO: Using unsecurePointer() has some associated security pitfalls
125 // (see declaration for details).
126 // Either document why it is safe in this case or address the
127 // issue (e.g. by copying).
128 mCblk = static_cast<effect_param_cblk_t*>(cblk->unsecurePointer());
129 int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int);
130 mCblk->buffer = (uint8_t *)mCblk + bufOffset;
131
132 IInterface::asBinder(iEffect)->linkToDeath(mIEffectClient);
133 ALOGV("set() %p OK effect: %s id: %d status %d enabled %d pid %d", this, mDescriptor.name, mId,
134 mStatus, mEnabled, mClientPid);
135
136 if (!audio_is_global_session(mSessionId)) {
137 AudioSystem::acquireAudioSessionId(mSessionId, mClientPid, mClientUid);
138 }
139
140 return mStatus;
141 }
142
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)143 status_t AudioEffect::set(const char *typeStr,
144 const char *uuidStr,
145 int32_t priority,
146 effect_callback_t cbf,
147 void* user,
148 audio_session_t sessionId,
149 audio_io_handle_t io,
150 const AudioDeviceTypeAddr& device,
151 bool probe)
152 {
153 effect_uuid_t type;
154 effect_uuid_t *pType = nullptr;
155 effect_uuid_t uuid;
156 effect_uuid_t *pUuid = nullptr;
157
158 ALOGV("AudioEffect::set string\n - type: %s\n - uuid: %s",
159 typeStr ? typeStr : "nullptr", uuidStr ? uuidStr : "nullptr");
160
161 if (stringToGuid(typeStr, &type) == NO_ERROR) {
162 pType = &type;
163 }
164 if (stringToGuid(uuidStr, &uuid) == NO_ERROR) {
165 pUuid = &uuid;
166 }
167
168 return set(pType, pUuid, priority, cbf, user, sessionId, io, device, probe);
169 }
170
171
~AudioEffect()172 AudioEffect::~AudioEffect()
173 {
174 ALOGV("Destructor %p", this);
175
176 if (!mProbe && (mStatus == NO_ERROR || mStatus == ALREADY_EXISTS)) {
177 if (!audio_is_global_session(mSessionId)) {
178 AudioSystem::releaseAudioSessionId(mSessionId, mClientPid);
179 }
180 if (mIEffect != NULL) {
181 mIEffect->disconnect();
182 IInterface::asBinder(mIEffect)->unlinkToDeath(mIEffectClient);
183 }
184 mIEffect.clear();
185 mCblkMemory.clear();
186 }
187 mIEffectClient.clear();
188 IPCThreadState::self()->flushCommands();
189 }
190
191
initCheck() const192 status_t AudioEffect::initCheck() const
193 {
194 return mStatus;
195 }
196
197 // -------------------------------------------------------------------------
198
descriptor() const199 effect_descriptor_t AudioEffect::descriptor() const
200 {
201 return mDescriptor;
202 }
203
getEnabled() const204 bool AudioEffect::getEnabled() const
205 {
206 return (mEnabled != 0);
207 }
208
setEnabled(bool enabled)209 status_t AudioEffect::setEnabled(bool enabled)
210 {
211 if (mProbe) {
212 return INVALID_OPERATION;
213 }
214 if (mStatus != NO_ERROR) {
215 return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
216 }
217
218 status_t status = NO_ERROR;
219
220 AutoMutex lock(mLock);
221 if (enabled != mEnabled) {
222 if (enabled) {
223 ALOGV("enable %p", this);
224 status = mIEffect->enable();
225 } else {
226 ALOGV("disable %p", this);
227 status = mIEffect->disable();
228 }
229 if (status == NO_ERROR) {
230 mEnabled = enabled;
231 }
232 }
233 return status;
234 }
235
command(uint32_t cmdCode,uint32_t cmdSize,void * cmdData,uint32_t * replySize,void * replyData)236 status_t AudioEffect::command(uint32_t cmdCode,
237 uint32_t cmdSize,
238 void *cmdData,
239 uint32_t *replySize,
240 void *replyData)
241 {
242 if (mProbe) {
243 return INVALID_OPERATION;
244 }
245 if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
246 ALOGV("command() bad status %d", mStatus);
247 return mStatus;
248 }
249
250 if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) {
251 if (mEnabled == (cmdCode == EFFECT_CMD_ENABLE)) {
252 return NO_ERROR;
253 }
254 if (replySize == NULL || *replySize != sizeof(status_t) || replyData == NULL) {
255 return BAD_VALUE;
256 }
257 mLock.lock();
258 }
259
260 status_t status = mIEffect->command(cmdCode, cmdSize, cmdData, replySize, replyData);
261
262 if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) {
263 if (status == NO_ERROR) {
264 status = *(status_t *)replyData;
265 }
266 if (status == NO_ERROR) {
267 mEnabled = (cmdCode == EFFECT_CMD_ENABLE);
268 }
269 mLock.unlock();
270 }
271
272 return status;
273 }
274
275
setParameter(effect_param_t * param)276 status_t AudioEffect::setParameter(effect_param_t *param)
277 {
278 if (mProbe) {
279 return INVALID_OPERATION;
280 }
281 if (mStatus != NO_ERROR) {
282 return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
283 }
284
285 if (param == NULL || param->psize == 0 || param->vsize == 0) {
286 return BAD_VALUE;
287 }
288
289 uint32_t size = sizeof(int);
290 uint32_t psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
291
292 ALOGV("setParameter: param: %d, param2: %d", *(int *)param->data,
293 (param->psize == 8) ? *((int *)param->data + 1): -1);
294
295 return mIEffect->command(EFFECT_CMD_SET_PARAM, sizeof (effect_param_t) + psize, param, &size,
296 ¶m->status);
297 }
298
setParameterDeferred(effect_param_t * param)299 status_t AudioEffect::setParameterDeferred(effect_param_t *param)
300 {
301 if (mProbe) {
302 return INVALID_OPERATION;
303 }
304 if (mStatus != NO_ERROR) {
305 return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
306 }
307
308 if (param == NULL || param->psize == 0 || param->vsize == 0) {
309 return BAD_VALUE;
310 }
311
312 Mutex::Autolock _l(mCblk->lock);
313
314 int psize = ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + param->vsize;
315 int size = ((sizeof(effect_param_t) + psize - 1) / sizeof(int) + 1) * sizeof(int);
316
317 if (mCblk->clientIndex + size > EFFECT_PARAM_BUFFER_SIZE) {
318 return NO_MEMORY;
319 }
320 int *p = (int *)(mCblk->buffer + mCblk->clientIndex);
321 *p++ = size;
322 memcpy(p, param, sizeof(effect_param_t) + psize);
323 mCblk->clientIndex += size;
324
325 return NO_ERROR;
326 }
327
setParameterCommit()328 status_t AudioEffect::setParameterCommit()
329 {
330 if (mProbe) {
331 return INVALID_OPERATION;
332 }
333 if (mStatus != NO_ERROR) {
334 return (mStatus == ALREADY_EXISTS) ? (status_t) INVALID_OPERATION : mStatus;
335 }
336
337 Mutex::Autolock _l(mCblk->lock);
338 if (mCblk->clientIndex == 0) {
339 return INVALID_OPERATION;
340 }
341 uint32_t size = 0;
342 return mIEffect->command(EFFECT_CMD_SET_PARAM_COMMIT, 0, NULL, &size, NULL);
343 }
344
getParameter(effect_param_t * param)345 status_t AudioEffect::getParameter(effect_param_t *param)
346 {
347 if (mProbe) {
348 return INVALID_OPERATION;
349 }
350 if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
351 return mStatus;
352 }
353
354 if (param == NULL || param->psize == 0 || param->vsize == 0) {
355 return BAD_VALUE;
356 }
357
358 ALOGV("getParameter: param: %d, param2: %d", *(int *)param->data,
359 (param->psize == 8) ? *((int *)param->data + 1): -1);
360
361 uint32_t psize = sizeof(effect_param_t) + ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) +
362 param->vsize;
363
364 return mIEffect->command(EFFECT_CMD_GET_PARAM, sizeof(effect_param_t) + param->psize, param,
365 &psize, param);
366 }
367
368
369 // -------------------------------------------------------------------------
370
binderDied()371 void AudioEffect::binderDied()
372 {
373 ALOGW("IEffect died");
374 mStatus = DEAD_OBJECT;
375 if (mCbf != NULL) {
376 status_t status = DEAD_OBJECT;
377 mCbf(EVENT_ERROR, mUserData, &status);
378 }
379 mIEffect.clear();
380 }
381
382 // -------------------------------------------------------------------------
383
controlStatusChanged(bool controlGranted)384 void AudioEffect::controlStatusChanged(bool controlGranted)
385 {
386 ALOGV("controlStatusChanged %p control %d callback %p mUserData %p", this, controlGranted, mCbf,
387 mUserData);
388 if (controlGranted) {
389 if (mStatus == ALREADY_EXISTS) {
390 mStatus = NO_ERROR;
391 }
392 } else {
393 if (mStatus == NO_ERROR) {
394 mStatus = ALREADY_EXISTS;
395 }
396 }
397 if (mCbf != NULL) {
398 mCbf(EVENT_CONTROL_STATUS_CHANGED, mUserData, &controlGranted);
399 }
400 }
401
enableStatusChanged(bool enabled)402 void AudioEffect::enableStatusChanged(bool enabled)
403 {
404 ALOGV("enableStatusChanged %p enabled %d mCbf %p", this, enabled, mCbf);
405 if (mStatus == ALREADY_EXISTS) {
406 mEnabled = enabled;
407 if (mCbf != NULL) {
408 mCbf(EVENT_ENABLE_STATUS_CHANGED, mUserData, &enabled);
409 }
410 }
411 }
412
commandExecuted(uint32_t cmdCode,uint32_t cmdSize __unused,void * cmdData,uint32_t replySize __unused,void * replyData)413 void AudioEffect::commandExecuted(uint32_t cmdCode,
414 uint32_t cmdSize __unused,
415 void *cmdData,
416 uint32_t replySize __unused,
417 void *replyData)
418 {
419 if (cmdData == NULL || replyData == NULL) {
420 return;
421 }
422
423 if (mCbf != NULL && cmdCode == EFFECT_CMD_SET_PARAM) {
424 effect_param_t *cmd = (effect_param_t *)cmdData;
425 cmd->status = *(int32_t *)replyData;
426 mCbf(EVENT_PARAMETER_CHANGED, mUserData, cmd);
427 }
428 }
429
430 // -------------------------------------------------------------------------
431
queryNumberEffects(uint32_t * numEffects)432 status_t AudioEffect::queryNumberEffects(uint32_t *numEffects)
433 {
434 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
435 if (af == 0) return PERMISSION_DENIED;
436 return af->queryNumberEffects(numEffects);
437 }
438
queryEffect(uint32_t index,effect_descriptor_t * descriptor)439 status_t AudioEffect::queryEffect(uint32_t index, effect_descriptor_t *descriptor)
440 {
441 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
442 if (af == 0) return PERMISSION_DENIED;
443 return af->queryEffect(index, descriptor);
444 }
445
getEffectDescriptor(const effect_uuid_t * uuid,const effect_uuid_t * type,uint32_t preferredTypeFlag,effect_descriptor_t * descriptor)446 status_t AudioEffect::getEffectDescriptor(const effect_uuid_t *uuid,
447 const effect_uuid_t *type,
448 uint32_t preferredTypeFlag,
449 effect_descriptor_t *descriptor)
450 {
451 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
452 if (af == 0) return PERMISSION_DENIED;
453 return af->getEffectDescriptor(uuid, type, preferredTypeFlag, descriptor);
454 }
455
queryDefaultPreProcessing(audio_session_t audioSession,effect_descriptor_t * descriptors,uint32_t * count)456 status_t AudioEffect::queryDefaultPreProcessing(audio_session_t audioSession,
457 effect_descriptor_t *descriptors,
458 uint32_t *count)
459 {
460 const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
461 if (aps == 0) return PERMISSION_DENIED;
462 return aps->queryDefaultPreProcessing(audioSession, descriptors, count);
463 }
464
newEffectUniqueId(audio_unique_id_t * id)465 status_t AudioEffect::newEffectUniqueId(audio_unique_id_t* id)
466 {
467 const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
468 if (af == 0) return PERMISSION_DENIED;
469 *id = af->newAudioUniqueId(AUDIO_UNIQUE_ID_USE_EFFECT);
470 return NO_ERROR;
471 }
472
addSourceDefaultEffect(const char * typeStr,const String16 & opPackageName,const char * uuidStr,int32_t priority,audio_source_t source,audio_unique_id_t * id)473 status_t AudioEffect::addSourceDefaultEffect(const char *typeStr,
474 const String16& opPackageName,
475 const char *uuidStr,
476 int32_t priority,
477 audio_source_t source,
478 audio_unique_id_t *id)
479 {
480 const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
481 if (aps == 0) return PERMISSION_DENIED;
482
483 if (typeStr == NULL && uuidStr == NULL) return BAD_VALUE;
484
485 // Convert type & uuid from string to effect_uuid_t.
486 effect_uuid_t type;
487 if (typeStr != NULL) {
488 status_t res = stringToGuid(typeStr, &type);
489 if (res != OK) return res;
490 } else {
491 type = *EFFECT_UUID_NULL;
492 }
493
494 effect_uuid_t uuid;
495 if (uuidStr != NULL) {
496 status_t res = stringToGuid(uuidStr, &uuid);
497 if (res != OK) return res;
498 } else {
499 uuid = *EFFECT_UUID_NULL;
500 }
501
502 return aps->addSourceDefaultEffect(&type, opPackageName, &uuid, priority, source, id);
503 }
504
addStreamDefaultEffect(const char * typeStr,const String16 & opPackageName,const char * uuidStr,int32_t priority,audio_usage_t usage,audio_unique_id_t * id)505 status_t AudioEffect::addStreamDefaultEffect(const char *typeStr,
506 const String16& opPackageName,
507 const char *uuidStr,
508 int32_t priority,
509 audio_usage_t usage,
510 audio_unique_id_t *id)
511 {
512 const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
513 if (aps == 0) return PERMISSION_DENIED;
514
515 if (typeStr == NULL && uuidStr == NULL) return BAD_VALUE;
516
517 // Convert type & uuid from string to effect_uuid_t.
518 effect_uuid_t type;
519 if (typeStr != NULL) {
520 status_t res = stringToGuid(typeStr, &type);
521 if (res != OK) return res;
522 } else {
523 type = *EFFECT_UUID_NULL;
524 }
525
526 effect_uuid_t uuid;
527 if (uuidStr != NULL) {
528 status_t res = stringToGuid(uuidStr, &uuid);
529 if (res != OK) return res;
530 } else {
531 uuid = *EFFECT_UUID_NULL;
532 }
533
534 return aps->addStreamDefaultEffect(&type, opPackageName, &uuid, priority, usage, id);
535 }
536
removeSourceDefaultEffect(audio_unique_id_t id)537 status_t AudioEffect::removeSourceDefaultEffect(audio_unique_id_t id)
538 {
539 const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
540 if (aps == 0) return PERMISSION_DENIED;
541
542 return aps->removeSourceDefaultEffect(id);
543 }
544
removeStreamDefaultEffect(audio_unique_id_t id)545 status_t AudioEffect::removeStreamDefaultEffect(audio_unique_id_t id)
546 {
547 const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
548 if (aps == 0) return PERMISSION_DENIED;
549
550 return aps->removeStreamDefaultEffect(id);
551 }
552
553 // -------------------------------------------------------------------------
554
stringToGuid(const char * str,effect_uuid_t * guid)555 status_t AudioEffect::stringToGuid(const char *str, effect_uuid_t *guid)
556 {
557 if (str == NULL || guid == NULL) {
558 return BAD_VALUE;
559 }
560
561 int tmp[10];
562
563 if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
564 tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5, tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
565 return BAD_VALUE;
566 }
567 guid->timeLow = (uint32_t)tmp[0];
568 guid->timeMid = (uint16_t)tmp[1];
569 guid->timeHiAndVersion = (uint16_t)tmp[2];
570 guid->clockSeq = (uint16_t)tmp[3];
571 guid->node[0] = (uint8_t)tmp[4];
572 guid->node[1] = (uint8_t)tmp[5];
573 guid->node[2] = (uint8_t)tmp[6];
574 guid->node[3] = (uint8_t)tmp[7];
575 guid->node[4] = (uint8_t)tmp[8];
576 guid->node[5] = (uint8_t)tmp[9];
577
578 return NO_ERROR;
579 }
580
guidToString(const effect_uuid_t * guid,char * str,size_t maxLen)581 status_t AudioEffect::guidToString(const effect_uuid_t *guid, char *str, size_t maxLen)
582 {
583 if (guid == NULL || str == NULL) {
584 return BAD_VALUE;
585 }
586
587 snprintf(str, maxLen, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
588 guid->timeLow,
589 guid->timeMid,
590 guid->timeHiAndVersion,
591 guid->clockSeq,
592 guid->node[0],
593 guid->node[1],
594 guid->node[2],
595 guid->node[3],
596 guid->node[4],
597 guid->node[5]);
598
599 return NO_ERROR;
600 }
601
602
603 } // namespace android
604