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