Home | History | Annotate | Download | only in audioflinger
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "AudioPolicyService"
     18 //#define LOG_NDEBUG 0
     19 
     20 #undef __STRICT_ANSI__
     21 #define __STDINT_LIMITS
     22 #define __STDC_LIMIT_MACROS
     23 #include <stdint.h>
     24 
     25 #include <sys/time.h>
     26 #include <binder/IServiceManager.h>
     27 #include <utils/Log.h>
     28 #include <cutils/properties.h>
     29 #include <binder/IPCThreadState.h>
     30 #include <utils/String16.h>
     31 #include <utils/threads.h>
     32 #include "AudioPolicyService.h"
     33 #include <hardware_legacy/AudioPolicyManagerBase.h>
     34 #include <cutils/properties.h>
     35 #include <dlfcn.h>
     36 #include <hardware_legacy/power.h>
     37 
     38 // ----------------------------------------------------------------------------
     39 // the sim build doesn't have gettid
     40 
     41 #ifndef HAVE_GETTID
     42 # define gettid getpid
     43 #endif
     44 
     45 namespace android {
     46 
     47 
     48 static const char *kDeadlockedString = "AudioPolicyService may be deadlocked\n";
     49 static const char *kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n";
     50 
     51 static const int kDumpLockRetries = 50;
     52 static const int kDumpLockSleep = 20000;
     53 
     54 static bool checkPermission() {
     55 #ifndef HAVE_ANDROID_OS
     56     return true;
     57 #endif
     58     if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
     59     bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
     60     if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
     61     return ok;
     62 }
     63 
     64 // ----------------------------------------------------------------------------
     65 
     66 AudioPolicyService::AudioPolicyService()
     67     : BnAudioPolicyService() , mpPolicyManager(NULL)
     68 {
     69     char value[PROPERTY_VALUE_MAX];
     70 
     71     // start tone playback thread
     72     mTonePlaybackThread = new AudioCommandThread(String8(""));
     73     // start audio commands thread
     74     mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread"));
     75 
     76 #if (defined GENERIC_AUDIO) || (defined AUDIO_POLICY_TEST)
     77     mpPolicyManager = new AudioPolicyManagerBase(this);
     78     LOGV("build for GENERIC_AUDIO - using generic audio policy");
     79 #else
     80     // if running in emulation - use the emulator driver
     81     if (property_get("ro.kernel.qemu", value, 0)) {
     82         LOGV("Running in emulation - using generic audio policy");
     83         mpPolicyManager = new AudioPolicyManagerBase(this);
     84     }
     85     else {
     86         LOGV("Using hardware specific audio policy");
     87         mpPolicyManager = createAudioPolicyManager(this);
     88     }
     89 #endif
     90 
     91     // load properties
     92     property_get("ro.camera.sound.forced", value, "0");
     93     mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value);
     94 }
     95 
     96 AudioPolicyService::~AudioPolicyService()
     97 {
     98     mTonePlaybackThread->exit();
     99     mTonePlaybackThread.clear();
    100     mAudioCommandThread->exit();
    101     mAudioCommandThread.clear();
    102 
    103     if (mpPolicyManager) {
    104         delete mpPolicyManager;
    105     }
    106 }
    107 
    108 
    109 status_t AudioPolicyService::setDeviceConnectionState(AudioSystem::audio_devices device,
    110                                                   AudioSystem::device_connection_state state,
    111                                                   const char *device_address)
    112 {
    113     if (mpPolicyManager == NULL) {
    114         return NO_INIT;
    115     }
    116     if (!checkPermission()) {
    117         return PERMISSION_DENIED;
    118     }
    119     if (!AudioSystem::isOutputDevice(device) && !AudioSystem::isInputDevice(device)) {
    120         return BAD_VALUE;
    121     }
    122     if (state != AudioSystem::DEVICE_STATE_AVAILABLE &&
    123             state != AudioSystem::DEVICE_STATE_UNAVAILABLE) {
    124         return BAD_VALUE;
    125     }
    126 
    127     LOGV("setDeviceConnectionState() tid %d", gettid());
    128     Mutex::Autolock _l(mLock);
    129     return mpPolicyManager->setDeviceConnectionState(device, state, device_address);
    130 }
    131 
    132 AudioSystem::device_connection_state AudioPolicyService::getDeviceConnectionState(
    133                                                               AudioSystem::audio_devices device,
    134                                                               const char *device_address)
    135 {
    136     if (mpPolicyManager == NULL) {
    137         return AudioSystem::DEVICE_STATE_UNAVAILABLE;
    138     }
    139     if (!checkPermission()) {
    140         return AudioSystem::DEVICE_STATE_UNAVAILABLE;
    141     }
    142     return mpPolicyManager->getDeviceConnectionState(device, device_address);
    143 }
    144 
    145 status_t AudioPolicyService::setPhoneState(int state)
    146 {
    147     if (mpPolicyManager == NULL) {
    148         return NO_INIT;
    149     }
    150     if (!checkPermission()) {
    151         return PERMISSION_DENIED;
    152     }
    153     if (state < 0 || state >= AudioSystem::NUM_MODES) {
    154         return BAD_VALUE;
    155     }
    156 
    157     LOGV("setPhoneState() tid %d", gettid());
    158 
    159     // TODO: check if it is more appropriate to do it in platform specific policy manager
    160     AudioSystem::setMode(state);
    161 
    162     Mutex::Autolock _l(mLock);
    163     mpPolicyManager->setPhoneState(state);
    164     return NO_ERROR;
    165 }
    166 
    167 status_t AudioPolicyService::setRingerMode(uint32_t mode, uint32_t mask)
    168 {
    169     if (mpPolicyManager == NULL) {
    170         return NO_INIT;
    171     }
    172     if (!checkPermission()) {
    173         return PERMISSION_DENIED;
    174     }
    175 
    176     mpPolicyManager->setRingerMode(mode, mask);
    177     return NO_ERROR;
    178 }
    179 
    180 status_t AudioPolicyService::setForceUse(AudioSystem::force_use usage,
    181                                          AudioSystem::forced_config config)
    182 {
    183     if (mpPolicyManager == NULL) {
    184         return NO_INIT;
    185     }
    186     if (!checkPermission()) {
    187         return PERMISSION_DENIED;
    188     }
    189     if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) {
    190         return BAD_VALUE;
    191     }
    192     if (config < 0 || config >= AudioSystem::NUM_FORCE_CONFIG) {
    193         return BAD_VALUE;
    194     }
    195     LOGV("setForceUse() tid %d", gettid());
    196     Mutex::Autolock _l(mLock);
    197     mpPolicyManager->setForceUse(usage, config);
    198     return NO_ERROR;
    199 }
    200 
    201 AudioSystem::forced_config AudioPolicyService::getForceUse(AudioSystem::force_use usage)
    202 {
    203     if (mpPolicyManager == NULL) {
    204         return AudioSystem::FORCE_NONE;
    205     }
    206     if (!checkPermission()) {
    207         return AudioSystem::FORCE_NONE;
    208     }
    209     if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) {
    210         return AudioSystem::FORCE_NONE;
    211     }
    212     return mpPolicyManager->getForceUse(usage);
    213 }
    214 
    215 audio_io_handle_t AudioPolicyService::getOutput(AudioSystem::stream_type stream,
    216                                     uint32_t samplingRate,
    217                                     uint32_t format,
    218                                     uint32_t channels,
    219                                     AudioSystem::output_flags flags)
    220 {
    221     if (mpPolicyManager == NULL) {
    222         return 0;
    223     }
    224     LOGV("getOutput() tid %d", gettid());
    225     Mutex::Autolock _l(mLock);
    226     return mpPolicyManager->getOutput(stream, samplingRate, format, channels, flags);
    227 }
    228 
    229 status_t AudioPolicyService::startOutput(audio_io_handle_t output,
    230                                          AudioSystem::stream_type stream,
    231                                          int session)
    232 {
    233     if (mpPolicyManager == NULL) {
    234         return NO_INIT;
    235     }
    236     LOGV("startOutput() tid %d", gettid());
    237     Mutex::Autolock _l(mLock);
    238     return mpPolicyManager->startOutput(output, stream, session);
    239 }
    240 
    241 status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
    242                                         AudioSystem::stream_type stream,
    243                                         int session)
    244 {
    245     if (mpPolicyManager == NULL) {
    246         return NO_INIT;
    247     }
    248     LOGV("stopOutput() tid %d", gettid());
    249     Mutex::Autolock _l(mLock);
    250     return mpPolicyManager->stopOutput(output, stream, session);
    251 }
    252 
    253 void AudioPolicyService::releaseOutput(audio_io_handle_t output)
    254 {
    255     if (mpPolicyManager == NULL) {
    256         return;
    257     }
    258     LOGV("releaseOutput() tid %d", gettid());
    259     Mutex::Autolock _l(mLock);
    260     mpPolicyManager->releaseOutput(output);
    261 }
    262 
    263 audio_io_handle_t AudioPolicyService::getInput(int inputSource,
    264                                     uint32_t samplingRate,
    265                                     uint32_t format,
    266                                     uint32_t channels,
    267                                     AudioSystem::audio_in_acoustics acoustics)
    268 {
    269     if (mpPolicyManager == NULL) {
    270         return 0;
    271     }
    272     Mutex::Autolock _l(mLock);
    273     return mpPolicyManager->getInput(inputSource, samplingRate, format, channels, acoustics);
    274 }
    275 
    276 status_t AudioPolicyService::startInput(audio_io_handle_t input)
    277 {
    278     if (mpPolicyManager == NULL) {
    279         return NO_INIT;
    280     }
    281     Mutex::Autolock _l(mLock);
    282     return mpPolicyManager->startInput(input);
    283 }
    284 
    285 status_t AudioPolicyService::stopInput(audio_io_handle_t input)
    286 {
    287     if (mpPolicyManager == NULL) {
    288         return NO_INIT;
    289     }
    290     Mutex::Autolock _l(mLock);
    291     return mpPolicyManager->stopInput(input);
    292 }
    293 
    294 void AudioPolicyService::releaseInput(audio_io_handle_t input)
    295 {
    296     if (mpPolicyManager == NULL) {
    297         return;
    298     }
    299     Mutex::Autolock _l(mLock);
    300     mpPolicyManager->releaseInput(input);
    301 }
    302 
    303 status_t AudioPolicyService::initStreamVolume(AudioSystem::stream_type stream,
    304                                             int indexMin,
    305                                             int indexMax)
    306 {
    307     if (mpPolicyManager == NULL) {
    308         return NO_INIT;
    309     }
    310     if (!checkPermission()) {
    311         return PERMISSION_DENIED;
    312     }
    313     if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
    314         return BAD_VALUE;
    315     }
    316     mpPolicyManager->initStreamVolume(stream, indexMin, indexMax);
    317     return NO_ERROR;
    318 }
    319 
    320 status_t AudioPolicyService::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
    321 {
    322     if (mpPolicyManager == NULL) {
    323         return NO_INIT;
    324     }
    325     if (!checkPermission()) {
    326         return PERMISSION_DENIED;
    327     }
    328     if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
    329         return BAD_VALUE;
    330     }
    331 
    332     return mpPolicyManager->setStreamVolumeIndex(stream, index);
    333 }
    334 
    335 status_t AudioPolicyService::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
    336 {
    337     if (mpPolicyManager == NULL) {
    338         return NO_INIT;
    339     }
    340     if (!checkPermission()) {
    341         return PERMISSION_DENIED;
    342     }
    343     if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
    344         return BAD_VALUE;
    345     }
    346     return mpPolicyManager->getStreamVolumeIndex(stream, index);
    347 }
    348 
    349 uint32_t AudioPolicyService::getStrategyForStream(AudioSystem::stream_type stream)
    350 {
    351     if (mpPolicyManager == NULL) {
    352         return 0;
    353     }
    354     return mpPolicyManager->getStrategyForStream(stream);
    355 }
    356 
    357 audio_io_handle_t AudioPolicyService::getOutputForEffect(effect_descriptor_t *desc)
    358 {
    359     if (mpPolicyManager == NULL) {
    360         return NO_INIT;
    361     }
    362     Mutex::Autolock _l(mLock);
    363     return mpPolicyManager->getOutputForEffect(desc);
    364 }
    365 
    366 status_t AudioPolicyService::registerEffect(effect_descriptor_t *desc,
    367                                 audio_io_handle_t output,
    368                                 uint32_t strategy,
    369                                 int session,
    370                                 int id)
    371 {
    372     if (mpPolicyManager == NULL) {
    373         return NO_INIT;
    374     }
    375     return mpPolicyManager->registerEffect(desc, output, strategy, session, id);
    376 }
    377 
    378 status_t AudioPolicyService::unregisterEffect(int id)
    379 {
    380     if (mpPolicyManager == NULL) {
    381         return NO_INIT;
    382     }
    383     return mpPolicyManager->unregisterEffect(id);
    384 }
    385 
    386 void AudioPolicyService::binderDied(const wp<IBinder>& who) {
    387     LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(),
    388             IPCThreadState::self()->getCallingPid());
    389 }
    390 
    391 static bool tryLock(Mutex& mutex)
    392 {
    393     bool locked = false;
    394     for (int i = 0; i < kDumpLockRetries; ++i) {
    395         if (mutex.tryLock() == NO_ERROR) {
    396             locked = true;
    397             break;
    398         }
    399         usleep(kDumpLockSleep);
    400     }
    401     return locked;
    402 }
    403 
    404 status_t AudioPolicyService::dumpInternals(int fd)
    405 {
    406     const size_t SIZE = 256;
    407     char buffer[SIZE];
    408     String8 result;
    409 
    410     snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpPolicyManager);
    411     result.append(buffer);
    412     snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
    413     result.append(buffer);
    414     snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
    415     result.append(buffer);
    416 
    417     write(fd, result.string(), result.size());
    418     return NO_ERROR;
    419 }
    420 
    421 status_t AudioPolicyService::dump(int fd, const Vector<String16>& args)
    422 {
    423     if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
    424         dumpPermissionDenial(fd);
    425     } else {
    426         bool locked = tryLock(mLock);
    427         if (!locked) {
    428             String8 result(kDeadlockedString);
    429             write(fd, result.string(), result.size());
    430         }
    431 
    432         dumpInternals(fd);
    433         if (mAudioCommandThread != NULL) {
    434             mAudioCommandThread->dump(fd);
    435         }
    436         if (mTonePlaybackThread != NULL) {
    437             mTonePlaybackThread->dump(fd);
    438         }
    439 
    440         if (mpPolicyManager) {
    441             mpPolicyManager->dump(fd);
    442         }
    443 
    444         if (locked) mLock.unlock();
    445     }
    446     return NO_ERROR;
    447 }
    448 
    449 status_t AudioPolicyService::dumpPermissionDenial(int fd)
    450 {
    451     const size_t SIZE = 256;
    452     char buffer[SIZE];
    453     String8 result;
    454     snprintf(buffer, SIZE, "Permission Denial: "
    455             "can't dump AudioPolicyService from pid=%d, uid=%d\n",
    456             IPCThreadState::self()->getCallingPid(),
    457             IPCThreadState::self()->getCallingUid());
    458     result.append(buffer);
    459     write(fd, result.string(), result.size());
    460     return NO_ERROR;
    461 }
    462 
    463 status_t AudioPolicyService::onTransact(
    464         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    465 {
    466     return BnAudioPolicyService::onTransact(code, data, reply, flags);
    467 }
    468 
    469 
    470 // ----------------------------------------------------------------------------
    471 void AudioPolicyService::instantiate() {
    472     defaultServiceManager()->addService(
    473             String16("media.audio_policy"), new AudioPolicyService());
    474 }
    475 
    476 
    477 // ----------------------------------------------------------------------------
    478 // AudioPolicyClientInterface implementation
    479 // ----------------------------------------------------------------------------
    480 
    481 
    482 audio_io_handle_t AudioPolicyService::openOutput(uint32_t *pDevices,
    483                                 uint32_t *pSamplingRate,
    484                                 uint32_t *pFormat,
    485                                 uint32_t *pChannels,
    486                                 uint32_t *pLatencyMs,
    487                                 AudioSystem::output_flags flags)
    488 {
    489     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    490     if (af == 0) {
    491         LOGW("openOutput() could not get AudioFlinger");
    492         return 0;
    493     }
    494 
    495     return af->openOutput(pDevices,
    496                           pSamplingRate,
    497                           (uint32_t *)pFormat,
    498                           pChannels,
    499                           pLatencyMs,
    500                           flags);
    501 }
    502 
    503 audio_io_handle_t AudioPolicyService::openDuplicateOutput(audio_io_handle_t output1,
    504                                                           audio_io_handle_t output2)
    505 {
    506     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    507     if (af == 0) {
    508         LOGW("openDuplicateOutput() could not get AudioFlinger");
    509         return 0;
    510     }
    511     return af->openDuplicateOutput(output1, output2);
    512 }
    513 
    514 status_t AudioPolicyService::closeOutput(audio_io_handle_t output)
    515 {
    516     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    517     if (af == 0) return PERMISSION_DENIED;
    518 
    519     return af->closeOutput(output);
    520 }
    521 
    522 
    523 status_t AudioPolicyService::suspendOutput(audio_io_handle_t output)
    524 {
    525     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    526     if (af == 0) {
    527         LOGW("suspendOutput() could not get AudioFlinger");
    528         return PERMISSION_DENIED;
    529     }
    530 
    531     return af->suspendOutput(output);
    532 }
    533 
    534 status_t AudioPolicyService::restoreOutput(audio_io_handle_t output)
    535 {
    536     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    537     if (af == 0) {
    538         LOGW("restoreOutput() could not get AudioFlinger");
    539         return PERMISSION_DENIED;
    540     }
    541 
    542     return af->restoreOutput(output);
    543 }
    544 
    545 audio_io_handle_t AudioPolicyService::openInput(uint32_t *pDevices,
    546                                 uint32_t *pSamplingRate,
    547                                 uint32_t *pFormat,
    548                                 uint32_t *pChannels,
    549                                 uint32_t acoustics)
    550 {
    551     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    552     if (af == 0) {
    553         LOGW("openInput() could not get AudioFlinger");
    554         return 0;
    555     }
    556 
    557     return af->openInput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, acoustics);
    558 }
    559 
    560 status_t AudioPolicyService::closeInput(audio_io_handle_t input)
    561 {
    562     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    563     if (af == 0) return PERMISSION_DENIED;
    564 
    565     return af->closeInput(input);
    566 }
    567 
    568 status_t AudioPolicyService::setStreamVolume(AudioSystem::stream_type stream,
    569                                              float volume,
    570                                              audio_io_handle_t output,
    571                                              int delayMs)
    572 {
    573     return mAudioCommandThread->volumeCommand((int)stream, volume, (int)output, delayMs);
    574 }
    575 
    576 status_t AudioPolicyService::setStreamOutput(AudioSystem::stream_type stream,
    577                                              audio_io_handle_t output)
    578 {
    579     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    580     if (af == 0) return PERMISSION_DENIED;
    581 
    582     return af->setStreamOutput(stream, output);
    583 }
    584 
    585 status_t AudioPolicyService::moveEffects(int session, audio_io_handle_t srcOutput,
    586                                                audio_io_handle_t dstOutput)
    587 {
    588     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    589     if (af == 0) return PERMISSION_DENIED;
    590 
    591     return af->moveEffects(session, (int)srcOutput, (int)dstOutput);
    592 }
    593 
    594 void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
    595                                        const String8& keyValuePairs,
    596                                        int delayMs)
    597 {
    598     mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs, delayMs);
    599 }
    600 
    601 String8 AudioPolicyService::getParameters(audio_io_handle_t ioHandle, const String8& keys)
    602 {
    603     String8 result = AudioSystem::getParameters(ioHandle, keys);
    604     return result;
    605 }
    606 
    607 status_t AudioPolicyService::startTone(ToneGenerator::tone_type tone,
    608                                        AudioSystem::stream_type stream)
    609 {
    610     mTonePlaybackThread->startToneCommand(tone, stream);
    611     return NO_ERROR;
    612 }
    613 
    614 status_t AudioPolicyService::stopTone()
    615 {
    616     mTonePlaybackThread->stopToneCommand();
    617     return NO_ERROR;
    618 }
    619 
    620 status_t AudioPolicyService::setVoiceVolume(float volume, int delayMs)
    621 {
    622     return mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
    623 }
    624 
    625 // -----------  AudioPolicyService::AudioCommandThread implementation ----------
    626 
    627 AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name)
    628     : Thread(false), mName(name)
    629 {
    630     mpToneGenerator = NULL;
    631 }
    632 
    633 
    634 AudioPolicyService::AudioCommandThread::~AudioCommandThread()
    635 {
    636     if (mName != "" && !mAudioCommands.isEmpty()) {
    637         release_wake_lock(mName.string());
    638     }
    639     mAudioCommands.clear();
    640     if (mpToneGenerator != NULL) delete mpToneGenerator;
    641 }
    642 
    643 void AudioPolicyService::AudioCommandThread::onFirstRef()
    644 {
    645     if (mName != "") {
    646         run(mName.string(), ANDROID_PRIORITY_AUDIO);
    647     } else {
    648         run("AudioCommandThread", ANDROID_PRIORITY_AUDIO);
    649     }
    650 }
    651 
    652 bool AudioPolicyService::AudioCommandThread::threadLoop()
    653 {
    654     nsecs_t waitTime = INT64_MAX;
    655 
    656     mLock.lock();
    657     while (!exitPending())
    658     {
    659         while(!mAudioCommands.isEmpty()) {
    660             nsecs_t curTime = systemTime();
    661             // commands are sorted by increasing time stamp: execute them from index 0 and up
    662             if (mAudioCommands[0]->mTime <= curTime) {
    663                 AudioCommand *command = mAudioCommands[0];
    664                 mAudioCommands.removeAt(0);
    665                 mLastCommand = *command;
    666 
    667                 switch (command->mCommand) {
    668                 case START_TONE: {
    669                     mLock.unlock();
    670                     ToneData *data = (ToneData *)command->mParam;
    671                     LOGV("AudioCommandThread() processing start tone %d on stream %d",
    672                             data->mType, data->mStream);
    673                     if (mpToneGenerator != NULL)
    674                         delete mpToneGenerator;
    675                     mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
    676                     mpToneGenerator->startTone(data->mType);
    677                     delete data;
    678                     mLock.lock();
    679                     }break;
    680                 case STOP_TONE: {
    681                     mLock.unlock();
    682                     LOGV("AudioCommandThread() processing stop tone");
    683                     if (mpToneGenerator != NULL) {
    684                         mpToneGenerator->stopTone();
    685                         delete mpToneGenerator;
    686                         mpToneGenerator = NULL;
    687                     }
    688                     mLock.lock();
    689                     }break;
    690                 case SET_VOLUME: {
    691                     VolumeData *data = (VolumeData *)command->mParam;
    692                     LOGV("AudioCommandThread() processing set volume stream %d, \
    693                             volume %f, output %d", data->mStream, data->mVolume, data->mIO);
    694                     command->mStatus = AudioSystem::setStreamVolume(data->mStream,
    695                                                                     data->mVolume,
    696                                                                     data->mIO);
    697                     if (command->mWaitStatus) {
    698                         command->mCond.signal();
    699                         mWaitWorkCV.wait(mLock);
    700                     }
    701                     delete data;
    702                     }break;
    703                 case SET_PARAMETERS: {
    704                      ParametersData *data = (ParametersData *)command->mParam;
    705                      LOGV("AudioCommandThread() processing set parameters string %s, io %d",
    706                              data->mKeyValuePairs.string(), data->mIO);
    707                      command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
    708                      if (command->mWaitStatus) {
    709                          command->mCond.signal();
    710                          mWaitWorkCV.wait(mLock);
    711                      }
    712                      delete data;
    713                      }break;
    714                 case SET_VOICE_VOLUME: {
    715                     VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
    716                     LOGV("AudioCommandThread() processing set voice volume volume %f",
    717                             data->mVolume);
    718                     command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
    719                     if (command->mWaitStatus) {
    720                         command->mCond.signal();
    721                         mWaitWorkCV.wait(mLock);
    722                     }
    723                     delete data;
    724                     }break;
    725                 default:
    726                     LOGW("AudioCommandThread() unknown command %d", command->mCommand);
    727                 }
    728                 delete command;
    729                 waitTime = INT64_MAX;
    730             } else {
    731                 waitTime = mAudioCommands[0]->mTime - curTime;
    732                 break;
    733             }
    734         }
    735         // release delayed commands wake lock
    736         if (mName != "" && mAudioCommands.isEmpty()) {
    737             release_wake_lock(mName.string());
    738         }
    739         LOGV("AudioCommandThread() going to sleep");
    740         mWaitWorkCV.waitRelative(mLock, waitTime);
    741         LOGV("AudioCommandThread() waking up");
    742     }
    743     mLock.unlock();
    744     return false;
    745 }
    746 
    747 status_t AudioPolicyService::AudioCommandThread::dump(int fd)
    748 {
    749     const size_t SIZE = 256;
    750     char buffer[SIZE];
    751     String8 result;
    752 
    753     snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
    754     result.append(buffer);
    755     write(fd, result.string(), result.size());
    756 
    757     bool locked = tryLock(mLock);
    758     if (!locked) {
    759         String8 result2(kCmdDeadlockedString);
    760         write(fd, result2.string(), result2.size());
    761     }
    762 
    763     snprintf(buffer, SIZE, "- Commands:\n");
    764     result = String8(buffer);
    765     result.append("   Command Time        Wait pParam\n");
    766     for (int i = 0; i < (int)mAudioCommands.size(); i++) {
    767         mAudioCommands[i]->dump(buffer, SIZE);
    768         result.append(buffer);
    769     }
    770     result.append("  Last Command\n");
    771     mLastCommand.dump(buffer, SIZE);
    772     result.append(buffer);
    773 
    774     write(fd, result.string(), result.size());
    775 
    776     if (locked) mLock.unlock();
    777 
    778     return NO_ERROR;
    779 }
    780 
    781 void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
    782 {
    783     AudioCommand *command = new AudioCommand();
    784     command->mCommand = START_TONE;
    785     ToneData *data = new ToneData();
    786     data->mType = type;
    787     data->mStream = stream;
    788     command->mParam = (void *)data;
    789     command->mWaitStatus = false;
    790     Mutex::Autolock _l(mLock);
    791     insertCommand_l(command);
    792     LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
    793     mWaitWorkCV.signal();
    794 }
    795 
    796 void AudioPolicyService::AudioCommandThread::stopToneCommand()
    797 {
    798     AudioCommand *command = new AudioCommand();
    799     command->mCommand = STOP_TONE;
    800     command->mParam = NULL;
    801     command->mWaitStatus = false;
    802     Mutex::Autolock _l(mLock);
    803     insertCommand_l(command);
    804     LOGV("AudioCommandThread() adding tone stop");
    805     mWaitWorkCV.signal();
    806 }
    807 
    808 status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream,
    809                                                                float volume,
    810                                                                int output,
    811                                                                int delayMs)
    812 {
    813     status_t status = NO_ERROR;
    814 
    815     AudioCommand *command = new AudioCommand();
    816     command->mCommand = SET_VOLUME;
    817     VolumeData *data = new VolumeData();
    818     data->mStream = stream;
    819     data->mVolume = volume;
    820     data->mIO = output;
    821     command->mParam = data;
    822     if (delayMs == 0) {
    823         command->mWaitStatus = true;
    824     } else {
    825         command->mWaitStatus = false;
    826     }
    827     Mutex::Autolock _l(mLock);
    828     insertCommand_l(command, delayMs);
    829     LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
    830             stream, volume, output);
    831     mWaitWorkCV.signal();
    832     if (command->mWaitStatus) {
    833         command->mCond.wait(mLock);
    834         status =  command->mStatus;
    835         mWaitWorkCV.signal();
    836     }
    837     return status;
    838 }
    839 
    840 status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
    841                                                                    const String8& keyValuePairs,
    842                                                                    int delayMs)
    843 {
    844     status_t status = NO_ERROR;
    845 
    846     AudioCommand *command = new AudioCommand();
    847     command->mCommand = SET_PARAMETERS;
    848     ParametersData *data = new ParametersData();
    849     data->mIO = ioHandle;
    850     data->mKeyValuePairs = keyValuePairs;
    851     command->mParam = data;
    852     if (delayMs == 0) {
    853         command->mWaitStatus = true;
    854     } else {
    855         command->mWaitStatus = false;
    856     }
    857     Mutex::Autolock _l(mLock);
    858     insertCommand_l(command, delayMs);
    859     LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
    860             keyValuePairs.string(), ioHandle, delayMs);
    861     mWaitWorkCV.signal();
    862     if (command->mWaitStatus) {
    863         command->mCond.wait(mLock);
    864         status =  command->mStatus;
    865         mWaitWorkCV.signal();
    866     }
    867     return status;
    868 }
    869 
    870 status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
    871 {
    872     status_t status = NO_ERROR;
    873 
    874     AudioCommand *command = new AudioCommand();
    875     command->mCommand = SET_VOICE_VOLUME;
    876     VoiceVolumeData *data = new VoiceVolumeData();
    877     data->mVolume = volume;
    878     command->mParam = data;
    879     if (delayMs == 0) {
    880         command->mWaitStatus = true;
    881     } else {
    882         command->mWaitStatus = false;
    883     }
    884     Mutex::Autolock _l(mLock);
    885     insertCommand_l(command, delayMs);
    886     LOGV("AudioCommandThread() adding set voice volume volume %f", volume);
    887     mWaitWorkCV.signal();
    888     if (command->mWaitStatus) {
    889         command->mCond.wait(mLock);
    890         status =  command->mStatus;
    891         mWaitWorkCV.signal();
    892     }
    893     return status;
    894 }
    895 
    896 // insertCommand_l() must be called with mLock held
    897 void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
    898 {
    899     ssize_t i;
    900     Vector <AudioCommand *> removedCommands;
    901 
    902     command->mTime = systemTime() + milliseconds(delayMs);
    903 
    904     // acquire wake lock to make sure delayed commands are processed
    905     if (mName != "" && mAudioCommands.isEmpty()) {
    906         acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
    907     }
    908 
    909     // check same pending commands with later time stamps and eliminate them
    910     for (i = mAudioCommands.size()-1; i >= 0; i--) {
    911         AudioCommand *command2 = mAudioCommands[i];
    912         // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
    913         if (command2->mTime <= command->mTime) break;
    914         if (command2->mCommand != command->mCommand) continue;
    915 
    916         switch (command->mCommand) {
    917         case SET_PARAMETERS: {
    918             ParametersData *data = (ParametersData *)command->mParam;
    919             ParametersData *data2 = (ParametersData *)command2->mParam;
    920             if (data->mIO != data2->mIO) break;
    921             LOGV("Comparing parameter command %s to new command %s",
    922                     data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
    923             AudioParameter param = AudioParameter(data->mKeyValuePairs);
    924             AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
    925             for (size_t j = 0; j < param.size(); j++) {
    926                String8 key;
    927                String8 value;
    928                param.getAt(j, key, value);
    929                for (size_t k = 0; k < param2.size(); k++) {
    930                   String8 key2;
    931                   String8 value2;
    932                   param2.getAt(k, key2, value2);
    933                   if (key2 == key) {
    934                       param2.remove(key2);
    935                       LOGV("Filtering out parameter %s", key2.string());
    936                       break;
    937                   }
    938                }
    939             }
    940             // if all keys have been filtered out, remove the command.
    941             // otherwise, update the key value pairs
    942             if (param2.size() == 0) {
    943                 removedCommands.add(command2);
    944             } else {
    945                 data2->mKeyValuePairs = param2.toString();
    946             }
    947         } break;
    948 
    949         case SET_VOLUME: {
    950             VolumeData *data = (VolumeData *)command->mParam;
    951             VolumeData *data2 = (VolumeData *)command2->mParam;
    952             if (data->mIO != data2->mIO) break;
    953             if (data->mStream != data2->mStream) break;
    954             LOGV("Filtering out volume command on output %d for stream %d",
    955                     data->mIO, data->mStream);
    956             removedCommands.add(command2);
    957         } break;
    958         case START_TONE:
    959         case STOP_TONE:
    960         default:
    961             break;
    962         }
    963     }
    964 
    965     // remove filtered commands
    966     for (size_t j = 0; j < removedCommands.size(); j++) {
    967         // removed commands always have time stamps greater than current command
    968         for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
    969             if (mAudioCommands[k] == removedCommands[j]) {
    970                 LOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
    971                 mAudioCommands.removeAt(k);
    972                 break;
    973             }
    974         }
    975     }
    976     removedCommands.clear();
    977 
    978     // insert command at the right place according to its time stamp
    979     LOGV("inserting command: %d at index %d, num commands %d",
    980             command->mCommand, (int)i+1, mAudioCommands.size());
    981     mAudioCommands.insertAt(command, i + 1);
    982 }
    983 
    984 void AudioPolicyService::AudioCommandThread::exit()
    985 {
    986     LOGV("AudioCommandThread::exit");
    987     {
    988         AutoMutex _l(mLock);
    989         requestExit();
    990         mWaitWorkCV.signal();
    991     }
    992     requestExitAndWait();
    993 }
    994 
    995 void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
    996 {
    997     snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
    998             mCommand,
    999             (int)ns2s(mTime),
   1000             (int)ns2ms(mTime)%1000,
   1001             mWaitStatus,
   1002             mParam);
   1003 }
   1004 
   1005 }; // namespace android
   1006