Effects.cpp revision 726b6a7540ac997928df1a14dfede872a82f6210
1/* 2** 3** Copyright 2012, 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_TAG "AudioFlinger" 20//#define LOG_NDEBUG 0 21 22#include "Configuration.h" 23#include <utils/Log.h> 24#include <audio_effects/effect_visualizer.h> 25#include <audio_utils/primitives.h> 26#include <private/media/AudioEffectShared.h> 27#include <media/EffectsFactoryApi.h> 28 29#include "AudioFlinger.h" 30#include "ServiceUtilities.h" 31 32// ---------------------------------------------------------------------------- 33 34// Note: the following macro is used for extremely verbose logging message. In 35// order to run with ALOG_ASSERT turned on, we need to have LOG_NDEBUG set to 36// 0; but one side effect of this is to turn all LOGV's as well. Some messages 37// are so verbose that we want to suppress them even when we have ALOG_ASSERT 38// turned on. Do not uncomment the #def below unless you really know what you 39// are doing and want to see all of the extremely verbose messages. 40//#define VERY_VERY_VERBOSE_LOGGING 41#ifdef VERY_VERY_VERBOSE_LOGGING 42#define ALOGVV ALOGV 43#else 44#define ALOGVV(a...) do { } while(0) 45#endif 46 47#define min(a, b) ((a) < (b) ? (a) : (b)) 48 49namespace android { 50 51// ---------------------------------------------------------------------------- 52// EffectModule implementation 53// ---------------------------------------------------------------------------- 54 55#undef LOG_TAG 56#define LOG_TAG "AudioFlinger::EffectModule" 57 58AudioFlinger::EffectModule::EffectModule(ThreadBase *thread, 59 const wp<AudioFlinger::EffectChain>& chain, 60 effect_descriptor_t *desc, 61 int id, 62 int sessionId) 63 : mPinned(sessionId > AUDIO_SESSION_OUTPUT_MIX), 64 mThread(thread), mChain(chain), mId(id), mSessionId(sessionId), 65 mDescriptor(*desc), 66 // mConfig is set by configure() and not used before then 67 mEffectInterface(NULL), 68 mStatus(NO_INIT), mState(IDLE), 69 // mMaxDisableWaitCnt is set by configure() and not used before then 70 // mDisableWaitCnt is set by process() and updateState() and not used before then 71 mSuspended(false) 72{ 73 ALOGV("Constructor %p", this); 74 int lStatus; 75 76 // create effect engine from effect factory 77 mStatus = EffectCreate(&desc->uuid, sessionId, thread->id(), &mEffectInterface); 78 79 if (mStatus != NO_ERROR) { 80 return; 81 } 82 lStatus = init(); 83 if (lStatus < 0) { 84 mStatus = lStatus; 85 goto Error; 86 } 87 88 ALOGV("Constructor success name %s, Interface %p", mDescriptor.name, mEffectInterface); 89 return; 90Error: 91 EffectRelease(mEffectInterface); 92 mEffectInterface = NULL; 93 ALOGV("Constructor Error %d", mStatus); 94} 95 96AudioFlinger::EffectModule::~EffectModule() 97{ 98 ALOGV("Destructor %p", this); 99 if (mEffectInterface != NULL) { 100 remove_effect_from_hal_l(); 101 // release effect engine 102 EffectRelease(mEffectInterface); 103 } 104} 105 106status_t AudioFlinger::EffectModule::addHandle(EffectHandle *handle) 107{ 108 status_t status; 109 110 Mutex::Autolock _l(mLock); 111 int priority = handle->priority(); 112 size_t size = mHandles.size(); 113 EffectHandle *controlHandle = NULL; 114 size_t i; 115 for (i = 0; i < size; i++) { 116 EffectHandle *h = mHandles[i]; 117 if (h == NULL || h->destroyed_l()) { 118 continue; 119 } 120 // first non destroyed handle is considered in control 121 if (controlHandle == NULL) { 122 controlHandle = h; 123 } 124 if (h->priority() <= priority) { 125 break; 126 } 127 } 128 // if inserted in first place, move effect control from previous owner to this handle 129 if (i == 0) { 130 bool enabled = false; 131 if (controlHandle != NULL) { 132 enabled = controlHandle->enabled(); 133 controlHandle->setControl(false/*hasControl*/, true /*signal*/, enabled /*enabled*/); 134 } 135 handle->setControl(true /*hasControl*/, false /*signal*/, enabled /*enabled*/); 136 status = NO_ERROR; 137 } else { 138 status = ALREADY_EXISTS; 139 } 140 ALOGV("addHandle() %p added handle %p in position %d", this, handle, i); 141 mHandles.insertAt(handle, i); 142 return status; 143} 144 145size_t AudioFlinger::EffectModule::removeHandle(EffectHandle *handle) 146{ 147 Mutex::Autolock _l(mLock); 148 size_t size = mHandles.size(); 149 size_t i; 150 for (i = 0; i < size; i++) { 151 if (mHandles[i] == handle) { 152 break; 153 } 154 } 155 if (i == size) { 156 return size; 157 } 158 ALOGV("removeHandle() %p removed handle %p in position %d", this, handle, i); 159 160 mHandles.removeAt(i); 161 // if removed from first place, move effect control from this handle to next in line 162 if (i == 0) { 163 EffectHandle *h = controlHandle_l(); 164 if (h != NULL) { 165 h->setControl(true /*hasControl*/, true /*signal*/ , handle->enabled() /*enabled*/); 166 } 167 } 168 169 // Prevent calls to process() and other functions on effect interface from now on. 170 // The effect engine will be released by the destructor when the last strong reference on 171 // this object is released which can happen after next process is called. 172 if (mHandles.size() == 0 && !mPinned) { 173 mState = DESTROYED; 174 } 175 176 return mHandles.size(); 177} 178 179// must be called with EffectModule::mLock held 180AudioFlinger::EffectHandle *AudioFlinger::EffectModule::controlHandle_l() 181{ 182 // the first valid handle in the list has control over the module 183 for (size_t i = 0; i < mHandles.size(); i++) { 184 EffectHandle *h = mHandles[i]; 185 if (h != NULL && !h->destroyed_l()) { 186 return h; 187 } 188 } 189 190 return NULL; 191} 192 193size_t AudioFlinger::EffectModule::disconnect(EffectHandle *handle, bool unpinIfLast) 194{ 195 ALOGV("disconnect() %p handle %p", this, handle); 196 // keep a strong reference on this EffectModule to avoid calling the 197 // destructor before we exit 198 sp<EffectModule> keep(this); 199 { 200 sp<ThreadBase> thread = mThread.promote(); 201 if (thread != 0) { 202 thread->disconnectEffect(keep, handle, unpinIfLast); 203 } 204 } 205 return mHandles.size(); 206} 207 208void AudioFlinger::EffectModule::updateState() { 209 Mutex::Autolock _l(mLock); 210 211 switch (mState) { 212 case RESTART: 213 reset_l(); 214 // FALL THROUGH 215 216 case STARTING: 217 // clear auxiliary effect input buffer for next accumulation 218 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { 219 memset(mConfig.inputCfg.buffer.raw, 220 0, 221 mConfig.inputCfg.buffer.frameCount*sizeof(int32_t)); 222 } 223 if (start_l() == NO_ERROR) { 224 mState = ACTIVE; 225 } else { 226 mState = IDLE; 227 } 228 break; 229 case STOPPING: 230 if (stop_l() == NO_ERROR) { 231 mDisableWaitCnt = mMaxDisableWaitCnt; 232 } else { 233 mDisableWaitCnt = 1; // will cause immediate transition to IDLE 234 } 235 mState = STOPPED; 236 break; 237 case STOPPED: 238 // mDisableWaitCnt is forced to 1 by process() when the engine indicates the end of the 239 // turn off sequence. 240 if (--mDisableWaitCnt == 0) { 241 reset_l(); 242 mState = IDLE; 243 } 244 break; 245 default: //IDLE , ACTIVE, DESTROYED 246 break; 247 } 248} 249 250void AudioFlinger::EffectModule::process() 251{ 252 Mutex::Autolock _l(mLock); 253 254 if (mState == DESTROYED || mEffectInterface == NULL || 255 mConfig.inputCfg.buffer.raw == NULL || 256 mConfig.outputCfg.buffer.raw == NULL) { 257 return; 258 } 259 260 if (isProcessEnabled()) { 261 // do 32 bit to 16 bit conversion for auxiliary effect input buffer 262 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { 263 ditherAndClamp(mConfig.inputCfg.buffer.s32, 264 mConfig.inputCfg.buffer.s32, 265 mConfig.inputCfg.buffer.frameCount/2); 266 } 267 268 // do the actual processing in the effect engine 269 int ret = (*mEffectInterface)->process(mEffectInterface, 270 &mConfig.inputCfg.buffer, 271 &mConfig.outputCfg.buffer); 272 273 // force transition to IDLE state when engine is ready 274 if (mState == STOPPED && ret == -ENODATA) { 275 mDisableWaitCnt = 1; 276 } 277 278 // clear auxiliary effect input buffer for next accumulation 279 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { 280 memset(mConfig.inputCfg.buffer.raw, 0, 281 mConfig.inputCfg.buffer.frameCount*sizeof(int32_t)); 282 } 283 } else if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT && 284 mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) { 285 // If an insert effect is idle and input buffer is different from output buffer, 286 // accumulate input onto output 287 sp<EffectChain> chain = mChain.promote(); 288 if (chain != 0 && chain->activeTrackCnt() != 0) { 289 size_t frameCnt = mConfig.inputCfg.buffer.frameCount * 2; //always stereo here 290 int16_t *in = mConfig.inputCfg.buffer.s16; 291 int16_t *out = mConfig.outputCfg.buffer.s16; 292 for (size_t i = 0; i < frameCnt; i++) { 293 out[i] = clamp16((int32_t)out[i] + (int32_t)in[i]); 294 } 295 } 296 } 297} 298 299void AudioFlinger::EffectModule::reset_l() 300{ 301 if (mStatus != NO_ERROR || mEffectInterface == NULL) { 302 return; 303 } 304 (*mEffectInterface)->command(mEffectInterface, EFFECT_CMD_RESET, 0, NULL, 0, NULL); 305} 306 307status_t AudioFlinger::EffectModule::configure() 308{ 309 status_t status; 310 sp<ThreadBase> thread; 311 uint32_t size; 312 audio_channel_mask_t channelMask; 313 314 if (mEffectInterface == NULL) { 315 status = NO_INIT; 316 goto exit; 317 } 318 319 thread = mThread.promote(); 320 if (thread == 0) { 321 status = DEAD_OBJECT; 322 goto exit; 323 } 324 325 // TODO: handle configuration of effects replacing track process 326 channelMask = thread->channelMask(); 327 328 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { 329 mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO; 330 } else { 331 mConfig.inputCfg.channels = channelMask; 332 } 333 mConfig.outputCfg.channels = channelMask; 334 mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 335 mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; 336 mConfig.inputCfg.samplingRate = thread->sampleRate(); 337 mConfig.outputCfg.samplingRate = mConfig.inputCfg.samplingRate; 338 mConfig.inputCfg.bufferProvider.cookie = NULL; 339 mConfig.inputCfg.bufferProvider.getBuffer = NULL; 340 mConfig.inputCfg.bufferProvider.releaseBuffer = NULL; 341 mConfig.outputCfg.bufferProvider.cookie = NULL; 342 mConfig.outputCfg.bufferProvider.getBuffer = NULL; 343 mConfig.outputCfg.bufferProvider.releaseBuffer = NULL; 344 mConfig.inputCfg.accessMode = EFFECT_BUFFER_ACCESS_READ; 345 // Insert effect: 346 // - in session AUDIO_SESSION_OUTPUT_MIX or AUDIO_SESSION_OUTPUT_STAGE, 347 // always overwrites output buffer: input buffer == output buffer 348 // - in other sessions: 349 // last effect in the chain accumulates in output buffer: input buffer != output buffer 350 // other effect: overwrites output buffer: input buffer == output buffer 351 // Auxiliary effect: 352 // accumulates in output buffer: input buffer != output buffer 353 // Therefore: accumulate <=> input buffer != output buffer 354 if (mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) { 355 mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_ACCUMULATE; 356 } else { 357 mConfig.outputCfg.accessMode = EFFECT_BUFFER_ACCESS_WRITE; 358 } 359 mConfig.inputCfg.mask = EFFECT_CONFIG_ALL; 360 mConfig.outputCfg.mask = EFFECT_CONFIG_ALL; 361 mConfig.inputCfg.buffer.frameCount = thread->frameCount(); 362 mConfig.outputCfg.buffer.frameCount = mConfig.inputCfg.buffer.frameCount; 363 364 ALOGV("configure() %p thread %p buffer %p framecount %d", 365 this, thread.get(), mConfig.inputCfg.buffer.raw, mConfig.inputCfg.buffer.frameCount); 366 367 status_t cmdStatus; 368 size = sizeof(int); 369 status = (*mEffectInterface)->command(mEffectInterface, 370 EFFECT_CMD_SET_CONFIG, 371 sizeof(effect_config_t), 372 &mConfig, 373 &size, 374 &cmdStatus); 375 if (status == 0) { 376 status = cmdStatus; 377 } 378 379 if (status == 0 && 380 (memcmp(&mDescriptor.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0)) { 381 uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2]; 382 effect_param_t *p = (effect_param_t *)buf32; 383 384 p->psize = sizeof(uint32_t); 385 p->vsize = sizeof(uint32_t); 386 size = sizeof(int); 387 *(int32_t *)p->data = VISUALIZER_PARAM_LATENCY; 388 389 uint32_t latency = 0; 390 PlaybackThread *pbt = thread->mAudioFlinger->checkPlaybackThread_l(thread->mId); 391 if (pbt != NULL) { 392 latency = pbt->latency_l(); 393 } 394 395 *((int32_t *)p->data + 1)= latency; 396 (*mEffectInterface)->command(mEffectInterface, 397 EFFECT_CMD_SET_PARAM, 398 sizeof(effect_param_t) + 8, 399 &buf32, 400 &size, 401 &cmdStatus); 402 } 403 404 mMaxDisableWaitCnt = (MAX_DISABLE_TIME_MS * mConfig.outputCfg.samplingRate) / 405 (1000 * mConfig.outputCfg.buffer.frameCount); 406 407exit: 408 mStatus = status; 409 return status; 410} 411 412status_t AudioFlinger::EffectModule::init() 413{ 414 Mutex::Autolock _l(mLock); 415 if (mEffectInterface == NULL) { 416 return NO_INIT; 417 } 418 status_t cmdStatus; 419 uint32_t size = sizeof(status_t); 420 status_t status = (*mEffectInterface)->command(mEffectInterface, 421 EFFECT_CMD_INIT, 422 0, 423 NULL, 424 &size, 425 &cmdStatus); 426 if (status == 0) { 427 status = cmdStatus; 428 } 429 return status; 430} 431 432status_t AudioFlinger::EffectModule::start() 433{ 434 Mutex::Autolock _l(mLock); 435 return start_l(); 436} 437 438status_t AudioFlinger::EffectModule::start_l() 439{ 440 if (mEffectInterface == NULL) { 441 return NO_INIT; 442 } 443 if (mStatus != NO_ERROR) { 444 return mStatus; 445 } 446 status_t cmdStatus; 447 uint32_t size = sizeof(status_t); 448 status_t status = (*mEffectInterface)->command(mEffectInterface, 449 EFFECT_CMD_ENABLE, 450 0, 451 NULL, 452 &size, 453 &cmdStatus); 454 if (status == 0) { 455 status = cmdStatus; 456 } 457 if (status == 0 && 458 ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC || 459 (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC)) { 460 sp<ThreadBase> thread = mThread.promote(); 461 if (thread != 0) { 462 audio_stream_t *stream = thread->stream(); 463 if (stream != NULL) { 464 stream->add_audio_effect(stream, mEffectInterface); 465 } 466 } 467 } 468 return status; 469} 470 471status_t AudioFlinger::EffectModule::stop() 472{ 473 Mutex::Autolock _l(mLock); 474 return stop_l(); 475} 476 477status_t AudioFlinger::EffectModule::stop_l() 478{ 479 if (mEffectInterface == NULL) { 480 return NO_INIT; 481 } 482 if (mStatus != NO_ERROR) { 483 return mStatus; 484 } 485 status_t cmdStatus = NO_ERROR; 486 uint32_t size = sizeof(status_t); 487 status_t status = (*mEffectInterface)->command(mEffectInterface, 488 EFFECT_CMD_DISABLE, 489 0, 490 NULL, 491 &size, 492 &cmdStatus); 493 if (status == NO_ERROR) { 494 status = cmdStatus; 495 } 496 if (status == NO_ERROR) { 497 status = remove_effect_from_hal_l(); 498 } 499 return status; 500} 501 502status_t AudioFlinger::EffectModule::remove_effect_from_hal_l() 503{ 504 if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC || 505 (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) { 506 sp<ThreadBase> thread = mThread.promote(); 507 if (thread != 0) { 508 audio_stream_t *stream = thread->stream(); 509 if (stream != NULL) { 510 stream->remove_audio_effect(stream, mEffectInterface); 511 } 512 } 513 } 514 return NO_ERROR; 515} 516 517status_t AudioFlinger::EffectModule::command(uint32_t cmdCode, 518 uint32_t cmdSize, 519 void *pCmdData, 520 uint32_t *replySize, 521 void *pReplyData) 522{ 523 Mutex::Autolock _l(mLock); 524 ALOGVV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface); 525 526 if (mState == DESTROYED || mEffectInterface == NULL) { 527 return NO_INIT; 528 } 529 if (mStatus != NO_ERROR) { 530 return mStatus; 531 } 532 status_t status = (*mEffectInterface)->command(mEffectInterface, 533 cmdCode, 534 cmdSize, 535 pCmdData, 536 replySize, 537 pReplyData); 538 if (cmdCode != EFFECT_CMD_GET_PARAM && status == NO_ERROR) { 539 uint32_t size = (replySize == NULL) ? 0 : *replySize; 540 for (size_t i = 1; i < mHandles.size(); i++) { 541 EffectHandle *h = mHandles[i]; 542 if (h != NULL && !h->destroyed_l()) { 543 h->commandExecuted(cmdCode, cmdSize, pCmdData, size, pReplyData); 544 } 545 } 546 } 547 return status; 548} 549 550status_t AudioFlinger::EffectModule::setEnabled(bool enabled) 551{ 552 Mutex::Autolock _l(mLock); 553 return setEnabled_l(enabled); 554} 555 556// must be called with EffectModule::mLock held 557status_t AudioFlinger::EffectModule::setEnabled_l(bool enabled) 558{ 559 560 ALOGV("setEnabled %p enabled %d", this, enabled); 561 562 if (enabled != isEnabled()) { 563 status_t status = AudioSystem::setEffectEnabled(mId, enabled); 564 if (enabled && status != NO_ERROR) { 565 return status; 566 } 567 568 switch (mState) { 569 // going from disabled to enabled 570 case IDLE: 571 mState = STARTING; 572 break; 573 case STOPPED: 574 mState = RESTART; 575 break; 576 case STOPPING: 577 mState = ACTIVE; 578 break; 579 580 // going from enabled to disabled 581 case RESTART: 582 mState = STOPPED; 583 break; 584 case STARTING: 585 mState = IDLE; 586 break; 587 case ACTIVE: 588 mState = STOPPING; 589 break; 590 case DESTROYED: 591 return NO_ERROR; // simply ignore as we are being destroyed 592 } 593 for (size_t i = 1; i < mHandles.size(); i++) { 594 EffectHandle *h = mHandles[i]; 595 if (h != NULL && !h->destroyed_l()) { 596 h->setEnabled(enabled); 597 } 598 } 599 } 600 return NO_ERROR; 601} 602 603bool AudioFlinger::EffectModule::isEnabled() const 604{ 605 switch (mState) { 606 case RESTART: 607 case STARTING: 608 case ACTIVE: 609 return true; 610 case IDLE: 611 case STOPPING: 612 case STOPPED: 613 case DESTROYED: 614 default: 615 return false; 616 } 617} 618 619bool AudioFlinger::EffectModule::isProcessEnabled() const 620{ 621 if (mStatus != NO_ERROR) { 622 return false; 623 } 624 625 switch (mState) { 626 case RESTART: 627 case ACTIVE: 628 case STOPPING: 629 case STOPPED: 630 return true; 631 case IDLE: 632 case STARTING: 633 case DESTROYED: 634 default: 635 return false; 636 } 637} 638 639status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, bool controller) 640{ 641 Mutex::Autolock _l(mLock); 642 if (mStatus != NO_ERROR) { 643 return mStatus; 644 } 645 status_t status = NO_ERROR; 646 // Send volume indication if EFFECT_FLAG_VOLUME_IND is set and read back altered volume 647 // if controller flag is set (Note that controller == TRUE => EFFECT_FLAG_VOLUME_CTRL set) 648 if (isProcessEnabled() && 649 ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL || 650 (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND)) { 651 status_t cmdStatus; 652 uint32_t volume[2]; 653 uint32_t *pVolume = NULL; 654 uint32_t size = sizeof(volume); 655 volume[0] = *left; 656 volume[1] = *right; 657 if (controller) { 658 pVolume = volume; 659 } 660 status = (*mEffectInterface)->command(mEffectInterface, 661 EFFECT_CMD_SET_VOLUME, 662 size, 663 volume, 664 &size, 665 pVolume); 666 if (controller && status == NO_ERROR && size == sizeof(volume)) { 667 *left = volume[0]; 668 *right = volume[1]; 669 } 670 } 671 return status; 672} 673 674status_t AudioFlinger::EffectModule::setDevice(audio_devices_t device) 675{ 676 if (device == AUDIO_DEVICE_NONE) { 677 return NO_ERROR; 678 } 679 680 Mutex::Autolock _l(mLock); 681 if (mStatus != NO_ERROR) { 682 return mStatus; 683 } 684 status_t status = NO_ERROR; 685 if ((mDescriptor.flags & EFFECT_FLAG_DEVICE_MASK) == EFFECT_FLAG_DEVICE_IND) { 686 status_t cmdStatus; 687 uint32_t size = sizeof(status_t); 688 uint32_t cmd = audio_is_output_devices(device) ? EFFECT_CMD_SET_DEVICE : 689 EFFECT_CMD_SET_INPUT_DEVICE; 690 status = (*mEffectInterface)->command(mEffectInterface, 691 cmd, 692 sizeof(uint32_t), 693 &device, 694 &size, 695 &cmdStatus); 696 } 697 return status; 698} 699 700status_t AudioFlinger::EffectModule::setMode(audio_mode_t mode) 701{ 702 Mutex::Autolock _l(mLock); 703 if (mStatus != NO_ERROR) { 704 return mStatus; 705 } 706 status_t status = NO_ERROR; 707 if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_MODE_MASK) == EFFECT_FLAG_AUDIO_MODE_IND) { 708 status_t cmdStatus; 709 uint32_t size = sizeof(status_t); 710 status = (*mEffectInterface)->command(mEffectInterface, 711 EFFECT_CMD_SET_AUDIO_MODE, 712 sizeof(audio_mode_t), 713 &mode, 714 &size, 715 &cmdStatus); 716 if (status == NO_ERROR) { 717 status = cmdStatus; 718 } 719 } 720 return status; 721} 722 723status_t AudioFlinger::EffectModule::setAudioSource(audio_source_t source) 724{ 725 Mutex::Autolock _l(mLock); 726 if (mStatus != NO_ERROR) { 727 return mStatus; 728 } 729 status_t status = NO_ERROR; 730 if ((mDescriptor.flags & EFFECT_FLAG_AUDIO_SOURCE_MASK) == EFFECT_FLAG_AUDIO_SOURCE_IND) { 731 uint32_t size = 0; 732 status = (*mEffectInterface)->command(mEffectInterface, 733 EFFECT_CMD_SET_AUDIO_SOURCE, 734 sizeof(audio_source_t), 735 &source, 736 &size, 737 NULL); 738 } 739 return status; 740} 741 742void AudioFlinger::EffectModule::setSuspended(bool suspended) 743{ 744 Mutex::Autolock _l(mLock); 745 mSuspended = suspended; 746} 747 748bool AudioFlinger::EffectModule::suspended() const 749{ 750 Mutex::Autolock _l(mLock); 751 return mSuspended; 752} 753 754bool AudioFlinger::EffectModule::purgeHandles() 755{ 756 bool enabled = false; 757 Mutex::Autolock _l(mLock); 758 for (size_t i = 0; i < mHandles.size(); i++) { 759 EffectHandle *handle = mHandles[i]; 760 if (handle != NULL && !handle->destroyed_l()) { 761 handle->effect().clear(); 762 if (handle->hasControl()) { 763 enabled = handle->enabled(); 764 } 765 } 766 } 767 return enabled; 768} 769 770status_t AudioFlinger::EffectModule::setOffloaded(bool offloaded, audio_io_handle_t io) 771{ 772 Mutex::Autolock _l(mLock); 773 if (mStatus != NO_ERROR) { 774 return mStatus; 775 } 776 status_t status = NO_ERROR; 777 if ((mDescriptor.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) != 0) { 778 status_t cmdStatus; 779 uint32_t size = sizeof(status_t); 780 effect_offload_param_t cmd; 781 782 cmd.isOffload = offloaded; 783 cmd.ioHandle = io; 784 status = (*mEffectInterface)->command(mEffectInterface, 785 EFFECT_CMD_OFFLOAD, 786 sizeof(effect_offload_param_t), 787 &cmd, 788 &size, 789 &cmdStatus); 790 if (status == NO_ERROR) { 791 status = cmdStatus; 792 } 793 mOffloaded = (status == NO_ERROR) ? offloaded : false; 794 } else { 795 if (offloaded) { 796 status = INVALID_OPERATION; 797 } 798 mOffloaded = false; 799 } 800 ALOGV("setOffloaded() offloaded %d io %d status %d", offloaded, io, status); 801 return status; 802} 803 804bool AudioFlinger::EffectModule::isOffloaded() const 805{ 806 Mutex::Autolock _l(mLock); 807 return mOffloaded; 808} 809 810String8 effectFlagsToString(uint32_t flags) { 811 String8 s; 812 813 s.append("conn. mode: "); 814 switch (flags & EFFECT_FLAG_TYPE_MASK) { 815 case EFFECT_FLAG_TYPE_INSERT: s.append("insert"); break; 816 case EFFECT_FLAG_TYPE_AUXILIARY: s.append("auxiliary"); break; 817 case EFFECT_FLAG_TYPE_REPLACE: s.append("replace"); break; 818 case EFFECT_FLAG_TYPE_PRE_PROC: s.append("preproc"); break; 819 case EFFECT_FLAG_TYPE_POST_PROC: s.append("postproc"); break; 820 default: s.append("unknown/reserved"); break; 821 } 822 s.append(", "); 823 824 s.append("insert pref: "); 825 switch (flags & EFFECT_FLAG_INSERT_MASK) { 826 case EFFECT_FLAG_INSERT_ANY: s.append("any"); break; 827 case EFFECT_FLAG_INSERT_FIRST: s.append("first"); break; 828 case EFFECT_FLAG_INSERT_LAST: s.append("last"); break; 829 case EFFECT_FLAG_INSERT_EXCLUSIVE: s.append("exclusive"); break; 830 default: s.append("unknown/reserved"); break; 831 } 832 s.append(", "); 833 834 s.append("volume mgmt: "); 835 switch (flags & EFFECT_FLAG_VOLUME_MASK) { 836 case EFFECT_FLAG_VOLUME_NONE: s.append("none"); break; 837 case EFFECT_FLAG_VOLUME_CTRL: s.append("implements control"); break; 838 case EFFECT_FLAG_VOLUME_IND: s.append("requires indication"); break; 839 default: s.append("unknown/reserved"); break; 840 } 841 s.append(", "); 842 843 uint32_t devind = flags & EFFECT_FLAG_DEVICE_MASK; 844 if (devind) { 845 s.append("device indication: "); 846 switch (devind) { 847 case EFFECT_FLAG_DEVICE_IND: s.append("requires updates"); break; 848 default: s.append("unknown/reserved"); break; 849 } 850 s.append(", "); 851 } 852 853 s.append("input mode: "); 854 switch (flags & EFFECT_FLAG_INPUT_MASK) { 855 case EFFECT_FLAG_INPUT_DIRECT: s.append("direct"); break; 856 case EFFECT_FLAG_INPUT_PROVIDER: s.append("provider"); break; 857 case EFFECT_FLAG_INPUT_BOTH: s.append("direct+provider"); break; 858 default: s.append("not set"); break; 859 } 860 s.append(", "); 861 862 s.append("output mode: "); 863 switch (flags & EFFECT_FLAG_OUTPUT_MASK) { 864 case EFFECT_FLAG_OUTPUT_DIRECT: s.append("direct"); break; 865 case EFFECT_FLAG_OUTPUT_PROVIDER: s.append("provider"); break; 866 case EFFECT_FLAG_OUTPUT_BOTH: s.append("direct+provider"); break; 867 default: s.append("not set"); break; 868 } 869 s.append(", "); 870 871 uint32_t accel = flags & EFFECT_FLAG_HW_ACC_MASK; 872 if (accel) { 873 s.append("hardware acceleration: "); 874 switch (accel) { 875 case EFFECT_FLAG_HW_ACC_SIMPLE: s.append("non-tunneled"); break; 876 case EFFECT_FLAG_HW_ACC_TUNNEL: s.append("tunneled"); break; 877 default: s.append("unknown/reserved"); break; 878 } 879 s.append(", "); 880 } 881 882 uint32_t modeind = flags & EFFECT_FLAG_AUDIO_MODE_MASK; 883 if (modeind) { 884 s.append("mode indication: "); 885 switch (modeind) { 886 case EFFECT_FLAG_AUDIO_MODE_IND: s.append("required"); break; 887 default: s.append("unknown/reserved"); break; 888 } 889 s.append(", "); 890 } 891 892 uint32_t srcind = flags & EFFECT_FLAG_AUDIO_SOURCE_MASK; 893 if (srcind) { 894 s.append("source indication: "); 895 switch (srcind) { 896 case EFFECT_FLAG_AUDIO_SOURCE_IND: s.append("required"); break; 897 default: s.append("unknown/reserved"); break; 898 } 899 s.append(", "); 900 } 901 902 if (flags & EFFECT_FLAG_OFFLOAD_MASK) { 903 s.append("offloadable, "); 904 } 905 906 int len = s.length(); 907 if (s.length() > 2) { 908 char *str = s.lockBuffer(len); 909 s.unlockBuffer(len - 2); 910 } 911 return s; 912} 913 914 915void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args __unused) 916{ 917 const size_t SIZE = 256; 918 char buffer[SIZE]; 919 String8 result; 920 921 snprintf(buffer, SIZE, "\tEffect ID %d:\n", mId); 922 result.append(buffer); 923 924 bool locked = AudioFlinger::dumpTryLock(mLock); 925 // failed to lock - AudioFlinger is probably deadlocked 926 if (!locked) { 927 result.append("\t\tCould not lock Fx mutex:\n"); 928 } 929 930 result.append("\t\tSession Status State Engine:\n"); 931 snprintf(buffer, SIZE, "\t\t%05d %03d %03d %p\n", 932 mSessionId, mStatus, mState, mEffectInterface); 933 result.append(buffer); 934 935 result.append("\t\tDescriptor:\n"); 936 snprintf(buffer, SIZE, "\t\t- UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n", 937 mDescriptor.uuid.timeLow, mDescriptor.uuid.timeMid, mDescriptor.uuid.timeHiAndVersion, 938 mDescriptor.uuid.clockSeq, mDescriptor.uuid.node[0], mDescriptor.uuid.node[1], 939 mDescriptor.uuid.node[2], 940 mDescriptor.uuid.node[3],mDescriptor.uuid.node[4],mDescriptor.uuid.node[5]); 941 result.append(buffer); 942 snprintf(buffer, SIZE, "\t\t- TYPE: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X\n", 943 mDescriptor.type.timeLow, mDescriptor.type.timeMid, 944 mDescriptor.type.timeHiAndVersion, 945 mDescriptor.type.clockSeq, mDescriptor.type.node[0], mDescriptor.type.node[1], 946 mDescriptor.type.node[2], 947 mDescriptor.type.node[3],mDescriptor.type.node[4],mDescriptor.type.node[5]); 948 result.append(buffer); 949 snprintf(buffer, SIZE, "\t\t- apiVersion: %08X\n\t\t- flags: %08X (%s)\n", 950 mDescriptor.apiVersion, 951 mDescriptor.flags, 952 effectFlagsToString(mDescriptor.flags).string()); 953 result.append(buffer); 954 snprintf(buffer, SIZE, "\t\t- name: %s\n", 955 mDescriptor.name); 956 result.append(buffer); 957 snprintf(buffer, SIZE, "\t\t- implementor: %s\n", 958 mDescriptor.implementor); 959 result.append(buffer); 960 961 result.append("\t\t- Input configuration:\n"); 962 result.append("\t\t\tFrames Smp rate Channels Format Buffer\n"); 963 snprintf(buffer, SIZE, "\t\t\t%05zu %05d %08x %6d (%s) %p\n", 964 mConfig.inputCfg.buffer.frameCount, 965 mConfig.inputCfg.samplingRate, 966 mConfig.inputCfg.channels, 967 mConfig.inputCfg.format, 968 formatToString((audio_format_t)mConfig.inputCfg.format), 969 mConfig.inputCfg.buffer.raw); 970 result.append(buffer); 971 972 result.append("\t\t- Output configuration:\n"); 973 result.append("\t\t\tBuffer Frames Smp rate Channels Format\n"); 974 snprintf(buffer, SIZE, "\t\t\t%p %05zu %05d %08x %d (%s)\n", 975 mConfig.outputCfg.buffer.raw, 976 mConfig.outputCfg.buffer.frameCount, 977 mConfig.outputCfg.samplingRate, 978 mConfig.outputCfg.channels, 979 mConfig.outputCfg.format, 980 formatToString((audio_format_t)mConfig.outputCfg.format)); 981 result.append(buffer); 982 983 snprintf(buffer, SIZE, "\t\t%zu Clients:\n", mHandles.size()); 984 result.append(buffer); 985 result.append("\t\t\t Pid Priority Ctrl Locked client server\n"); 986 for (size_t i = 0; i < mHandles.size(); ++i) { 987 EffectHandle *handle = mHandles[i]; 988 if (handle != NULL && !handle->destroyed_l()) { 989 handle->dumpToBuffer(buffer, SIZE); 990 result.append(buffer); 991 } 992 } 993 994 write(fd, result.string(), result.length()); 995 996 if (locked) { 997 mLock.unlock(); 998 } 999} 1000 1001// ---------------------------------------------------------------------------- 1002// EffectHandle implementation 1003// ---------------------------------------------------------------------------- 1004 1005#undef LOG_TAG 1006#define LOG_TAG "AudioFlinger::EffectHandle" 1007 1008AudioFlinger::EffectHandle::EffectHandle(const sp<EffectModule>& effect, 1009 const sp<AudioFlinger::Client>& client, 1010 const sp<IEffectClient>& effectClient, 1011 int32_t priority) 1012 : BnEffect(), 1013 mEffect(effect), mEffectClient(effectClient), mClient(client), mCblk(NULL), 1014 mPriority(priority), mHasControl(false), mEnabled(false), mDestroyed(false) 1015{ 1016 ALOGV("constructor %p", this); 1017 1018 if (client == 0) { 1019 return; 1020 } 1021 int bufOffset = ((sizeof(effect_param_cblk_t) - 1) / sizeof(int) + 1) * sizeof(int); 1022 mCblkMemory = client->heap()->allocate(EFFECT_PARAM_BUFFER_SIZE + bufOffset); 1023 if (mCblkMemory == 0 || 1024 (mCblk = static_cast<effect_param_cblk_t *>(mCblkMemory->pointer())) == NULL) { 1025 ALOGE("not enough memory for Effect size=%u", EFFECT_PARAM_BUFFER_SIZE + 1026 sizeof(effect_param_cblk_t)); 1027 mCblkMemory.clear(); 1028 return; 1029 } 1030 new(mCblk) effect_param_cblk_t(); 1031 mBuffer = (uint8_t *)mCblk + bufOffset; 1032} 1033 1034AudioFlinger::EffectHandle::~EffectHandle() 1035{ 1036 ALOGV("Destructor %p", this); 1037 1038 if (mEffect == 0) { 1039 mDestroyed = true; 1040 return; 1041 } 1042 mEffect->lock(); 1043 mDestroyed = true; 1044 mEffect->unlock(); 1045 disconnect(false); 1046} 1047 1048status_t AudioFlinger::EffectHandle::initCheck() 1049{ 1050 return mClient == 0 || mCblkMemory != 0 ? OK : NO_MEMORY; 1051} 1052 1053status_t AudioFlinger::EffectHandle::enable() 1054{ 1055 ALOGV("enable %p", this); 1056 if (!mHasControl) { 1057 return INVALID_OPERATION; 1058 } 1059 if (mEffect == 0) { 1060 return DEAD_OBJECT; 1061 } 1062 1063 if (mEnabled) { 1064 return NO_ERROR; 1065 } 1066 1067 mEnabled = true; 1068 1069 sp<ThreadBase> thread = mEffect->thread().promote(); 1070 if (thread != 0) { 1071 thread->checkSuspendOnEffectEnabled(mEffect, true, mEffect->sessionId()); 1072 } 1073 1074 // checkSuspendOnEffectEnabled() can suspend this same effect when enabled 1075 if (mEffect->suspended()) { 1076 return NO_ERROR; 1077 } 1078 1079 status_t status = mEffect->setEnabled(true); 1080 if (status != NO_ERROR) { 1081 if (thread != 0) { 1082 thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId()); 1083 } 1084 mEnabled = false; 1085 } else { 1086 if (thread != 0) { 1087 if (thread->type() == ThreadBase::OFFLOAD) { 1088 PlaybackThread *t = (PlaybackThread *)thread.get(); 1089 Mutex::Autolock _l(t->mLock); 1090 t->broadcast_l(); 1091 } 1092 if (!mEffect->isOffloadable()) { 1093 if (thread->type() == ThreadBase::OFFLOAD) { 1094 PlaybackThread *t = (PlaybackThread *)thread.get(); 1095 t->invalidateTracks(AUDIO_STREAM_MUSIC); 1096 } 1097 if (mEffect->sessionId() == AUDIO_SESSION_OUTPUT_MIX) { 1098 thread->mAudioFlinger->onNonOffloadableGlobalEffectEnable(); 1099 } 1100 } 1101 } 1102 } 1103 return status; 1104} 1105 1106status_t AudioFlinger::EffectHandle::disable() 1107{ 1108 ALOGV("disable %p", this); 1109 if (!mHasControl) { 1110 return INVALID_OPERATION; 1111 } 1112 if (mEffect == 0) { 1113 return DEAD_OBJECT; 1114 } 1115 1116 if (!mEnabled) { 1117 return NO_ERROR; 1118 } 1119 mEnabled = false; 1120 1121 if (mEffect->suspended()) { 1122 return NO_ERROR; 1123 } 1124 1125 status_t status = mEffect->setEnabled(false); 1126 1127 sp<ThreadBase> thread = mEffect->thread().promote(); 1128 if (thread != 0) { 1129 thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId()); 1130 if (thread->type() == ThreadBase::OFFLOAD) { 1131 PlaybackThread *t = (PlaybackThread *)thread.get(); 1132 Mutex::Autolock _l(t->mLock); 1133 t->broadcast_l(); 1134 } 1135 } 1136 1137 return status; 1138} 1139 1140void AudioFlinger::EffectHandle::disconnect() 1141{ 1142 disconnect(true); 1143} 1144 1145void AudioFlinger::EffectHandle::disconnect(bool unpinIfLast) 1146{ 1147 ALOGV("disconnect(%s)", unpinIfLast ? "true" : "false"); 1148 if (mEffect == 0) { 1149 return; 1150 } 1151 // restore suspended effects if the disconnected handle was enabled and the last one. 1152 if ((mEffect->disconnect(this, unpinIfLast) == 0) && mEnabled) { 1153 sp<ThreadBase> thread = mEffect->thread().promote(); 1154 if (thread != 0) { 1155 thread->checkSuspendOnEffectEnabled(mEffect, false, mEffect->sessionId()); 1156 } 1157 } 1158 1159 // release sp on module => module destructor can be called now 1160 mEffect.clear(); 1161 if (mClient != 0) { 1162 if (mCblk != NULL) { 1163 // unlike ~TrackBase(), mCblk is never a local new, so don't delete 1164 mCblk->~effect_param_cblk_t(); // destroy our shared-structure. 1165 } 1166 mCblkMemory.clear(); // free the shared memory before releasing the heap it belongs to 1167 // Client destructor must run with AudioFlinger client mutex locked 1168 Mutex::Autolock _l(mClient->audioFlinger()->mClientLock); 1169 mClient.clear(); 1170 } 1171} 1172 1173status_t AudioFlinger::EffectHandle::command(uint32_t cmdCode, 1174 uint32_t cmdSize, 1175 void *pCmdData, 1176 uint32_t *replySize, 1177 void *pReplyData) 1178{ 1179 ALOGVV("command(), cmdCode: %d, mHasControl: %d, mEffect: %p", 1180 cmdCode, mHasControl, (mEffect == 0) ? 0 : mEffect.get()); 1181 1182 // only get parameter command is permitted for applications not controlling the effect 1183 if (!mHasControl && cmdCode != EFFECT_CMD_GET_PARAM) { 1184 return INVALID_OPERATION; 1185 } 1186 if (mEffect == 0) { 1187 return DEAD_OBJECT; 1188 } 1189 if (mClient == 0) { 1190 return INVALID_OPERATION; 1191 } 1192 1193 // handle commands that are not forwarded transparently to effect engine 1194 if (cmdCode == EFFECT_CMD_SET_PARAM_COMMIT) { 1195 // No need to trylock() here as this function is executed in the binder thread serving a 1196 // particular client process: no risk to block the whole media server process or mixer 1197 // threads if we are stuck here 1198 Mutex::Autolock _l(mCblk->lock); 1199 if (mCblk->clientIndex > EFFECT_PARAM_BUFFER_SIZE || 1200 mCblk->serverIndex > EFFECT_PARAM_BUFFER_SIZE) { 1201 mCblk->serverIndex = 0; 1202 mCblk->clientIndex = 0; 1203 return BAD_VALUE; 1204 } 1205 status_t status = NO_ERROR; 1206 while (mCblk->serverIndex < mCblk->clientIndex) { 1207 int reply; 1208 uint32_t rsize = sizeof(int); 1209 int *p = (int *)(mBuffer + mCblk->serverIndex); 1210 int size = *p++; 1211 if (((uint8_t *)p + size) > mBuffer + mCblk->clientIndex) { 1212 ALOGW("command(): invalid parameter block size"); 1213 break; 1214 } 1215 effect_param_t *param = (effect_param_t *)p; 1216 if (param->psize == 0 || param->vsize == 0) { 1217 ALOGW("command(): null parameter or value size"); 1218 mCblk->serverIndex += size; 1219 continue; 1220 } 1221 uint32_t psize = sizeof(effect_param_t) + 1222 ((param->psize - 1) / sizeof(int) + 1) * sizeof(int) + 1223 param->vsize; 1224 status_t ret = mEffect->command(EFFECT_CMD_SET_PARAM, 1225 psize, 1226 p, 1227 &rsize, 1228 &reply); 1229 // stop at first error encountered 1230 if (ret != NO_ERROR) { 1231 status = ret; 1232 *(int *)pReplyData = reply; 1233 break; 1234 } else if (reply != NO_ERROR) { 1235 *(int *)pReplyData = reply; 1236 break; 1237 } 1238 mCblk->serverIndex += size; 1239 } 1240 mCblk->serverIndex = 0; 1241 mCblk->clientIndex = 0; 1242 return status; 1243 } else if (cmdCode == EFFECT_CMD_ENABLE) { 1244 *(int *)pReplyData = NO_ERROR; 1245 return enable(); 1246 } else if (cmdCode == EFFECT_CMD_DISABLE) { 1247 *(int *)pReplyData = NO_ERROR; 1248 return disable(); 1249 } 1250 1251 return mEffect->command(cmdCode, cmdSize, pCmdData, replySize, pReplyData); 1252} 1253 1254void AudioFlinger::EffectHandle::setControl(bool hasControl, bool signal, bool enabled) 1255{ 1256 ALOGV("setControl %p control %d", this, hasControl); 1257 1258 mHasControl = hasControl; 1259 mEnabled = enabled; 1260 1261 if (signal && mEffectClient != 0) { 1262 mEffectClient->controlStatusChanged(hasControl); 1263 } 1264} 1265 1266void AudioFlinger::EffectHandle::commandExecuted(uint32_t cmdCode, 1267 uint32_t cmdSize, 1268 void *pCmdData, 1269 uint32_t replySize, 1270 void *pReplyData) 1271{ 1272 if (mEffectClient != 0) { 1273 mEffectClient->commandExecuted(cmdCode, cmdSize, pCmdData, replySize, pReplyData); 1274 } 1275} 1276 1277 1278 1279void AudioFlinger::EffectHandle::setEnabled(bool enabled) 1280{ 1281 if (mEffectClient != 0) { 1282 mEffectClient->enableStatusChanged(enabled); 1283 } 1284} 1285 1286status_t AudioFlinger::EffectHandle::onTransact( 1287 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1288{ 1289 return BnEffect::onTransact(code, data, reply, flags); 1290} 1291 1292 1293void AudioFlinger::EffectHandle::dumpToBuffer(char* buffer, size_t size) 1294{ 1295 bool locked = mCblk != NULL && AudioFlinger::dumpTryLock(mCblk->lock); 1296 1297 snprintf(buffer, size, "\t\t\t%5d %5d %3s %3s %5u %5u\n", 1298 (mClient == 0) ? getpid_cached : mClient->pid(), 1299 mPriority, 1300 mHasControl ? "yes" : "no", 1301 locked ? "yes" : "no", 1302 mCblk ? mCblk->clientIndex : 0, 1303 mCblk ? mCblk->serverIndex : 0 1304 ); 1305 1306 if (locked) { 1307 mCblk->lock.unlock(); 1308 } 1309} 1310 1311#undef LOG_TAG 1312#define LOG_TAG "AudioFlinger::EffectChain" 1313 1314AudioFlinger::EffectChain::EffectChain(ThreadBase *thread, 1315 int sessionId) 1316 : mThread(thread), mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0), 1317 mOwnInBuffer(false), mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX), 1318 mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX) 1319{ 1320 mStrategy = AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC); 1321 if (thread == NULL) { 1322 return; 1323 } 1324 mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) / 1325 thread->frameCount(); 1326} 1327 1328AudioFlinger::EffectChain::~EffectChain() 1329{ 1330 if (mOwnInBuffer) { 1331 delete mInBuffer; 1332 } 1333 1334} 1335 1336// getEffectFromDesc_l() must be called with ThreadBase::mLock held 1337sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromDesc_l( 1338 effect_descriptor_t *descriptor) 1339{ 1340 size_t size = mEffects.size(); 1341 1342 for (size_t i = 0; i < size; i++) { 1343 if (memcmp(&mEffects[i]->desc().uuid, &descriptor->uuid, sizeof(effect_uuid_t)) == 0) { 1344 return mEffects[i]; 1345 } 1346 } 1347 return 0; 1348} 1349 1350// getEffectFromId_l() must be called with ThreadBase::mLock held 1351sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int id) 1352{ 1353 size_t size = mEffects.size(); 1354 1355 for (size_t i = 0; i < size; i++) { 1356 // by convention, return first effect if id provided is 0 (0 is never a valid id) 1357 if (id == 0 || mEffects[i]->id() == id) { 1358 return mEffects[i]; 1359 } 1360 } 1361 return 0; 1362} 1363 1364// getEffectFromType_l() must be called with ThreadBase::mLock held 1365sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l( 1366 const effect_uuid_t *type) 1367{ 1368 size_t size = mEffects.size(); 1369 1370 for (size_t i = 0; i < size; i++) { 1371 if (memcmp(&mEffects[i]->desc().type, type, sizeof(effect_uuid_t)) == 0) { 1372 return mEffects[i]; 1373 } 1374 } 1375 return 0; 1376} 1377 1378void AudioFlinger::EffectChain::clearInputBuffer() 1379{ 1380 Mutex::Autolock _l(mLock); 1381 sp<ThreadBase> thread = mThread.promote(); 1382 if (thread == 0) { 1383 ALOGW("clearInputBuffer(): cannot promote mixer thread"); 1384 return; 1385 } 1386 clearInputBuffer_l(thread); 1387} 1388 1389// Must be called with EffectChain::mLock locked 1390void AudioFlinger::EffectChain::clearInputBuffer_l(sp<ThreadBase> thread) 1391{ 1392 // TODO: This will change in the future, depending on multichannel 1393 // and sample format changes for effects. 1394 // Currently effects processing is only available for stereo, AUDIO_FORMAT_PCM_16_BIT 1395 // (4 bytes frame size) 1396 const size_t frameSize = 1397 audio_bytes_per_sample(AUDIO_FORMAT_PCM_16_BIT) * min(FCC_2, thread->channelCount()); 1398 memset(mInBuffer, 0, thread->frameCount() * frameSize); 1399} 1400 1401// Must be called with EffectChain::mLock locked 1402void AudioFlinger::EffectChain::process_l() 1403{ 1404 sp<ThreadBase> thread = mThread.promote(); 1405 if (thread == 0) { 1406 ALOGW("process_l(): cannot promote mixer thread"); 1407 return; 1408 } 1409 bool isGlobalSession = (mSessionId == AUDIO_SESSION_OUTPUT_MIX) || 1410 (mSessionId == AUDIO_SESSION_OUTPUT_STAGE); 1411 // never process effects when: 1412 // - on an OFFLOAD thread 1413 // - no more tracks are on the session and the effect tail has been rendered 1414 bool doProcess = (thread->type() != ThreadBase::OFFLOAD); 1415 if (!isGlobalSession) { 1416 bool tracksOnSession = (trackCnt() != 0); 1417 1418 if (!tracksOnSession && mTailBufferCount == 0) { 1419 doProcess = false; 1420 } 1421 1422 if (activeTrackCnt() == 0) { 1423 // if no track is active and the effect tail has not been rendered, 1424 // the input buffer must be cleared here as the mixer process will not do it 1425 if (tracksOnSession || mTailBufferCount > 0) { 1426 clearInputBuffer_l(thread); 1427 if (mTailBufferCount > 0) { 1428 mTailBufferCount--; 1429 } 1430 } 1431 } 1432 } 1433 1434 size_t size = mEffects.size(); 1435 if (doProcess) { 1436 for (size_t i = 0; i < size; i++) { 1437 mEffects[i]->process(); 1438 } 1439 } 1440 for (size_t i = 0; i < size; i++) { 1441 mEffects[i]->updateState(); 1442 } 1443} 1444 1445// addEffect_l() must be called with PlaybackThread::mLock held 1446status_t AudioFlinger::EffectChain::addEffect_l(const sp<EffectModule>& effect) 1447{ 1448 effect_descriptor_t desc = effect->desc(); 1449 uint32_t insertPref = desc.flags & EFFECT_FLAG_INSERT_MASK; 1450 1451 Mutex::Autolock _l(mLock); 1452 effect->setChain(this); 1453 sp<ThreadBase> thread = mThread.promote(); 1454 if (thread == 0) { 1455 return NO_INIT; 1456 } 1457 effect->setThread(thread); 1458 1459 if ((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { 1460 // Auxiliary effects are inserted at the beginning of mEffects vector as 1461 // they are processed first and accumulated in chain input buffer 1462 mEffects.insertAt(effect, 0); 1463 1464 // the input buffer for auxiliary effect contains mono samples in 1465 // 32 bit format. This is to avoid saturation in AudoMixer 1466 // accumulation stage. Saturation is done in EffectModule::process() before 1467 // calling the process in effect engine 1468 size_t numSamples = thread->frameCount(); 1469 int32_t *buffer = new int32_t[numSamples]; 1470 memset(buffer, 0, numSamples * sizeof(int32_t)); 1471 effect->setInBuffer((int16_t *)buffer); 1472 // auxiliary effects output samples to chain input buffer for further processing 1473 // by insert effects 1474 effect->setOutBuffer(mInBuffer); 1475 } else { 1476 // Insert effects are inserted at the end of mEffects vector as they are processed 1477 // after track and auxiliary effects. 1478 // Insert effect order as a function of indicated preference: 1479 // if EFFECT_FLAG_INSERT_EXCLUSIVE, insert in first position or reject if 1480 // another effect is present 1481 // else if EFFECT_FLAG_INSERT_FIRST, insert in first position or after the 1482 // last effect claiming first position 1483 // else if EFFECT_FLAG_INSERT_LAST, insert in last position or before the 1484 // first effect claiming last position 1485 // else if EFFECT_FLAG_INSERT_ANY insert after first or before last 1486 // Reject insertion if an effect with EFFECT_FLAG_INSERT_EXCLUSIVE is 1487 // already present 1488 1489 size_t size = mEffects.size(); 1490 size_t idx_insert = size; 1491 ssize_t idx_insert_first = -1; 1492 ssize_t idx_insert_last = -1; 1493 1494 for (size_t i = 0; i < size; i++) { 1495 effect_descriptor_t d = mEffects[i]->desc(); 1496 uint32_t iMode = d.flags & EFFECT_FLAG_TYPE_MASK; 1497 uint32_t iPref = d.flags & EFFECT_FLAG_INSERT_MASK; 1498 if (iMode == EFFECT_FLAG_TYPE_INSERT) { 1499 // check invalid effect chaining combinations 1500 if (insertPref == EFFECT_FLAG_INSERT_EXCLUSIVE || 1501 iPref == EFFECT_FLAG_INSERT_EXCLUSIVE) { 1502 ALOGW("addEffect_l() could not insert effect %s: exclusive conflict with %s", 1503 desc.name, d.name); 1504 return INVALID_OPERATION; 1505 } 1506 // remember position of first insert effect and by default 1507 // select this as insert position for new effect 1508 if (idx_insert == size) { 1509 idx_insert = i; 1510 } 1511 // remember position of last insert effect claiming 1512 // first position 1513 if (iPref == EFFECT_FLAG_INSERT_FIRST) { 1514 idx_insert_first = i; 1515 } 1516 // remember position of first insert effect claiming 1517 // last position 1518 if (iPref == EFFECT_FLAG_INSERT_LAST && 1519 idx_insert_last == -1) { 1520 idx_insert_last = i; 1521 } 1522 } 1523 } 1524 1525 // modify idx_insert from first position if needed 1526 if (insertPref == EFFECT_FLAG_INSERT_LAST) { 1527 if (idx_insert_last != -1) { 1528 idx_insert = idx_insert_last; 1529 } else { 1530 idx_insert = size; 1531 } 1532 } else { 1533 if (idx_insert_first != -1) { 1534 idx_insert = idx_insert_first + 1; 1535 } 1536 } 1537 1538 // always read samples from chain input buffer 1539 effect->setInBuffer(mInBuffer); 1540 1541 // if last effect in the chain, output samples to chain 1542 // output buffer, otherwise to chain input buffer 1543 if (idx_insert == size) { 1544 if (idx_insert != 0) { 1545 mEffects[idx_insert-1]->setOutBuffer(mInBuffer); 1546 mEffects[idx_insert-1]->configure(); 1547 } 1548 effect->setOutBuffer(mOutBuffer); 1549 } else { 1550 effect->setOutBuffer(mInBuffer); 1551 } 1552 mEffects.insertAt(effect, idx_insert); 1553 1554 ALOGV("addEffect_l() effect %p, added in chain %p at rank %d", effect.get(), this, 1555 idx_insert); 1556 } 1557 effect->configure(); 1558 return NO_ERROR; 1559} 1560 1561// removeEffect_l() must be called with PlaybackThread::mLock held 1562size_t AudioFlinger::EffectChain::removeEffect_l(const sp<EffectModule>& effect) 1563{ 1564 Mutex::Autolock _l(mLock); 1565 size_t size = mEffects.size(); 1566 uint32_t type = effect->desc().flags & EFFECT_FLAG_TYPE_MASK; 1567 1568 for (size_t i = 0; i < size; i++) { 1569 if (effect == mEffects[i]) { 1570 // calling stop here will remove pre-processing effect from the audio HAL. 1571 // This is safe as we hold the EffectChain mutex which guarantees that we are not in 1572 // the middle of a read from audio HAL 1573 if (mEffects[i]->state() == EffectModule::ACTIVE || 1574 mEffects[i]->state() == EffectModule::STOPPING) { 1575 mEffects[i]->stop(); 1576 } 1577 if (type == EFFECT_FLAG_TYPE_AUXILIARY) { 1578 delete[] effect->inBuffer(); 1579 } else { 1580 if (i == size - 1 && i != 0) { 1581 mEffects[i - 1]->setOutBuffer(mOutBuffer); 1582 mEffects[i - 1]->configure(); 1583 } 1584 } 1585 mEffects.removeAt(i); 1586 ALOGV("removeEffect_l() effect %p, removed from chain %p at rank %d", effect.get(), 1587 this, i); 1588 break; 1589 } 1590 } 1591 1592 return mEffects.size(); 1593} 1594 1595// setDevice_l() must be called with PlaybackThread::mLock held 1596void AudioFlinger::EffectChain::setDevice_l(audio_devices_t device) 1597{ 1598 size_t size = mEffects.size(); 1599 for (size_t i = 0; i < size; i++) { 1600 mEffects[i]->setDevice(device); 1601 } 1602} 1603 1604// setMode_l() must be called with PlaybackThread::mLock held 1605void AudioFlinger::EffectChain::setMode_l(audio_mode_t mode) 1606{ 1607 size_t size = mEffects.size(); 1608 for (size_t i = 0; i < size; i++) { 1609 mEffects[i]->setMode(mode); 1610 } 1611} 1612 1613// setAudioSource_l() must be called with PlaybackThread::mLock held 1614void AudioFlinger::EffectChain::setAudioSource_l(audio_source_t source) 1615{ 1616 size_t size = mEffects.size(); 1617 for (size_t i = 0; i < size; i++) { 1618 mEffects[i]->setAudioSource(source); 1619 } 1620} 1621 1622// setVolume_l() must be called with PlaybackThread::mLock held 1623bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right) 1624{ 1625 uint32_t newLeft = *left; 1626 uint32_t newRight = *right; 1627 bool hasControl = false; 1628 int ctrlIdx = -1; 1629 size_t size = mEffects.size(); 1630 1631 // first update volume controller 1632 for (size_t i = size; i > 0; i--) { 1633 if (mEffects[i - 1]->isProcessEnabled() && 1634 (mEffects[i - 1]->desc().flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL) { 1635 ctrlIdx = i - 1; 1636 hasControl = true; 1637 break; 1638 } 1639 } 1640 1641 if (ctrlIdx == mVolumeCtrlIdx && *left == mLeftVolume && *right == mRightVolume) { 1642 if (hasControl) { 1643 *left = mNewLeftVolume; 1644 *right = mNewRightVolume; 1645 } 1646 return hasControl; 1647 } 1648 1649 mVolumeCtrlIdx = ctrlIdx; 1650 mLeftVolume = newLeft; 1651 mRightVolume = newRight; 1652 1653 // second get volume update from volume controller 1654 if (ctrlIdx >= 0) { 1655 mEffects[ctrlIdx]->setVolume(&newLeft, &newRight, true); 1656 mNewLeftVolume = newLeft; 1657 mNewRightVolume = newRight; 1658 } 1659 // then indicate volume to all other effects in chain. 1660 // Pass altered volume to effects before volume controller 1661 // and requested volume to effects after controller 1662 uint32_t lVol = newLeft; 1663 uint32_t rVol = newRight; 1664 1665 for (size_t i = 0; i < size; i++) { 1666 if ((int)i == ctrlIdx) { 1667 continue; 1668 } 1669 // this also works for ctrlIdx == -1 when there is no volume controller 1670 if ((int)i > ctrlIdx) { 1671 lVol = *left; 1672 rVol = *right; 1673 } 1674 mEffects[i]->setVolume(&lVol, &rVol, false); 1675 } 1676 *left = newLeft; 1677 *right = newRight; 1678 1679 return hasControl; 1680} 1681 1682void AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args) 1683{ 1684 const size_t SIZE = 256; 1685 char buffer[SIZE]; 1686 String8 result; 1687 1688 size_t numEffects = mEffects.size(); 1689 snprintf(buffer, SIZE, " %d effects for session %d\n", numEffects, mSessionId); 1690 result.append(buffer); 1691 1692 if (numEffects) { 1693 bool locked = AudioFlinger::dumpTryLock(mLock); 1694 // failed to lock - AudioFlinger is probably deadlocked 1695 if (!locked) { 1696 result.append("\tCould not lock mutex:\n"); 1697 } 1698 1699 result.append("\tIn buffer Out buffer Active tracks:\n"); 1700 snprintf(buffer, SIZE, "\t%p %p %d\n", 1701 mInBuffer, 1702 mOutBuffer, 1703 mActiveTrackCnt); 1704 result.append(buffer); 1705 write(fd, result.string(), result.size()); 1706 1707 for (size_t i = 0; i < numEffects; ++i) { 1708 sp<EffectModule> effect = mEffects[i]; 1709 if (effect != 0) { 1710 effect->dump(fd, args); 1711 } 1712 } 1713 1714 if (locked) { 1715 mLock.unlock(); 1716 } 1717 } 1718} 1719 1720// must be called with ThreadBase::mLock held 1721void AudioFlinger::EffectChain::setEffectSuspended_l( 1722 const effect_uuid_t *type, bool suspend) 1723{ 1724 sp<SuspendedEffectDesc> desc; 1725 // use effect type UUID timelow as key as there is no real risk of identical 1726 // timeLow fields among effect type UUIDs. 1727 ssize_t index = mSuspendedEffects.indexOfKey(type->timeLow); 1728 if (suspend) { 1729 if (index >= 0) { 1730 desc = mSuspendedEffects.valueAt(index); 1731 } else { 1732 desc = new SuspendedEffectDesc(); 1733 desc->mType = *type; 1734 mSuspendedEffects.add(type->timeLow, desc); 1735 ALOGV("setEffectSuspended_l() add entry for %08x", type->timeLow); 1736 } 1737 if (desc->mRefCount++ == 0) { 1738 sp<EffectModule> effect = getEffectIfEnabled(type); 1739 if (effect != 0) { 1740 desc->mEffect = effect; 1741 effect->setSuspended(true); 1742 effect->setEnabled(false); 1743 } 1744 } 1745 } else { 1746 if (index < 0) { 1747 return; 1748 } 1749 desc = mSuspendedEffects.valueAt(index); 1750 if (desc->mRefCount <= 0) { 1751 ALOGW("setEffectSuspended_l() restore refcount should not be 0 %d", desc->mRefCount); 1752 desc->mRefCount = 1; 1753 } 1754 if (--desc->mRefCount == 0) { 1755 ALOGV("setEffectSuspended_l() remove entry for %08x", mSuspendedEffects.keyAt(index)); 1756 if (desc->mEffect != 0) { 1757 sp<EffectModule> effect = desc->mEffect.promote(); 1758 if (effect != 0) { 1759 effect->setSuspended(false); 1760 effect->lock(); 1761 EffectHandle *handle = effect->controlHandle_l(); 1762 if (handle != NULL && !handle->destroyed_l()) { 1763 effect->setEnabled_l(handle->enabled()); 1764 } 1765 effect->unlock(); 1766 } 1767 desc->mEffect.clear(); 1768 } 1769 mSuspendedEffects.removeItemsAt(index); 1770 } 1771 } 1772} 1773 1774// must be called with ThreadBase::mLock held 1775void AudioFlinger::EffectChain::setEffectSuspendedAll_l(bool suspend) 1776{ 1777 sp<SuspendedEffectDesc> desc; 1778 1779 ssize_t index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll); 1780 if (suspend) { 1781 if (index >= 0) { 1782 desc = mSuspendedEffects.valueAt(index); 1783 } else { 1784 desc = new SuspendedEffectDesc(); 1785 mSuspendedEffects.add((int)kKeyForSuspendAll, desc); 1786 ALOGV("setEffectSuspendedAll_l() add entry for 0"); 1787 } 1788 if (desc->mRefCount++ == 0) { 1789 Vector< sp<EffectModule> > effects; 1790 getSuspendEligibleEffects(effects); 1791 for (size_t i = 0; i < effects.size(); i++) { 1792 setEffectSuspended_l(&effects[i]->desc().type, true); 1793 } 1794 } 1795 } else { 1796 if (index < 0) { 1797 return; 1798 } 1799 desc = mSuspendedEffects.valueAt(index); 1800 if (desc->mRefCount <= 0) { 1801 ALOGW("setEffectSuspendedAll_l() restore refcount should not be 0 %d", desc->mRefCount); 1802 desc->mRefCount = 1; 1803 } 1804 if (--desc->mRefCount == 0) { 1805 Vector<const effect_uuid_t *> types; 1806 for (size_t i = 0; i < mSuspendedEffects.size(); i++) { 1807 if (mSuspendedEffects.keyAt(i) == (int)kKeyForSuspendAll) { 1808 continue; 1809 } 1810 types.add(&mSuspendedEffects.valueAt(i)->mType); 1811 } 1812 for (size_t i = 0; i < types.size(); i++) { 1813 setEffectSuspended_l(types[i], false); 1814 } 1815 ALOGV("setEffectSuspendedAll_l() remove entry for %08x", 1816 mSuspendedEffects.keyAt(index)); 1817 mSuspendedEffects.removeItem((int)kKeyForSuspendAll); 1818 } 1819 } 1820} 1821 1822 1823// The volume effect is used for automated tests only 1824#ifndef OPENSL_ES_H_ 1825static const effect_uuid_t SL_IID_VOLUME_ = { 0x09e8ede0, 0xddde, 0x11db, 0xb4f6, 1826 { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } }; 1827const effect_uuid_t * const SL_IID_VOLUME = &SL_IID_VOLUME_; 1828#endif //OPENSL_ES_H_ 1829 1830bool AudioFlinger::EffectChain::isEffectEligibleForSuspend(const effect_descriptor_t& desc) 1831{ 1832 // auxiliary effects and visualizer are never suspended on output mix 1833 if ((mSessionId == AUDIO_SESSION_OUTPUT_MIX) && 1834 (((desc.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) || 1835 (memcmp(&desc.type, SL_IID_VISUALIZATION, sizeof(effect_uuid_t)) == 0) || 1836 (memcmp(&desc.type, SL_IID_VOLUME, sizeof(effect_uuid_t)) == 0))) { 1837 return false; 1838 } 1839 return true; 1840} 1841 1842void AudioFlinger::EffectChain::getSuspendEligibleEffects( 1843 Vector< sp<AudioFlinger::EffectModule> > &effects) 1844{ 1845 effects.clear(); 1846 for (size_t i = 0; i < mEffects.size(); i++) { 1847 if (isEffectEligibleForSuspend(mEffects[i]->desc())) { 1848 effects.add(mEffects[i]); 1849 } 1850 } 1851} 1852 1853sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectIfEnabled( 1854 const effect_uuid_t *type) 1855{ 1856 sp<EffectModule> effect = getEffectFromType_l(type); 1857 return effect != 0 && effect->isEnabled() ? effect : 0; 1858} 1859 1860void AudioFlinger::EffectChain::checkSuspendOnEffectEnabled(const sp<EffectModule>& effect, 1861 bool enabled) 1862{ 1863 ssize_t index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow); 1864 if (enabled) { 1865 if (index < 0) { 1866 // if the effect is not suspend check if all effects are suspended 1867 index = mSuspendedEffects.indexOfKey((int)kKeyForSuspendAll); 1868 if (index < 0) { 1869 return; 1870 } 1871 if (!isEffectEligibleForSuspend(effect->desc())) { 1872 return; 1873 } 1874 setEffectSuspended_l(&effect->desc().type, enabled); 1875 index = mSuspendedEffects.indexOfKey(effect->desc().type.timeLow); 1876 if (index < 0) { 1877 ALOGW("checkSuspendOnEffectEnabled() Fx should be suspended here!"); 1878 return; 1879 } 1880 } 1881 ALOGV("checkSuspendOnEffectEnabled() enable suspending fx %08x", 1882 effect->desc().type.timeLow); 1883 sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index); 1884 // if effect is requested to suspended but was not yet enabled, supend it now. 1885 if (desc->mEffect == 0) { 1886 desc->mEffect = effect; 1887 effect->setEnabled(false); 1888 effect->setSuspended(true); 1889 } 1890 } else { 1891 if (index < 0) { 1892 return; 1893 } 1894 ALOGV("checkSuspendOnEffectEnabled() disable restoring fx %08x", 1895 effect->desc().type.timeLow); 1896 sp<SuspendedEffectDesc> desc = mSuspendedEffects.valueAt(index); 1897 desc->mEffect.clear(); 1898 effect->setSuspended(false); 1899 } 1900} 1901 1902bool AudioFlinger::EffectChain::isNonOffloadableEnabled() 1903{ 1904 Mutex::Autolock _l(mLock); 1905 size_t size = mEffects.size(); 1906 for (size_t i = 0; i < size; i++) { 1907 if (mEffects[i]->isEnabled() && !mEffects[i]->isOffloadable()) { 1908 return true; 1909 } 1910 } 1911 return false; 1912} 1913 1914}; // namespace android 1915