Home | History | Annotate | Download | only in audiopolicy
      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 #include "Configuration.h"
     21 #undef __STRICT_ANSI__
     22 #define __STDINT_LIMITS
     23 #define __STDC_LIMIT_MACROS
     24 #include <stdint.h>
     25 
     26 #include <sys/time.h>
     27 #include <binder/IServiceManager.h>
     28 #include <utils/Log.h>
     29 #include <cutils/properties.h>
     30 #include <binder/IPCThreadState.h>
     31 #include <utils/String16.h>
     32 #include <utils/threads.h>
     33 #include "AudioPolicyService.h"
     34 #include "ServiceUtilities.h"
     35 #include <hardware_legacy/power.h>
     36 #include <media/AudioEffect.h>
     37 #include <media/EffectsFactoryApi.h>
     38 
     39 #include <hardware/hardware.h>
     40 #include <system/audio.h>
     41 #include <system/audio_policy.h>
     42 #include <hardware/audio_policy.h>
     43 
     44 namespace android {
     45 
     46 static const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
     47 static const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n";
     48 
     49 static const int kDumpLockRetries = 50;
     50 static const int kDumpLockSleepUs = 20000;
     51 
     52 static const nsecs_t kAudioCommandTimeoutNs = seconds(3); // 3 seconds
     53 
     54 namespace {
     55     extern struct audio_policy_service_ops aps_ops;
     56 };
     57 
     58 // ----------------------------------------------------------------------------
     59 
     60 AudioPolicyService::AudioPolicyService()
     61     : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
     62       mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
     63 {
     64 }
     65 
     66 void AudioPolicyService::onFirstRef()
     67 {
     68     char value[PROPERTY_VALUE_MAX];
     69     const struct hw_module_t *module;
     70     int forced_val;
     71     int rc;
     72 
     73     {
     74         Mutex::Autolock _l(mLock);
     75 
     76         // start tone playback thread
     77         mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
     78         // start audio commands thread
     79         mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
     80         // start output activity command thread
     81         mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
     82 
     83 #ifdef USE_LEGACY_AUDIO_POLICY
     84         ALOGI("AudioPolicyService CSTOR in legacy mode");
     85 
     86         /* instantiate the audio policy manager */
     87         rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
     88         if (rc) {
     89             return;
     90         }
     91         rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
     92         ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
     93         if (rc) {
     94             return;
     95         }
     96 
     97         rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
     98                                                    &mpAudioPolicy);
     99         ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));
    100         if (rc) {
    101             return;
    102         }
    103 
    104         rc = mpAudioPolicy->init_check(mpAudioPolicy);
    105         ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));
    106         if (rc) {
    107             return;
    108         }
    109         ALOGI("Loaded audio policy from %s (%s)", module->name, module->id);
    110 #else
    111         ALOGI("AudioPolicyService CSTOR in new mode");
    112 
    113         mAudioPolicyClient = new AudioPolicyClient(this);
    114         mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
    115 #endif
    116     }
    117     // load audio processing modules
    118     sp<AudioPolicyEffects>audioPolicyEffects = new AudioPolicyEffects();
    119     {
    120         Mutex::Autolock _l(mLock);
    121         mAudioPolicyEffects = audioPolicyEffects;
    122     }
    123 }
    124 
    125 AudioPolicyService::~AudioPolicyService()
    126 {
    127     mTonePlaybackThread->exit();
    128     mAudioCommandThread->exit();
    129     mOutputCommandThread->exit();
    130 
    131 #ifdef USE_LEGACY_AUDIO_POLICY
    132     if (mpAudioPolicy != NULL && mpAudioPolicyDev != NULL) {
    133         mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy);
    134     }
    135     if (mpAudioPolicyDev != NULL) {
    136         audio_policy_dev_close(mpAudioPolicyDev);
    137     }
    138 #else
    139     destroyAudioPolicyManager(mAudioPolicyManager);
    140     delete mAudioPolicyClient;
    141 #endif
    142 
    143     mNotificationClients.clear();
    144     mAudioPolicyEffects.clear();
    145 }
    146 
    147 // A notification client is always registered by AudioSystem when the client process
    148 // connects to AudioPolicyService.
    149 void AudioPolicyService::registerClient(const sp<IAudioPolicyServiceClient>& client)
    150 {
    151 
    152     Mutex::Autolock _l(mNotificationClientsLock);
    153 
    154     uid_t uid = IPCThreadState::self()->getCallingUid();
    155     if (mNotificationClients.indexOfKey(uid) < 0) {
    156         sp<NotificationClient> notificationClient = new NotificationClient(this,
    157                                                                            client,
    158                                                                            uid);
    159         ALOGV("registerClient() client %p, uid %d", client.get(), uid);
    160 
    161         mNotificationClients.add(uid, notificationClient);
    162 
    163         sp<IBinder> binder = client->asBinder();
    164         binder->linkToDeath(notificationClient);
    165     }
    166 }
    167 
    168 // removeNotificationClient() is called when the client process dies.
    169 void AudioPolicyService::removeNotificationClient(uid_t uid)
    170 {
    171     {
    172         Mutex::Autolock _l(mNotificationClientsLock);
    173         mNotificationClients.removeItem(uid);
    174     }
    175 #ifndef USE_LEGACY_AUDIO_POLICY
    176     {
    177         Mutex::Autolock _l(mLock);
    178         if (mAudioPolicyManager) {
    179             mAudioPolicyManager->clearAudioPatches(uid);
    180         }
    181     }
    182 #endif
    183 }
    184 
    185 void AudioPolicyService::onAudioPortListUpdate()
    186 {
    187     mOutputCommandThread->updateAudioPortListCommand();
    188 }
    189 
    190 void AudioPolicyService::doOnAudioPortListUpdate()
    191 {
    192     Mutex::Autolock _l(mNotificationClientsLock);
    193     for (size_t i = 0; i < mNotificationClients.size(); i++) {
    194         mNotificationClients.valueAt(i)->onAudioPortListUpdate();
    195     }
    196 }
    197 
    198 void AudioPolicyService::onAudioPatchListUpdate()
    199 {
    200     mOutputCommandThread->updateAudioPatchListCommand();
    201 }
    202 
    203 status_t AudioPolicyService::clientCreateAudioPatch(const struct audio_patch *patch,
    204                                                 audio_patch_handle_t *handle,
    205                                                 int delayMs)
    206 {
    207     return mAudioCommandThread->createAudioPatchCommand(patch, handle, delayMs);
    208 }
    209 
    210 status_t AudioPolicyService::clientReleaseAudioPatch(audio_patch_handle_t handle,
    211                                                  int delayMs)
    212 {
    213     return mAudioCommandThread->releaseAudioPatchCommand(handle, delayMs);
    214 }
    215 
    216 void AudioPolicyService::doOnAudioPatchListUpdate()
    217 {
    218     Mutex::Autolock _l(mNotificationClientsLock);
    219     for (size_t i = 0; i < mNotificationClients.size(); i++) {
    220         mNotificationClients.valueAt(i)->onAudioPatchListUpdate();
    221     }
    222 }
    223 
    224 status_t AudioPolicyService::clientSetAudioPortConfig(const struct audio_port_config *config,
    225                                                       int delayMs)
    226 {
    227     return mAudioCommandThread->setAudioPortConfigCommand(config, delayMs);
    228 }
    229 
    230 AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
    231                                                      const sp<IAudioPolicyServiceClient>& client,
    232                                                      uid_t uid)
    233     : mService(service), mUid(uid), mAudioPolicyServiceClient(client)
    234 {
    235 }
    236 
    237 AudioPolicyService::NotificationClient::~NotificationClient()
    238 {
    239 }
    240 
    241 void AudioPolicyService::NotificationClient::binderDied(const wp<IBinder>& who __unused)
    242 {
    243     sp<NotificationClient> keep(this);
    244     sp<AudioPolicyService> service = mService.promote();
    245     if (service != 0) {
    246         service->removeNotificationClient(mUid);
    247     }
    248 }
    249 
    250 void AudioPolicyService::NotificationClient::onAudioPortListUpdate()
    251 {
    252     if (mAudioPolicyServiceClient != 0) {
    253         mAudioPolicyServiceClient->onAudioPortListUpdate();
    254     }
    255 }
    256 
    257 void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
    258 {
    259     if (mAudioPolicyServiceClient != 0) {
    260         mAudioPolicyServiceClient->onAudioPatchListUpdate();
    261     }
    262 }
    263 
    264 void AudioPolicyService::binderDied(const wp<IBinder>& who) {
    265     ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
    266             IPCThreadState::self()->getCallingPid());
    267 }
    268 
    269 static bool tryLock(Mutex& mutex)
    270 {
    271     bool locked = false;
    272     for (int i = 0; i < kDumpLockRetries; ++i) {
    273         if (mutex.tryLock() == NO_ERROR) {
    274             locked = true;
    275             break;
    276         }
    277         usleep(kDumpLockSleepUs);
    278     }
    279     return locked;
    280 }
    281 
    282 status_t AudioPolicyService::dumpInternals(int fd)
    283 {
    284     const size_t SIZE = 256;
    285     char buffer[SIZE];
    286     String8 result;
    287 
    288 #ifdef USE_LEGACY_AUDIO_POLICY
    289     snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy);
    290 #else
    291     snprintf(buffer, SIZE, "AudioPolicyManager: %p\n", mAudioPolicyManager);
    292 #endif
    293     result.append(buffer);
    294     snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
    295     result.append(buffer);
    296     snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
    297     result.append(buffer);
    298 
    299     write(fd, result.string(), result.size());
    300     return NO_ERROR;
    301 }
    302 
    303 status_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused)
    304 {
    305     if (!dumpAllowed()) {
    306         dumpPermissionDenial(fd);
    307     } else {
    308         bool locked = tryLock(mLock);
    309         if (!locked) {
    310             String8 result(kDeadlockedString);
    311             write(fd, result.string(), result.size());
    312         }
    313 
    314         dumpInternals(fd);
    315         if (mAudioCommandThread != 0) {
    316             mAudioCommandThread->dump(fd);
    317         }
    318         if (mTonePlaybackThread != 0) {
    319             mTonePlaybackThread->dump(fd);
    320         }
    321 
    322 #ifdef USE_LEGACY_AUDIO_POLICY
    323         if (mpAudioPolicy) {
    324             mpAudioPolicy->dump(mpAudioPolicy, fd);
    325         }
    326 #else
    327         if (mAudioPolicyManager) {
    328             mAudioPolicyManager->dump(fd);
    329         }
    330 #endif
    331 
    332         if (locked) mLock.unlock();
    333     }
    334     return NO_ERROR;
    335 }
    336 
    337 status_t AudioPolicyService::dumpPermissionDenial(int fd)
    338 {
    339     const size_t SIZE = 256;
    340     char buffer[SIZE];
    341     String8 result;
    342     snprintf(buffer, SIZE, "Permission Denial: "
    343             "can't dump AudioPolicyService from pid=%d, uid=%d\n",
    344             IPCThreadState::self()->getCallingPid(),
    345             IPCThreadState::self()->getCallingUid());
    346     result.append(buffer);
    347     write(fd, result.string(), result.size());
    348     return NO_ERROR;
    349 }
    350 
    351 status_t AudioPolicyService::onTransact(
    352         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    353 {
    354     return BnAudioPolicyService::onTransact(code, data, reply, flags);
    355 }
    356 
    357 
    358 // -----------  AudioPolicyService::AudioCommandThread implementation ----------
    359 
    360 AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
    361                                                            const wp<AudioPolicyService>& service)
    362     : Thread(false), mName(name), mService(service)
    363 {
    364     mpToneGenerator = NULL;
    365 }
    366 
    367 
    368 AudioPolicyService::AudioCommandThread::~AudioCommandThread()
    369 {
    370     if (!mAudioCommands.isEmpty()) {
    371         release_wake_lock(mName.string());
    372     }
    373     mAudioCommands.clear();
    374     delete mpToneGenerator;
    375 }
    376 
    377 void AudioPolicyService::AudioCommandThread::onFirstRef()
    378 {
    379     run(mName.string(), ANDROID_PRIORITY_AUDIO);
    380 }
    381 
    382 bool AudioPolicyService::AudioCommandThread::threadLoop()
    383 {
    384     nsecs_t waitTime = INT64_MAX;
    385 
    386     mLock.lock();
    387     while (!exitPending())
    388     {
    389         sp<AudioPolicyService> svc;
    390         while (!mAudioCommands.isEmpty() && !exitPending()) {
    391             nsecs_t curTime = systemTime();
    392             // commands are sorted by increasing time stamp: execute them from index 0 and up
    393             if (mAudioCommands[0]->mTime <= curTime) {
    394                 sp<AudioCommand> command = mAudioCommands[0];
    395                 mAudioCommands.removeAt(0);
    396                 mLastCommand = command;
    397 
    398                 switch (command->mCommand) {
    399                 case START_TONE: {
    400                     mLock.unlock();
    401                     ToneData *data = (ToneData *)command->mParam.get();
    402                     ALOGV("AudioCommandThread() processing start tone %d on stream %d",
    403                             data->mType, data->mStream);
    404                     delete mpToneGenerator;
    405                     mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
    406                     mpToneGenerator->startTone(data->mType);
    407                     mLock.lock();
    408                     }break;
    409                 case STOP_TONE: {
    410                     mLock.unlock();
    411                     ALOGV("AudioCommandThread() processing stop tone");
    412                     if (mpToneGenerator != NULL) {
    413                         mpToneGenerator->stopTone();
    414                         delete mpToneGenerator;
    415                         mpToneGenerator = NULL;
    416                     }
    417                     mLock.lock();
    418                     }break;
    419                 case SET_VOLUME: {
    420                     VolumeData *data = (VolumeData *)command->mParam.get();
    421                     ALOGV("AudioCommandThread() processing set volume stream %d, \
    422                             volume %f, output %d", data->mStream, data->mVolume, data->mIO);
    423                     command->mStatus = AudioSystem::setStreamVolume(data->mStream,
    424                                                                     data->mVolume,
    425                                                                     data->mIO);
    426                     }break;
    427                 case SET_PARAMETERS: {
    428                     ParametersData *data = (ParametersData *)command->mParam.get();
    429                     ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
    430                             data->mKeyValuePairs.string(), data->mIO);
    431                     command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
    432                     }break;
    433                 case SET_VOICE_VOLUME: {
    434                     VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
    435                     ALOGV("AudioCommandThread() processing set voice volume volume %f",
    436                             data->mVolume);
    437                     command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
    438                     }break;
    439                 case STOP_OUTPUT: {
    440                     StopOutputData *data = (StopOutputData *)command->mParam.get();
    441                     ALOGV("AudioCommandThread() processing stop output %d",
    442                             data->mIO);
    443                     svc = mService.promote();
    444                     if (svc == 0) {
    445                         break;
    446                     }
    447                     mLock.unlock();
    448                     svc->doStopOutput(data->mIO, data->mStream, data->mSession);
    449                     mLock.lock();
    450                     }break;
    451                 case RELEASE_OUTPUT: {
    452                     ReleaseOutputData *data = (ReleaseOutputData *)command->mParam.get();
    453                     ALOGV("AudioCommandThread() processing release output %d",
    454                             data->mIO);
    455                     svc = mService.promote();
    456                     if (svc == 0) {
    457                         break;
    458                     }
    459                     mLock.unlock();
    460                     svc->doReleaseOutput(data->mIO, data->mStream, data->mSession);
    461                     mLock.lock();
    462                     }break;
    463                 case CREATE_AUDIO_PATCH: {
    464                     CreateAudioPatchData *data = (CreateAudioPatchData *)command->mParam.get();
    465                     ALOGV("AudioCommandThread() processing create audio patch");
    466                     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    467                     if (af == 0) {
    468                         command->mStatus = PERMISSION_DENIED;
    469                     } else {
    470                         command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle);
    471                     }
    472                     } break;
    473                 case RELEASE_AUDIO_PATCH: {
    474                     ReleaseAudioPatchData *data = (ReleaseAudioPatchData *)command->mParam.get();
    475                     ALOGV("AudioCommandThread() processing release audio patch");
    476                     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    477                     if (af == 0) {
    478                         command->mStatus = PERMISSION_DENIED;
    479                     } else {
    480                         command->mStatus = af->releaseAudioPatch(data->mHandle);
    481                     }
    482                     } break;
    483                 case UPDATE_AUDIOPORT_LIST: {
    484                     ALOGV("AudioCommandThread() processing update audio port list");
    485                     svc = mService.promote();
    486                     if (svc == 0) {
    487                         break;
    488                     }
    489                     mLock.unlock();
    490                     svc->doOnAudioPortListUpdate();
    491                     mLock.lock();
    492                     }break;
    493                 case UPDATE_AUDIOPATCH_LIST: {
    494                     ALOGV("AudioCommandThread() processing update audio patch list");
    495                     svc = mService.promote();
    496                     if (svc == 0) {
    497                         break;
    498                     }
    499                     mLock.unlock();
    500                     svc->doOnAudioPatchListUpdate();
    501                     mLock.lock();
    502                     }break;
    503                 case SET_AUDIOPORT_CONFIG: {
    504                     SetAudioPortConfigData *data = (SetAudioPortConfigData *)command->mParam.get();
    505                     ALOGV("AudioCommandThread() processing set port config");
    506                     sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
    507                     if (af == 0) {
    508                         command->mStatus = PERMISSION_DENIED;
    509                     } else {
    510                         command->mStatus = af->setAudioPortConfig(&data->mConfig);
    511                     }
    512                     } break;
    513                 default:
    514                     ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
    515                 }
    516                 {
    517                     Mutex::Autolock _l(command->mLock);
    518                     if (command->mWaitStatus) {
    519                         command->mWaitStatus = false;
    520                         command->mCond.signal();
    521                     }
    522                 }
    523                 waitTime = INT64_MAX;
    524             } else {
    525                 waitTime = mAudioCommands[0]->mTime - curTime;
    526                 break;
    527             }
    528         }
    529         // release mLock before releasing strong reference on the service as
    530         // AudioPolicyService destructor calls AudioCommandThread::exit() which acquires mLock.
    531         mLock.unlock();
    532         svc.clear();
    533         mLock.lock();
    534         if (!exitPending() && mAudioCommands.isEmpty()) {
    535             // release delayed commands wake lock
    536             release_wake_lock(mName.string());
    537             ALOGV("AudioCommandThread() going to sleep");
    538             mWaitWorkCV.waitRelative(mLock, waitTime);
    539             ALOGV("AudioCommandThread() waking up");
    540         }
    541     }
    542     // release delayed commands wake lock before quitting
    543     if (!mAudioCommands.isEmpty()) {
    544         release_wake_lock(mName.string());
    545     }
    546     mLock.unlock();
    547     return false;
    548 }
    549 
    550 status_t AudioPolicyService::AudioCommandThread::dump(int fd)
    551 {
    552     const size_t SIZE = 256;
    553     char buffer[SIZE];
    554     String8 result;
    555 
    556     snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
    557     result.append(buffer);
    558     write(fd, result.string(), result.size());
    559 
    560     bool locked = tryLock(mLock);
    561     if (!locked) {
    562         String8 result2(kCmdDeadlockedString);
    563         write(fd, result2.string(), result2.size());
    564     }
    565 
    566     snprintf(buffer, SIZE, "- Commands:\n");
    567     result = String8(buffer);
    568     result.append("   Command Time        Wait pParam\n");
    569     for (size_t i = 0; i < mAudioCommands.size(); i++) {
    570         mAudioCommands[i]->dump(buffer, SIZE);
    571         result.append(buffer);
    572     }
    573     result.append("  Last Command\n");
    574     if (mLastCommand != 0) {
    575         mLastCommand->dump(buffer, SIZE);
    576         result.append(buffer);
    577     } else {
    578         result.append("     none\n");
    579     }
    580 
    581     write(fd, result.string(), result.size());
    582 
    583     if (locked) mLock.unlock();
    584 
    585     return NO_ERROR;
    586 }
    587 
    588 void AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type,
    589         audio_stream_type_t stream)
    590 {
    591     sp<AudioCommand> command = new AudioCommand();
    592     command->mCommand = START_TONE;
    593     sp<ToneData> data = new ToneData();
    594     data->mType = type;
    595     data->mStream = stream;
    596     command->mParam = data;
    597     ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
    598     sendCommand(command);
    599 }
    600 
    601 void AudioPolicyService::AudioCommandThread::stopToneCommand()
    602 {
    603     sp<AudioCommand> command = new AudioCommand();
    604     command->mCommand = STOP_TONE;
    605     ALOGV("AudioCommandThread() adding tone stop");
    606     sendCommand(command);
    607 }
    608 
    609 status_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
    610                                                                float volume,
    611                                                                audio_io_handle_t output,
    612                                                                int delayMs)
    613 {
    614     sp<AudioCommand> command = new AudioCommand();
    615     command->mCommand = SET_VOLUME;
    616     sp<VolumeData> data = new VolumeData();
    617     data->mStream = stream;
    618     data->mVolume = volume;
    619     data->mIO = output;
    620     command->mParam = data;
    621     command->mWaitStatus = true;
    622     ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
    623             stream, volume, output);
    624     return sendCommand(command, delayMs);
    625 }
    626 
    627 status_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle,
    628                                                                    const char *keyValuePairs,
    629                                                                    int delayMs)
    630 {
    631     sp<AudioCommand> command = new AudioCommand();
    632     command->mCommand = SET_PARAMETERS;
    633     sp<ParametersData> data = new ParametersData();
    634     data->mIO = ioHandle;
    635     data->mKeyValuePairs = String8(keyValuePairs);
    636     command->mParam = data;
    637     command->mWaitStatus = true;
    638     ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
    639             keyValuePairs, ioHandle, delayMs);
    640     return sendCommand(command, delayMs);
    641 }
    642 
    643 status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
    644 {
    645     sp<AudioCommand> command = new AudioCommand();
    646     command->mCommand = SET_VOICE_VOLUME;
    647     sp<VoiceVolumeData> data = new VoiceVolumeData();
    648     data->mVolume = volume;
    649     command->mParam = data;
    650     command->mWaitStatus = true;
    651     ALOGV("AudioCommandThread() adding set voice volume volume %f", volume);
    652     return sendCommand(command, delayMs);
    653 }
    654 
    655 void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output,
    656                                                                audio_stream_type_t stream,
    657                                                                audio_session_t session)
    658 {
    659     sp<AudioCommand> command = new AudioCommand();
    660     command->mCommand = STOP_OUTPUT;
    661     sp<StopOutputData> data = new StopOutputData();
    662     data->mIO = output;
    663     data->mStream = stream;
    664     data->mSession = session;
    665     command->mParam = data;
    666     ALOGV("AudioCommandThread() adding stop output %d", output);
    667     sendCommand(command);
    668 }
    669 
    670 void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output,
    671                                                                   audio_stream_type_t stream,
    672                                                                   audio_session_t session)
    673 {
    674     sp<AudioCommand> command = new AudioCommand();
    675     command->mCommand = RELEASE_OUTPUT;
    676     sp<ReleaseOutputData> data = new ReleaseOutputData();
    677     data->mIO = output;
    678     data->mStream = stream;
    679     data->mSession = session;
    680     command->mParam = data;
    681     ALOGV("AudioCommandThread() adding release output %d", output);
    682     sendCommand(command);
    683 }
    684 
    685 status_t AudioPolicyService::AudioCommandThread::createAudioPatchCommand(
    686                                                 const struct audio_patch *patch,
    687                                                 audio_patch_handle_t *handle,
    688                                                 int delayMs)
    689 {
    690     status_t status = NO_ERROR;
    691 
    692     sp<AudioCommand> command = new AudioCommand();
    693     command->mCommand = CREATE_AUDIO_PATCH;
    694     CreateAudioPatchData *data = new CreateAudioPatchData();
    695     data->mPatch = *patch;
    696     data->mHandle = *handle;
    697     command->mParam = data;
    698     command->mWaitStatus = true;
    699     ALOGV("AudioCommandThread() adding create patch delay %d", delayMs);
    700     status = sendCommand(command, delayMs);
    701     if (status == NO_ERROR) {
    702         *handle = data->mHandle;
    703     }
    704     return status;
    705 }
    706 
    707 status_t AudioPolicyService::AudioCommandThread::releaseAudioPatchCommand(audio_patch_handle_t handle,
    708                                                  int delayMs)
    709 {
    710     sp<AudioCommand> command = new AudioCommand();
    711     command->mCommand = RELEASE_AUDIO_PATCH;
    712     ReleaseAudioPatchData *data = new ReleaseAudioPatchData();
    713     data->mHandle = handle;
    714     command->mParam = data;
    715     command->mWaitStatus = true;
    716     ALOGV("AudioCommandThread() adding release patch delay %d", delayMs);
    717     return sendCommand(command, delayMs);
    718 }
    719 
    720 void AudioPolicyService::AudioCommandThread::updateAudioPortListCommand()
    721 {
    722     sp<AudioCommand> command = new AudioCommand();
    723     command->mCommand = UPDATE_AUDIOPORT_LIST;
    724     ALOGV("AudioCommandThread() adding update audio port list");
    725     sendCommand(command);
    726 }
    727 
    728 void AudioPolicyService::AudioCommandThread::updateAudioPatchListCommand()
    729 {
    730     sp<AudioCommand>command = new AudioCommand();
    731     command->mCommand = UPDATE_AUDIOPATCH_LIST;
    732     ALOGV("AudioCommandThread() adding update audio patch list");
    733     sendCommand(command);
    734 }
    735 
    736 status_t AudioPolicyService::AudioCommandThread::setAudioPortConfigCommand(
    737                                             const struct audio_port_config *config, int delayMs)
    738 {
    739     sp<AudioCommand> command = new AudioCommand();
    740     command->mCommand = SET_AUDIOPORT_CONFIG;
    741     SetAudioPortConfigData *data = new SetAudioPortConfigData();
    742     data->mConfig = *config;
    743     command->mParam = data;
    744     command->mWaitStatus = true;
    745     ALOGV("AudioCommandThread() adding set port config delay %d", delayMs);
    746     return sendCommand(command, delayMs);
    747 }
    748 
    749 status_t AudioPolicyService::AudioCommandThread::sendCommand(sp<AudioCommand>& command, int delayMs)
    750 {
    751     {
    752         Mutex::Autolock _l(mLock);
    753         insertCommand_l(command, delayMs);
    754         mWaitWorkCV.signal();
    755     }
    756     Mutex::Autolock _l(command->mLock);
    757     while (command->mWaitStatus) {
    758         nsecs_t timeOutNs = kAudioCommandTimeoutNs + milliseconds(delayMs);
    759         if (command->mCond.waitRelative(command->mLock, timeOutNs) != NO_ERROR) {
    760             command->mStatus = TIMED_OUT;
    761             command->mWaitStatus = false;
    762         }
    763     }
    764     return command->mStatus;
    765 }
    766 
    767 // insertCommand_l() must be called with mLock held
    768 void AudioPolicyService::AudioCommandThread::insertCommand_l(sp<AudioCommand>& command, int delayMs)
    769 {
    770     ssize_t i;  // not size_t because i will count down to -1
    771     Vector < sp<AudioCommand> > removedCommands;
    772     command->mTime = systemTime() + milliseconds(delayMs);
    773 
    774     // acquire wake lock to make sure delayed commands are processed
    775     if (mAudioCommands.isEmpty()) {
    776         acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
    777     }
    778 
    779     // check same pending commands with later time stamps and eliminate them
    780     for (i = mAudioCommands.size()-1; i >= 0; i--) {
    781         sp<AudioCommand> command2 = mAudioCommands[i];
    782         // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
    783         if (command2->mTime <= command->mTime) break;
    784 
    785         // create audio patch or release audio patch commands are equivalent
    786         // with regard to filtering
    787         if ((command->mCommand == CREATE_AUDIO_PATCH) ||
    788                 (command->mCommand == RELEASE_AUDIO_PATCH)) {
    789             if ((command2->mCommand != CREATE_AUDIO_PATCH) &&
    790                     (command2->mCommand != RELEASE_AUDIO_PATCH)) {
    791                 continue;
    792             }
    793         } else if (command2->mCommand != command->mCommand) continue;
    794 
    795         switch (command->mCommand) {
    796         case SET_PARAMETERS: {
    797             ParametersData *data = (ParametersData *)command->mParam.get();
    798             ParametersData *data2 = (ParametersData *)command2->mParam.get();
    799             if (data->mIO != data2->mIO) break;
    800             ALOGV("Comparing parameter command %s to new command %s",
    801                     data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
    802             AudioParameter param = AudioParameter(data->mKeyValuePairs);
    803             AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
    804             for (size_t j = 0; j < param.size(); j++) {
    805                 String8 key;
    806                 String8 value;
    807                 param.getAt(j, key, value);
    808                 for (size_t k = 0; k < param2.size(); k++) {
    809                     String8 key2;
    810                     String8 value2;
    811                     param2.getAt(k, key2, value2);
    812                     if (key2 == key) {
    813                         param2.remove(key2);
    814                         ALOGV("Filtering out parameter %s", key2.string());
    815                         break;
    816                     }
    817                 }
    818             }
    819             // if all keys have been filtered out, remove the command.
    820             // otherwise, update the key value pairs
    821             if (param2.size() == 0) {
    822                 removedCommands.add(command2);
    823             } else {
    824                 data2->mKeyValuePairs = param2.toString();
    825             }
    826             command->mTime = command2->mTime;
    827             // force delayMs to non 0 so that code below does not request to wait for
    828             // command status as the command is now delayed
    829             delayMs = 1;
    830         } break;
    831 
    832         case SET_VOLUME: {
    833             VolumeData *data = (VolumeData *)command->mParam.get();
    834             VolumeData *data2 = (VolumeData *)command2->mParam.get();
    835             if (data->mIO != data2->mIO) break;
    836             if (data->mStream != data2->mStream) break;
    837             ALOGV("Filtering out volume command on output %d for stream %d",
    838                     data->mIO, data->mStream);
    839             removedCommands.add(command2);
    840             command->mTime = command2->mTime;
    841             // force delayMs to non 0 so that code below does not request to wait for
    842             // command status as the command is now delayed
    843             delayMs = 1;
    844         } break;
    845 
    846         case CREATE_AUDIO_PATCH:
    847         case RELEASE_AUDIO_PATCH: {
    848             audio_patch_handle_t handle;
    849             struct audio_patch patch;
    850             if (command->mCommand == CREATE_AUDIO_PATCH) {
    851                 handle = ((CreateAudioPatchData *)command->mParam.get())->mHandle;
    852                 patch = ((CreateAudioPatchData *)command->mParam.get())->mPatch;
    853             } else {
    854                 handle = ((ReleaseAudioPatchData *)command->mParam.get())->mHandle;
    855             }
    856             audio_patch_handle_t handle2;
    857             struct audio_patch patch2;
    858             if (command2->mCommand == CREATE_AUDIO_PATCH) {
    859                 handle2 = ((CreateAudioPatchData *)command2->mParam.get())->mHandle;
    860                 patch2 = ((CreateAudioPatchData *)command2->mParam.get())->mPatch;
    861             } else {
    862                 handle2 = ((ReleaseAudioPatchData *)command2->mParam.get())->mHandle;
    863             }
    864             if (handle != handle2) break;
    865             /* Filter CREATE_AUDIO_PATCH commands only when they are issued for
    866                same output. */
    867             if( (command->mCommand == CREATE_AUDIO_PATCH) &&
    868                 (command2->mCommand == CREATE_AUDIO_PATCH) ) {
    869                 bool isOutputDiff = false;
    870                 if (patch.num_sources == patch2.num_sources) {
    871                     for (unsigned count = 0; count < patch.num_sources; count++) {
    872                         if (patch.sources[count].id != patch2.sources[count].id) {
    873                             isOutputDiff = true;
    874                             break;
    875                         }
    876                     }
    877                     if (isOutputDiff)
    878                        break;
    879                 }
    880             }
    881             ALOGV("Filtering out %s audio patch command for handle %d",
    882                   (command->mCommand == CREATE_AUDIO_PATCH) ? "create" : "release", handle);
    883             removedCommands.add(command2);
    884             command->mTime = command2->mTime;
    885             // force delayMs to non 0 so that code below does not request to wait for
    886             // command status as the command is now delayed
    887             delayMs = 1;
    888         } break;
    889 
    890         case START_TONE:
    891         case STOP_TONE:
    892         default:
    893             break;
    894         }
    895     }
    896 
    897     // remove filtered commands
    898     for (size_t j = 0; j < removedCommands.size(); j++) {
    899         // removed commands always have time stamps greater than current command
    900         for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
    901             if (mAudioCommands[k].get() == removedCommands[j].get()) {
    902                 ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
    903                 mAudioCommands.removeAt(k);
    904                 break;
    905             }
    906         }
    907     }
    908     removedCommands.clear();
    909 
    910     // Disable wait for status if delay is not 0.
    911     // Except for create audio patch command because the returned patch handle
    912     // is needed by audio policy manager
    913     if (delayMs != 0 && command->mCommand != CREATE_AUDIO_PATCH) {
    914         command->mWaitStatus = false;
    915     }
    916 
    917     // insert command at the right place according to its time stamp
    918     ALOGV("inserting command: %d at index %zd, num commands %zu",
    919             command->mCommand, i+1, mAudioCommands.size());
    920     mAudioCommands.insertAt(command, i + 1);
    921 }
    922 
    923 void AudioPolicyService::AudioCommandThread::exit()
    924 {
    925     ALOGV("AudioCommandThread::exit");
    926     {
    927         AutoMutex _l(mLock);
    928         requestExit();
    929         mWaitWorkCV.signal();
    930     }
    931     requestExitAndWait();
    932 }
    933 
    934 void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
    935 {
    936     snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
    937             mCommand,
    938             (int)ns2s(mTime),
    939             (int)ns2ms(mTime)%1000,
    940             mWaitStatus,
    941             mParam.get());
    942 }
    943 
    944 /******* helpers for the service_ops callbacks defined below *********/
    945 void AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
    946                                        const char *keyValuePairs,
    947                                        int delayMs)
    948 {
    949     mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
    950                                            delayMs);
    951 }
    952 
    953 int AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
    954                                         float volume,
    955                                         audio_io_handle_t output,
    956                                         int delayMs)
    957 {
    958     return (int)mAudioCommandThread->volumeCommand(stream, volume,
    959                                                    output, delayMs);
    960 }
    961 
    962 int AudioPolicyService::startTone(audio_policy_tone_t tone,
    963                                   audio_stream_type_t stream)
    964 {
    965     if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) {
    966         ALOGE("startTone: illegal tone requested (%d)", tone);
    967     }
    968     if (stream != AUDIO_STREAM_VOICE_CALL) {
    969         ALOGE("startTone: illegal stream (%d) requested for tone %d", stream,
    970             tone);
    971     }
    972     mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING,
    973                                           AUDIO_STREAM_VOICE_CALL);
    974     return 0;
    975 }
    976 
    977 int AudioPolicyService::stopTone()
    978 {
    979     mTonePlaybackThread->stopToneCommand();
    980     return 0;
    981 }
    982 
    983 int AudioPolicyService::setVoiceVolume(float volume, int delayMs)
    984 {
    985     return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
    986 }
    987 
    988 extern "C" {
    989 audio_module_handle_t aps_load_hw_module(void *service __unused,
    990                                              const char *name);
    991 audio_io_handle_t aps_open_output(void *service __unused,
    992                                          audio_devices_t *pDevices,
    993                                          uint32_t *pSamplingRate,
    994                                          audio_format_t *pFormat,
    995                                          audio_channel_mask_t *pChannelMask,
    996                                          uint32_t *pLatencyMs,
    997                                          audio_output_flags_t flags);
    998 
    999 audio_io_handle_t aps_open_output_on_module(void *service __unused,
   1000                                                    audio_module_handle_t module,
   1001                                                    audio_devices_t *pDevices,
   1002                                                    uint32_t *pSamplingRate,
   1003                                                    audio_format_t *pFormat,
   1004                                                    audio_channel_mask_t *pChannelMask,
   1005                                                    uint32_t *pLatencyMs,
   1006                                                    audio_output_flags_t flags,
   1007                                                    const audio_offload_info_t *offloadInfo);
   1008 audio_io_handle_t aps_open_dup_output(void *service __unused,
   1009                                                  audio_io_handle_t output1,
   1010                                                  audio_io_handle_t output2);
   1011 int aps_close_output(void *service __unused, audio_io_handle_t output);
   1012 int aps_suspend_output(void *service __unused, audio_io_handle_t output);
   1013 int aps_restore_output(void *service __unused, audio_io_handle_t output);
   1014 audio_io_handle_t aps_open_input(void *service __unused,
   1015                                         audio_devices_t *pDevices,
   1016                                         uint32_t *pSamplingRate,
   1017                                         audio_format_t *pFormat,
   1018                                         audio_channel_mask_t *pChannelMask,
   1019                                         audio_in_acoustics_t acoustics __unused);
   1020 audio_io_handle_t aps_open_input_on_module(void *service __unused,
   1021                                                   audio_module_handle_t module,
   1022                                                   audio_devices_t *pDevices,
   1023                                                   uint32_t *pSamplingRate,
   1024                                                   audio_format_t *pFormat,
   1025                                                   audio_channel_mask_t *pChannelMask);
   1026 int aps_close_input(void *service __unused, audio_io_handle_t input);
   1027 int aps_invalidate_stream(void *service __unused, audio_stream_type_t stream);
   1028 int aps_move_effects(void *service __unused, int session,
   1029                                 audio_io_handle_t src_output,
   1030                                 audio_io_handle_t dst_output);
   1031 char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
   1032                                      const char *keys);
   1033 void aps_set_parameters(void *service, audio_io_handle_t io_handle,
   1034                                    const char *kv_pairs, int delay_ms);
   1035 int aps_set_stream_volume(void *service, audio_stream_type_t stream,
   1036                                      float volume, audio_io_handle_t output,
   1037                                      int delay_ms);
   1038 int aps_start_tone(void *service, audio_policy_tone_t tone,
   1039                               audio_stream_type_t stream);
   1040 int aps_stop_tone(void *service);
   1041 int aps_set_voice_volume(void *service, float volume, int delay_ms);
   1042 };
   1043 
   1044 namespace {
   1045     struct audio_policy_service_ops aps_ops = {
   1046         .open_output           = aps_open_output,
   1047         .open_duplicate_output = aps_open_dup_output,
   1048         .close_output          = aps_close_output,
   1049         .suspend_output        = aps_suspend_output,
   1050         .restore_output        = aps_restore_output,
   1051         .open_input            = aps_open_input,
   1052         .close_input           = aps_close_input,
   1053         .set_stream_volume     = aps_set_stream_volume,
   1054         .invalidate_stream     = aps_invalidate_stream,
   1055         .set_parameters        = aps_set_parameters,
   1056         .get_parameters        = aps_get_parameters,
   1057         .start_tone            = aps_start_tone,
   1058         .stop_tone             = aps_stop_tone,
   1059         .set_voice_volume      = aps_set_voice_volume,
   1060         .move_effects          = aps_move_effects,
   1061         .load_hw_module        = aps_load_hw_module,
   1062         .open_output_on_module = aps_open_output_on_module,
   1063         .open_input_on_module  = aps_open_input_on_module,
   1064     };
   1065 }; // namespace <unnamed>
   1066 
   1067 }; // namespace android
   1068