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    }
18524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_device_connection_state(mpAudioPolicy, device,
18624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                      device_address);
187a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
188a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
189a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setPhoneState(int state)
190a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
19124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
192a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
193a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
194a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
195a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
196a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
19724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (state < 0 || state >= AUDIO_MODE_CNT) {
198a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
199a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
200a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
201a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setPhoneState() tid %d", gettid());
202a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
203a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    // TODO: check if it is more appropriate to do it in platform specific policy manager
204a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioSystem::setMode(state);
205a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
206a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
20724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->set_phone_state(mpAudioPolicy, state);
208a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
209a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
210a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
211a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setRingerMode(uint32_t mode, uint32_t mask)
212a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
21324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
214a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
215a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
216a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
217a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
218a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
219a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
22024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->set_ringer_mode(mpAudioPolicy, mode, mask);
221a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
222a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
223a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
22424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatus_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage,
22524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                         audio_policy_forced_cfg_t config)
226a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
22724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
228a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
229a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
230a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
231a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
232a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
23324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
234a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
235a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
23624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (config < 0 || config >= AUDIO_POLICY_FORCE_CFG_CNT) {
237a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
238a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
239a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setForceUse() tid %d", gettid());
240a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
24124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->set_force_use(mpAudioPolicy, usage, config);
242a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
243a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
244a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
24524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinaudio_policy_forced_cfg_t AudioPolicyService::getForceUse(audio_policy_force_use_t usage)
246a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
24724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
24824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return AUDIO_POLICY_FORCE_NONE;
249a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
25024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
25124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return AUDIO_POLICY_FORCE_NONE;
252a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
25324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_force_use(mpAudioPolicy, usage);
254a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
255a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
25624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinaudio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
257a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t samplingRate,
258a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t format,
259a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t channels,
26024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                    audio_policy_output_flags_t flags)
261a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
26224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
263ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
264a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
265a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("getOutput() tid %d", gettid());
266a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
26724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate, format, channels, flags);
268a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
269a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
2708ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentstatus_t AudioPolicyService::startOutput(audio_io_handle_t output,
27124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                         audio_stream_type_t stream,
2728ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                         int session)
273a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
27424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
275a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
276a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
277a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("startOutput() tid %d", gettid());
278a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
27924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->start_output(mpAudioPolicy, output, stream, session);
280a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
281a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
2828ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentstatus_t AudioPolicyService::stopOutput(audio_io_handle_t output,
28324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                        audio_stream_type_t stream,
2848ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                        int session)
285a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
28624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
287a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
288a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
289a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("stopOutput() tid %d", gettid());
290a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
29124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->stop_output(mpAudioPolicy, output, stream, session);
292a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
293a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
294a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::releaseOutput(audio_io_handle_t output)
295a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
29624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
297a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return;
298a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
299a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("releaseOutput() tid %d", gettid());
300a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
30124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->release_output(mpAudioPolicy, output);
302a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
303a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
304a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentaudio_io_handle_t AudioPolicyService::getInput(int inputSource,
305a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t samplingRate,
306a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t format,
307a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t channels,
308464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                    audio_in_acoustics_t acoustics,
309464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                    int audioSession)
310a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
31124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
312ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
313a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
314a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
315464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
316464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                                       format, channels, acoustics);
317464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
318464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (input == 0) {
319464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return input;
320464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
321464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    // create audio pre processors according to input source
322464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    ssize_t index = mInputSources.indexOfKey((audio_source_t)inputSource);
323464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (index < 0) {
324464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return input;
325464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
326464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    ssize_t idx = mInputs.indexOfKey(input);
327464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    InputDesc *inputDesc;
328464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (idx < 0) {
329464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        inputDesc = new InputDesc();
330464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        inputDesc->mSessionId = audioSession;
331464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        mInputs.add(input, inputDesc);
332464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    } else {
333464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        inputDesc = mInputs.valueAt(idx);
334464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
335464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
336464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
337464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    for (size_t i = 0; i < effects.size(); i++) {
338464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        EffectDesc *effect = effects[i];
339464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
340464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        status_t status = fx->initCheck();
341464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (status != NO_ERROR && status != ALREADY_EXISTS) {
342464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            LOGW("Failed to create Fx %s on input %d", effect->mName, input);
343464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            // fx goes out of scope and strong ref on AudioEffect is released
344464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            continue;
345464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
346464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        for (size_t j = 0; j < effect->mParams.size(); j++) {
347464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            fx->setParameter(effect->mParams[j]);
348464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
349464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        inputDesc->mEffects.add(fx);
350464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
351464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    setPreProcessorEnabled(inputDesc, true);
352464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return input;
353a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
354a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
355a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::startInput(audio_io_handle_t input)
356a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
35724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
358a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
359a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
360a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
361464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
36224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->start_input(mpAudioPolicy, input);
363a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
364a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
365a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::stopInput(audio_io_handle_t input)
366a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
36724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
368a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
369a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
370a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
371464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
37224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->stop_input(mpAudioPolicy, input);
373a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
374a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
375a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::releaseInput(audio_io_handle_t input)
376a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
37724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
378a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return;
379a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
380a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
38124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->release_input(mpAudioPolicy, input);
382464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
383464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    ssize_t index = mInputs.indexOfKey(input);
384464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (index < 0) {
385464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return;
386464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
387464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    InputDesc *inputDesc = mInputs.valueAt(index);
388464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    setPreProcessorEnabled(inputDesc, false);
389464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    inputDesc->mEffects.clear();
390464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    delete inputDesc;
391464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    mInputs.removeItemsAt(index);
392a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
393a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
39424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatus_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
395a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                            int indexMin,
396a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                            int indexMax)
397a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
39824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
399a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
400a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
401a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
402a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
403a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
40424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
405a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
406a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
40724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mpAudioPolicy->init_stream_volume(mpAudioPolicy, stream, indexMin, indexMax);
408a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
409a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
410a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
41124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatus_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream, int index)
412a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
41324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
414a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
415a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
416a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
417a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
418a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
41924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
420a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
421a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
422a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
42324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);
424a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
425a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
42624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatus_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream, int *index)
427a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
42824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
429a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
430a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
43124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
432a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
433a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
43424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_stream_volume_index(mpAudioPolicy, stream, index);
435a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
436a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
43724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinuint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
4388ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent{
43924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
4408ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent        return 0;
4418ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    }
44224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_strategy_for_stream(mpAudioPolicy, stream);
4438ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent}
4448ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent
44524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinuint32_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
4468b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten{
44724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
4488b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten        return 0;
4498b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten    }
45024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_devices_for_stream(mpAudioPolicy, stream);
4518b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten}
4528b4b97a14ad9b5b982d8fe92755efabec8ad0076Glenn Kasten
4538ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentaudio_io_handle_t AudioPolicyService::getOutputForEffect(effect_descriptor_t *desc)
4548ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent{
45524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
4568ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent        return NO_INIT;
4578ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    }
4588ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    Mutex::Autolock _l(mLock);
45924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->get_output_for_effect(mpAudioPolicy, desc);
4608ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent}
4618ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent
4628ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentstatus_t AudioPolicyService::registerEffect(effect_descriptor_t *desc,
463464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                audio_io_handle_t io,
4648ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                uint32_t strategy,
4658ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                int session,
4668ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                int id)
4678ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent{
46824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
4698ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent        return NO_INIT;
4708ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    }
471464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return mpAudioPolicy->register_effect(mpAudioPolicy, desc, io, strategy, session, id);
4728ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent}
4738ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent
4748ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentstatus_t AudioPolicyService::unregisterEffect(int id)
4758ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent{
47624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
4778ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent        return NO_INIT;
4788ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    }
47924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->unregister_effect(mpAudioPolicy, id);
4808ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent}
4818ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent
4826752ec80b25cb1f39507d18745c7e62323772cdaEric Laurentstatus_t AudioPolicyService::setEffectEnabled(int id, bool enabled)
4836752ec80b25cb1f39507d18745c7e62323772cdaEric Laurent{
4846752ec80b25cb1f39507d18745c7e62323772cdaEric Laurent    if (mpAudioPolicy == NULL) {
4856752ec80b25cb1f39507d18745c7e62323772cdaEric Laurent        return NO_INIT;
4866752ec80b25cb1f39507d18745c7e62323772cdaEric Laurent    }
4876752ec80b25cb1f39507d18745c7e62323772cdaEric Laurent    return mpAudioPolicy->set_effect_enabled(mpAudioPolicy, id, enabled);
4886752ec80b25cb1f39507d18745c7e62323772cdaEric Laurent}
4896752ec80b25cb1f39507d18745c7e62323772cdaEric Laurent
49025101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurentbool AudioPolicyService::isStreamActive(int stream, uint32_t inPastMs) const
49125101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent{
49224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (mpAudioPolicy == NULL) {
49325101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent        return 0;
49425101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent    }
49525101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent    Mutex::Autolock _l(mLock);
49624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return mpAudioPolicy->is_stream_active(mpAudioPolicy, stream, inPastMs);
49725101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent}
49825101b0b9a84571ead15b26e9f4cd9c4298d7823Eric Laurent
4990f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurentstatus_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
5000f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent                                                       effect_descriptor_t *descriptors,
5010f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent                                                       uint32_t *count)
5020f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent{
5030f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
5040f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    if (mpAudioPolicy == NULL) {
5050f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        *count = 0;
5060f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        return NO_INIT;
5070f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
5080f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    Mutex::Autolock _l(mLock);
5090f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    status_t status = NO_ERROR;
5100f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
5110f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    size_t index;
5120f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    for (index = 0; index < mInputs.size(); index++) {
5130f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        if (mInputs.valueAt(index)->mSessionId == audioSession) {
5140f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            break;
5150f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        }
5160f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
5170f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    if (index == mInputs.size()) {
5180f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        *count = 0;
5190f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        return BAD_VALUE;
5200f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
5210f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects;
5220f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
5230f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    for (size_t i = 0; i < effects.size(); i++) {
5240f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        effect_descriptor_t desc = effects[i]->descriptor();
5250f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        if (i < *count) {
5260f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent            memcpy(descriptors + i, &desc, sizeof(effect_descriptor_t));
5270f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        }
5280f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
5290f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    if (effects.size() > *count) {
5300f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent        status = NO_MEMORY;
5310f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    }
5320f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    *count = effects.size();
5330f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent    return status;
5340f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent}
5350f7f4ece1b6b73caf608d533d833a8cdc11c8131Eric Laurent
536a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::binderDied(const wp<IBinder>& who) {
5378ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(),
5388ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent            IPCThreadState::self()->getCallingPid());
539a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
540a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
541f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatic bool tryLock(Mutex& mutex)
542f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
543f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    bool locked = false;
544f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    for (int i = 0; i < kDumpLockRetries; ++i) {
545f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mutex.tryLock() == NO_ERROR) {
546f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            locked = true;
547f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            break;
548f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
549f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        usleep(kDumpLockSleep);
550f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    }
551f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    return locked;
552f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
553f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
554f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatus_t AudioPolicyService::dumpInternals(int fd)
555f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
556f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    const size_t SIZE = 256;
557f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    char buffer[SIZE];
558f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    String8 result;
559f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
56024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy);
561f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
562f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
563f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
564f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
565f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
566f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
567f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    write(fd, result.string(), result.size());
568f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    return NO_ERROR;
569f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
570f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
571a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args)
572a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
573a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
574f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        dumpPermissionDenial(fd);
575a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    } else {
576f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        bool locked = tryLock(mLock);
577f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (!locked) {
578f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            String8 result(kDeadlockedString);
579f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            write(fd, result.string(), result.size());
580f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
581a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
582f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        dumpInternals(fd);
583f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mAudioCommandThread != NULL) {
584f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mAudioCommandThread->dump(fd);
585f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
586f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mTonePlaybackThread != NULL) {
587f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mTonePlaybackThread->dump(fd);
588f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
589f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
59024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        if (mpAudioPolicy) {
59124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin            mpAudioPolicy->dump(mpAudioPolicy, fd);
592f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
593f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
594f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (locked) mLock.unlock();
595a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
596a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
597a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
598a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
599f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatus_t AudioPolicyService::dumpPermissionDenial(int fd)
600a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
601a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    const size_t SIZE = 256;
602a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    char buffer[SIZE];
603a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 result;
604a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    snprintf(buffer, SIZE, "Permission Denial: "
605a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
606a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            IPCThreadState::self()->getCallingPid(),
607a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            IPCThreadState::self()->getCallingUid());
608a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    result.append(buffer);
609a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    write(fd, result.string(), result.size());
610a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
611a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
612a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
613464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentvoid AudioPolicyService::setPreProcessorEnabled(InputDesc *inputDesc, bool enabled)
614464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
615464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    Vector<sp<AudioEffect> > fxVector = inputDesc->mEffects;
616464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    for (size_t i = 0; i < fxVector.size(); i++) {
617464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        sp<AudioEffect> fx = fxVector.itemAt(i);
618464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        fx->setEnabled(enabled);
619464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
620464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
621464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
622a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::onTransact(
623a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
624a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
625a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return BnAudioPolicyService::onTransact(code, data, reply, flags);
626a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
627a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
628a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
629a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// -----------  AudioPolicyService::AudioCommandThread implementation ----------
630a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
631cef3cd79489fa7897ffbacbc4e435651fb04f10dEric LaurentAudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name)
632cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    : Thread(false), mName(name)
633a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
634a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpToneGenerator = NULL;
635a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
636a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
637a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
638a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioPolicyService::AudioCommandThread::~AudioCommandThread()
639a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
640cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    if (mName != "" && !mAudioCommands.isEmpty()) {
641cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        release_wake_lock(mName.string());
642cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    }
643a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mAudioCommands.clear();
644a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpToneGenerator != NULL) delete mpToneGenerator;
645a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
646a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
647a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::onFirstRef()
648a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
649cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    if (mName != "") {
650cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        run(mName.string(), ANDROID_PRIORITY_AUDIO);
651cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    } else {
652cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        run("AudioCommandThread", ANDROID_PRIORITY_AUDIO);
653cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    }
654a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
655a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
656a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentbool AudioPolicyService::AudioCommandThread::threadLoop()
657a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
658327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    nsecs_t waitTime = INT64_MAX;
659327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
660a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mLock.lock();
661a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    while (!exitPending())
662a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {
663a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        while(!mAudioCommands.isEmpty()) {
664327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            nsecs_t curTime = systemTime();
665327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            // commands are sorted by increasing time stamp: execute them from index 0 and up
666327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (mAudioCommands[0]->mTime <= curTime) {
667327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                AudioCommand *command = mAudioCommands[0];
668327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                mAudioCommands.removeAt(0);
6693fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent                mLastCommand = *command;
6703fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent
671327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                switch (command->mCommand) {
672327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case START_TONE: {
673327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.unlock();
674327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    ToneData *data = (ToneData *)command->mParam;
675327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGV("AudioCommandThread() processing start tone %d on stream %d",
676327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                            data->mType, data->mStream);
677327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    if (mpToneGenerator != NULL)
678327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        delete mpToneGenerator;
679327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
680327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mpToneGenerator->startTone(data->mType);
681327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    delete data;
682327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.lock();
683327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }break;
684327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case STOP_TONE: {
685327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.unlock();
686327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGV("AudioCommandThread() processing stop tone");
687327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    if (mpToneGenerator != NULL) {
688327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        mpToneGenerator->stopTone();
689327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        delete mpToneGenerator;
690327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        mpToneGenerator = NULL;
691327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }
692327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.lock();
693327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }break;
694327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case SET_VOLUME: {
695327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    VolumeData *data = (VolumeData *)command->mParam;
6968ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                    LOGV("AudioCommandThread() processing set volume stream %d, \
6978ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                            volume %f, output %d", data->mStream, data->mVolume, data->mIO);
6988ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                    command->mStatus = AudioSystem::setStreamVolume(data->mStream,
6998ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                                    data->mVolume,
7008ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                                    data->mIO);
701327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    if (command->mWaitStatus) {
702327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        command->mCond.signal();
703327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        mWaitWorkCV.wait(mLock);
704327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }
705327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    delete data;
706327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }break;
707327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case SET_PARAMETERS: {
708327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     ParametersData *data = (ParametersData *)command->mParam;
7098ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                     LOGV("AudioCommandThread() processing set parameters string %s, io %d",
7108ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                             data->mKeyValuePairs.string(), data->mIO);
711327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
712327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     if (command->mWaitStatus) {
713327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                         command->mCond.signal();
714327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                         mWaitWorkCV.wait(mLock);
715327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     }
716327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     delete data;
717327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     }break;
718415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                case SET_VOICE_VOLUME: {
719415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
7208ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                    LOGV("AudioCommandThread() processing set voice volume volume %f",
7218ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                            data->mVolume);
722415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
723415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    if (command->mWaitStatus) {
724415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                        command->mCond.signal();
725415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                        mWaitWorkCV.wait(mLock);
726415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    }
727415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    delete data;
728415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    }break;
729327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                default:
730327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGW("AudioCommandThread() unknown command %d", command->mCommand);
731a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                }
732327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                delete command;
733327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                waitTime = INT64_MAX;
734327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            } else {
735327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                waitTime = mAudioCommands[0]->mTime - curTime;
736327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                break;
737a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            }
738a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        }
739cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        // release delayed commands wake lock
740cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        if (mName != "" && mAudioCommands.isEmpty()) {
741cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent            release_wake_lock(mName.string());
742cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        }
743a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGV("AudioCommandThread() going to sleep");
744327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        mWaitWorkCV.waitRelative(mLock, waitTime);
745a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGV("AudioCommandThread() waking up");
746a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
747a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mLock.unlock();
748a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return false;
749a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
750a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
751f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::dump(int fd)
752f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
753f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    const size_t SIZE = 256;
754f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    char buffer[SIZE];
755f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    String8 result;
756f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
757f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
758f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
759f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    write(fd, result.string(), result.size());
760f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
761f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    bool locked = tryLock(mLock);
762f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    if (!locked) {
763f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        String8 result2(kCmdDeadlockedString);
764f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        write(fd, result2.string(), result2.size());
765f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    }
766f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
767f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "- Commands:\n");
768f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result = String8(buffer);
7693fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    result.append("   Command Time        Wait pParam\n");
770f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    for (int i = 0; i < (int)mAudioCommands.size(); i++) {
771f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        mAudioCommands[i]->dump(buffer, SIZE);
772f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        result.append(buffer);
773f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    }
7743fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    result.append("  Last Command\n");
7753fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    mLastCommand.dump(buffer, SIZE);
7763fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    result.append(buffer);
7773fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent
778f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    write(fd, result.string(), result.size());
779f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
780f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    if (locked) mLock.unlock();
781f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
782f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    return NO_ERROR;
783f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
784f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
785a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
786a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
787a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
788a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = START_TONE;
789a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    ToneData *data = new ToneData();
790a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mType = type;
791a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mStream = stream;
792a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = (void *)data;
793327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    command->mWaitStatus = false;
794415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
795327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command);
796a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
797a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
798a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
799a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
800a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::stopToneCommand()
801a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
802a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
803a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = STOP_TONE;
804a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = NULL;
805327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    command->mWaitStatus = false;
806415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
807327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command);
808a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("AudioCommandThread() adding tone stop");
809a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
810a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
811a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
8128ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream,
8138ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                               float volume,
8148ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                               int output,
8158ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                               int delayMs)
816a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
817327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    status_t status = NO_ERROR;
818327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
819a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
820a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = SET_VOLUME;
821a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    VolumeData *data = new VolumeData();
822a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mStream = stream;
823a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mVolume = volume;
824a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mIO = output;
825a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = data;
826327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (delayMs == 0) {
827327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = true;
828327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    } else {
829327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = false;
830327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
831415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
832327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command, delayMs);
8338ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
8348ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent            stream, volume, output);
835a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
836327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (command->mWaitStatus) {
837327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mCond.wait(mLock);
838327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        status =  command->mStatus;
839327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        mWaitWorkCV.signal();
840327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
841a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return status;
842a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
843a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
8448ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurentstatus_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle,
84524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                                   const char *keyValuePairs,
8468ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                                                                   int delayMs)
847a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
848327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    status_t status = NO_ERROR;
849327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
850a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
851a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = SET_PARAMETERS;
852a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    ParametersData *data = new ParametersData();
853a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mIO = ioHandle;
85424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    data->mKeyValuePairs = String8(keyValuePairs);
855a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = data;
856327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (delayMs == 0) {
857327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = true;
858327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    } else {
859327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = false;
860327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
861415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
862327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command, delayMs);
8638ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
86424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin            keyValuePairs, ioHandle, delayMs);
865a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
866327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (command->mWaitStatus) {
867327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mCond.wait(mLock);
868327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        status =  command->mStatus;
869327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        mWaitWorkCV.signal();
870327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
871a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return status;
872a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
873a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
874415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurentstatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
875415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent{
876415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    status_t status = NO_ERROR;
877415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent
878415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    AudioCommand *command = new AudioCommand();
879415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    command->mCommand = SET_VOICE_VOLUME;
880415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    VoiceVolumeData *data = new VoiceVolumeData();
881415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    data->mVolume = volume;
882415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    command->mParam = data;
883415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    if (delayMs == 0) {
884415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        command->mWaitStatus = true;
885415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    } else {
886415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        command->mWaitStatus = false;
887415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    }
888415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
889415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    insertCommand_l(command, delayMs);
890415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    LOGV("AudioCommandThread() adding set voice volume volume %f", volume);
891415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    mWaitWorkCV.signal();
892415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    if (command->mWaitStatus) {
893415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        command->mCond.wait(mLock);
894415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        status =  command->mStatus;
895415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        mWaitWorkCV.signal();
896415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    }
897415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    return status;
898415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent}
899415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent
900327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent// insertCommand_l() must be called with mLock held
901327c27be19ad333c4835c84397152a0b2cb33081Eric Laurentvoid AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
902327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent{
903327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    ssize_t i;
904327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    Vector <AudioCommand *> removedCommands;
905327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
906327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    command->mTime = systemTime() + milliseconds(delayMs);
907327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
908cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    // acquire wake lock to make sure delayed commands are processed
909cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    if (mName != "" && mAudioCommands.isEmpty()) {
910cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
911cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    }
912cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent
913327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    // check same pending commands with later time stamps and eliminate them
914327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    for (i = mAudioCommands.size()-1; i >= 0; i--) {
915327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        AudioCommand *command2 = mAudioCommands[i];
916327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
917327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        if (command2->mTime <= command->mTime) break;
918327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        if (command2->mCommand != command->mCommand) continue;
919327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
920327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        switch (command->mCommand) {
921327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case SET_PARAMETERS: {
922327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            ParametersData *data = (ParametersData *)command->mParam;
923327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            ParametersData *data2 = (ParametersData *)command2->mParam;
924327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (data->mIO != data2->mIO) break;
9258ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent            LOGV("Comparing parameter command %s to new command %s",
9268ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                    data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
927327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            AudioParameter param = AudioParameter(data->mKeyValuePairs);
928327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
929327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            for (size_t j = 0; j < param.size(); j++) {
930327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               String8 key;
931327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               String8 value;
932327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               param.getAt(j, key, value);
933327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               for (size_t k = 0; k < param2.size(); k++) {
934327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  String8 key2;
935327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  String8 value2;
936327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  param2.getAt(k, key2, value2);
937327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  if (key2 == key) {
938327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                      param2.remove(key2);
939327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                      LOGV("Filtering out parameter %s", key2.string());
940327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                      break;
941327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  }
942327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               }
943327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            }
944327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            // if all keys have been filtered out, remove the command.
945327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            // otherwise, update the key value pairs
946327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (param2.size() == 0) {
947327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                removedCommands.add(command2);
948327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            } else {
949327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                data2->mKeyValuePairs = param2.toString();
950327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            }
951327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        } break;
952327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
953327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case SET_VOLUME: {
954327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            VolumeData *data = (VolumeData *)command->mParam;
955327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            VolumeData *data2 = (VolumeData *)command2->mParam;
956327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (data->mIO != data2->mIO) break;
957327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (data->mStream != data2->mStream) break;
9588ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent            LOGV("Filtering out volume command on output %d for stream %d",
9598ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent                    data->mIO, data->mStream);
960327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            removedCommands.add(command2);
961327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        } break;
962327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case START_TONE:
963327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case STOP_TONE:
964327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        default:
965327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            break;
966327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        }
967327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
968327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
969327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    // remove filtered commands
970327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    for (size_t j = 0; j < removedCommands.size(); j++) {
971327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        // removed commands always have time stamps greater than current command
972327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
973327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (mAudioCommands[k] == removedCommands[j]) {
974327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                LOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
975327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                mAudioCommands.removeAt(k);
976327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                break;
977327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            }
978327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        }
979327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
980327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    removedCommands.clear();
981327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
982327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    // insert command at the right place according to its time stamp
9838ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent    LOGV("inserting command: %d at index %d, num commands %d",
9848ed6ed0b6216a9dfcbcd6a5ba6a62d28a901baecEric Laurent            command->mCommand, (int)i+1, mAudioCommands.size());
985327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mAudioCommands.insertAt(command, i + 1);
986327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent}
987327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
988a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::exit()
989a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
990a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("AudioCommandThread::exit");
991a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {
992a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        AutoMutex _l(mLock);
993a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        requestExit();
994a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        mWaitWorkCV.signal();
995a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
996a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    requestExitAndWait();
997a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
998a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
999f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentvoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
1000f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
10013fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
1002f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mCommand,
1003f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            (int)ns2s(mTime),
1004f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            (int)ns2ms(mTime)%1000,
1005f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mWaitStatus,
1006f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mParam);
1007f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
1008f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
100924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin/******* helpers for the service_ops callbacks defined below *********/
101024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
101124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                       const char *keyValuePairs,
101224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                       int delayMs)
101324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
101424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs,
101524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                           delayMs);
101624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
101724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
101824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinint AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
101924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                        float volume,
102024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                        audio_io_handle_t output,
102124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                        int delayMs)
102224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
102324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return (int)mAudioCommandThread->volumeCommand((int)stream, volume,
102424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                   (int)output, delayMs);
102524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
102624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
102724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinint AudioPolicyService::startTone(audio_policy_tone_t tone,
102824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                  audio_stream_type_t stream)
102924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
103024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION)
103124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGE("startTone: illegal tone requested (%d)", tone);
103224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (stream != AUDIO_STREAM_VOICE_CALL)
103324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGE("startTone: illegal stream (%d) requested for tone %d", stream,
103424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin             tone);
103524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING,
103624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                          AUDIO_STREAM_VOICE_CALL);
103724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return 0;
103824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
103924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
104024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinint AudioPolicyService::stopTone()
104124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
104224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    mTonePlaybackThread->stopToneCommand();
104324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return 0;
104424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
104524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
104624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinint AudioPolicyService::setVoiceVolume(float volume, int delayMs)
104724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
104824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
104924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
105024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
1051464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent// ----------------------------------------------------------------------------
1052464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent// Audio pre-processing configuration
1053464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent// ----------------------------------------------------------------------------
1054464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1055464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentconst char *AudioPolicyService::kInputSourceNames[AUDIO_SOURCE_CNT -1] = {
1056464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    MIC_SRC_TAG,
1057464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    VOICE_UL_SRC_TAG,
1058464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    VOICE_DL_SRC_TAG,
1059464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    VOICE_CALL_SRC_TAG,
1060464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    CAMCORDER_SRC_TAG,
1061464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    VOICE_REC_SRC_TAG,
1062464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    VOICE_COMM_SRC_TAG
1063464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent};
1064464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1065464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent// returns the audio_source_t enum corresponding to the input source name or
1066464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent// AUDIO_SOURCE_CNT is no match found
1067464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentaudio_source_t AudioPolicyService::inputSourceNameToEnum(const char *name)
1068464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1069464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    int i;
1070464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) {
1071464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) {
1072464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            LOGV("inputSourceNameToEnum found source %s %d", name, i);
1073464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            break;
1074464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1075464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1076464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return (audio_source_t)i;
1077464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1078464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1079464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentsize_t AudioPolicyService::growParamSize(char *param,
1080464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                         size_t size,
1081464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                         size_t *curSize,
1082464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                         size_t *totSize)
1083464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1084464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int)
1085464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    size_t pos = ((*curSize - 1 ) / size + 1) * size;
1086464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1087464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (pos + size > *totSize) {
1088464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        while (pos + size > *totSize) {
1089464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            *totSize += ((*totSize + 7) / 8) * 4;
1090464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1091464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        param = (char *)realloc(param, *totSize);
1092464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1093464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    *curSize = pos + size;
1094464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return pos;
1095464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1096464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1097464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentsize_t AudioPolicyService::readParamValue(cnode *node,
1098464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                          char *param,
1099464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                          size_t *curSize,
1100464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                          size_t *totSize)
1101464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1102464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) {
1103464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t pos = growParamSize(param, sizeof(short), curSize, totSize);
1104464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        *(short *)((char *)param + pos) = (short)atoi(node->value);
1105464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("readParamValue() reading short %d", *(short *)((char *)param + pos));
1106464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return sizeof(short);
1107464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) {
1108464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t pos = growParamSize(param, sizeof(int), curSize, totSize);
1109464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        *(int *)((char *)param + pos) = atoi(node->value);
1110464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("readParamValue() reading int %d", *(int *)((char *)param + pos));
1111464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return sizeof(int);
1112464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) {
1113464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t pos = growParamSize(param, sizeof(float), curSize, totSize);
1114464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        *(float *)((char *)param + pos) = (float)atof(node->value);
1115464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("readParamValue() reading float %f",*(float *)((char *)param + pos));
1116464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return sizeof(float);
1117464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) {
1118464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t pos = growParamSize(param, sizeof(bool), curSize, totSize);
1119464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (strncmp(node->value, "false", strlen("false") + 1) == 0) {
1120464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            *(bool *)((char *)param + pos) = false;
1121464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        } else {
1122464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            *(bool *)((char *)param + pos) = true;
1123464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1124464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("readParamValue() reading bool %s",*(bool *)((char *)param + pos) ? "true" : "false");
1125464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return sizeof(bool);
1126464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) {
1127464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
1128464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (*curSize + len + 1 > *totSize) {
1129464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            *totSize = *curSize + len + 1;
1130464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            param = (char *)realloc(param, *totSize);
1131464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1132464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        strncpy(param + *curSize, node->value, len);
1133464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        *curSize += len;
1134464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        param[*curSize] = '\0';
1135464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("readParamValue() reading string %s", param + *curSize - len);
1136464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return len;
1137464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1138464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    LOGW("readParamValue() unknown param type %s", node->name);
1139464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return 0;
1140464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1141464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1142464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurenteffect_param_t *AudioPolicyService::loadEffectParameter(cnode *root)
1143464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1144464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *param;
1145464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *value;
1146464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    size_t curSize = sizeof(effect_param_t);
1147464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
1148464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
1149464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1150464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    param = config_find(root, PARAM_TAG);
1151464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    value = config_find(root, VALUE_TAG);
1152464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (param == NULL && value == NULL) {
1153464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        // try to parse simple parameter form {int int}
1154464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        param = root->first_child;
1155464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (param) {
1156464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            // Note: that a pair of random strings is read as 0 0
1157464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            int *ptr = (int *)fx_param->data;
1158464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            int *ptr2 = (int *)((char *)param + sizeof(effect_param_t));
1159464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            LOGW("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2);
1160464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            *ptr++ = atoi(param->name);
1161464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            *ptr = atoi(param->value);
1162464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            fx_param->psize = sizeof(int);
1163464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            fx_param->vsize = sizeof(int);
1164464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            return fx_param;
1165464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1166464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1167464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (param == NULL || value == NULL) {
1168464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGW("loadEffectParameter() invalid parameter description %s", root->name);
1169464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        goto error;
1170464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1171464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1172464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    fx_param->psize = 0;
1173464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    param = param->first_child;
1174464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    while (param) {
1175464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("loadEffectParameter() reading param of type %s", param->name);
1176464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t size = readParamValue(param, (char *)fx_param, &curSize, &totSize);
1177464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (size == 0) {
1178464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            goto error;
1179464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1180464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        fx_param->psize += size;
1181464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        param = param->next;
1182464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1183464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1184464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    // align start of value field on 32 bit boundary
1185464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int);
1186464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1187464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    fx_param->vsize = 0;
1188464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    value = value->first_child;
1189464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    while (value) {
1190464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("loadEffectParameter() reading value of type %s", value->name);
1191464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t size = readParamValue(value, (char *)fx_param, &curSize, &totSize);
1192464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (size == 0) {
1193464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            goto error;
1194464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1195464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        fx_param->vsize += size;
1196464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        value = value->next;
1197464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1198464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1199464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return fx_param;
1200464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1201464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurenterror:
1202464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    delete fx_param;
1203464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return NULL;
1204464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1205464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1206464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentvoid AudioPolicyService::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params)
1207464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1208464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *node = root->first_child;
1209464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    while (node) {
1210464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("loadEffectParameters() loading param %s", node->name);
1211464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        effect_param_t *param = loadEffectParameter(node);
1212464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (param == NULL) {
1213464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            node = node->next;
1214464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            continue;
1215464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1216464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        params.add(param);
1217464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        node = node->next;
1218464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1219464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1220464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1221464d5b3da21c84ba13dc69c611d40f6bed49badbEric LaurentAudioPolicyService::InputSourceDesc *AudioPolicyService::loadInputSource(
1222464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                                            cnode *root,
1223464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                                                            const Vector <EffectDesc *>& effects)
1224464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1225464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *node = root->first_child;
1226464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (node == NULL) {
1227464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGW("loadInputSource() empty element %s", root->name);
1228464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return NULL;
1229464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1230464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    InputSourceDesc *source = new InputSourceDesc();
1231464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    while (node) {
1232464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        size_t i;
1233464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        for (i = 0; i < effects.size(); i++) {
1234464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) {
1235464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                LOGV("loadInputSource() found effect %s in list", node->name);
1236464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent                break;
1237464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            }
1238464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1239464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (i == effects.size()) {
1240464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            LOGV("loadInputSource() effect %s not in list", node->name);
1241464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            node = node->next;
1242464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            continue;
1243464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1244464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        EffectDesc *effect = new EffectDesc(*effects[i]);
1245464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        loadEffectParameters(node, effect->mParams);
1246464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("loadInputSource() adding effect %s uuid %08x", effect->mName, effect->mUuid.timeLow);
1247464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        source->mEffects.add(effect);
1248464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        node = node->next;
1249464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1250464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (source->mEffects.size() == 0) {
1251464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGW("loadInputSource() no valid effects found in source %s", root->name);
1252464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        delete source;
1253464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return NULL;
1254464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1255464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return source;
1256464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1257464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1258464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentstatus_t AudioPolicyService::loadInputSources(cnode *root, const Vector <EffectDesc *>& effects)
1259464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1260464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *node = config_find(root, PREPROCESSING_TAG);
1261464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (node == NULL) {
1262464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return -ENOENT;
1263464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1264464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    node = node->first_child;
1265464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    while (node) {
1266464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        audio_source_t source = inputSourceNameToEnum(node->name);
1267464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (source == AUDIO_SOURCE_CNT) {
1268464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            LOGW("loadInputSources() invalid input source %s", node->name);
1269464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            node = node->next;
1270464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            continue;
1271464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1272464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("loadInputSources() loading input source %s", node->name);
1273464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        InputSourceDesc *desc = loadInputSource(node, effects);
1274464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (desc == NULL) {
1275464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            node = node->next;
1276464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            continue;
1277464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1278464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        mInputSources.add(source, desc);
1279464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        node = node->next;
1280464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1281464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return NO_ERROR;
1282464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1283464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1284464d5b3da21c84ba13dc69c611d40f6bed49badbEric LaurentAudioPolicyService::EffectDesc *AudioPolicyService::loadEffect(cnode *root)
1285464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1286464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *node = config_find(root, UUID_TAG);
1287464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (node == NULL) {
1288464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return NULL;
1289464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1290464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    effect_uuid_t uuid;
1291464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) {
1292464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGW("loadEffect() invalid uuid %s", node->value);
1293464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return NULL;
1294464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1295464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    EffectDesc *effect = new EffectDesc();
1296464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    effect->mName = strdup(root->name);
1297464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    memcpy(&effect->mUuid, &uuid, sizeof(effect_uuid_t));
1298464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1299464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return effect;
1300464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1301464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1302464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentstatus_t AudioPolicyService::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
1303464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1304464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *node = config_find(root, EFFECTS_TAG);
1305464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (node == NULL) {
1306464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return -ENOENT;
1307464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1308464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    node = node->first_child;
1309464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    while (node) {
1310464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        LOGV("loadEffects() loading effect %s", node->name);
1311464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        EffectDesc *effect = loadEffect(node);
1312464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        if (effect == NULL) {
1313464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            node = node->next;
1314464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent            continue;
1315464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        }
1316464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        effects.add(effect);
1317464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        node = node->next;
1318464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1319464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return NO_ERROR;
1320464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1321464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1322464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurentstatus_t AudioPolicyService::loadPreProcessorConfig(const char *path)
1323464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent{
1324464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    cnode *root;
1325464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    char *data;
1326464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1327464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    data = (char *)load_file(path, NULL);
1328464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    if (data == NULL) {
1329464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent        return -ENODEV;
1330464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    }
1331464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    root = config_node("", "");
1332464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    config_load(root, data);
1333464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1334464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    Vector <EffectDesc *> effects;
1335464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    loadEffects(root, effects);
1336464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    loadInputSources(root, effects);
1337464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1338464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    config_free(root);
1339464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    free(root);
1340464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    free(data);
1341464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
1342464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent    return NO_ERROR;
1343464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent}
1344464d5b3da21c84ba13dc69c611d40f6bed49badbEric Laurent
134524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin/* implementation of the interface to the policy manager */
134624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinextern "C" {
134724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
134824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic audio_io_handle_t aps_open_output(void *service,
134924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                             uint32_t *pDevices,
135024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                             uint32_t *pSamplingRate,
135124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                             uint32_t *pFormat,
135224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                             uint32_t *pChannels,
135324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                             uint32_t *pLatencyMs,
135424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                             audio_policy_output_flags_t flags)
135524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
135624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
135724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL) {
135824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGW("%s: could not get AudioFlinger", __func__);
135924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return 0;
136024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    }
136124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
136224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->openOutput(pDevices, pSamplingRate, pFormat, pChannels,
136324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                          pLatencyMs, flags);
136424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
136524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
136624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic audio_io_handle_t aps_open_dup_output(void *service,
136724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                 audio_io_handle_t output1,
136824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                                 audio_io_handle_t output2)
136924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
137024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
137124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL) {
137224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGW("%s: could not get AudioFlinger", __func__);
137324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return 0;
137424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    }
137524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->openDuplicateOutput(output1, output2);
137624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
137724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
137824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_close_output(void *service, audio_io_handle_t output)
137924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
138024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
138124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL)
138224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return PERMISSION_DENIED;
138324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
138424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->closeOutput(output);
138524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
138624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
138724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_suspend_output(void *service, audio_io_handle_t output)
138824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
138924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
139024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL) {
139124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGW("%s: could not get AudioFlinger", __func__);
139224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return PERMISSION_DENIED;
139324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    }
139424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
139524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->suspendOutput(output);
139624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
139724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
139824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_restore_output(void *service, audio_io_handle_t output)
139924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
140024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
140124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL) {
140224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGW("%s: could not get AudioFlinger", __func__);
140324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return PERMISSION_DENIED;
140424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    }
140524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
140624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->restoreOutput(output);
140724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
140824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
140924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic audio_io_handle_t aps_open_input(void *service,
141024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                            uint32_t *pDevices,
141124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                            uint32_t *pSamplingRate,
141224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                            uint32_t *pFormat,
141324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                            uint32_t *pChannels,
141424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                            uint32_t acoustics)
141524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
141624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
141724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL) {
141824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        LOGW("%s: could not get AudioFlinger", __func__);
141924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return 0;
142024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    }
142124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
142224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->openInput(pDevices, pSamplingRate, pFormat, pChannels,
142324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                         acoustics);
142424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
142524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
142624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_close_input(void *service, audio_io_handle_t input)
142724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
142824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
142924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL)
143024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return PERMISSION_DENIED;
143124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
143224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->closeInput(input);
143324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
143424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
143524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_set_stream_output(void *service, audio_stream_type_t stream,
143624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                     audio_io_handle_t output)
143724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
143824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
143924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL)
144024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return PERMISSION_DENIED;
144124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
144224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->setStreamOutput(stream, output);
144324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
144424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
144524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_move_effects(void *service, int session,
144624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                audio_io_handle_t src_output,
144724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                audio_io_handle_t dst_output)
144824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
144924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
145024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    if (af == NULL)
145124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        return PERMISSION_DENIED;
145224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
145324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return af->moveEffects(session, (int)src_output, (int)dst_output);
145424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
145524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
145624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic char * aps_get_parameters(void *service, audio_io_handle_t io_handle,
145724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                     const char *keys)
145824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
145924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    String8 result = AudioSystem::getParameters(io_handle, String8(keys));
146024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return strdup(result.string());
146124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
146224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
146324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic void aps_set_parameters(void *service, audio_io_handle_t io_handle,
146424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                   const char *kv_pairs, int delay_ms)
146524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
146624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
146724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
146824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    audioPolicyService->setParameters(io_handle, kv_pairs, delay_ms);
146924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
147024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
147124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_set_stream_volume(void *service, audio_stream_type_t stream,
147224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                     float volume, audio_io_handle_t output,
147324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                     int delay_ms)
147424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
147524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
147624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
147724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return audioPolicyService->setStreamVolume(stream, volume, output,
147824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                                               delay_ms);
147924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
148024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
148124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_start_tone(void *service, audio_policy_tone_t tone,
148224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin                              audio_stream_type_t stream)
148324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
148424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
148524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
148624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return audioPolicyService->startTone(tone, stream);
148724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
148824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
148924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_stop_tone(void *service)
149024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
149124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
149224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
149324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return audioPolicyService->stopTone();
149424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
149524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
149624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinstatic int aps_set_voice_volume(void *service, float volume, int delay_ms)
149724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin{
149824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
149924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
150024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    return audioPolicyService->setVoiceVolume(volume, delay_ms);
150124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}
150224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
150324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}; // extern "C"
150424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
150524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavinnamespace {
150624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    struct audio_policy_service_ops aps_ops = {
150724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        open_output           : aps_open_output,
150824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        open_duplicate_output : aps_open_dup_output,
150924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        close_output          : aps_close_output,
151024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        suspend_output        : aps_suspend_output,
151124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        restore_output        : aps_restore_output,
151224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        open_input            : aps_open_input,
151324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        close_input           : aps_close_input,
151424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        set_stream_volume     : aps_set_stream_volume,
151524fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        set_stream_output     : aps_set_stream_output,
151624fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        set_parameters        : aps_set_parameters,
151724fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        get_parameters        : aps_get_parameters,
151824fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        start_tone            : aps_start_tone,
151924fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        stop_tone             : aps_stop_tone,
152024fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        set_voice_volume      : aps_set_voice_volume,
152124fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin        move_effects          : aps_move_effects,
152224fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin    };
152324fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin}; // namespace <unnamed>
152424fc2fb1c541e954b83fd31ea9f786a5e9b45501Dima Zavin
1525a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}; // namespace android
1526