AudioPolicyService.cpp revision 0f7f4ece1b6b73caf608d533d833a8cdc11c8131
1a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent/*
2a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * Copyright (C) 2009 The Android Open Source Project
3a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent *
4a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * you may not use this file except in compliance with the License.
6a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * You may obtain a copy of the License at
7a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent *
8a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent *
10a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * Unless required by applicable law or agreed to in writing, software
11a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * See the License for the specific language governing permissions and
14a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * limitations under the License.
15a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent */
16a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
17a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#define LOG_TAG "AudioPolicyService"
18a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent//#define LOG_NDEBUG 0
19327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
20327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent#undef __STRICT_ANSI__
21327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent#define __STDINT_LIMITS
22327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent#define __STDC_LIMIT_MACROS
23327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent#include <stdint.h>
24327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
25327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent#include <sys/time.h>
26a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <binder/IServiceManager.h>
27a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <utils/Log.h>
28a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <cutils/properties.h>
29a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <binder/IPCThreadState.h>
30a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <utils/String16.h>
31a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <utils/threads.h>
32a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include "AudioPolicyService.h"
33a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <cutils/properties.h>
34a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <dlfcn.h>
35cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent#include <hardware_legacy/power.h>
36464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent#include <media/AudioEffect.h>
37464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent#include <media/EffectsFactoryApi.h>
38a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
3924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin#include <hardware/hardware.h>
4034bb419e5946ab28112e9e27a4d1b3928d31e0e2Dima Zavin#include <system/audio.h>
41290029d19a9d314e925b73e19453ab0497602f80Dima Zavin#include <system/audio_policy.h>
4224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin#include <hardware/audio_policy.h>
43464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent#include <audio_effects/audio_effects_conf.h>
4424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
45a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentnamespace android {
46a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
47cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurentstatic const char *kDeadlockedString = "AudioPolicyService may be deadlocked\n";
48cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurentstatic const char *kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n";
49f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
50f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatic const int kDumpLockRetries = 50;
51f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatic const int kDumpLockSleep = 20000;
52f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
53a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatic bool checkPermission() {
54a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
55a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
56a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
57a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return ok;
58a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
59a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
6024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinnamespace {
6124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    extern struct audio_policy_service_ops aps_ops;
6224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin};
6324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
64a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// ----------------------------------------------------------------------------
65a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
66a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioPolicyService::AudioPolicyService()
6724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    : BnAudioPolicyService() , mpAudioPolicyDev(NULL) , mpAudioPolicy(NULL)
68a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
69a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    char value[PROPERTY_VALUE_MAX];
7024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    const struct hw_module_t *module;
7124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    int forced_val;
7224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    int rc;
73a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
7401635943012f82ed714f00ee357003519f3de45dEric Laurent    Mutex::Autolock _l(mLock);
7501635943012f82ed714f00ee357003519f3de45dEric Laurent
764192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent    // start tone playback thread
77cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    mTonePlaybackThread = new AudioCommandThread(String8(""));
784192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent    // start audio commands thread
79cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread"));
804192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent
8124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    /* instantiate the audio policy manager */
8224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
8324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (rc)
8424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return;
85a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
8624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
8724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    LOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
8824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (rc)
8924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return;
9001635943012f82ed714f00ee357003519f3de45dEric Laurent
9124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
9224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                               &mpAudioPolicy);
9324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    LOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));
9424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (rc)
9524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return;
9624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
9724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    rc = mpAudioPolicy->init_check(mpAudioPolicy);
9824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    LOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));
9924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (rc)
10024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return;
10124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
10224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    property_get("ro.camera.sound.forced", value, "0");
10324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    forced_val = strtol(value, NULL, 0);
10424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->set_can_mute_enforced_audible(mpAudioPolicy, !forced_val);
10524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
10624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    LOGI("Loaded audio policy from %s (%s)", module->name, module->id);
107464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
108464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    // load audio pre processing modules
109464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
110464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
111464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
112464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
113464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
114a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
115a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
116a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioPolicyService::~AudioPolicyService()
117a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
118327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mTonePlaybackThread->exit();
119327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mTonePlaybackThread.clear();
120a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mAudioCommandThread->exit();
121a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mAudioCommandThread.clear();
122a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
123464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
124464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    // release audio pre processing resources
125464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    for (size_t i = 0; i < mInputSources.size(); i++) {
126464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        InputSourceDesc *source = mInputSources.valueAt(i);
127464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        Vector <EffectDesc *> effects = source->mEffects;
128464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        for (size_t j = 0; j < effects.size(); j++) {
129464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            delete effects[j]->mName;
130464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            Vector <effect_param_t *> params = effects[j]->mParams;
131464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            for (size_t k = 0; k < params.size(); k++) {
132464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                delete params[k];
133464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            }
134464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            params.clear();
135464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            delete effects[j];
136464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
137464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        effects.clear();
138464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        delete source;
139464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
140464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    mInputSources.clear();
141464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
142464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
143464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        mInputs.valueAt(i)->mEffects.clear();
144464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        delete mInputs.valueAt(i);
145464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
146464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    mInputs.clear();
147464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
14824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy && mpAudioPolicyDev)
14924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy);
15024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicyDev)
15124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        audio_policy_dev_close(mpAudioPolicyDev);
152a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
153a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
15424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatus_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
15524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                  audio_policy_dev_state_t state,
156a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                                  const char *device_address)
157a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
15824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
159a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
160a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
161a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
162a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
163a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
16424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (!audio_is_output_device(device) && !audio_is_input_device(device)) {
165a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
166a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
16724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE &&
16824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin            state != AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
169a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
170a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
171a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
172a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setDeviceConnectionState() tid %d", gettid());
173a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
17424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->set_device_connection_state(mpAudioPolicy, device,
17524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                      state, device_address);
176a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
177a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
17824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinaudio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
17924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                              audio_devices_t device,
1808ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                              const char *device_address)
181a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
18224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
18324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
184a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
185a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
18624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
187a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
18824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_device_connection_state(mpAudioPolicy, device,
18924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                      device_address);
190a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
191a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
192a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setPhoneState(int state)
193a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
19424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
195a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
196a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
197a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
198a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
199a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
20024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (state < 0 || state >= AUDIO_MODE_CNT) {
201a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
202a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
203a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
204a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setPhoneState() tid %d", gettid());
205a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
206a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    // TODO: check if it is more appropriate to do it in platform specific policy manager
207a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioSystem::setMode(state);
208a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
209a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
21024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->set_phone_state(mpAudioPolicy, state);
211a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
212a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
213a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
214a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setRingerMode(uint32_t mode, uint32_t mask)
215a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
21624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
217a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
218a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
219a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
220a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
221a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
222a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
22324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->set_ringer_mode(mpAudioPolicy, mode, mask);
224a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
225a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
226a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
22724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatus_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage,
22824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                         audio_policy_forced_cfg_t config)
229a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
23024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
231a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
232a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
233a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
234a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
235a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
23624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
237a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
238a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
23924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (config < 0 || config >= AUDIO_POLICY_FORCE_CFG_CNT) {
240a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
241a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
242a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setForceUse() tid %d", gettid());
243a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
24424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->set_force_use(mpAudioPolicy, usage, config);
245a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
246a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
247a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
24824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinaudio_policy_forced_cfg_t AudioPolicyService::getForceUse(audio_policy_force_use_t usage)
249a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
25024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
25124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return AUDIO_POLICY_FORCE_NONE;
252a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
253a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
25424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return AUDIO_POLICY_FORCE_NONE;
255a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
25624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
25724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return AUDIO_POLICY_FORCE_NONE;
258a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
25924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_force_use(mpAudioPolicy, usage);
260a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
261a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
26224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinaudio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
263a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t samplingRate,
264a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t format,
265a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t channels,
26624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                    audio_policy_output_flags_t flags)
267a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
26824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
269ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
270a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
271a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("getOutput() tid %d", gettid());
272a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
27324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate, format, channels, flags);
274a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
275a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
2768ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentstatus_t AudioPolicyService::startOutput(audio_io_handle_t output,
27724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                         audio_stream_type_t stream,
2788ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                         int session)
279a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
28024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
281a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
282a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
283a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("startOutput() tid %d", gettid());
284a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
28524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->start_output(mpAudioPolicy, output, stream, session);
286a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
287a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
2888ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentstatus_t AudioPolicyService::stopOutput(audio_io_handle_t output,
28924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                        audio_stream_type_t stream,
2908ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                        int session)
291a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
29224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
293a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
294a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
295a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("stopOutput() tid %d", gettid());
296a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
29724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->stop_output(mpAudioPolicy, output, stream, session);
298a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
299a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
300a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::releaseOutput(audio_io_handle_t output)
301a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
30224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
303a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return;
304a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
305a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("releaseOutput() tid %d", gettid());
306a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
30724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->release_output(mpAudioPolicy, output);
308a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
309a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
310a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentaudio_io_handle_t AudioPolicyService::getInput(int inputSource,
311a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t samplingRate,
312a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t format,
313a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t channels,
314464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                    audio_in_acoustics_t acoustics,
315464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                    int audioSession)
316a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
31724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
318ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
319a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
320a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
321464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
322464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                                       format, channels, acoustics);
323464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
324464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (input == 0) {
325464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return input;
326464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
327464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    // create audio pre processors according to input source
328464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    ssize_t index = mInputSources.indexOfKey((audio_source_t)inputSource);
329464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (index < 0) {
330464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return input;
331464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
332464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    ssize_t idx = mInputs.indexOfKey(input);
333464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    InputDesc *inputDesc;
334464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (idx < 0) {
335464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        inputDesc = new InputDesc();
336464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        inputDesc->mSessionId = audioSession;
337464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        mInputs.add(input, inputDesc);
338464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    } else {
339464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        inputDesc = mInputs.valueAt(idx);
340464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
341464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
342464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
343464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    for (size_t i = 0; i < effects.size(); i++) {
344464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        EffectDesc *effect = effects[i];
345464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
346464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        status_t status = fx->initCheck();
347464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (status != NO_ERROR && status != ALREADY_EXISTS) {
348464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            LOGW("Failed to create Fx %s on input %d", effect->mName, input);
349464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            // fx goes out of scope and strong ref on AudioEffect is released
350464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            continue;
351464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
352464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        for (size_t j = 0; j < effect->mParams.size(); j++) {
353464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            fx->setParameter(effect->mParams[j]);
354464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
355464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        inputDesc->mEffects.add(fx);
356464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
357464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    setPreProcessorEnabled(inputDesc, true);
358464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return input;
359a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
360a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
361a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::startInput(audio_io_handle_t input)
362a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
36324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
364a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
365a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
366a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
367464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
36824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->start_input(mpAudioPolicy, input);
369a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
370a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
371a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::stopInput(audio_io_handle_t input)
372a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
37324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
374a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
375a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
376a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
377464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
37824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->stop_input(mpAudioPolicy, input);
379a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
380a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
381a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::releaseInput(audio_io_handle_t input)
382a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
38324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
384a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return;
385a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
386a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
38724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->release_input(mpAudioPolicy, input);
388464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
389464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    ssize_t index = mInputs.indexOfKey(input);
390464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (index < 0) {
391464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return;
392464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
393464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    InputDesc *inputDesc = mInputs.valueAt(index);
394464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    setPreProcessorEnabled(inputDesc, false);
395464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    inputDesc->mEffects.clear();
396464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    delete inputDesc;
397464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    mInputs.removeItemsAt(index);
398a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
399a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
40024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatus_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
401a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                            int indexMin,
402a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                            int indexMax)
403a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
40424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
405a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
406a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
407a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
408a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
409a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
41024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
411a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
412a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
41324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->init_stream_volume(mpAudioPolicy, stream, indexMin, indexMax);
414a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
415a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
416a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
41724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatus_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream, int index)
418a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
41924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
420a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
421a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
422a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
423a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
424a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
42524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
426a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
427a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
428a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
42924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);
430a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
431a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
43224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatus_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream, int *index)
433a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
43424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
435a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
436a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
437a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
438a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
439a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
44024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
441a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
442a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
44324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_stream_volume_index(mpAudioPolicy, stream, index);
444a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
445a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
44624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinuint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
4478ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent{
44824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
4498ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent        return 0;
4508ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    }
45124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_strategy_for_stream(mpAudioPolicy, stream);
4528ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent}
4538ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent
45424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinuint32_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
4558b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten{
45624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
4578b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        return 0;
4588b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    }
45924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_devices_for_stream(mpAudioPolicy, stream);
4608b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten}
4618b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten
4628ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentaudio_io_handle_t AudioPolicyService::getOutputForEffect(effect_descriptor_t *desc)
4638ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent{
46424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
4658ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent        return NO_INIT;
4668ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    }
4678ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    Mutex::Autolock _l(mLock);
46824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_output_for_effect(mpAudioPolicy, desc);
4698ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent}
4708ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent
4718ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentstatus_t AudioPolicyService::registerEffect(effect_descriptor_t *desc,
472464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                audio_io_handle_t io,
4738ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                uint32_t strategy,
4748ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                int session,
4758ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                int id)
4768ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent{
47724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
4788ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent        return NO_INIT;
4798ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    }
480464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return mpAudioPolicy->register_effect(mpAudioPolicy, desc, io, strategy, session, id);
4818ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent}
4828ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent
4838ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentstatus_t AudioPolicyService::unregisterEffect(int id)
4848ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent{
48524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
4868ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent        return NO_INIT;
4878ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    }
48824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->unregister_effect(mpAudioPolicy, id);
4898ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent}
4908ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent
49125101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurentbool AudioPolicyService::isStreamActive(int stream, uint32_t inPastMs) const
49225101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent{
49324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
49425101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent        return 0;
49525101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent    }
49625101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent    Mutex::Autolock _l(mLock);
49724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->is_stream_active(mpAudioPolicy, stream, inPastMs);
49825101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent}
49925101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent
5000f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurentstatus_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
5010f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent                                                       effect_descriptor_t *descriptors,
5020f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent                                                       uint32_t *count)
5030f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent{
5040f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
5050f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    if (mpAudioPolicy == NULL) {
5060f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        *count = 0;
5070f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        return NO_INIT;
5080f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
5090f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    Mutex::Autolock _l(mLock);
5100f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    status_t status = NO_ERROR;
5110f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
5120f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    size_t index;
5130f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    for (index = 0; index < mInputs.size(); index++) {
5140f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        if (mInputs.valueAt(index)->mSessionId == audioSession) {
5150f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            break;
5160f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        }
5170f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
5180f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    if (index == mInputs.size()) {
5190f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        *count = 0;
5200f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        return BAD_VALUE;
5210f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
5220f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects;
5230f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
5240f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    for (size_t i = 0; i < effects.size(); i++) {
5250f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        effect_descriptor_t desc = effects[i]->descriptor();
5260f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        if (i < *count) {
5270f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            memcpy(descriptors + i, &desc, sizeof(effect_descriptor_t));
5280f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        }
5290f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
5300f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    if (effects.size() > *count) {
5310f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        status = NO_MEMORY;
5320f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
5330f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    *count = effects.size();
5340f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    return status;
5350f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent}
5360f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
537a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::binderDied(const wp<IBinder>& who) {
5388ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(),
5398ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent            IPCThreadState::self()->getCallingPid());
540a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
541a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
542f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatic bool tryLock(Mutex& mutex)
543f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
544f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    bool locked = false;
545f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    for (int i = 0; i < kDumpLockRetries; ++i) {
546f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mutex.tryLock() == NO_ERROR) {
547f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            locked = true;
548f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            break;
549f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
550f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        usleep(kDumpLockSleep);
551f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    }
552f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    return locked;
553f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
554f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
555f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatus_t AudioPolicyService::dumpInternals(int fd)
556f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
557f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    const size_t SIZE = 256;
558f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    char buffer[SIZE];
559f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    String8 result;
560f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
56124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy);
562f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
563f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
564f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
565f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
566f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
567f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
568f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    write(fd, result.string(), result.size());
569f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    return NO_ERROR;
570f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
571f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
572a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args)
573a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
574a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
575f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        dumpPermissionDenial(fd);
576a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    } else {
577f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        bool locked = tryLock(mLock);
578f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (!locked) {
579f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            String8 result(kDeadlockedString);
580f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            write(fd, result.string(), result.size());
581f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
582a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
583f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        dumpInternals(fd);
584f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mAudioCommandThread != NULL) {
585f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mAudioCommandThread->dump(fd);
586f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
587f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mTonePlaybackThread != NULL) {
588f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mTonePlaybackThread->dump(fd);
589f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
590f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
59124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        if (mpAudioPolicy) {
59224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin            mpAudioPolicy->dump(mpAudioPolicy, fd);
593f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
594f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
595f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (locked) mLock.unlock();
596a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
597a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
598a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
599a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
600f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatus_t AudioPolicyService::dumpPermissionDenial(int fd)
601a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
602a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    const size_t SIZE = 256;
603a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    char buffer[SIZE];
604a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 result;
605a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    snprintf(buffer, SIZE, "Permission Denial: "
606a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
607a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            IPCThreadState::self()->getCallingPid(),
608a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            IPCThreadState::self()->getCallingUid());
609a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    result.append(buffer);
610a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    write(fd, result.string(), result.size());
611a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
612a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
613a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
614464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentvoid AudioPolicyService::setPreProcessorEnabled(InputDesc *inputDesc, bool enabled)
615464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
616464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    Vector<sp<AudioEffect> > fxVector = inputDesc->mEffects;
617464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    for (size_t i = 0; i < fxVector.size(); i++) {
618464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        sp<AudioEffect> fx = fxVector.itemAt(i);
619464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        fx->setEnabled(enabled);
620464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
621464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
622464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
623a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::onTransact(
624a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
625a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
626a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return BnAudioPolicyService::onTransact(code, data, reply, flags);
627a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
628a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
629a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
630a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// -----------  AudioPolicyService::AudioCommandThread implementation ----------
631a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
632cef3cd79489fa7897ffbacbc4e435651fb04f10dEric LaurentAudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name)
633cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    : Thread(false), mName(name)
634a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
635a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpToneGenerator = NULL;
636a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
637a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
638a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
639a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioPolicyService::AudioCommandThread::~AudioCommandThread()
640a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
641cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    if (mName != "" && !mAudioCommands.isEmpty()) {
642cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        release_wake_lock(mName.string());
643cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    }
644a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mAudioCommands.clear();
645a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpToneGenerator != NULL) delete mpToneGenerator;
646a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
647a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
648a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::onFirstRef()
649a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
650cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    if (mName != "") {
651cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        run(mName.string(), ANDROID_PRIORITY_AUDIO);
652cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    } else {
653cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        run("AudioCommandThread", ANDROID_PRIORITY_AUDIO);
654cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    }
655a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
656a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
657a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentbool AudioPolicyService::AudioCommandThread::threadLoop()
658a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
659327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    nsecs_t waitTime = INT64_MAX;
660327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
661a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mLock.lock();
662a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    while (!exitPending())
663a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {
664a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        while(!mAudioCommands.isEmpty()) {
665327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            nsecs_t curTime = systemTime();
666327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            // commands are sorted by increasing time stamp: execute them from index 0 and up
667327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (mAudioCommands[0]->mTime <= curTime) {
668327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                AudioCommand *command = mAudioCommands[0];
669327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                mAudioCommands.removeAt(0);
6703fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent                mLastCommand = *command;
6713fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent
672327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                switch (command->mCommand) {
673327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case START_TONE: {
674327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.unlock();
675327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    ToneData *data = (ToneData *)command->mParam;
676327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGV("AudioCommandThread() processing start tone %d on stream %d",
677327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                            data->mType, data->mStream);
678327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    if (mpToneGenerator != NULL)
679327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        delete mpToneGenerator;
680327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
681327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mpToneGenerator->startTone(data->mType);
682327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    delete data;
683327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.lock();
684327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }break;
685327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case STOP_TONE: {
686327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.unlock();
687327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGV("AudioCommandThread() processing stop tone");
688327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    if (mpToneGenerator != NULL) {
689327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        mpToneGenerator->stopTone();
690327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        delete mpToneGenerator;
691327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        mpToneGenerator = NULL;
692327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }
693327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.lock();
694327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }break;
695327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case SET_VOLUME: {
696327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    VolumeData *data = (VolumeData *)command->mParam;
6978ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                    LOGV("AudioCommandThread() processing set volume stream %d, \
6988ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                            volume %f, output %d", data->mStream, data->mVolume, data->mIO);
6998ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                    command->mStatus = AudioSystem::setStreamVolume(data->mStream,
7008ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                                    data->mVolume,
7018ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                                    data->mIO);
702327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    if (command->mWaitStatus) {
703327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        command->mCond.signal();
704327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        mWaitWorkCV.wait(mLock);
705327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }
706327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    delete data;
707327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }break;
708327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case SET_PARAMETERS: {
709327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     ParametersData *data = (ParametersData *)command->mParam;
7108ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                     LOGV("AudioCommandThread() processing set parameters string %s, io %d",
7118ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                             data->mKeyValuePairs.string(), data->mIO);
712327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
713327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     if (command->mWaitStatus) {
714327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                         command->mCond.signal();
715327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                         mWaitWorkCV.wait(mLock);
716327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     }
717327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     delete data;
718327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     }break;
719415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                case SET_VOICE_VOLUME: {
720415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
7218ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                    LOGV("AudioCommandThread() processing set voice volume volume %f",
7228ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                            data->mVolume);
723415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
724415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    if (command->mWaitStatus) {
725415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                        command->mCond.signal();
726415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                        mWaitWorkCV.wait(mLock);
727415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    }
728415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    delete data;
729415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    }break;
730327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                default:
731327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGW("AudioCommandThread() unknown command %d", command->mCommand);
732a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                }
733327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                delete command;
734327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                waitTime = INT64_MAX;
735327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            } else {
736327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                waitTime = mAudioCommands[0]->mTime - curTime;
737327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                break;
738a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            }
739a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        }
740cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        // release delayed commands wake lock
741cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        if (mName != "" && mAudioCommands.isEmpty()) {
742cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent            release_wake_lock(mName.string());
743cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        }
744a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGV("AudioCommandThread() going to sleep");
745327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        mWaitWorkCV.waitRelative(mLock, waitTime);
746a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGV("AudioCommandThread() waking up");
747a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
748a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mLock.unlock();
749a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return false;
750a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
751a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
752f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::dump(int fd)
753f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
754f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    const size_t SIZE = 256;
755f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    char buffer[SIZE];
756f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    String8 result;
757f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
758f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
759f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
760f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    write(fd, result.string(), result.size());
761f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
762f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    bool locked = tryLock(mLock);
763f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    if (!locked) {
764f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        String8 result2(kCmdDeadlockedString);
765f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        write(fd, result2.string(), result2.size());
766f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    }
767f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
768f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "- Commands:\n");
769f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result = String8(buffer);
7703fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    result.append("   Command Time        Wait pParam\n");
771f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    for (int i = 0; i < (int)mAudioCommands.size(); i++) {
772f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        mAudioCommands[i]->dump(buffer, SIZE);
773f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        result.append(buffer);
774f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    }
7753fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    result.append("  Last Command\n");
7763fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    mLastCommand.dump(buffer, SIZE);
7773fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    result.append(buffer);
7783fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent
779f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    write(fd, result.string(), result.size());
780f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
781f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    if (locked) mLock.unlock();
782f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
783f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    return NO_ERROR;
784f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
785f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
786a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
787a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
788a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
789a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = START_TONE;
790a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    ToneData *data = new ToneData();
791a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mType = type;
792a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mStream = stream;
793a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = (void *)data;
794327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    command->mWaitStatus = false;
795415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
796327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command);
797a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
798a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
799a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
800a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
801a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::stopToneCommand()
802a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
803a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
804a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = STOP_TONE;
805a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = NULL;
806327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    command->mWaitStatus = false;
807415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
808327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command);
809a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("AudioCommandThread() adding tone stop");
810a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
811a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
812a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
8138ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream,
8148ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                               float volume,
8158ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                               int output,
8168ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                               int delayMs)
817a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
818327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    status_t status = NO_ERROR;
819327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
820a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
821a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = SET_VOLUME;
822a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    VolumeData *data = new VolumeData();
823a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mStream = stream;
824a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mVolume = volume;
825a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mIO = output;
826a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = data;
827327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (delayMs == 0) {
828327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = true;
829327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    } else {
830327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = false;
831327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
832415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
833327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command, delayMs);
8348ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
8358ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent            stream, volume, output);
836a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
837327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (command->mWaitStatus) {
838327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mCond.wait(mLock);
839327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        status =  command->mStatus;
840327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        mWaitWorkCV.signal();
841327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
842a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return status;
843a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
844a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
8458ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentstatus_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
84624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                                   const char *keyValuePairs,
8478ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                                   int delayMs)
848a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
849327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    status_t status = NO_ERROR;
850327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
851a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
852a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = SET_PARAMETERS;
853a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    ParametersData *data = new ParametersData();
854a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mIO = ioHandle;
85524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    data->mKeyValuePairs = String8(keyValuePairs);
856a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = data;
857327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (delayMs == 0) {
858327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = true;
859327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    } else {
860327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = false;
861327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
862415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
863327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command, delayMs);
8648ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
86524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin            keyValuePairs, ioHandle, delayMs);
866a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
867327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (command->mWaitStatus) {
868327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mCond.wait(mLock);
869327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        status =  command->mStatus;
870327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        mWaitWorkCV.signal();
871327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
872a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return status;
873a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
874a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
875415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurentstatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
876415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent{
877415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    status_t status = NO_ERROR;
878415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent
879415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    AudioCommand *command = new AudioCommand();
880415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    command->mCommand = SET_VOICE_VOLUME;
881415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    VoiceVolumeData *data = new VoiceVolumeData();
882415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    data->mVolume = volume;
883415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    command->mParam = data;
884415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    if (delayMs == 0) {
885415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        command->mWaitStatus = true;
886415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    } else {
887415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        command->mWaitStatus = false;
888415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    }
889415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
890415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    insertCommand_l(command, delayMs);
891415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    LOGV("AudioCommandThread() adding set voice volume volume %f", volume);
892415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    mWaitWorkCV.signal();
893415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    if (command->mWaitStatus) {
894415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        command->mCond.wait(mLock);
895415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        status =  command->mStatus;
896415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        mWaitWorkCV.signal();
897415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    }
898415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    return status;
899415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent}
900415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent
901327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent// insertCommand_l() must be called with mLock held
902327c27be19ad333c4835c84397152a0b2cb33081Eric Laurentvoid AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
903327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent{
904327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    ssize_t i;
905327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    Vector <AudioCommand *> removedCommands;
906327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
907327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    command->mTime = systemTime() + milliseconds(delayMs);
908327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
909cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    // acquire wake lock to make sure delayed commands are processed
910cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    if (mName != "" && mAudioCommands.isEmpty()) {
911cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
912cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    }
913cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent
914327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    // check same pending commands with later time stamps and eliminate them
915327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    for (i = mAudioCommands.size()-1; i >= 0; i--) {
916327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        AudioCommand *command2 = mAudioCommands[i];
917327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
918327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        if (command2->mTime <= command->mTime) break;
919327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        if (command2->mCommand != command->mCommand) continue;
920327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
921327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        switch (command->mCommand) {
922327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case SET_PARAMETERS: {
923327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            ParametersData *data = (ParametersData *)command->mParam;
924327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            ParametersData *data2 = (ParametersData *)command2->mParam;
925327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (data->mIO != data2->mIO) break;
9268ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent            LOGV("Comparing parameter command %s to new command %s",
9278ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                    data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
928327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            AudioParameter param = AudioParameter(data->mKeyValuePairs);
929327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
930327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            for (size_t j = 0; j < param.size(); j++) {
931327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               String8 key;
932327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               String8 value;
933327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               param.getAt(j, key, value);
934327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               for (size_t k = 0; k < param2.size(); k++) {
935327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  String8 key2;
936327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  String8 value2;
937327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  param2.getAt(k, key2, value2);
938327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  if (key2 == key) {
939327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                      param2.remove(key2);
940327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                      LOGV("Filtering out parameter %s", key2.string());
941327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                      break;
942327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  }
943327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               }
944327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            }
945327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            // if all keys have been filtered out, remove the command.
946327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            // otherwise, update the key value pairs
947327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (param2.size() == 0) {
948327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                removedCommands.add(command2);
949327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            } else {
950327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                data2->mKeyValuePairs = param2.toString();
951327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            }
952327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        } break;
953327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
954327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case SET_VOLUME: {
955327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            VolumeData *data = (VolumeData *)command->mParam;
956327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            VolumeData *data2 = (VolumeData *)command2->mParam;
957327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (data->mIO != data2->mIO) break;
958327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (data->mStream != data2->mStream) break;
9598ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent            LOGV("Filtering out volume command on output %d for stream %d",
9608ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                    data->mIO, data->mStream);
961327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            removedCommands.add(command2);
962327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        } break;
963327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case START_TONE:
964327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case STOP_TONE:
965327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        default:
966327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            break;
967327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        }
968327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
969327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
970327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    // remove filtered commands
971327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    for (size_t j = 0; j < removedCommands.size(); j++) {
972327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        // removed commands always have time stamps greater than current command
973327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
974327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (mAudioCommands[k] == removedCommands[j]) {
975327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                LOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
976327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                mAudioCommands.removeAt(k);
977327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                break;
978327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            }
979327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        }
980327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
981327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    removedCommands.clear();
982327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
983327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    // insert command at the right place according to its time stamp
9848ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    LOGV("inserting command: %d at index %d, num commands %d",
9858ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent            command->mCommand, (int)i+1, mAudioCommands.size());
986327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mAudioCommands.insertAt(command, i + 1);
987327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent}
988327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
989a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::exit()
990a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
991a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("AudioCommandThread::exit");
992a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {
993a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        AutoMutex _l(mLock);
994a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        requestExit();
995a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        mWaitWorkCV.signal();
996a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
997a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    requestExitAndWait();
998a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
999a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
1000f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentvoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
1001f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
10023fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
1003f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mCommand,
1004f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            (int)ns2s(mTime),
1005f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            (int)ns2ms(mTime)%1000,
1006f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mWaitStatus,
1007f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mParam);
1008f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
1009f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
101024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin/******* helpers for the service_ops callbacks defined below *********/
101124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
101224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                       const char *keyValuePairs,
101324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                       int delayMs)
101424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
101524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs,
101624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                           delayMs);
101724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
101824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
101924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinint AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
102024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                        float volume,
102124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                        audio_io_handle_t output,
102224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                        int delayMs)
102324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
102424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return (int)mAudioCommandThread->volumeCommand((int)stream, volume,
102524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                   (int)output, delayMs);
102624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
102724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
102824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinint AudioPolicyService::startTone(audio_policy_tone_t tone,
102924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                  audio_stream_type_t stream)
103024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
103124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION)
103224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGE("startTone: illegal tone requested (%d)", tone);
103324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (stream != AUDIO_STREAM_VOICE_CALL)
103424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGE("startTone: illegal stream (%d) requested for tone %d", stream,
103524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin             tone);
103624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING,
103724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                          AUDIO_STREAM_VOICE_CALL);
103824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return 0;
103924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
104024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
104124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinint AudioPolicyService::stopTone()
104224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
104324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mTonePlaybackThread->stopToneCommand();
104424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return 0;
104524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
104624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
104724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinint AudioPolicyService::setVoiceVolume(float volume, int delayMs)
104824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
104924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
105024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
105124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
1052464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent// ----------------------------------------------------------------------------
1053464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent// Audio pre-processing configuration
1054464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent// ----------------------------------------------------------------------------
1055464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1056464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentconst char *AudioPolicyService::kInputSourceNames[AUDIO_SOURCE_CNT -1] = {
1057464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    MIC_SRC_TAG,
1058464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    VOICE_UL_SRC_TAG,
1059464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    VOICE_DL_SRC_TAG,
1060464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    VOICE_CALL_SRC_TAG,
1061464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    CAMCORDER_SRC_TAG,
1062464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    VOICE_REC_SRC_TAG,
1063464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    VOICE_COMM_SRC_TAG
1064464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent};
1065464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1066464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent// returns the audio_source_t enum corresponding to the input source name or
1067464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent// AUDIO_SOURCE_CNT is no match found
1068464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentaudio_source_t AudioPolicyService::inputSourceNameToEnum(const char *name)
1069464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1070464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    int i;
1071464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) {
1072464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) {
1073464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            LOGV("inputSourceNameToEnum found source %s %d", name, i);
1074464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            break;
1075464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1076464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1077464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return (audio_source_t)i;
1078464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1079464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1080464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentsize_t AudioPolicyService::growParamSize(char *param,
1081464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                         size_t size,
1082464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                         size_t *curSize,
1083464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                         size_t *totSize)
1084464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1085464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int)
1086464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    size_t pos = ((*curSize - 1 ) / size + 1) * size;
1087464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1088464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (pos + size > *totSize) {
1089464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        while (pos + size > *totSize) {
1090464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            *totSize += ((*totSize + 7) / 8) * 4;
1091464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1092464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        param = (char *)realloc(param, *totSize);
1093464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1094464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    *curSize = pos + size;
1095464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return pos;
1096464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1097464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1098464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentsize_t AudioPolicyService::readParamValue(cnode *node,
1099464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                          char *param,
1100464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                          size_t *curSize,
1101464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                          size_t *totSize)
1102464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1103464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) {
1104464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t pos = growParamSize(param, sizeof(short), curSize, totSize);
1105464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        *(short *)((char *)param + pos) = (short)atoi(node->value);
1106464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("readParamValue() reading short %d", *(short *)((char *)param + pos));
1107464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return sizeof(short);
1108464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) {
1109464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t pos = growParamSize(param, sizeof(int), curSize, totSize);
1110464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        *(int *)((char *)param + pos) = atoi(node->value);
1111464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("readParamValue() reading int %d", *(int *)((char *)param + pos));
1112464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return sizeof(int);
1113464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) {
1114464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t pos = growParamSize(param, sizeof(float), curSize, totSize);
1115464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        *(float *)((char *)param + pos) = (float)atof(node->value);
1116464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("readParamValue() reading float %f",*(float *)((char *)param + pos));
1117464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return sizeof(float);
1118464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) {
1119464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t pos = growParamSize(param, sizeof(bool), curSize, totSize);
1120464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (strncmp(node->value, "false", strlen("false") + 1) == 0) {
1121464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            *(bool *)((char *)param + pos) = false;
1122464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        } else {
1123464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            *(bool *)((char *)param + pos) = true;
1124464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1125464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("readParamValue() reading bool %s",*(bool *)((char *)param + pos) ? "true" : "false");
1126464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return sizeof(bool);
1127464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) {
1128464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
1129464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (*curSize + len + 1 > *totSize) {
1130464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            *totSize = *curSize + len + 1;
1131464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            param = (char *)realloc(param, *totSize);
1132464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1133464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        strncpy(param + *curSize, node->value, len);
1134464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        *curSize += len;
1135464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        param[*curSize] = '\0';
1136464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("readParamValue() reading string %s", param + *curSize - len);
1137464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return len;
1138464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1139464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    LOGW("readParamValue() unknown param type %s", node->name);
1140464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return 0;
1141464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1142464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1143464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurenteffect_param_t *AudioPolicyService::loadEffectParameter(cnode *root)
1144464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1145464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *param;
1146464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *value;
1147464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    size_t curSize = sizeof(effect_param_t);
1148464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
1149464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
1150464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1151464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    param = config_find(root, PARAM_TAG);
1152464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    value = config_find(root, VALUE_TAG);
1153464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (param == NULL && value == NULL) {
1154464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        // try to parse simple parameter form {int int}
1155464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        param = root->first_child;
1156464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (param) {
1157464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            // Note: that a pair of random strings is read as 0 0
1158464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            int *ptr = (int *)fx_param->data;
1159464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            int *ptr2 = (int *)((char *)param + sizeof(effect_param_t));
1160464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            LOGW("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2);
1161464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            *ptr++ = atoi(param->name);
1162464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            *ptr = atoi(param->value);
1163464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            fx_param->psize = sizeof(int);
1164464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            fx_param->vsize = sizeof(int);
1165464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            return fx_param;
1166464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1167464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1168464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (param == NULL || value == NULL) {
1169464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGW("loadEffectParameter() invalid parameter description %s", root->name);
1170464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        goto error;
1171464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1172464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1173464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    fx_param->psize = 0;
1174464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    param = param->first_child;
1175464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    while (param) {
1176464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("loadEffectParameter() reading param of type %s", param->name);
1177464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t size = readParamValue(param, (char *)fx_param, &curSize, &totSize);
1178464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (size == 0) {
1179464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            goto error;
1180464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1181464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        fx_param->psize += size;
1182464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        param = param->next;
1183464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1184464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1185464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    // align start of value field on 32 bit boundary
1186464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int);
1187464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1188464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    fx_param->vsize = 0;
1189464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    value = value->first_child;
1190464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    while (value) {
1191464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("loadEffectParameter() reading value of type %s", value->name);
1192464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t size = readParamValue(value, (char *)fx_param, &curSize, &totSize);
1193464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (size == 0) {
1194464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            goto error;
1195464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1196464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        fx_param->vsize += size;
1197464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        value = value->next;
1198464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1199464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1200464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return fx_param;
1201464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1202464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurenterror:
1203464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    delete fx_param;
1204464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return NULL;
1205464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1206464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1207464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentvoid AudioPolicyService::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params)
1208464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1209464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *node = root->first_child;
1210464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    while (node) {
1211464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("loadEffectParameters() loading param %s", node->name);
1212464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        effect_param_t *param = loadEffectParameter(node);
1213464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (param == NULL) {
1214464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            node = node->next;
1215464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            continue;
1216464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1217464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        params.add(param);
1218464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        node = node->next;
1219464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1220464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1221464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1222464d5b3da21c84ba13dc69c611d40f6bed49badbEric LaurentAudioPolicyService::InputSourceDesc *AudioPolicyService::loadInputSource(
1223464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                                            cnode *root,
1224464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                                            const Vector <EffectDesc *>& effects)
1225464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1226464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *node = root->first_child;
1227464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (node == NULL) {
1228464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGW("loadInputSource() empty element %s", root->name);
1229464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return NULL;
1230464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1231464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    InputSourceDesc *source = new InputSourceDesc();
1232464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    while (node) {
1233464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t i;
1234464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        for (i = 0; i < effects.size(); i++) {
1235464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) {
1236464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                LOGV("loadInputSource() found effect %s in list", node->name);
1237464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                break;
1238464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            }
1239464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1240464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (i == effects.size()) {
1241464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            LOGV("loadInputSource() effect %s not in list", node->name);
1242464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            node = node->next;
1243464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            continue;
1244464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1245464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        EffectDesc *effect = new EffectDesc(*effects[i]);
1246464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        loadEffectParameters(node, effect->mParams);
1247464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("loadInputSource() adding effect %s uuid %08x", effect->mName, effect->mUuid.timeLow);
1248464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        source->mEffects.add(effect);
1249464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        node = node->next;
1250464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1251464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (source->mEffects.size() == 0) {
1252464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGW("loadInputSource() no valid effects found in source %s", root->name);
1253464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        delete source;
1254464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return NULL;
1255464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1256464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return source;
1257464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1258464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1259464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentstatus_t AudioPolicyService::loadInputSources(cnode *root, const Vector <EffectDesc *>& effects)
1260464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1261464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *node = config_find(root, PREPROCESSING_TAG);
1262464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (node == NULL) {
1263464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return -ENOENT;
1264464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1265464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    node = node->first_child;
1266464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    while (node) {
1267464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        audio_source_t source = inputSourceNameToEnum(node->name);
1268464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (source == AUDIO_SOURCE_CNT) {
1269464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            LOGW("loadInputSources() invalid input source %s", node->name);
1270464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            node = node->next;
1271464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            continue;
1272464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1273464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("loadInputSources() loading input source %s", node->name);
1274464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        InputSourceDesc *desc = loadInputSource(node, effects);
1275464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (desc == NULL) {
1276464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            node = node->next;
1277464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            continue;
1278464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1279464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        mInputSources.add(source, desc);
1280464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        node = node->next;
1281464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1282464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return NO_ERROR;
1283464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1284464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1285464d5b3da21c84ba13dc69c611d40f6bed49badbEric LaurentAudioPolicyService::EffectDesc *AudioPolicyService::loadEffect(cnode *root)
1286464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1287464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *node = config_find(root, UUID_TAG);
1288464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (node == NULL) {
1289464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return NULL;
1290464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1291464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    effect_uuid_t uuid;
1292464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) {
1293464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGW("loadEffect() invalid uuid %s", node->value);
1294464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return NULL;
1295464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1296464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    EffectDesc *effect = new EffectDesc();
1297464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    effect->mName = strdup(root->name);
1298464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    memcpy(&effect->mUuid, &uuid, sizeof(effect_uuid_t));
1299464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1300464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return effect;
1301464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1302464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1303464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentstatus_t AudioPolicyService::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
1304464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1305464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *node = config_find(root, EFFECTS_TAG);
1306464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (node == NULL) {
1307464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return -ENOENT;
1308464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1309464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    node = node->first_child;
1310464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    while (node) {
1311464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("loadEffects() loading effect %s", node->name);
1312464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        EffectDesc *effect = loadEffect(node);
1313464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (effect == NULL) {
1314464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            node = node->next;
1315464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            continue;
1316464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1317464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        effects.add(effect);
1318464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        node = node->next;
1319464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1320464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return NO_ERROR;
1321464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1322464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1323464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentstatus_t AudioPolicyService::loadPreProcessorConfig(const char *path)
1324464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1325464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *root;
1326464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    char *data;
1327464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1328464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    data = (char *)load_file(path, NULL);
1329464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (data == NULL) {
1330464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return -ENODEV;
1331464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1332464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    root = config_node("", "");
1333464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    config_load(root, data);
1334464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1335464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    Vector <EffectDesc *> effects;
1336464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    loadEffects(root, effects);
1337464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    loadInputSources(root, effects);
1338464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1339464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    config_free(root);
1340464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    free(root);
1341464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    free(data);
1342464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1343464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return NO_ERROR;
1344464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1345464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
134624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin/* implementation of the interface to the policy manager */
134724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinextern "C" {
134824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
134924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic audio_io_handle_t aps_open_output(void *service,
135024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                             uint32_t *pDevices,
135124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                             uint32_t *pSamplingRate,
135224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                             uint32_t *pFormat,
135324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                             uint32_t *pChannels,
135424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                             uint32_t *pLatencyMs,
135524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                             audio_policy_output_flags_t flags)
135624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
135724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
135824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL) {
135924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGW("%s: could not get AudioFlinger", __func__);
136024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return 0;
136124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    }
136224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
136324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->openOutput(pDevices, pSamplingRate, pFormat, pChannels,
136424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                          pLatencyMs, flags);
136524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
136624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
136724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic audio_io_handle_t aps_open_dup_output(void *service,
136824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                 audio_io_handle_t output1,
136924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                 audio_io_handle_t output2)
137024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
137124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
137224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL) {
137324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGW("%s: could not get AudioFlinger", __func__);
137424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return 0;
137524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    }
137624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->openDuplicateOutput(output1, output2);
137724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
137824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
137924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_close_output(void *service, audio_io_handle_t output)
138024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
138124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
138224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL)
138324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return PERMISSION_DENIED;
138424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
138524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->closeOutput(output);
138624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
138724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
138824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_suspend_output(void *service, audio_io_handle_t output)
138924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
139024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
139124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL) {
139224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGW("%s: could not get AudioFlinger", __func__);
139324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return PERMISSION_DENIED;
139424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    }
139524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
139624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->suspendOutput(output);
139724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
139824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
139924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_restore_output(void *service, audio_io_handle_t output)
140024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
140124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
140224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL) {
140324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGW("%s: could not get AudioFlinger", __func__);
140424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return PERMISSION_DENIED;
140524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    }
140624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
140724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->restoreOutput(output);
140824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
140924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
141024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic audio_io_handle_t aps_open_input(void *service,
141124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                            uint32_t *pDevices,
141224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                            uint32_t *pSamplingRate,
141324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                            uint32_t *pFormat,
141424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                            uint32_t *pChannels,
141524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                            uint32_t acoustics)
141624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
141724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
141824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL) {
141924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGW("%s: could not get AudioFlinger", __func__);
142024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return 0;
142124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    }
142224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
142324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->openInput(pDevices, pSamplingRate, pFormat, pChannels,
142424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                         acoustics);
142524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
142624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
142724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_close_input(void *service, audio_io_handle_t input)
142824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
142924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
143024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL)
143124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return PERMISSION_DENIED;
143224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
143324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->closeInput(input);
143424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
143524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
143624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_set_stream_output(void *service, audio_stream_type_t stream,
143724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                     audio_io_handle_t output)
143824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
143924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
144024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL)
144124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return PERMISSION_DENIED;
144224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
144324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->setStreamOutput(stream, output);
144424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
144524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
144624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_move_effects(void *service, int session,
144724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                audio_io_handle_t src_output,
144824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                audio_io_handle_t dst_output)
144924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
145024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
145124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL)
145224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return PERMISSION_DENIED;
145324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
145424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->moveEffects(session, (int)src_output, (int)dst_output);
145524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
145624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
145724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic char * aps_get_parameters(void *service, audio_io_handle_t io_handle,
145824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                     const char *keys)
145924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
146024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    String8 result = AudioSystem::getParameters(io_handle, String8(keys));
146124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return strdup(result.string());
146224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
146324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
146424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic void aps_set_parameters(void *service, audio_io_handle_t io_handle,
146524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                   const char *kv_pairs, int delay_ms)
146624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
146724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
146824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
146924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    audioPolicyService->setParameters(io_handle, kv_pairs, delay_ms);
147024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
147124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
147224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_set_stream_volume(void *service, audio_stream_type_t stream,
147324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                     float volume, audio_io_handle_t output,
147424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                     int delay_ms)
147524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
147624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
147724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
147824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return audioPolicyService->setStreamVolume(stream, volume, output,
147924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                               delay_ms);
148024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
148124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
148224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_start_tone(void *service, audio_policy_tone_t tone,
148324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                              audio_stream_type_t stream)
148424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
148524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
148624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
148724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return audioPolicyService->startTone(tone, stream);
148824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
148924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
149024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_stop_tone(void *service)
149124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
149224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
149324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
149424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return audioPolicyService->stopTone();
149524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
149624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
149724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_set_voice_volume(void *service, float volume, int delay_ms)
149824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
149924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
150024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
150124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return audioPolicyService->setVoiceVolume(volume, delay_ms);
150224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
150324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
150424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}; // extern "C"
150524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
150624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinnamespace {
150724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    struct audio_policy_service_ops aps_ops = {
150824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        open_output           : aps_open_output,
150924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        open_duplicate_output : aps_open_dup_output,
151024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        close_output          : aps_close_output,
151124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        suspend_output        : aps_suspend_output,
151224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        restore_output        : aps_restore_output,
151324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        open_input            : aps_open_input,
151424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        close_input           : aps_close_input,
151524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        set_stream_volume     : aps_set_stream_volume,
151624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        set_stream_output     : aps_set_stream_output,
151724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        set_parameters        : aps_set_parameters,
151824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        get_parameters        : aps_get_parameters,
151924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        start_tone            : aps_start_tone,
152024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        stop_tone             : aps_stop_tone,
152124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        set_voice_volume      : aps_set_voice_volume,
152224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        move_effects          : aps_move_effects,
152324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    };
152424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}; // namespace <unnamed>
152524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
1526a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}; // namespace android
1527