AudioPolicyService.cpp revision 0f11b51a57bc9062c4fe8af73747319cedabc5d6
165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian/*
265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Copyright (C) 2009 The Android Open Source Project
365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * you may not use this file except in compliance with the License.
665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * You may obtain a copy of the License at
765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian *
1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * Unless required by applicable law or agreed to in writing, software
1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * See the License for the specific language governing permissions and
1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian * limitations under the License.
1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian */
1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "AudioPolicyService"
1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//#define LOG_NDEBUG 0
1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
20153b9fe667e6e78e0218ff0159353097428c7657Glenn Kasten#include "Configuration.h"
2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#undef __STRICT_ANSI__
2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define __STDINT_LIMITS
2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define __STDC_LIMIT_MACROS
2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <stdint.h>
2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/time.h>
2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h>
2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h>
2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/properties.h>
3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h>
3165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h>
3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/threads.h>
3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "AudioPolicyService.h"
3444deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten#include "ServiceUtilities.h"
3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware_legacy/power.h>
367c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent#include <media/AudioEffect.h>
377c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent#include <media/EffectsFactoryApi.h>
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <hardware/hardware.h>
4064760240f931714858a59c1579f07264d7182ba2Dima Zavin#include <system/audio.h>
417394a4f358fa9908a9f0a7c954b65c399f4268e6Dima Zavin#include <system/audio_policy.h>
42fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include <hardware/audio_policy.h>
437c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent#include <audio_effects/audio_effects_conf.h>
441ab85ec401801ef9a9184650d0f5a1639b45eeb9Glenn Kasten#include <media/AudioParameter.h>
45fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
488dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kDeadlockedString[] = "AudioPolicyService may be deadlocked\n";
498dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kastenstatic const char kCmdDeadlockedString[] = "AudioPolicyService command thread may be deadlocked\n";
5065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
5222ecc912a87099cff8cadc424cd12f85c118673fGlenn Kastenstatic const int kDumpLockSleepUs = 20000;
5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
541b8ae3d9f3605fab7d14c323f2118ba3c769a42aGlenn Kastenstatic const nsecs_t kAudioCommandTimeout = 3000000000LL; // 3 seconds
555fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher
56fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinnamespace {
57fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    extern struct audio_policy_service_ops aps_ops;
58fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin};
59fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioPolicyService()
63fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    : BnAudioPolicyService() , mpAudioPolicyDev(NULL) , mpAudioPolicy(NULL)
6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char value[PROPERTY_VALUE_MAX];
66fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    const struct hw_module_t *module;
67fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    int forced_val;
68fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    int rc;
6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
70935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent    Mutex::Autolock _l(mLock);
71935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent
7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // start tone playback thread
73bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    mTonePlaybackThread = new AudioCommandThread(String8("ApmTone"), this);
7465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // start audio commands thread
75bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
76bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    // start output activity command thread
77bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);
78fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    /* instantiate the audio policy manager */
79fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    rc = hw_get_module(AUDIO_POLICY_HARDWARE_MODULE_ID, &module);
806e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (rc) {
81fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return;
826e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
8365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
84fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    rc = audio_policy_dev_open(module, &mpAudioPolicyDev);
8529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE_IF(rc, "couldn't open audio policy device (%s)", strerror(-rc));
866e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (rc) {
87fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return;
886e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
89935752053ef2691dbb6d5a6d149e0e362c6e3c74Eric Laurent
90fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    rc = mpAudioPolicyDev->create_audio_policy(mpAudioPolicyDev, &aps_ops, this,
91fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                               &mpAudioPolicy);
9229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE_IF(rc, "couldn't create audio policy (%s)", strerror(-rc));
936e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (rc) {
94fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return;
956e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
96fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
97fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    rc = mpAudioPolicy->init_check(mpAudioPolicy);
9829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE_IF(rc, "couldn't init_check the audio policy (%s)", strerror(-rc));
996e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (rc) {
100fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return;
1016e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
102fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
103df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("Loaded audio policy from %s (%s)", module->name, module->id);
1047c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
1057c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    // load audio pre processing modules
1067c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (access(AUDIO_EFFECT_VENDOR_CONFIG_FILE, R_OK) == 0) {
1077c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        loadPreProcessorConfig(AUDIO_EFFECT_VENDOR_CONFIG_FILE);
1087c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    } else if (access(AUDIO_EFFECT_DEFAULT_CONFIG_FILE, R_OK) == 0) {
1097c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        loadPreProcessorConfig(AUDIO_EFFECT_DEFAULT_CONFIG_FILE);
1107c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
11165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
11265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
11365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::~AudioPolicyService()
11465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
11565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mTonePlaybackThread->exit();
11665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mTonePlaybackThread.clear();
11765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioCommandThread->exit();
11865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioCommandThread.clear();
11965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1207c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
1217c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    // release audio pre processing resources
1227c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    for (size_t i = 0; i < mInputSources.size(); i++) {
1239fda4b87441fe17d90d8144639c9de6d9022c3c0Glenn Kasten        delete mInputSources.valueAt(i);
1247c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
1257c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    mInputSources.clear();
1267c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
1277c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    for (size_t i = 0; i < mInputs.size(); i++) {
1287c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        mInputs.valueAt(i)->mEffects.clear();
1297c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        delete mInputs.valueAt(i);
1307c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
1317c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    mInputs.clear();
1327c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
1336e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (mpAudioPolicy != NULL && mpAudioPolicyDev != NULL) {
134fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        mpAudioPolicyDev->destroy_audio_policy(mpAudioPolicyDev, mpAudioPolicy);
1356e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
1366e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (mpAudioPolicyDev != NULL) {
137fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        audio_policy_dev_close(mpAudioPolicyDev);
1386e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
13965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
14065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
141fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatus_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
142fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                  audio_policy_dev_state_t state,
14365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                                  const char *device_address)
14465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
145fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
14665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
14765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
14844deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!settingsAllowed()) {
14965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
15065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
151fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (!audio_is_output_device(device) && !audio_is_input_device(device)) {
15265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
15365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
154fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE &&
155fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            state != AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
15665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
15765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
15865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
159411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten    ALOGV("setDeviceConnectionState()");
16065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
161fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return mpAudioPolicy->set_device_connection_state(mpAudioPolicy, device,
162fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                      state, device_address);
16365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
16465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
165fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinaudio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
166fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                              audio_devices_t device,
167de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                              const char *device_address)
16865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
169fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
170fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
17165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
172fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return mpAudioPolicy->get_device_connection_state(mpAudioPolicy, device,
173fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                      device_address);
17465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
17565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
176f78aee70d15daf4690de7e7b4983ee68b0d1381dGlenn Kastenstatus_t AudioPolicyService::setPhoneState(audio_mode_t state)
17765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
178fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
17965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
18065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
18144deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!settingsAllowed()) {
18265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
18365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
184930f4caa1e311ef7ff538c421a324396157eb24fGlenn Kasten    if (uint32_t(state) >= AUDIO_MODE_CNT) {
18565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
18665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
18765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
188411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten    ALOGV("setPhoneState()");
18965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
19065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // TODO: check if it is more appropriate to do it in platform specific policy manager
19165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AudioSystem::setMode(state);
19265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
19365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
194fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mpAudioPolicy->set_phone_state(mpAudioPolicy, state);
19565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
19665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
19765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
198fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatus_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage,
199fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                         audio_policy_forced_cfg_t config)
20065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
201fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
20265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
20365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
20444deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!settingsAllowed()) {
20565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
20665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
207fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
20965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
210fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (config < 0 || config >= AUDIO_POLICY_FORCE_CFG_CNT) {
21165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
21265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
213411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten    ALOGV("setForceUse()");
21465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
215fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mpAudioPolicy->set_force_use(mpAudioPolicy, usage, config);
21665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
21765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
21865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
219fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinaudio_policy_forced_cfg_t AudioPolicyService::getForceUse(audio_policy_force_use_t usage)
22065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
221fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
222fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return AUDIO_POLICY_FORCE_NONE;
22365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
224fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
225fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return AUDIO_POLICY_FORCE_NONE;
22665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
227fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return mpAudioPolicy->get_force_use(mpAudioPolicy, usage);
22865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
22965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
230fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinaudio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
23165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                    uint32_t samplingRate,
23258f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten                                    audio_format_t format,
233254af180475346b6186b49c297f340c9c4817511Glenn Kasten                                    audio_channel_mask_t channelMask,
234ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                                    audio_output_flags_t flags,
235ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                                    const audio_offload_info_t *offloadInfo)
23665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
237fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
23865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
23965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
240411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten    ALOGV("getOutput()");
24165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
242ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald    return mpAudioPolicy->get_output(mpAudioPolicy, stream, samplingRate,
243ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                                    format, channelMask, flags, offloadInfo);
24465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
24565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
246de070137f11d346fba77605bd76a44c040a618fcEric Laurentstatus_t AudioPolicyService::startOutput(audio_io_handle_t output,
247fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                         audio_stream_type_t stream,
248de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                         int session)
24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
250fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
253411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten    ALOGV("startOutput()");
25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
255fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return mpAudioPolicy->start_output(mpAudioPolicy, output, stream, session);
25665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
25765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
258de070137f11d346fba77605bd76a44c040a618fcEric Laurentstatus_t AudioPolicyService::stopOutput(audio_io_handle_t output,
259fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                        audio_stream_type_t stream,
260de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                        int session)
26165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
262fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
26365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
26465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
265411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten    ALOGV("stopOutput()");
266bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    mOutputCommandThread->stopOutputCommand(output, stream, session);
267bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    return NO_ERROR;
268bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
269bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
270bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentstatus_t  AudioPolicyService::doStopOutput(audio_io_handle_t output,
271bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                                      audio_stream_type_t stream,
272bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                                      int session)
273bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{
274bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ALOGV("doStopOutput from tid %d", gettid());
27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
276fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return mpAudioPolicy->stop_output(mpAudioPolicy, output, stream, session);
27765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
27865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::releaseOutput(audio_io_handle_t output)
28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
281fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
28265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
28365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
284411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten    ALOGV("releaseOutput()");
285bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    mOutputCommandThread->releaseOutputCommand(output);
286bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
287bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
288bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioPolicyService::doReleaseOutput(audio_io_handle_t output)
289bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{
290bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ALOGV("doReleaseOutput from tid %d", gettid());
29165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
292fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mpAudioPolicy->release_output(mpAudioPolicy, output);
29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
29465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
295eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kastenaudio_io_handle_t AudioPolicyService::getInput(audio_source_t inputSource,
29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                    uint32_t samplingRate,
29758f30210ea540b6ce5aa6a46330cd3499483cb97Glenn Kasten                                    audio_format_t format,
298254af180475346b6186b49c297f340c9c4817511Glenn Kasten                                    audio_channel_mask_t channelMask,
2997c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                    int audioSession)
30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
301fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return 0;
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
304eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten    // already checked by client, but double-check in case the client wrapper is bypassed
3059a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    if (inputSource >= AUDIO_SOURCE_CNT && inputSource != AUDIO_SOURCE_HOTWORD) {
306eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten        return 0;
307eba51fb3a361f67a6a64d5a16eba6084fe27d60eGlenn Kasten    }
3089a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent
3099a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    if ((inputSource == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) {
3109a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent        return 0;
3119a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    }
3129a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent
31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
31420010053daabfa43fcfe781bbf004473b4c08538Glenn Kasten    // the audio_in_acoustics_t parameter is ignored by get_input()
3157c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    audio_io_handle_t input = mpAudioPolicy->get_input(mpAudioPolicy, inputSource, samplingRate,
3168af901cdea0af7e536579dee6d56e69987035a01Glenn Kasten                                                   format, channelMask, (audio_in_acoustics_t) 0);
3177c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
3187c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (input == 0) {
3197c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return input;
3207c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
3217c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    // create audio pre processors according to input source
3229a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    audio_source_t aliasSource = (inputSource == AUDIO_SOURCE_HOTWORD) ?
3239a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent                                    AUDIO_SOURCE_VOICE_RECOGNITION : inputSource;
3249a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent
3259a54bc27876acd5d8be5b1fc3dc46701fe76fbb3Eric Laurent    ssize_t index = mInputSources.indexOfKey(aliasSource);
3267c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (index < 0) {
3277c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return input;
3287c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
3297c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    ssize_t idx = mInputs.indexOfKey(input);
3307c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    InputDesc *inputDesc;
3317c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (idx < 0) {
33281872a2ce65653ae980621ba2907da56a83ba9a7Glenn Kasten        inputDesc = new InputDesc(audioSession);
3337c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        mInputs.add(input, inputDesc);
3347c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    } else {
3357c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        inputDesc = mInputs.valueAt(idx);
3367c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
3377c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
3387c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    Vector <EffectDesc *> effects = mInputSources.valueAt(index)->mEffects;
3397c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    for (size_t i = 0; i < effects.size(); i++) {
3407c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        EffectDesc *effect = effects[i];
3417c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        sp<AudioEffect> fx = new AudioEffect(NULL, &effect->mUuid, -1, 0, 0, audioSession, input);
3427c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        status_t status = fx->initCheck();
3437c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (status != NO_ERROR && status != ALREADY_EXISTS) {
3445ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("Failed to create Fx %s on input %d", effect->mName, input);
3457c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            // fx goes out of scope and strong ref on AudioEffect is released
3467c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            continue;
3477c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
3487c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        for (size_t j = 0; j < effect->mParams.size(); j++) {
3497c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            fx->setParameter(effect->mParams[j]);
3507c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
3517c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        inputDesc->mEffects.add(fx);
3527c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
3537c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    setPreProcessorEnabled(inputDesc, true);
3547c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return input;
35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::startInput(audio_io_handle_t input)
35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
359fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
36265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
3637c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
364fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return mpAudioPolicy->start_input(mpAudioPolicy, input);
36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::stopInput(audio_io_handle_t input)
36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
369fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
3737c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
374fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return mpAudioPolicy->stop_input(mpAudioPolicy, input);
37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::releaseInput(audio_io_handle_t input)
37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
379fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
383fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mpAudioPolicy->release_input(mpAudioPolicy, input);
3847c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
3857c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    ssize_t index = mInputs.indexOfKey(input);
3867c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (index < 0) {
3877c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return;
3887c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
3897c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    InputDesc *inputDesc = mInputs.valueAt(index);
3907c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    setPreProcessorEnabled(inputDesc, false);
3917c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    delete inputDesc;
3927c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    mInputs.removeItemsAt(index);
39365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
39465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
395fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatus_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
39665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                            int indexMin,
39765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                            int indexMax)
39865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
399fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
40165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
40244deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!settingsAllowed()) {
40365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
40465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
405263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
4085f12136299918ea30555f3481668ec0dbb775e5fEric Laurent    Mutex::Autolock _l(mLock);
409fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mpAudioPolicy->init_stream_volume(mpAudioPolicy, stream, indexMin, indexMax);
41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
41165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
41265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
41383844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurentstatus_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
41483844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent                                                  int index,
41583844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent                                                  audio_devices_t device)
41665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
417fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
41865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
41965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
42044deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!settingsAllowed()) {
42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return PERMISSION_DENIED;
42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
423263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
42465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
42565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
4265f12136299918ea30555f3481668ec0dbb775e5fEric Laurent    Mutex::Autolock _l(mLock);
42783844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent    if (mpAudioPolicy->set_stream_volume_index_for_device) {
42883844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent        return mpAudioPolicy->set_stream_volume_index_for_device(mpAudioPolicy,
42983844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent                                                                stream,
43083844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent                                                                index,
43183844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent                                                                device);
43283844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent    } else {
43383844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent        return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);
43483844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent    }
43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
43665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43783844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurentstatus_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
43883844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent                                                  int *index,
43983844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent                                                  audio_devices_t device)
44065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
441fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
44265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_INIT;
44365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
444263709e7be37c7040aaef385bc5c9389a9b5f514Glenn Kasten    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
4475f12136299918ea30555f3481668ec0dbb775e5fEric Laurent    Mutex::Autolock _l(mLock);
44883844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent    if (mpAudioPolicy->get_stream_volume_index_for_device) {
44983844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent        return mpAudioPolicy->get_stream_volume_index_for_device(mpAudioPolicy,
45083844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent                                                                stream,
45183844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent                                                                index,
45283844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent                                                                device);
45383844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent    } else {
45483844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent        return mpAudioPolicy->get_stream_volume_index(mpAudioPolicy, stream, index);
45583844cc2f95dc279015b47fd1e18c7cb4eabe9a1Eric Laurent    }
45665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
45765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
458fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinuint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
459de070137f11d346fba77605bd76a44c040a618fcEric Laurent{
460fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
461de070137f11d346fba77605bd76a44c040a618fcEric Laurent        return 0;
462de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
463fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return mpAudioPolicy->get_strategy_for_stream(mpAudioPolicy, stream);
464de070137f11d346fba77605bd76a44c040a618fcEric Laurent}
465de070137f11d346fba77605bd76a44c040a618fcEric Laurent
4666374252107fd6539397598195ea6defd5870fafbEric Laurent//audio policy: use audio_device_t appropriately
4676374252107fd6539397598195ea6defd5870fafbEric Laurent
4686374252107fd6539397598195ea6defd5870fafbEric Laurentaudio_devices_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
4696b2718c67aa7b1a8e3b0f25a73a0d5f72c59ffc3Glenn Kasten{
470fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
4716374252107fd6539397598195ea6defd5870fafbEric Laurent        return (audio_devices_t)0;
4726b2718c67aa7b1a8e3b0f25a73a0d5f72c59ffc3Glenn Kasten    }
473fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return mpAudioPolicy->get_devices_for_stream(mpAudioPolicy, stream);
4746b2718c67aa7b1a8e3b0f25a73a0d5f72c59ffc3Glenn Kasten}
4756b2718c67aa7b1a8e3b0f25a73a0d5f72c59ffc3Glenn Kasten
47658e5aa34f01d663654d8bafad65db1dda42161ffGlenn Kastenaudio_io_handle_t AudioPolicyService::getOutputForEffect(const effect_descriptor_t *desc)
477de070137f11d346fba77605bd76a44c040a618fcEric Laurent{
478efa6ea97022780b68e595e5326e30dbe2a799202Glenn Kasten    // FIXME change return type to status_t, and return NO_INIT here
479fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
480efa6ea97022780b68e595e5326e30dbe2a799202Glenn Kasten        return 0;
481de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
482de070137f11d346fba77605bd76a44c040a618fcEric Laurent    Mutex::Autolock _l(mLock);
483fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return mpAudioPolicy->get_output_for_effect(mpAudioPolicy, desc);
484de070137f11d346fba77605bd76a44c040a618fcEric Laurent}
485de070137f11d346fba77605bd76a44c040a618fcEric Laurent
48658e5aa34f01d663654d8bafad65db1dda42161ffGlenn Kastenstatus_t AudioPolicyService::registerEffect(const effect_descriptor_t *desc,
4877c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                audio_io_handle_t io,
488de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                uint32_t strategy,
489de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                int session,
490de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                int id)
491de070137f11d346fba77605bd76a44c040a618fcEric Laurent{
492fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
493de070137f11d346fba77605bd76a44c040a618fcEric Laurent        return NO_INIT;
494de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
4957c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return mpAudioPolicy->register_effect(mpAudioPolicy, desc, io, strategy, session, id);
496de070137f11d346fba77605bd76a44c040a618fcEric Laurent}
497de070137f11d346fba77605bd76a44c040a618fcEric Laurent
498de070137f11d346fba77605bd76a44c040a618fcEric Laurentstatus_t AudioPolicyService::unregisterEffect(int id)
499de070137f11d346fba77605bd76a44c040a618fcEric Laurent{
500fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
501de070137f11d346fba77605bd76a44c040a618fcEric Laurent        return NO_INIT;
502de070137f11d346fba77605bd76a44c040a618fcEric Laurent    }
503fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return mpAudioPolicy->unregister_effect(mpAudioPolicy, id);
504de070137f11d346fba77605bd76a44c040a618fcEric Laurent}
505de070137f11d346fba77605bd76a44c040a618fcEric Laurent
506db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurentstatus_t AudioPolicyService::setEffectEnabled(int id, bool enabled)
507db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent{
508db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    if (mpAudioPolicy == NULL) {
509db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent        return NO_INIT;
510db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    }
511db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent    return mpAudioPolicy->set_effect_enabled(mpAudioPolicy, id, enabled);
512db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent}
513db7c079f284f6e91266f6653ae0ec198b1c5006eEric Laurent
514fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenbool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
515eda6c364c253ba97ee45a3adeb8c2b45db1f81dbEric Laurent{
516fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    if (mpAudioPolicy == NULL) {
517eda6c364c253ba97ee45a3adeb8c2b45db1f81dbEric Laurent        return 0;
518eda6c364c253ba97ee45a3adeb8c2b45db1f81dbEric Laurent    }
519eda6c364c253ba97ee45a3adeb8c2b45db1f81dbEric Laurent    Mutex::Autolock _l(mLock);
520fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return mpAudioPolicy->is_stream_active(mpAudioPolicy, stream, inPastMs);
521eda6c364c253ba97ee45a3adeb8c2b45db1f81dbEric Laurent}
522eda6c364c253ba97ee45a3adeb8c2b45db1f81dbEric Laurent
523e336f9113bdd35119866a3c3f8008ca01c576660Jean-Michel Trivibool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
524e336f9113bdd35119866a3c3f8008ca01c576660Jean-Michel Trivi{
525e336f9113bdd35119866a3c3f8008ca01c576660Jean-Michel Trivi    if (mpAudioPolicy == NULL) {
526e336f9113bdd35119866a3c3f8008ca01c576660Jean-Michel Trivi        return 0;
527e336f9113bdd35119866a3c3f8008ca01c576660Jean-Michel Trivi    }
528e336f9113bdd35119866a3c3f8008ca01c576660Jean-Michel Trivi    Mutex::Autolock _l(mLock);
529e336f9113bdd35119866a3c3f8008ca01c576660Jean-Michel Trivi    return mpAudioPolicy->is_stream_active_remotely(mpAudioPolicy, stream, inPastMs);
530e336f9113bdd35119866a3c3f8008ca01c576660Jean-Michel Trivi}
531e336f9113bdd35119866a3c3f8008ca01c576660Jean-Michel Trivi
532e3f641fd9348bf7f4c07f6cc707347fccea1439cJean-Michel Trivibool AudioPolicyService::isSourceActive(audio_source_t source) const
533e3f641fd9348bf7f4c07f6cc707347fccea1439cJean-Michel Trivi{
534e3f641fd9348bf7f4c07f6cc707347fccea1439cJean-Michel Trivi    if (mpAudioPolicy == NULL) {
535e3f641fd9348bf7f4c07f6cc707347fccea1439cJean-Michel Trivi        return false;
536e3f641fd9348bf7f4c07f6cc707347fccea1439cJean-Michel Trivi    }
537e3f641fd9348bf7f4c07f6cc707347fccea1439cJean-Michel Trivi    if (mpAudioPolicy->is_source_active == 0) {
538e3f641fd9348bf7f4c07f6cc707347fccea1439cJean-Michel Trivi        return false;
539e3f641fd9348bf7f4c07f6cc707347fccea1439cJean-Michel Trivi    }
540e3f641fd9348bf7f4c07f6cc707347fccea1439cJean-Michel Trivi    Mutex::Autolock _l(mLock);
541e3f641fd9348bf7f4c07f6cc707347fccea1439cJean-Michel Trivi    return mpAudioPolicy->is_source_active(mpAudioPolicy, source);
542e3f641fd9348bf7f4c07f6cc707347fccea1439cJean-Michel Trivi}
543e3f641fd9348bf7f4c07f6cc707347fccea1439cJean-Michel Trivi
54457dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurentstatus_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
54557dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent                                                       effect_descriptor_t *descriptors,
54657dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent                                                       uint32_t *count)
54757dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent{
54857dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent
54957dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    if (mpAudioPolicy == NULL) {
55057dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent        *count = 0;
55157dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent        return NO_INIT;
55257dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    }
55357dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    Mutex::Autolock _l(mLock);
55457dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    status_t status = NO_ERROR;
55557dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent
55657dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    size_t index;
55757dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    for (index = 0; index < mInputs.size(); index++) {
55857dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent        if (mInputs.valueAt(index)->mSessionId == audioSession) {
55957dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent            break;
56057dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent        }
56157dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    }
56257dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    if (index == mInputs.size()) {
56357dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent        *count = 0;
56457dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent        return BAD_VALUE;
56557dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    }
56657dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects;
56757dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent
56857dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    for (size_t i = 0; i < effects.size(); i++) {
56957dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent        effect_descriptor_t desc = effects[i]->descriptor();
57057dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent        if (i < *count) {
571a189a6883ee55cf62da1d7bf5bf5a8ab501938a4Glenn Kasten            descriptors[i] = desc;
57257dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent        }
57357dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    }
57457dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    if (effects.size() > *count) {
57557dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent        status = NO_MEMORY;
57657dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    }
57757dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    *count = effects.size();
57857dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent    return status;
57957dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent}
58057dae99c9fcd6becd2b5ed0c53f277ba4d7dbcfcEric Laurent
58165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::binderDied(const wp<IBinder>& who) {
582411e447c4b90298f5ff635429c53f94fbce4fff9Glenn Kasten    ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
583de070137f11d346fba77605bd76a44c040a618fcEric Laurent            IPCThreadState::self()->getCallingPid());
58465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
58565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
58665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
58765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
58865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
58965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
59065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
59165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
59265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
59365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
59422ecc912a87099cff8cadc424cd12f85c118673fGlenn Kasten        usleep(kDumpLockSleepUs);
59565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
59665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
59765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
59865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
59965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpInternals(int fd)
60065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
60165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
60265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
60365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
60465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
605fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpAudioPolicy);
60665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
60765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
60865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
60965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
61065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
61165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
61265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
61365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
61465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
61565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6160f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args __unused)
61765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
61844deb053252a3bd2f57a007ab9560f4924f62394Glenn Kasten    if (!dumpAllowed()) {
61965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpPermissionDenial(fd);
62065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
62165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool locked = tryLock(mLock);
62265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
62365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kDeadlockedString);
62465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
62565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
62665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
62765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        dumpInternals(fd);
6289d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten        if (mAudioCommandThread != 0) {
62965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mAudioCommandThread->dump(fd);
63065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
6319d1f02d74fd395ec4de6861147da289423f0ab6fGlenn Kasten        if (mTonePlaybackThread != 0) {
63265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mTonePlaybackThread->dump(fd);
63365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
63465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
635fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (mpAudioPolicy) {
636fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            mpAudioPolicy->dump(mpAudioPolicy, fd);
63765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
63865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
63965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (locked) mLock.unlock();
64065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
64265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
64365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
64465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::dumpPermissionDenial(int fd)
64565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
64665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
64765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
64865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
64965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "Permission Denial: "
65065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
65165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingPid(),
65265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            IPCThreadState::self()->getCallingUid());
65365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
65565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
65665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
65765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
65881872a2ce65653ae980621ba2907da56a83ba9a7Glenn Kastenvoid AudioPolicyService::setPreProcessorEnabled(const InputDesc *inputDesc, bool enabled)
6597c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
66081872a2ce65653ae980621ba2907da56a83ba9a7Glenn Kasten    const Vector<sp<AudioEffect> > &fxVector = inputDesc->mEffects;
6617c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    for (size_t i = 0; i < fxVector.size(); i++) {
662a111792f1314479c649d1d44c30c2caf70c00c2aGlenn Kasten        fxVector.itemAt(i)->setEnabled(enabled);
6637c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
6647c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
6657c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::onTransact(
66765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
66865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnAudioPolicyService::onTransact(code, data, reply, flags);
67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
67165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
67265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
67365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// -----------  AudioPolicyService::AudioCommandThread implementation ----------
67465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
675bfb1b832079bbb9426f72f3863199a54aefd02daEric LaurentAudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
676bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                                                           const wp<AudioPolicyService>& service)
677bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    : Thread(false), mName(name), mService(service)
67865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
67965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mpToneGenerator = NULL;
68065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
68265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianAudioPolicyService::AudioCommandThread::~AudioCommandThread()
68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
685bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (!mAudioCommands.isEmpty()) {
68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        release_wake_lock(mName.string());
68765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
68865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioCommands.clear();
689e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten    delete mpToneGenerator;
69065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
69165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
69265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::onFirstRef()
69365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
694bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    run(mName.string(), ANDROID_PRIORITY_AUDIO);
69565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
69665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
69765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool AudioPolicyService::AudioCommandThread::threadLoop()
69865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
69965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    nsecs_t waitTime = INT64_MAX;
70065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
70165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.lock();
70265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (!exitPending())
70365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
704e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten        while (!mAudioCommands.isEmpty()) {
70565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            nsecs_t curTime = systemTime();
70665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // commands are sorted by increasing time stamp: execute them from index 0 and up
70765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mAudioCommands[0]->mTime <= curTime) {
70865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                AudioCommand *command = mAudioCommands[0];
70965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mAudioCommands.removeAt(0);
71065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mLastCommand = *command;
71165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
71265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                switch (command->mCommand) {
71365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case START_TONE: {
71465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mLock.unlock();
71565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    ToneData *data = (ToneData *)command->mParam;
7163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("AudioCommandThread() processing start tone %d on stream %d",
71765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            data->mType, data->mStream);
718e9dd0176933d6233916c84e18f3e8c0d644ca05dGlenn Kasten                    delete mpToneGenerator;
71965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
72065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mpToneGenerator->startTone(data->mType);
72165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    delete data;
72265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mLock.lock();
72365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }break;
72465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case STOP_TONE: {
72565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mLock.unlock();
7263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("AudioCommandThread() processing stop tone");
72765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    if (mpToneGenerator != NULL) {
72865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        mpToneGenerator->stopTone();
72965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        delete mpToneGenerator;
73065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        mpToneGenerator = NULL;
73165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }
73265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    mLock.lock();
73365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }break;
73465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case SET_VOLUME: {
73565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    VolumeData *data = (VolumeData *)command->mParam;
7363856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("AudioCommandThread() processing set volume stream %d, \
737de070137f11d346fba77605bd76a44c040a618fcEric Laurent                            volume %f, output %d", data->mStream, data->mVolume, data->mIO);
738de070137f11d346fba77605bd76a44c040a618fcEric Laurent                    command->mStatus = AudioSystem::setStreamVolume(data->mStream,
739de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                                    data->mVolume,
740de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                                    data->mIO);
74165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    if (command->mWaitStatus) {
74265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        command->mCond.signal();
7435fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher                        command->mCond.waitRelative(mLock, kAudioCommandTimeout);
74465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }
74565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    delete data;
74665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }break;
74765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case SET_PARAMETERS: {
748e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    ParametersData *data = (ParametersData *)command->mParam;
749e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
750e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                            data->mKeyValuePairs.string(), data->mIO);
751e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
752e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    if (command->mWaitStatus) {
753e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        command->mCond.signal();
7545fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher                        command->mCond.waitRelative(mLock, kAudioCommandTimeout);
755e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    }
756e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    delete data;
757e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    }break;
75865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                case SET_VOICE_VOLUME: {
75965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
7603856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                    ALOGV("AudioCommandThread() processing set voice volume volume %f",
761de070137f11d346fba77605bd76a44c040a618fcEric Laurent                            data->mVolume);
76265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
76365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    if (command->mWaitStatus) {
76465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        command->mCond.signal();
7655fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher                        command->mCond.waitRelative(mLock, kAudioCommandTimeout);
76665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }
76765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    delete data;
76865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    }break;
769bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                case STOP_OUTPUT: {
770bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    StopOutputData *data = (StopOutputData *)command->mParam;
771bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    ALOGV("AudioCommandThread() processing stop output %d",
772bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                            data->mIO);
773bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    sp<AudioPolicyService> svc = mService.promote();
774bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    if (svc == 0) {
775bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                        break;
776bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    }
777bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mLock.unlock();
778bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    svc->doStopOutput(data->mIO, data->mStream, data->mSession);
779bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mLock.lock();
780bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    delete data;
781bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    }break;
782bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                case RELEASE_OUTPUT: {
783bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    ReleaseOutputData *data = (ReleaseOutputData *)command->mParam;
784bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    ALOGV("AudioCommandThread() processing release output %d",
785bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                            data->mIO);
786bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    sp<AudioPolicyService> svc = mService.promote();
787bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    if (svc == 0) {
788bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                        break;
789bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    }
790bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mLock.unlock();
791bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    svc->doReleaseOutput(data->mIO);
792bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    mLock.lock();
793bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    delete data;
794bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                    }break;
79565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                default:
7965ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                    ALOGW("AudioCommandThread() unknown command %d", command->mCommand);
79765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
79865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                delete command;
79965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                waitTime = INT64_MAX;
80065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
80165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                waitTime = mAudioCommands[0]->mTime - curTime;
80265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                break;
80365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
80465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
80565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // release delayed commands wake lock
806bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        if (mAudioCommands.isEmpty()) {
80765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            release_wake_lock(mName.string());
80865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
8093856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("AudioCommandThread() going to sleep");
81065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mWaitWorkCV.waitRelative(mLock, waitTime);
8113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("AudioCommandThread() waking up");
81265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
81365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.unlock();
81465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return false;
81565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
81665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::dump(int fd)
81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
81965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
82065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
82165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
82265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
82365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
82465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
82565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
82665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
82765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = tryLock(mLock);
82865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!locked) {
82965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        String8 result2(kCmdDeadlockedString);
83065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        write(fd, result2.string(), result2.size());
83165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
83265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, SIZE, "- Commands:\n");
83465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result = String8(buffer);
83565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("   Command Time        Wait pParam\n");
8368d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    for (size_t i = 0; i < mAudioCommands.size(); i++) {
83765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mAudioCommands[i]->dump(buffer, SIZE);
83865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
83965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
84065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append("  Last Command\n");
84165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLastCommand.dump(buffer, SIZE);
84265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result.append(buffer);
84365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
84465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    write(fd, result.string(), result.size());
84565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
84665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (locked) mLock.unlock();
84765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
84865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
84965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
85065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
8513d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kastenvoid AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::tone_type type,
8523d2f877c1cb4e4ae4ddde7f57f4353de9341f11bGlenn Kasten        audio_stream_type_t stream)
85365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
85465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AudioCommand *command = new AudioCommand();
85565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = START_TONE;
85665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ToneData *data = new ToneData();
85765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mType = type;
85865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mStream = stream;
85965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mParam = (void *)data;
86065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
86165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    insertCommand_l(command);
8623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
86365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mWaitWorkCV.signal();
86465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
86565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
86665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::stopToneCommand()
86765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
86865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AudioCommand *command = new AudioCommand();
86965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = STOP_TONE;
87065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mParam = NULL;
87165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
87265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    insertCommand_l(command);
8733856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding tone stop");
87465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mWaitWorkCV.signal();
87565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
87665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
877fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(audio_stream_type_t stream,
878de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                               float volume,
87972ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten                                                               audio_io_handle_t output,
880de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                               int delayMs)
88165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
88265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status = NO_ERROR;
88365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
88465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AudioCommand *command = new AudioCommand();
88565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = SET_VOLUME;
88665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    VolumeData *data = new VolumeData();
88765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mStream = stream;
88865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mVolume = volume;
88965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mIO = output;
89065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mParam = data;
89165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
89265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    insertCommand_l(command, delayMs);
8933856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d",
894de070137f11d346fba77605bd76a44c040a618fcEric Laurent            stream, volume, output);
89565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mWaitWorkCV.signal();
89665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (command->mWaitStatus) {
89765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        command->mCond.wait(mLock);
89865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status =  command->mStatus;
8995fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher        command->mCond.signal();
90065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
90165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
90265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
90365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
90472ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kastenstatus_t AudioPolicyService::AudioCommandThread::parametersCommand(audio_io_handle_t ioHandle,
905fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                                   const char *keyValuePairs,
906de070137f11d346fba77605bd76a44c040a618fcEric Laurent                                                                   int delayMs)
90765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
90865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status = NO_ERROR;
90965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AudioCommand *command = new AudioCommand();
91165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = SET_PARAMETERS;
91265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ParametersData *data = new ParametersData();
91365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mIO = ioHandle;
914fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    data->mKeyValuePairs = String8(keyValuePairs);
91565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mParam = data;
91665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
91765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    insertCommand_l(command, delayMs);
9183856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d",
919fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin            keyValuePairs, ioHandle, delayMs);
92065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mWaitWorkCV.signal();
92165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (command->mWaitStatus) {
92265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        command->mCond.wait(mLock);
92365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status =  command->mStatus;
9245fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher        command->mCond.signal();
92565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
92665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
92765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
92865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
92965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
93065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
93165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t status = NO_ERROR;
93265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
93365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    AudioCommand *command = new AudioCommand();
93465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mCommand = SET_VOICE_VOLUME;
93565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    VoiceVolumeData *data = new VoiceVolumeData();
93665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    data->mVolume = volume;
93765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mParam = data;
93865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock _l(mLock);
93965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    insertCommand_l(command, delayMs);
9403856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread() adding set voice volume volume %f", volume);
94165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mWaitWorkCV.signal();
94265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (command->mWaitStatus) {
94365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        command->mCond.wait(mLock);
94465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        status =  command->mStatus;
9455fa8c4bf81275d5e1f5ef71bc66fc22e3152eeb0Christer Fletcher        command->mCond.signal();
94665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
94765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return status;
94865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
94965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
950bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t output,
951bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                                                               audio_stream_type_t stream,
952bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                                                               int session)
953bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{
954bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    AudioCommand *command = new AudioCommand();
955bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    command->mCommand = STOP_OUTPUT;
956bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    StopOutputData *data = new StopOutputData();
957bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    data->mIO = output;
958bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    data->mStream = stream;
959bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    data->mSession = session;
960bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    command->mParam = (void *)data;
961bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    Mutex::Autolock _l(mLock);
962bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    insertCommand_l(command);
963bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ALOGV("AudioCommandThread() adding stop output %d", output);
964bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    mWaitWorkCV.signal();
965bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
966bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
967bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurentvoid AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handle_t output)
968bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent{
969bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    AudioCommand *command = new AudioCommand();
970bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    command->mCommand = RELEASE_OUTPUT;
971bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ReleaseOutputData *data = new ReleaseOutputData();
972bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    data->mIO = output;
973bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    command->mParam = (void *)data;
974bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    Mutex::Autolock _l(mLock);
975bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    insertCommand_l(command);
976bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    ALOGV("AudioCommandThread() adding release output %d", output);
977bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    mWaitWorkCV.signal();
978bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent}
979bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
98065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// insertCommand_l() must be called with mLock held
98165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
98265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
9838d6a2449a91f5116d7243ab039393195ebd663feGlenn Kasten    ssize_t i;  // not size_t because i will count down to -1
98465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Vector <AudioCommand *> removedCommands;
98565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    command->mTime = systemTime() + milliseconds(delayMs);
98665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
98765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // acquire wake lock to make sure delayed commands are processed
988bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (mAudioCommands.isEmpty()) {
98965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
99065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
99165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
99265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // check same pending commands with later time stamps and eliminate them
99365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (i = mAudioCommands.size()-1; i >= 0; i--) {
99465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        AudioCommand *command2 = mAudioCommands[i];
99565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
99665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (command2->mTime <= command->mTime) break;
99765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (command2->mCommand != command->mCommand) continue;
99865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
99965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        switch (command->mCommand) {
100065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case SET_PARAMETERS: {
100165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ParametersData *data = (ParametersData *)command->mParam;
100265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            ParametersData *data2 = (ParametersData *)command2->mParam;
100365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (data->mIO != data2->mIO) break;
10043856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Comparing parameter command %s to new command %s",
1005de070137f11d346fba77605bd76a44c040a618fcEric Laurent                    data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
100665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            AudioParameter param = AudioParameter(data->mKeyValuePairs);
100765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
100865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            for (size_t j = 0; j < param.size(); j++) {
1009e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                String8 key;
1010e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                String8 value;
1011e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                param.getAt(j, key, value);
1012e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                for (size_t k = 0; k < param2.size(); k++) {
1013e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    String8 key2;
1014e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    String8 value2;
1015e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    param2.getAt(k, key2, value2);
1016e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    if (key2 == key) {
1017e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        param2.remove(key2);
1018e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        ALOGV("Filtering out parameter %s", key2.string());
1019e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                        break;
1020e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                    }
1021e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten                }
102265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
102365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // if all keys have been filtered out, remove the command.
102465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // otherwise, update the key value pairs
102565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (param2.size() == 0) {
102665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                removedCommands.add(command2);
102765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
102865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                data2->mKeyValuePairs = param2.toString();
102965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
103021e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            command->mTime = command2->mTime;
103121e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            // force delayMs to non 0 so that code below does not request to wait for
103221e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            // command status as the command is now delayed
103321e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            delayMs = 1;
103465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } break;
103565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case SET_VOLUME: {
103765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            VolumeData *data = (VolumeData *)command->mParam;
103865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            VolumeData *data2 = (VolumeData *)command2->mParam;
103965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (data->mIO != data2->mIO) break;
104065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (data->mStream != data2->mStream) break;
10413856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("Filtering out volume command on output %d for stream %d",
1042de070137f11d346fba77605bd76a44c040a618fcEric Laurent                    data->mIO, data->mStream);
104365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            removedCommands.add(command2);
104421e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            command->mTime = command2->mTime;
104521e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            // force delayMs to non 0 so that code below does not request to wait for
104621e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            // command status as the command is now delayed
104721e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent            delayMs = 1;
104865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } break;
104965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case START_TONE:
105065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case STOP_TONE:
105165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        default:
105265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
105365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
105465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
105565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // remove filtered commands
105765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (size_t j = 0; j < removedCommands.size(); j++) {
105865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // removed commands always have time stamps greater than current command
105965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
106065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (mAudioCommands[k] == removedCommands[j]) {
10613856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
106265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mAudioCommands.removeAt(k);
106365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                break;
106465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
106565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
106665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
106765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    removedCommands.clear();
106865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
106921e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent    // wait for status only if delay is 0
107021e5456821e3c107d09b0629adbf23c9e06e7c0bEric Laurent    if (delayMs == 0) {
1071cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent        command->mWaitStatus = true;
1072cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent    } else {
1073cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent        command->mWaitStatus = false;
1074cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent    }
1075cec4abb2a39eafa75cf6894170a200322aa7226eEric Laurent
107665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // insert command at the right place according to its time stamp
10773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("inserting command: %d at index %d, num commands %d",
1078de070137f11d346fba77605bd76a44c040a618fcEric Laurent            command->mCommand, (int)i+1, mAudioCommands.size());
107965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mAudioCommands.insertAt(command, i + 1);
108065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
108165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
108265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::exit()
108365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
10843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block    ALOGV("AudioCommandThread::exit");
108565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    {
108665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        AutoMutex _l(mLock);
108765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        requestExit();
108865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mWaitWorkCV.signal();
108965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
109065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    requestExitAndWait();
109165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
109265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
109365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
109465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
109565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
109665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mCommand,
109765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (int)ns2s(mTime),
109865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            (int)ns2ms(mTime)%1000,
109965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mWaitStatus,
110065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mParam);
110165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
110265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1103fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin/******* helpers for the service_ops callbacks defined below *********/
1104fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle,
1105fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                       const char *keyValuePairs,
1106fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                       int delayMs)
1107fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
110872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    mAudioCommandThread->parametersCommand(ioHandle, keyValuePairs,
1109fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                           delayMs);
1110fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1111fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1112fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setStreamVolume(audio_stream_type_t stream,
1113fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                        float volume,
1114fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                        audio_io_handle_t output,
1115fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                        int delayMs)
1116fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1117fff6d715a8db0daf08a50634f242c40268de3d49Glenn Kasten    return (int)mAudioCommandThread->volumeCommand(stream, volume,
111872ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten                                                   output, delayMs);
1119fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1120fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1121fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::startTone(audio_policy_tone_t tone,
1122fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                  audio_stream_type_t stream)
1123fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
11246e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (tone != AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION) {
112529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("startTone: illegal tone requested (%d)", tone);
11266e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
11276e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (stream != AUDIO_STREAM_VOICE_CALL) {
112829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("startTone: illegal stream (%d) requested for tone %d", stream,
1129e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten            tone);
11306e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
1131fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mTonePlaybackThread->startToneCommand(ToneGenerator::TONE_SUP_CALL_WAITING,
1132fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                          AUDIO_STREAM_VOICE_CALL);
1133fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return 0;
1134fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1135fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1136fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::stopTone()
1137fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1138fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    mTonePlaybackThread->stopToneCommand();
1139fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return 0;
1140fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1141fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1142fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinint AudioPolicyService::setVoiceVolume(float volume, int delayMs)
1143fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1144fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return (int)mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
1145fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1146fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1147ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgeraldbool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
1148ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald{
1149bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (mpAudioPolicy == NULL) {
1150bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        ALOGV("mpAudioPolicy == NULL");
1151bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return false;
1152bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    }
1153bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
1154bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    if (mpAudioPolicy->is_offload_supported == NULL) {
1155bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        ALOGV("HAL does not implement is_offload_supported");
1156bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent        return false;
1157bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    }
1158bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent
1159bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent    return mpAudioPolicy->is_offload_supported(mpAudioPolicy, &info);
1160ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald}
1161ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald
11627c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent// ----------------------------------------------------------------------------
11637c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent// Audio pre-processing configuration
11647c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent// ----------------------------------------------------------------------------
11657c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
11668dad0e31c2366c501bd1d600261d0af35a6ca786Glenn Kasten/*static*/ const char * const AudioPolicyService::kInputSourceNames[AUDIO_SOURCE_CNT -1] = {
11677c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    MIC_SRC_TAG,
11687c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    VOICE_UL_SRC_TAG,
11697c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    VOICE_DL_SRC_TAG,
11707c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    VOICE_CALL_SRC_TAG,
11717c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    CAMCORDER_SRC_TAG,
11727c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    VOICE_REC_SRC_TAG,
11737c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    VOICE_COMM_SRC_TAG
11747c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent};
11757c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
11767c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent// returns the audio_source_t enum corresponding to the input source name or
11777c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent// AUDIO_SOURCE_CNT is no match found
11787c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentaudio_source_t AudioPolicyService::inputSourceNameToEnum(const char *name)
11797c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
11807c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    int i;
11817c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    for (i = AUDIO_SOURCE_MIC; i < AUDIO_SOURCE_CNT; i++) {
11827c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (strcmp(name, kInputSourceNames[i - AUDIO_SOURCE_MIC]) == 0) {
11833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("inputSourceNameToEnum found source %s %d", name, i);
11847c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            break;
11857c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
11867c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
11877c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return (audio_source_t)i;
11887c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
11897c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
11907c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentsize_t AudioPolicyService::growParamSize(char *param,
11917c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                         size_t size,
11927c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                         size_t *curSize,
11937c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                         size_t *totSize)
11947c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
11957c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    // *curSize is at least sizeof(effect_param_t) + 2 * sizeof(int)
11967c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    size_t pos = ((*curSize - 1 ) / size + 1) * size;
11977c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
11987c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (pos + size > *totSize) {
11997c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        while (pos + size > *totSize) {
12007c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            *totSize += ((*totSize + 7) / 8) * 4;
12017c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
12027c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        param = (char *)realloc(param, *totSize);
12037c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
12047c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    *curSize = pos + size;
12057c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return pos;
12067c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
12077c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
12087c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentsize_t AudioPolicyService::readParamValue(cnode *node,
12097c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                          char *param,
12107c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                          size_t *curSize,
12117c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                          size_t *totSize)
12127c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
12137c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (strncmp(node->name, SHORT_TAG, sizeof(SHORT_TAG) + 1) == 0) {
12147c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        size_t pos = growParamSize(param, sizeof(short), curSize, totSize);
12157c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        *(short *)((char *)param + pos) = (short)atoi(node->value);
12163856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("readParamValue() reading short %d", *(short *)((char *)param + pos));
12177c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return sizeof(short);
12187c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    } else if (strncmp(node->name, INT_TAG, sizeof(INT_TAG) + 1) == 0) {
12197c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        size_t pos = growParamSize(param, sizeof(int), curSize, totSize);
12207c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        *(int *)((char *)param + pos) = atoi(node->value);
12213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("readParamValue() reading int %d", *(int *)((char *)param + pos));
12227c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return sizeof(int);
12237c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    } else if (strncmp(node->name, FLOAT_TAG, sizeof(FLOAT_TAG) + 1) == 0) {
12247c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        size_t pos = growParamSize(param, sizeof(float), curSize, totSize);
12257c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        *(float *)((char *)param + pos) = (float)atof(node->value);
12263856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("readParamValue() reading float %f",*(float *)((char *)param + pos));
12277c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return sizeof(float);
12287c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    } else if (strncmp(node->name, BOOL_TAG, sizeof(BOOL_TAG) + 1) == 0) {
12297c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        size_t pos = growParamSize(param, sizeof(bool), curSize, totSize);
12307c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (strncmp(node->value, "false", strlen("false") + 1) == 0) {
12317c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            *(bool *)((char *)param + pos) = false;
12327c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        } else {
12337c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            *(bool *)((char *)param + pos) = true;
12347c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
12353856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("readParamValue() reading bool %s",*(bool *)((char *)param + pos) ? "true" : "false");
12367c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return sizeof(bool);
12377c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    } else if (strncmp(node->name, STRING_TAG, sizeof(STRING_TAG) + 1) == 0) {
12387c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        size_t len = strnlen(node->value, EFFECT_STRING_LEN_MAX);
12397c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (*curSize + len + 1 > *totSize) {
12407c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            *totSize = *curSize + len + 1;
12417c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            param = (char *)realloc(param, *totSize);
12427c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
12437c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        strncpy(param + *curSize, node->value, len);
12447c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        *curSize += len;
12457c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        param[*curSize] = '\0';
12463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("readParamValue() reading string %s", param + *curSize - len);
12477c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return len;
12487c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
12495ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    ALOGW("readParamValue() unknown param type %s", node->name);
12507c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return 0;
12517c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
12527c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
12537c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurenteffect_param_t *AudioPolicyService::loadEffectParameter(cnode *root)
12547c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
12557c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    cnode *param;
12567c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    cnode *value;
12577c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    size_t curSize = sizeof(effect_param_t);
12587c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    size_t totSize = sizeof(effect_param_t) + 2 * sizeof(int);
12597c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    effect_param_t *fx_param = (effect_param_t *)malloc(totSize);
12607c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
12617c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    param = config_find(root, PARAM_TAG);
12627c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    value = config_find(root, VALUE_TAG);
12637c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (param == NULL && value == NULL) {
12647c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        // try to parse simple parameter form {int int}
12657c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        param = root->first_child;
1266a0d68338a88c2ddb4502f95017b546d603ef1ec7Glenn Kasten        if (param != NULL) {
12677c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            // Note: that a pair of random strings is read as 0 0
12687c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            int *ptr = (int *)fx_param->data;
12697c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            int *ptr2 = (int *)((char *)param + sizeof(effect_param_t));
12705ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("loadEffectParameter() ptr %p ptr2 %p", ptr, ptr2);
12717c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            *ptr++ = atoi(param->name);
12727c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            *ptr = atoi(param->value);
12737c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            fx_param->psize = sizeof(int);
12747c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            fx_param->vsize = sizeof(int);
12757c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            return fx_param;
12767c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
12777c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
12787c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (param == NULL || value == NULL) {
12795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadEffectParameter() invalid parameter description %s", root->name);
12807c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        goto error;
12817c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
12827c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
12837c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    fx_param->psize = 0;
12847c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    param = param->first_child;
12857c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    while (param) {
12863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("loadEffectParameter() reading param of type %s", param->name);
12877c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        size_t size = readParamValue(param, (char *)fx_param, &curSize, &totSize);
12887c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (size == 0) {
12897c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            goto error;
12907c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
12917c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        fx_param->psize += size;
12927c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        param = param->next;
12937c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
12947c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
12957c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    // align start of value field on 32 bit boundary
12967c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    curSize = ((curSize - 1 ) / sizeof(int) + 1) * sizeof(int);
12977c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
12987c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    fx_param->vsize = 0;
12997c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    value = value->first_child;
13007c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    while (value) {
13013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("loadEffectParameter() reading value of type %s", value->name);
13027c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        size_t size = readParamValue(value, (char *)fx_param, &curSize, &totSize);
13037c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (size == 0) {
13047c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            goto error;
13057c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
13067c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        fx_param->vsize += size;
13077c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        value = value->next;
13087c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
13097c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
13107c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return fx_param;
13117c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
13127c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurenterror:
13137c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    delete fx_param;
13147c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return NULL;
13157c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
13167c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
13177c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentvoid AudioPolicyService::loadEffectParameters(cnode *root, Vector <effect_param_t *>& params)
13187c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
13197c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    cnode *node = root->first_child;
13207c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    while (node) {
13213856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("loadEffectParameters() loading param %s", node->name);
13227c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        effect_param_t *param = loadEffectParameter(node);
13237c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (param == NULL) {
13247c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            node = node->next;
13257c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            continue;
13267c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
13277c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        params.add(param);
13287c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        node = node->next;
13297c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
13307c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
13317c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
13327c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric LaurentAudioPolicyService::InputSourceDesc *AudioPolicyService::loadInputSource(
13337c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                                            cnode *root,
13347c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                                                            const Vector <EffectDesc *>& effects)
13357c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
13367c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    cnode *node = root->first_child;
13377c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (node == NULL) {
13385ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadInputSource() empty element %s", root->name);
13397c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return NULL;
13407c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
13417c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    InputSourceDesc *source = new InputSourceDesc();
13427c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    while (node) {
13437c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        size_t i;
13447c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        for (i = 0; i < effects.size(); i++) {
13457c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            if (strncmp(effects[i]->mName, node->name, EFFECT_STRING_LEN_MAX) == 0) {
13463856b090cd04ba5dd4a59a12430ed724d5995909Steve Block                ALOGV("loadInputSource() found effect %s in list", node->name);
13477c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent                break;
13487c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            }
13497c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
13507c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (i == effects.size()) {
13513856b090cd04ba5dd4a59a12430ed724d5995909Steve Block            ALOGV("loadInputSource() effect %s not in list", node->name);
13527c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            node = node->next;
13537c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            continue;
13547c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
13559fda4b87441fe17d90d8144639c9de6d9022c3c0Glenn Kasten        EffectDesc *effect = new EffectDesc(*effects[i]);   // deep copy
13567c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        loadEffectParameters(node, effect->mParams);
13573856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("loadInputSource() adding effect %s uuid %08x", effect->mName, effect->mUuid.timeLow);
13587c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        source->mEffects.add(effect);
13597c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        node = node->next;
13607c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
13617c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (source->mEffects.size() == 0) {
13625ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadInputSource() no valid effects found in source %s", root->name);
13637c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        delete source;
13647c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return NULL;
13657c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
13667c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return source;
13677c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
13687c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
13697c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentstatus_t AudioPolicyService::loadInputSources(cnode *root, const Vector <EffectDesc *>& effects)
13707c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
13717c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    cnode *node = config_find(root, PREPROCESSING_TAG);
13727c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (node == NULL) {
13737c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return -ENOENT;
13747c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
13757c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    node = node->first_child;
13767c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    while (node) {
13777c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        audio_source_t source = inputSourceNameToEnum(node->name);
13787c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (source == AUDIO_SOURCE_CNT) {
13795ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("loadInputSources() invalid input source %s", node->name);
13807c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            node = node->next;
13817c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            continue;
13827c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
13833856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("loadInputSources() loading input source %s", node->name);
13847c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        InputSourceDesc *desc = loadInputSource(node, effects);
13857c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (desc == NULL) {
13867c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            node = node->next;
13877c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            continue;
13887c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
13897c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        mInputSources.add(source, desc);
13907c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        node = node->next;
13917c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
13927c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return NO_ERROR;
13937c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
13947c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
13957c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric LaurentAudioPolicyService::EffectDesc *AudioPolicyService::loadEffect(cnode *root)
13967c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
13977c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    cnode *node = config_find(root, UUID_TAG);
13987c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (node == NULL) {
13997c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return NULL;
14007c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
14017c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    effect_uuid_t uuid;
14027c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (AudioEffect::stringToGuid(node->value, &uuid) != NO_ERROR) {
14035ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("loadEffect() invalid uuid %s", node->value);
14047c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return NULL;
14057c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
14069fda4b87441fe17d90d8144639c9de6d9022c3c0Glenn Kasten    return new EffectDesc(root->name, uuid);
14077c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
14087c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
14097c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentstatus_t AudioPolicyService::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
14107c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
14117c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    cnode *node = config_find(root, EFFECTS_TAG);
14127c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (node == NULL) {
14137c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return -ENOENT;
14147c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
14157c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    node = node->first_child;
14167c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    while (node) {
14173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block        ALOGV("loadEffects() loading effect %s", node->name);
14187c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        EffectDesc *effect = loadEffect(node);
14197c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        if (effect == NULL) {
14207c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            node = node->next;
14217c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent            continue;
14227c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        }
14237c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        effects.add(effect);
14247c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        node = node->next;
14257c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
14267c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return NO_ERROR;
14277c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
14287c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
14297c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurentstatus_t AudioPolicyService::loadPreProcessorConfig(const char *path)
14307c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent{
14317c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    cnode *root;
14327c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    char *data;
14337c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
14347c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    data = (char *)load_file(path, NULL);
14357c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    if (data == NULL) {
14367c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent        return -ENODEV;
14377c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    }
14387c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    root = config_node("", "");
14397c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    config_load(root, data);
14407c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
14417c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    Vector <EffectDesc *> effects;
14427c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    loadEffects(root, effects);
14437c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    loadInputSources(root, effects);
14447c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
1445e6056ba0f2399fa3ebea9665e12a8237f99de250Yu Yezhong    // delete effects to fix memory leak.
1446e6056ba0f2399fa3ebea9665e12a8237f99de250Yu Yezhong    // as effects is local var and valgrind would treat this as memory leak
1447e6056ba0f2399fa3ebea9665e12a8237f99de250Yu Yezhong    // and although it only did in mediaserver init, but free it in case mediaserver reboot
1448e6056ba0f2399fa3ebea9665e12a8237f99de250Yu Yezhong    size_t i;
1449e6056ba0f2399fa3ebea9665e12a8237f99de250Yu Yezhong    for (i = 0; i < effects.size(); i++) {
1450e6056ba0f2399fa3ebea9665e12a8237f99de250Yu Yezhong      delete effects[i];
1451e6056ba0f2399fa3ebea9665e12a8237f99de250Yu Yezhong    }
1452e6056ba0f2399fa3ebea9665e12a8237f99de250Yu Yezhong
14537c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    config_free(root);
14547c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    free(root);
14557c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    free(data);
14567c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
14577c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent    return NO_ERROR;
14587c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent}
14597c7f10bd4fda9a084e5e7f0eb3a040dfcbf01745Eric Laurent
1460fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin/* implementation of the interface to the policy manager */
1461fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinextern "C" {
1462fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1463a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
14640f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic audio_module_handle_t aps_load_hw_module(void *service __unused,
1465a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                             const char *name)
1466a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent{
1467a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1468a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    if (af == 0) {
1469a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        ALOGW("%s: could not get AudioFlinger", __func__);
1470a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        return 0;
1471a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
1472a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
1473a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    return af->loadHwModule(name);
1474a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent}
1475a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
1476a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent// deprecated: replaced by aps_open_output_on_module()
14770f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic audio_io_handle_t aps_open_output(void *service __unused,
1478a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         audio_devices_t *pDevices,
1479a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         uint32_t *pSamplingRate,
1480a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         audio_format_t *pFormat,
1481a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         audio_channel_mask_t *pChannelMask,
1482a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                         uint32_t *pLatencyMs,
14830ca3cf94c0dfc173ad7886ae162c4b67067539f6Eric Laurent                                         audio_output_flags_t flags)
1484fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1485fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
14867378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten    if (af == 0) {
14875ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("%s: could not get AudioFlinger", __func__);
1488fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return 0;
1489fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    }
1490fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1491a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    return af->openOutput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask,
1492a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                          pLatencyMs, flags);
1493a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent}
1494a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
14950f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic audio_io_handle_t aps_open_output_on_module(void *service __unused,
1496a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   audio_module_handle_t module,
1497a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   audio_devices_t *pDevices,
1498a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   uint32_t *pSamplingRate,
1499a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   audio_format_t *pFormat,
1500a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   audio_channel_mask_t *pChannelMask,
1501a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                   uint32_t *pLatencyMs,
1502ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                                                   audio_output_flags_t flags,
1503ad3af3305f024bcbbd55c894a4995e449498e1baRichard Fitzgerald                                                   const audio_offload_info_t *offloadInfo)
1504a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent{
1505a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1506a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    if (af == 0) {
1507a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        ALOGW("%s: could not get AudioFlinger", __func__);
1508a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        return 0;
1509a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
1510a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask,
1511bfb1b832079bbb9426f72f3863199a54aefd02daEric Laurent                          pLatencyMs, flags, offloadInfo);
1512fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1513fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
15140f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic audio_io_handle_t aps_open_dup_output(void *service __unused,
1515fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                 audio_io_handle_t output1,
1516fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                                 audio_io_handle_t output2)
1517fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1518fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
15197378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten    if (af == 0) {
15205ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("%s: could not get AudioFlinger", __func__);
1521fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return 0;
1522fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    }
1523fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return af->openDuplicateOutput(output1, output2);
1524fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1525fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
15260f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic int aps_close_output(void *service __unused, audio_io_handle_t output)
1527fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1528fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
15296e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (af == 0) {
1530fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return PERMISSION_DENIED;
15316e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
1532fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1533fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return af->closeOutput(output);
1534fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1535fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
15360f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic int aps_suspend_output(void *service __unused, audio_io_handle_t output)
1537fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1538fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
15397378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten    if (af == 0) {
15405ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("%s: could not get AudioFlinger", __func__);
1541fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return PERMISSION_DENIED;
1542fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    }
1543fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1544fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return af->suspendOutput(output);
1545fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1546fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
15470f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic int aps_restore_output(void *service __unused, audio_io_handle_t output)
1548fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1549fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
15507378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten    if (af == 0) {
15515ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("%s: could not get AudioFlinger", __func__);
1552fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return PERMISSION_DENIED;
1553fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    }
1554fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1555fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return af->restoreOutput(output);
1556fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1557fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
155820010053daabfa43fcfe781bbf004473b4c08538Glenn Kasten// deprecated: replaced by aps_open_input_on_module(), and acoustics parameter is ignored
15590f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic audio_io_handle_t aps_open_input(void *service __unused,
1560a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                        audio_devices_t *pDevices,
1561a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                        uint32_t *pSamplingRate,
1562a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                        audio_format_t *pFormat,
1563a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                        audio_channel_mask_t *pChannelMask,
15640f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kasten                                        audio_in_acoustics_t acoustics __unused)
1565a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent{
1566a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
1567a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    if (af == 0) {
1568a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        ALOGW("%s: could not get AudioFlinger", __func__);
1569a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        return 0;
1570a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    }
1571a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
1572a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    return af->openInput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask);
1573a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent}
1574a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent
15750f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic audio_io_handle_t aps_open_input_on_module(void *service __unused,
1576a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  audio_module_handle_t module,
1577a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  audio_devices_t *pDevices,
1578a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  uint32_t *pSamplingRate,
1579a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  audio_format_t *pFormat,
1580a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent                                                  audio_channel_mask_t *pChannelMask)
1581fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1582fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
15837378ca506e4e20c2b2d4e94a131cf1b95831adb5Glenn Kasten    if (af == 0) {
15845ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("%s: could not get AudioFlinger", __func__);
1585fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return 0;
1586fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    }
1587fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1588a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent    return af->openInput(module, pDevices, pSamplingRate, pFormat, pChannelMask);
1589fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1590fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
15910f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic int aps_close_input(void *service __unused, audio_io_handle_t input)
1592fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1593fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
15946e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (af == 0) {
1595fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return PERMISSION_DENIED;
15966e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
1597fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1598fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return af->closeInput(input);
1599fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1600fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
16010f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic int aps_set_stream_output(void *service __unused, audio_stream_type_t stream,
1602fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                     audio_io_handle_t output)
1603fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1604fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
16056e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (af == 0) {
1606fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return PERMISSION_DENIED;
16076e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
1608fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1609fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return af->setStreamOutput(stream, output);
1610fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1611fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
16120f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic int aps_move_effects(void *service __unused, int session,
1613fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                audio_io_handle_t src_output,
1614fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                audio_io_handle_t dst_output)
1615fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1616fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
16176e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    if (af == 0) {
1618fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        return PERMISSION_DENIED;
16196e2ebe97f2ad0a21907f20f9ee644c4eacbb7a40Glenn Kasten    }
1620fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
162172ef00de10fa95bfcb948ed88ab9b7a177ed0b48Glenn Kasten    return af->moveEffects(session, src_output, dst_output);
1622fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1623fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
16240f11b51a57bc9062c4fe8af73747319cedabc5d6Glenn Kastenstatic char * aps_get_parameters(void *service __unused, audio_io_handle_t io_handle,
1625fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                     const char *keys)
1626fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1627fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    String8 result = AudioSystem::getParameters(io_handle, String8(keys));
1628fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return strdup(result.string());
1629fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1630fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1631fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatic void aps_set_parameters(void *service, audio_io_handle_t io_handle,
1632fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                   const char *kv_pairs, int delay_ms)
1633fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1634fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
1635fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1636fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    audioPolicyService->setParameters(io_handle, kv_pairs, delay_ms);
1637fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1638fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1639fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatic int aps_set_stream_volume(void *service, audio_stream_type_t stream,
1640fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                     float volume, audio_io_handle_t output,
1641fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                     int delay_ms)
1642fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1643fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
1644fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1645fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return audioPolicyService->setStreamVolume(stream, volume, output,
1646fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                                               delay_ms);
1647fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1648fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1649fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatic int aps_start_tone(void *service, audio_policy_tone_t tone,
1650fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin                              audio_stream_type_t stream)
1651fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1652fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
1653fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1654fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return audioPolicyService->startTone(tone, stream);
1655fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1656fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1657fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatic int aps_stop_tone(void *service)
1658fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1659fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
1660fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1661fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return audioPolicyService->stopTone();
1662fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1663fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1664fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatic int aps_set_voice_volume(void *service, float volume, int delay_ms)
1665fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin{
1666fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    AudioPolicyService *audioPolicyService = (AudioPolicyService *)service;
1667fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1668fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    return audioPolicyService->setVoiceVolume(volume, delay_ms);
1669fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}
1670fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1671fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}; // extern "C"
1672fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
1673fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinnamespace {
1674fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    struct audio_policy_service_ops aps_ops = {
1675fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        open_output           : aps_open_output,
1676fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        open_duplicate_output : aps_open_dup_output,
1677fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        close_output          : aps_close_output,
1678fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        suspend_output        : aps_suspend_output,
1679fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        restore_output        : aps_restore_output,
1680fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        open_input            : aps_open_input,
1681fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        close_input           : aps_close_input,
1682fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        set_stream_volume     : aps_set_stream_volume,
1683fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        set_stream_output     : aps_set_stream_output,
1684fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        set_parameters        : aps_set_parameters,
1685fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        get_parameters        : aps_get_parameters,
1686fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        start_tone            : aps_start_tone,
1687fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        stop_tone             : aps_stop_tone,
1688fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        set_voice_volume      : aps_set_voice_volume,
1689fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        move_effects          : aps_move_effects,
1690a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        load_hw_module        : aps_load_hw_module,
1691a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        open_output_on_module : aps_open_output_on_module,
1692a4c5a550e2a3bc237179b8684e51718e05894492Eric Laurent        open_input_on_module  : aps_open_input_on_module,
1693fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    };
1694fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin}; // namespace <unnamed>
1695fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
169665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
1697