AudioPolicyService.cpp revision f4ee40e26ec43e17359ff5788565349a9aa71908
1a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent/*
2a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * Copyright (C) 2009 The Android Open Source Project
3a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent *
4a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * Licensed under the Apache License, Version 2.0 (the "License");
5a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * you may not use this file except in compliance with the License.
6a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * You may obtain a copy of the License at
7a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent *
8a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent *      http://www.apache.org/licenses/LICENSE-2.0
9a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent *
10a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * Unless required by applicable law or agreed to in writing, software
11a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * distributed under the License is distributed on an "AS IS" BASIS,
12a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * See the License for the specific language governing permissions and
14a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent * limitations under the License.
15a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent */
16a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
17a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#define LOG_TAG "AudioPolicyService"
18a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent//#define LOG_NDEBUG 0
19327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
20327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent#undef __STRICT_ANSI__
21327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent#define __STDINT_LIMITS
22327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent#define __STDC_LIMIT_MACROS
23327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent#include <stdint.h>
24327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
25327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent#include <sys/time.h>
26a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <binder/IServiceManager.h>
27a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <utils/Log.h>
28a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <cutils/properties.h>
29a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <binder/IPCThreadState.h>
30a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <utils/String16.h>
31a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <utils/threads.h>
32a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include "AudioPolicyService.h"
334192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent#include "AudioPolicyManagerGeneric.h"
34a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <cutils/properties.h>
35a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <dlfcn.h>
36a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
37a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// ----------------------------------------------------------------------------
38a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// the sim build doesn't have gettid
39a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
40a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#ifndef HAVE_GETTID
41a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent# define gettid getpid
42a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#endif
43a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
44a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentnamespace android {
45a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
46f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatic const char* kDeadlockedString = "AudioPolicyService may be deadlocked\n";
47f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatic const char* kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n";
48f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
49f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatic const int kDumpLockRetries = 50;
50f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatic const int kDumpLockSleep = 20000;
51f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
52a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatic bool checkPermission() {
53a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#ifndef HAVE_ANDROID_OS
54a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return true;
55a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#endif
56a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
57a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
58a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
59a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return ok;
60a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
61a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
62a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// ----------------------------------------------------------------------------
63a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
64a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioPolicyService::AudioPolicyService()
654192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent    : BnAudioPolicyService() , mpPolicyManager(NULL)
66a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
67a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    char value[PROPERTY_VALUE_MAX];
68a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
694192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent    // start tone playback thread
70327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mTonePlaybackThread = new AudioCommandThread();
714192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent    // start audio commands thread
724192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent    mAudioCommandThread = new AudioCommandThread();
734192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent
74a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#if (defined GENERIC_AUDIO) || (defined AUDIO_POLICY_TEST)
754192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent    mpPolicyManager = new AudioPolicyManagerGeneric(this);
76a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("build for GENERIC_AUDIO - using generic audio policy");
77a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#else
78a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    // if running in emulation - use the emulator driver
79a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (property_get("ro.kernel.qemu", value, 0)) {
80a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGV("Running in emulation - using generic audio policy");
814192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent        mpPolicyManager = new AudioPolicyManagerGeneric(this);
82a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
83a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    else {
84a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGV("Using hardware specific audio policy");
854192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent        mpPolicyManager = createAudioPolicyManager(this);
86a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
87a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#endif
88a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
89a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    // load properties
90a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    property_get("ro.camera.sound.forced", value, "0");
91a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value);
92a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
93a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
94a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioPolicyService::~AudioPolicyService()
95a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
96327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mTonePlaybackThread->exit();
97327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mTonePlaybackThread.clear();
98a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mAudioCommandThread->exit();
99a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mAudioCommandThread.clear();
100a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
101a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager) {
1024192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent        delete mpPolicyManager;
103a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
104a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
105a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
106a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
107a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setDeviceConnectionState(AudioSystem::audio_devices device,
108a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                                  AudioSystem::device_connection_state state,
109a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                                  const char *device_address)
110a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
111a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
112a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
113a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
114a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
115a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
116a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
117a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!AudioSystem::isOutputDevice(device) && !AudioSystem::isInputDevice(device)) {
118a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
119a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
120a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (state != AudioSystem::DEVICE_STATE_AVAILABLE && state != AudioSystem::DEVICE_STATE_UNAVAILABLE) {
121a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
122a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
123a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
124a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setDeviceConnectionState() tid %d", gettid());
125a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
126a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->setDeviceConnectionState(device, state, device_address);
127a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
128a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
129a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioSystem::device_connection_state AudioPolicyService::getDeviceConnectionState(AudioSystem::audio_devices device,
130a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                                  const char *device_address)
131a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
132a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
133a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return AudioSystem::DEVICE_STATE_UNAVAILABLE;
134a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
135a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
136a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return AudioSystem::DEVICE_STATE_UNAVAILABLE;
137a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
138a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->getDeviceConnectionState(device, device_address);
139a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
140a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
141a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setPhoneState(int state)
142a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
143a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
144a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
145a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
146a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
147a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
148a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
149a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (state < 0 || state >= AudioSystem::NUM_MODES) {
150a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
151a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
152a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
153a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setPhoneState() tid %d", gettid());
154a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
155a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    // TODO: check if it is more appropriate to do it in platform specific policy manager
156a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioSystem::setMode(state);
157a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
158a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
159a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->setPhoneState(state);
160a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
161a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
162a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
163a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setRingerMode(uint32_t mode, uint32_t mask)
164a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
165a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
166a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
167a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
168a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
169a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
170a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
171a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
172a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->setRingerMode(mode, mask);
173a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
174a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
175a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
176a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
177a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
178a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
179a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
180a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
181a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
182a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
183a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
184a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) {
185a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
186a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
187a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (config < 0 || config >= AudioSystem::NUM_FORCE_CONFIG) {
188a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
189a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
190a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setForceUse() tid %d", gettid());
191a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
192a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->setForceUse(usage, config);
193a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
194a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
195a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
196a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioSystem::forced_config AudioPolicyService::getForceUse(AudioSystem::force_use usage)
197a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
198a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
199a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return AudioSystem::FORCE_NONE;
200a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
201a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
202a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return AudioSystem::FORCE_NONE;
203a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
204a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) {
205a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return AudioSystem::FORCE_NONE;
206a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
207a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->getForceUse(usage);
208a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
209a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
210a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentaudio_io_handle_t AudioPolicyService::getOutput(AudioSystem::stream_type stream,
211a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t samplingRate,
212a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t format,
213a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t channels,
214a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    AudioSystem::output_flags flags)
215a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
216a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
217ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
218a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
219a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("getOutput() tid %d", gettid());
220a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
221a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->getOutput(stream, samplingRate, format, channels, flags);
222a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
223a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
224a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
225a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
226a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
227a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
228a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
229a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("startOutput() tid %d", gettid());
230a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
231a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->startOutput(output, stream);
232a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
233a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
234a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
235a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
236a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
237a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
238a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
239a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("stopOutput() tid %d", gettid());
240a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
241a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->stopOutput(output, stream);
242a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
243a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
244a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::releaseOutput(audio_io_handle_t output)
245a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
246a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
247a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return;
248a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
249a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("releaseOutput() tid %d", gettid());
250a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
251a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->releaseOutput(output);
252a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
253a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
254a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentaudio_io_handle_t AudioPolicyService::getInput(int inputSource,
255a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t samplingRate,
256a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t format,
257a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t channels,
258a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    AudioSystem::audio_in_acoustics acoustics)
259a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
260a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
261ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
262a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
263a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
264a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->getInput(inputSource, samplingRate, format, channels, acoustics);
265a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
266a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
267a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::startInput(audio_io_handle_t input)
268a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
269a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
270a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
271a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
272a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
273a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->startInput(input);
274a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
275a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
276a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::stopInput(audio_io_handle_t input)
277a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
278a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
279a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
280a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
281a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
282a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->stopInput(input);
283a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
284a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
285a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::releaseInput(audio_io_handle_t input)
286a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
287a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
288a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return;
289a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
290a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
291a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->releaseInput(input);
292a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
293a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
294a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::initStreamVolume(AudioSystem::stream_type stream,
295a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                            int indexMin,
296a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                            int indexMax)
297a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
298a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
299a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
300a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
301a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
302a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
303a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
304a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
305a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
306a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
307a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->initStreamVolume(stream, indexMin, indexMax);
308a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
309a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
310a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
311a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
312a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
313a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
314a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
315a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
316a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
317a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
318a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
319a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
320a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
321a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
322a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
323a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->setStreamVolumeIndex(stream, index);
324a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
325a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
326a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
327a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
328a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
329a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
330a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
331a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
332a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
333a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
334a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
335a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
336a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
337a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->getStreamVolumeIndex(stream, index);
338a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
339a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
340a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::binderDied(const wp<IBinder>& who) {
341a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
342a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
343a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
344f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatic bool tryLock(Mutex& mutex)
345f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
346f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    bool locked = false;
347f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    for (int i = 0; i < kDumpLockRetries; ++i) {
348f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mutex.tryLock() == NO_ERROR) {
349f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            locked = true;
350f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            break;
351f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
352f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        usleep(kDumpLockSleep);
353f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    }
354f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    return locked;
355f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
356f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
357f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatus_t AudioPolicyService::dumpInternals(int fd)
358f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
359f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    const size_t SIZE = 256;
360f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    char buffer[SIZE];
361f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    String8 result;
362f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
363f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpPolicyManager);
364f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
365f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
366f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
367f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
368f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
369f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
370f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    write(fd, result.string(), result.size());
371f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    return NO_ERROR;
372f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
373f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
374a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args)
375a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
376a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
377f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        dumpPermissionDenial(fd);
378a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    } else {
379f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        bool locked = tryLock(mLock);
380f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (!locked) {
381f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            String8 result(kDeadlockedString);
382f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            write(fd, result.string(), result.size());
383f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
384a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
385f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        dumpInternals(fd);
386f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mAudioCommandThread != NULL) {
387f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mAudioCommandThread->dump(fd);
388f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
389f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mTonePlaybackThread != NULL) {
390f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mTonePlaybackThread->dump(fd);
391f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
392f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
393f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mpPolicyManager) {
394f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mpPolicyManager->dump(fd);
395f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
396f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
397f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (locked) mLock.unlock();
398a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
399a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
400a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
401a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
402f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatus_t AudioPolicyService::dumpPermissionDenial(int fd)
403a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
404a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    const size_t SIZE = 256;
405a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    char buffer[SIZE];
406a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 result;
407a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    snprintf(buffer, SIZE, "Permission Denial: "
408a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
409a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            IPCThreadState::self()->getCallingPid(),
410a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            IPCThreadState::self()->getCallingUid());
411a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    result.append(buffer);
412a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    write(fd, result.string(), result.size());
413a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
414a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
415a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
416a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::onTransact(
417a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
418a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
419a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return BnAudioPolicyService::onTransact(code, data, reply, flags);
420a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
421a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
422a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
423a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// ----------------------------------------------------------------------------
424a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::instantiate() {
425a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    defaultServiceManager()->addService(
426a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            String16("media.audio_policy"), new AudioPolicyService());
427a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
428a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
429a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
430a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// ----------------------------------------------------------------------------
431a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// AudioPolicyClientInterface implementation
432a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// ----------------------------------------------------------------------------
433a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
434a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
435a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentaudio_io_handle_t AudioPolicyService::openOutput(uint32_t *pDevices,
436a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pSamplingRate,
437a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pFormat,
438a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pChannels,
439a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pLatencyMs,
440a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                AudioSystem::output_flags flags)
441a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
442a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
443a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) {
444a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGW("openOutput() could not get AudioFlinger");
445ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
446a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
447a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
448a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->openOutput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, pLatencyMs, flags);
449a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
450a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
451a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentaudio_io_handle_t AudioPolicyService::openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2)
452a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
453a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
454a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) {
455a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGW("openDuplicateOutput() could not get AudioFlinger");
456ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
457a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
458a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->openDuplicateOutput(output1, output2);
459a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
460a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
461a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::closeOutput(audio_io_handle_t output)
462a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
463a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
464a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) return PERMISSION_DENIED;
465a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
466a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->closeOutput(output);
467a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
468a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
469a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
470a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::suspendOutput(audio_io_handle_t output)
471a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
472a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
473a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) {
474a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGW("suspendOutput() could not get AudioFlinger");
475a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
476a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
477a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
478a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->suspendOutput(output);
479a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
480a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
481a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::restoreOutput(audio_io_handle_t output)
482a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
483a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
484a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) {
485a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGW("restoreOutput() could not get AudioFlinger");
486a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
487a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
488a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
489a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->restoreOutput(output);
490a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
491a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
492a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentaudio_io_handle_t AudioPolicyService::openInput(uint32_t *pDevices,
493a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pSamplingRate,
494a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pFormat,
495a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pChannels,
496a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t acoustics)
497a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
498a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
499a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) {
500a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGW("openInput() could not get AudioFlinger");
501ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
502a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
503a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
504a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->openInput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, acoustics);
505a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
506a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
507a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::closeInput(audio_io_handle_t input)
508a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
509a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
510a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) return PERMISSION_DENIED;
511a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
512a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->closeInput(input);
513a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
514a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
515327c27be19ad333c4835c84397152a0b2cb33081Eric Laurentstatus_t AudioPolicyService::setStreamVolume(AudioSystem::stream_type stream, float volume, audio_io_handle_t output, int delayMs)
516a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
517327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    return mAudioCommandThread->volumeCommand((int)stream, volume, (int)output, delayMs);
518a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
519a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
520a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setStreamOutput(AudioSystem::stream_type stream, audio_io_handle_t output)
521a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
522a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
523a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) return PERMISSION_DENIED;
524a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
525a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->setStreamOutput(stream, output);
526a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
527a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
528a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
529327c27be19ad333c4835c84397152a0b2cb33081Eric Laurentvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs, int delayMs)
530a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
531327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs, delayMs);
532a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
533a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
534a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentString8 AudioPolicyService::getParameters(audio_io_handle_t ioHandle, const String8& keys)
535a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
536a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 result = AudioSystem::getParameters(ioHandle, keys);
537a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return result;
538a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
539a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
540a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream)
541a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
542327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mTonePlaybackThread->startToneCommand(tone, stream);
543a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
544a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
545a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
546a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::stopTone()
547a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
548327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mTonePlaybackThread->stopToneCommand();
549a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
550a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
551a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
552415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurentstatus_t AudioPolicyService::setVoiceVolume(float volume, int delayMs)
553415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent{
554415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    return mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
555415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent}
556a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
557a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// -----------  AudioPolicyService::AudioCommandThread implementation ----------
558a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
559a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioPolicyService::AudioCommandThread::AudioCommandThread()
560a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    :   Thread(false)
561a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
562a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpToneGenerator = NULL;
563a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
564a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
565a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
566a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioPolicyService::AudioCommandThread::~AudioCommandThread()
567a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
568a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mAudioCommands.clear();
569a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpToneGenerator != NULL) delete mpToneGenerator;
570a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
571a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
572a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::onFirstRef()
573a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
574a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    const size_t SIZE = 256;
575a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    char buffer[SIZE];
576a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
577a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    snprintf(buffer, SIZE, "AudioCommandThread");
578a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
579a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    run(buffer, ANDROID_PRIORITY_AUDIO);
580a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
581a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
582a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentbool AudioPolicyService::AudioCommandThread::threadLoop()
583a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
584327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    nsecs_t waitTime = INT64_MAX;
585327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
586a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mLock.lock();
587a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    while (!exitPending())
588a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {
589a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        while(!mAudioCommands.isEmpty()) {
590327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            nsecs_t curTime = systemTime();
591327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            // commands are sorted by increasing time stamp: execute them from index 0 and up
592327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (mAudioCommands[0]->mTime <= curTime) {
593327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                AudioCommand *command = mAudioCommands[0];
594327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                mAudioCommands.removeAt(0);
595327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                switch (command->mCommand) {
596327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case START_TONE: {
597327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.unlock();
598327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    ToneData *data = (ToneData *)command->mParam;
599327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGV("AudioCommandThread() processing start tone %d on stream %d",
600327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                            data->mType, data->mStream);
601327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    if (mpToneGenerator != NULL)
602327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        delete mpToneGenerator;
603327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
604327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mpToneGenerator->startTone(data->mType);
605327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    delete data;
606327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.lock();
607327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }break;
608327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case STOP_TONE: {
609327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.unlock();
610327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGV("AudioCommandThread() processing stop tone");
611327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    if (mpToneGenerator != NULL) {
612327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        mpToneGenerator->stopTone();
613327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        delete mpToneGenerator;
614327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        mpToneGenerator = NULL;
615327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }
616327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.lock();
617327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }break;
618327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case SET_VOLUME: {
619327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    VolumeData *data = (VolumeData *)command->mParam;
620327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGV("AudioCommandThread() processing set volume stream %d, volume %f, output %d", data->mStream, data->mVolume, data->mIO);
621327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    command->mStatus = AudioSystem::setStreamVolume(data->mStream, data->mVolume, data->mIO);
622327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    if (command->mWaitStatus) {
623327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        command->mCond.signal();
624327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        mWaitWorkCV.wait(mLock);
625327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }
626327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    delete data;
627327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }break;
628327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case SET_PARAMETERS: {
629327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     ParametersData *data = (ParametersData *)command->mParam;
630327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     LOGV("AudioCommandThread() processing set parameters string %s, io %d", data->mKeyValuePairs.string(), data->mIO);
631327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
632327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     if (command->mWaitStatus) {
633327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                         command->mCond.signal();
634327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                         mWaitWorkCV.wait(mLock);
635327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     }
636327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     delete data;
637327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     }break;
638415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                case SET_VOICE_VOLUME: {
639415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
640415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    LOGV("AudioCommandThread() processing set voice volume volume %f", data->mVolume);
641415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
642415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    if (command->mWaitStatus) {
643415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                        command->mCond.signal();
644415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                        mWaitWorkCV.wait(mLock);
645415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    }
646415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    delete data;
647415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    }break;
648327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                default:
649327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGW("AudioCommandThread() unknown command %d", command->mCommand);
650a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                }
651327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                delete command;
652327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                waitTime = INT64_MAX;
653327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            } else {
654327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                waitTime = mAudioCommands[0]->mTime - curTime;
655327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                break;
656a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            }
657a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        }
658a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGV("AudioCommandThread() going to sleep");
659327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        mWaitWorkCV.waitRelative(mLock, waitTime);
660a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGV("AudioCommandThread() waking up");
661a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
662a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mLock.unlock();
663a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return false;
664a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
665a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
666f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::dump(int fd)
667f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
668f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    const size_t SIZE = 256;
669f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    char buffer[SIZE];
670f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    String8 result;
671f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
672f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
673f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
674f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    write(fd, result.string(), result.size());
675f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
676f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    bool locked = tryLock(mLock);
677f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    if (!locked) {
678f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        String8 result2(kCmdDeadlockedString);
679f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        write(fd, result2.string(), result2.size());
680f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    }
681f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
682f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "- Commands:\n");
683f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result = String8(buffer);
684f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append("   Command Time        Status  Wait pParam\n");
685f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    for (int i = 0; i < (int)mAudioCommands.size(); i++) {
686f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        mAudioCommands[i]->dump(buffer, SIZE);
687f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        result.append(buffer);
688f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    }
689f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    write(fd, result.string(), result.size());
690f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
691f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    if (locked) mLock.unlock();
692f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
693f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    return NO_ERROR;
694f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
695f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
696a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
697a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
698a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
699a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = START_TONE;
700a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    ToneData *data = new ToneData();
701a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mType = type;
702a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mStream = stream;
703a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = (void *)data;
704327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    command->mWaitStatus = false;
705415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
706327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command);
707a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
708a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
709a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
710a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
711a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::stopToneCommand()
712a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
713a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
714a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = STOP_TONE;
715a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = NULL;
716327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    command->mWaitStatus = false;
717415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
718327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command);
719a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("AudioCommandThread() adding tone stop");
720a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
721a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
722a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
723327c27be19ad333c4835c84397152a0b2cb33081Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float volume, int output, int delayMs)
724a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
725327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    status_t status = NO_ERROR;
726327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
727a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
728a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = SET_VOLUME;
729a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    VolumeData *data = new VolumeData();
730a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mStream = stream;
731a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mVolume = volume;
732a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mIO = output;
733a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = data;
734327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (delayMs == 0) {
735327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = true;
736327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    } else {
737327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = false;
738327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
739415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
740327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command, delayMs);
741ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent    LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", stream, volume, output);
742a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
743327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (command->mWaitStatus) {
744327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mCond.wait(mLock);
745327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        status =  command->mStatus;
746327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        mWaitWorkCV.signal();
747327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
748a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return status;
749a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
750a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
751327c27be19ad333c4835c84397152a0b2cb33081Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle, const String8& keyValuePairs, int delayMs)
752a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
753327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    status_t status = NO_ERROR;
754327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
755a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
756a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = SET_PARAMETERS;
757a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    ParametersData *data = new ParametersData();
758a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mIO = ioHandle;
759a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mKeyValuePairs = keyValuePairs;
760a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = data;
761327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (delayMs == 0) {
762327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = true;
763327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    } else {
764327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = false;
765327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
766415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
767327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command, delayMs);
768327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", keyValuePairs.string(), ioHandle, delayMs);
769a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
770327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (command->mWaitStatus) {
771327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mCond.wait(mLock);
772327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        status =  command->mStatus;
773327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        mWaitWorkCV.signal();
774327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
775a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return status;
776a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
777a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
778415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurentstatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
779415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent{
780415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    status_t status = NO_ERROR;
781415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent
782415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    AudioCommand *command = new AudioCommand();
783415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    command->mCommand = SET_VOICE_VOLUME;
784415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    VoiceVolumeData *data = new VoiceVolumeData();
785415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    data->mVolume = volume;
786415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    command->mParam = data;
787415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    if (delayMs == 0) {
788415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        command->mWaitStatus = true;
789415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    } else {
790415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        command->mWaitStatus = false;
791415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    }
792415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
793415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    insertCommand_l(command, delayMs);
794415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    LOGV("AudioCommandThread() adding set voice volume volume %f", volume);
795415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    mWaitWorkCV.signal();
796415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    if (command->mWaitStatus) {
797415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        command->mCond.wait(mLock);
798415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        status =  command->mStatus;
799415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        mWaitWorkCV.signal();
800415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    }
801415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    return status;
802415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent}
803415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent
804327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent// insertCommand_l() must be called with mLock held
805327c27be19ad333c4835c84397152a0b2cb33081Eric Laurentvoid AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
806327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent{
807327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    ssize_t i;
808327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    Vector <AudioCommand *> removedCommands;
809327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
810327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    command->mTime = systemTime() + milliseconds(delayMs);
811327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
812327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    // check same pending commands with later time stamps and eliminate them
813327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    for (i = mAudioCommands.size()-1; i >= 0; i--) {
814327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        AudioCommand *command2 = mAudioCommands[i];
815327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
816327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        if (command2->mTime <= command->mTime) break;
817327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        if (command2->mCommand != command->mCommand) continue;
818327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
819327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        switch (command->mCommand) {
820327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case SET_PARAMETERS: {
821327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            ParametersData *data = (ParametersData *)command->mParam;
822327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            ParametersData *data2 = (ParametersData *)command2->mParam;
823327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (data->mIO != data2->mIO) break;
824327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            LOGV("Comparing parameter command %s to new command %s", data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
825327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            AudioParameter param = AudioParameter(data->mKeyValuePairs);
826327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
827327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            for (size_t j = 0; j < param.size(); j++) {
828327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               String8 key;
829327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               String8 value;
830327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               param.getAt(j, key, value);
831327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               for (size_t k = 0; k < param2.size(); k++) {
832327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  String8 key2;
833327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  String8 value2;
834327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  param2.getAt(k, key2, value2);
835327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  if (key2 == key) {
836327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                      param2.remove(key2);
837327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                      LOGV("Filtering out parameter %s", key2.string());
838327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                      break;
839327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  }
840327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               }
841327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            }
842327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            // if all keys have been filtered out, remove the command.
843327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            // otherwise, update the key value pairs
844327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (param2.size() == 0) {
845327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                removedCommands.add(command2);
846327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            } else {
847327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                data2->mKeyValuePairs = param2.toString();
848327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            }
849327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        } break;
850327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
851327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case SET_VOLUME: {
852327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            VolumeData *data = (VolumeData *)command->mParam;
853327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            VolumeData *data2 = (VolumeData *)command2->mParam;
854327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (data->mIO != data2->mIO) break;
855327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (data->mStream != data2->mStream) break;
856327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            LOGV("Filtering out volume command on output %d for stream %d", data->mIO, data->mStream);
857327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            removedCommands.add(command2);
858327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        } break;
859327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case START_TONE:
860327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case STOP_TONE:
861327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        default:
862327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            break;
863327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        }
864327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
865327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
866327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    // remove filtered commands
867327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    for (size_t j = 0; j < removedCommands.size(); j++) {
868327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        // removed commands always have time stamps greater than current command
869327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
870327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (mAudioCommands[k] == removedCommands[j]) {
871327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                LOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
872327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                mAudioCommands.removeAt(k);
873327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                break;
874327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            }
875327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        }
876327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
877327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    removedCommands.clear();
878327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
879327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    // insert command at the right place according to its time stamp
880327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    LOGV("inserting command: %d at index %ld, num commands %d", command->mCommand, i+1, mAudioCommands.size());
881327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mAudioCommands.insertAt(command, i + 1);
882327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent}
883327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
884a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::exit()
885a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
886a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("AudioCommandThread::exit");
887a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {
888a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        AutoMutex _l(mLock);
889a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        requestExit();
890a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        mWaitWorkCV.signal();
891a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
892a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    requestExitAndWait();
893a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
894a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
895f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentvoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
896f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
897f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, size, "   %02d      %06d.%03d  %03d     %01u    %p\n",
898f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mCommand,
899f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            (int)ns2s(mTime),
900f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            (int)ns2ms(mTime)%1000,
901f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mStatus,
902f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mWaitStatus,
903f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mParam);
904f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
905f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
906a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}; // namespace android
907