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"
33cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent#include <hardware_legacy/AudioPolicyManagerBase.h>
34a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <cutils/properties.h>
35a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#include <dlfcn.h>
36cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent#include <hardware_legacy/power.h>
37a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
38a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// ----------------------------------------------------------------------------
39a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// the sim build doesn't have gettid
40a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
41a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#ifndef HAVE_GETTID
42a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent# define gettid getpid
43a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#endif
44a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
45a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentnamespace android {
46a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
47cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent
48cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurentstatic const char *kDeadlockedString = "AudioPolicyService may be deadlocked\n";
49cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurentstatic const char *kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n";
50f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
51f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatic const int kDumpLockRetries = 50;
52f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatic const int kDumpLockSleep = 20000;
53f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
54a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatic bool checkPermission() {
55a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#ifndef HAVE_ANDROID_OS
56a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return true;
57a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#endif
58a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
59a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
60a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
61a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return ok;
62a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
63a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
64a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// ----------------------------------------------------------------------------
65a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
66a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioPolicyService::AudioPolicyService()
674192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent    : BnAudioPolicyService() , mpPolicyManager(NULL)
68a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
69a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    char value[PROPERTY_VALUE_MAX];
70a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
714192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent    // start tone playback thread
72cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    mTonePlaybackThread = new AudioCommandThread(String8(""));
734192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent    // start audio commands thread
74cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread"));
754192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent
76a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#if (defined GENERIC_AUDIO) || (defined AUDIO_POLICY_TEST)
77cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    mpPolicyManager = new AudioPolicyManagerBase(this);
78a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("build for GENERIC_AUDIO - using generic audio policy");
79a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#else
80a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    // if running in emulation - use the emulator driver
81a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (property_get("ro.kernel.qemu", value, 0)) {
82a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGV("Running in emulation - using generic audio policy");
83cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        mpPolicyManager = new AudioPolicyManagerBase(this);
84a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
85a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    else {
86a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGV("Using hardware specific audio policy");
874192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent        mpPolicyManager = createAudioPolicyManager(this);
88a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
89a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent#endif
90a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
91a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    // load properties
92a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    property_get("ro.camera.sound.forced", value, "0");
93a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value);
94a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
95a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
96a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioPolicyService::~AudioPolicyService()
97a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
98327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mTonePlaybackThread->exit();
99327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mTonePlaybackThread.clear();
100a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mAudioCommandThread->exit();
101a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mAudioCommandThread.clear();
102a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
103a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager) {
1044192cce1f252932b6f3cae43e3da7584f4cb2c28Eric Laurent        delete mpPolicyManager;
105a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
106a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
107a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
108a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
109a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setDeviceConnectionState(AudioSystem::audio_devices device,
110a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                                  AudioSystem::device_connection_state state,
111a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                                  const char *device_address)
112a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
113a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
114a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
115a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
116a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
117a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
118a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
119a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!AudioSystem::isOutputDevice(device) && !AudioSystem::isInputDevice(device)) {
120a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
121a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
122a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (state != AudioSystem::DEVICE_STATE_AVAILABLE && state != AudioSystem::DEVICE_STATE_UNAVAILABLE) {
123a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
124a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
125a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
126a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setDeviceConnectionState() tid %d", gettid());
127a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
128a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->setDeviceConnectionState(device, state, device_address);
129a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
130a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
131a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioSystem::device_connection_state AudioPolicyService::getDeviceConnectionState(AudioSystem::audio_devices device,
132a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                                  const char *device_address)
133a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
134a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
135a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return AudioSystem::DEVICE_STATE_UNAVAILABLE;
136a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
137a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
138a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return AudioSystem::DEVICE_STATE_UNAVAILABLE;
139a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
140a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->getDeviceConnectionState(device, device_address);
141a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
142a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
143a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setPhoneState(int state)
144a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
145a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
146a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
147a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
148a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
149a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
150a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
151a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (state < 0 || state >= AudioSystem::NUM_MODES) {
152a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
153a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
154a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
155a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setPhoneState() tid %d", gettid());
156a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
157a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    // TODO: check if it is more appropriate to do it in platform specific policy manager
158a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioSystem::setMode(state);
159a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
160a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
161a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->setPhoneState(state);
162a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
163a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
164a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
165a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setRingerMode(uint32_t mode, uint32_t mask)
166a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
167a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
168a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
169a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
170a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
171a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
172a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
173a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
174a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->setRingerMode(mode, mask);
175a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
176a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
177a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
178a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
179a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
180a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
181a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
182a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
183a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
184a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
185a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
186a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) {
187a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
188a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
189a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (config < 0 || config >= AudioSystem::NUM_FORCE_CONFIG) {
190a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
191a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
192a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("setForceUse() tid %d", gettid());
193a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
194a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->setForceUse(usage, config);
195a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
196a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
197a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
198a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioSystem::forced_config AudioPolicyService::getForceUse(AudioSystem::force_use usage)
199a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
200a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
201a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return AudioSystem::FORCE_NONE;
202a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
203a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
204a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return AudioSystem::FORCE_NONE;
205a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
206a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) {
207a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return AudioSystem::FORCE_NONE;
208a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
209a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->getForceUse(usage);
210a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
211a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
212a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentaudio_io_handle_t AudioPolicyService::getOutput(AudioSystem::stream_type stream,
213a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t samplingRate,
214a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t format,
215a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t channels,
216a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    AudioSystem::output_flags flags)
217a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
218a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
219ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
220a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
221a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("getOutput() tid %d", gettid());
222a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
223a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->getOutput(stream, samplingRate, format, channels, flags);
224a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
225a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
226a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
227a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
228a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
229a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
230a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
231a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("startOutput() tid %d", gettid());
232a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
233a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->startOutput(output, stream);
234a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
235a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
236a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
237a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
238a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
239a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
240a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
241a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("stopOutput() tid %d", gettid());
242a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
243a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->stopOutput(output, stream);
244a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
245a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
246a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::releaseOutput(audio_io_handle_t output)
247a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
248a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
249a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return;
250a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
251a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("releaseOutput() tid %d", gettid());
252a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
253a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->releaseOutput(output);
254a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
255a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
256a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentaudio_io_handle_t AudioPolicyService::getInput(int inputSource,
257a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t samplingRate,
258a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t format,
259a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    uint32_t channels,
260a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                    AudioSystem::audio_in_acoustics acoustics)
261a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
262a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
263ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
264a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
265a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
266a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->getInput(inputSource, samplingRate, format, channels, acoustics);
267a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
268a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
269a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::startInput(audio_io_handle_t input)
270a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
271a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
272a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
273a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
274a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
275a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->startInput(input);
276a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
277a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
278a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::stopInput(audio_io_handle_t input)
279a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
280a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
281a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
282a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
283a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
284a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->stopInput(input);
285a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
286a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
287a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::releaseInput(audio_io_handle_t input)
288a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
289a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
290a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return;
291a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
292a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    Mutex::Autolock _l(mLock);
293a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->releaseInput(input);
294a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
295a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
296a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::initStreamVolume(AudioSystem::stream_type stream,
297a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                            int indexMin,
298a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                            int indexMax)
299a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
300a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
301a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
302a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
303a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
304a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
305a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
306a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
307a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
308a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
309a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpPolicyManager->initStreamVolume(stream, indexMin, indexMax);
310a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
311a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
312a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
313a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
314a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
315a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
316a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
317a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
318a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
319a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
320a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
321a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
322a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
323a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
324a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
325a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->setStreamVolumeIndex(stream, index);
326a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
327a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
328a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
329a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
330a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpPolicyManager == NULL) {
331a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return NO_INIT;
332a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
333a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (!checkPermission()) {
334a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
335a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
336a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
337a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return BAD_VALUE;
338a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
339a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return mpPolicyManager->getStreamVolumeIndex(stream, index);
340a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
341a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
342a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::binderDied(const wp<IBinder>& who) {
343a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
344a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
345a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
346f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatic bool tryLock(Mutex& mutex)
347f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
348f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    bool locked = false;
349f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    for (int i = 0; i < kDumpLockRetries; ++i) {
350f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mutex.tryLock() == NO_ERROR) {
351f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            locked = true;
352f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            break;
353f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
354f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        usleep(kDumpLockSleep);
355f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    }
356f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    return locked;
357f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
358f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
359f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatus_t AudioPolicyService::dumpInternals(int fd)
360f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
361f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    const size_t SIZE = 256;
362f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    char buffer[SIZE];
363f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    String8 result;
364f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
365f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpPolicyManager);
366f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
367f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
368f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
369f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
370f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
371f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
372f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    write(fd, result.string(), result.size());
373f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    return NO_ERROR;
374f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
375f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
376a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::dump(int fd, const Vector<String16>& args)
377a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
378a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
379f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        dumpPermissionDenial(fd);
380a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    } else {
381f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        bool locked = tryLock(mLock);
382f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (!locked) {
383f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            String8 result(kDeadlockedString);
384f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            write(fd, result.string(), result.size());
385f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
386a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
387f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        dumpInternals(fd);
388f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mAudioCommandThread != NULL) {
389f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mAudioCommandThread->dump(fd);
390f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
391f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mTonePlaybackThread != NULL) {
392f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mTonePlaybackThread->dump(fd);
393f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
394f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
395f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (mpPolicyManager) {
396f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mpPolicyManager->dump(fd);
397f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        }
398f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
399f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        if (locked) mLock.unlock();
400a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
401a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
402a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
403a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
404f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatus_t AudioPolicyService::dumpPermissionDenial(int fd)
405a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
406a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    const size_t SIZE = 256;
407a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    char buffer[SIZE];
408a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 result;
409a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    snprintf(buffer, SIZE, "Permission Denial: "
410a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
411a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            IPCThreadState::self()->getCallingPid(),
412a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            IPCThreadState::self()->getCallingUid());
413a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    result.append(buffer);
414a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    write(fd, result.string(), result.size());
415a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
416a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
417a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
418a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::onTransact(
419a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
420a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
421a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return BnAudioPolicyService::onTransact(code, data, reply, flags);
422a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
423a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
424a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
425a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// ----------------------------------------------------------------------------
426a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::instantiate() {
427a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    defaultServiceManager()->addService(
428a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            String16("media.audio_policy"), new AudioPolicyService());
429a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
430a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
431a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
432a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// ----------------------------------------------------------------------------
433a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// AudioPolicyClientInterface implementation
434a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// ----------------------------------------------------------------------------
435a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
436a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
437a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentaudio_io_handle_t AudioPolicyService::openOutput(uint32_t *pDevices,
438a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pSamplingRate,
439a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pFormat,
440a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pChannels,
441a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pLatencyMs,
442a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                AudioSystem::output_flags flags)
443a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
444a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
445a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) {
446a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGW("openOutput() could not get AudioFlinger");
447ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
448a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
449a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
450a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->openOutput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, pLatencyMs, flags);
451a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
452a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
453a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentaudio_io_handle_t AudioPolicyService::openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2)
454a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
455a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
456a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) {
457a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGW("openDuplicateOutput() could not get AudioFlinger");
458ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
459a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
460a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->openDuplicateOutput(output1, output2);
461a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
462a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
463a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::closeOutput(audio_io_handle_t output)
464a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
465a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
466a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) return PERMISSION_DENIED;
467a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
468a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->closeOutput(output);
469a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
470a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
471a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
472a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::suspendOutput(audio_io_handle_t output)
473a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
474a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
475a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) {
476a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGW("suspendOutput() could not get AudioFlinger");
477a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
478a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
479a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
480a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->suspendOutput(output);
481a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
482a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
483a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::restoreOutput(audio_io_handle_t output)
484a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
485a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
486a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) {
487a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGW("restoreOutput() could not get AudioFlinger");
488a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        return PERMISSION_DENIED;
489a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
490a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
491a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->restoreOutput(output);
492a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
493a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
494a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentaudio_io_handle_t AudioPolicyService::openInput(uint32_t *pDevices,
495a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pSamplingRate,
496a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pFormat,
497a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t *pChannels,
498a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                                uint32_t acoustics)
499a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
500a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
501a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) {
502a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGW("openInput() could not get AudioFlinger");
503ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent        return 0;
504a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
505a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
506a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->openInput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, acoustics);
507a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
508a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
509a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::closeInput(audio_io_handle_t input)
510a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
511a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
512a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) return PERMISSION_DENIED;
513a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
514a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->closeInput(input);
515a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
516a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
517327c27be19ad333c4835c84397152a0b2cb33081Eric Laurentstatus_t AudioPolicyService::setStreamVolume(AudioSystem::stream_type stream, float volume, audio_io_handle_t output, int delayMs)
518a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
519327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    return mAudioCommandThread->volumeCommand((int)stream, volume, (int)output, delayMs);
520a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
521a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
522a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::setStreamOutput(AudioSystem::stream_type stream, audio_io_handle_t output)
523a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
524a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
525a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (af == 0) return PERMISSION_DENIED;
526a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
527a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return af->setStreamOutput(stream, output);
528a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
529a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
530a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
531327c27be19ad333c4835c84397152a0b2cb33081Eric Laurentvoid AudioPolicyService::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs, int delayMs)
532a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
533327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs, delayMs);
534a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
535a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
536a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentString8 AudioPolicyService::getParameters(audio_io_handle_t ioHandle, const String8& keys)
537a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
538a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    String8 result = AudioSystem::getParameters(ioHandle, keys);
539a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return result;
540a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
541a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
542a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream)
543a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
544327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mTonePlaybackThread->startToneCommand(tone, stream);
545a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
546a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
547a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
548a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentstatus_t AudioPolicyService::stopTone()
549a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
550327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mTonePlaybackThread->stopToneCommand();
551a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return NO_ERROR;
552a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
553a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
554415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurentstatus_t AudioPolicyService::setVoiceVolume(float volume, int delayMs)
555415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent{
556415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    return mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
557415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent}
558a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
559a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent// -----------  AudioPolicyService::AudioCommandThread implementation ----------
560a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
561cef3cd79489fa7897ffbacbc4e435651fb04f10dEric LaurentAudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name)
562cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    : Thread(false), mName(name)
563a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
564a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mpToneGenerator = NULL;
565a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
566a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
567a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
568a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric LaurentAudioPolicyService::AudioCommandThread::~AudioCommandThread()
569a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
570cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    if (mName != "" && !mAudioCommands.isEmpty()) {
571cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        release_wake_lock(mName.string());
572cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    }
573a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mAudioCommands.clear();
574a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    if (mpToneGenerator != NULL) delete mpToneGenerator;
575a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
576a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
577a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::onFirstRef()
578a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
579cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    if (mName != "") {
580cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        run(mName.string(), ANDROID_PRIORITY_AUDIO);
581cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    } else {
582cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        run("AudioCommandThread", ANDROID_PRIORITY_AUDIO);
583cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    }
584a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
585a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
586a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentbool AudioPolicyService::AudioCommandThread::threadLoop()
587a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
588327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    nsecs_t waitTime = INT64_MAX;
589327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
590a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mLock.lock();
591a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    while (!exitPending())
592a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {
593a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        while(!mAudioCommands.isEmpty()) {
594327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            nsecs_t curTime = systemTime();
595327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            // commands are sorted by increasing time stamp: execute them from index 0 and up
596327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (mAudioCommands[0]->mTime <= curTime) {
597327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                AudioCommand *command = mAudioCommands[0];
598327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                mAudioCommands.removeAt(0);
5993fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent                mLastCommand = *command;
6003fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent
601327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                switch (command->mCommand) {
602327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case START_TONE: {
603327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.unlock();
604327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    ToneData *data = (ToneData *)command->mParam;
605327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGV("AudioCommandThread() processing start tone %d on stream %d",
606327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                            data->mType, data->mStream);
607327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    if (mpToneGenerator != NULL)
608327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        delete mpToneGenerator;
609327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
610327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mpToneGenerator->startTone(data->mType);
611327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    delete data;
612327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.lock();
613327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }break;
614327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case STOP_TONE: {
615327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.unlock();
616327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGV("AudioCommandThread() processing stop tone");
617327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    if (mpToneGenerator != NULL) {
618327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        mpToneGenerator->stopTone();
619327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        delete mpToneGenerator;
620327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        mpToneGenerator = NULL;
621327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }
622327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    mLock.lock();
623327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }break;
624327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case SET_VOLUME: {
625327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    VolumeData *data = (VolumeData *)command->mParam;
626327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGV("AudioCommandThread() processing set volume stream %d, volume %f, output %d", data->mStream, data->mVolume, data->mIO);
627327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    command->mStatus = AudioSystem::setStreamVolume(data->mStream, data->mVolume, data->mIO);
628327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    if (command->mWaitStatus) {
629327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        command->mCond.signal();
630327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                        mWaitWorkCV.wait(mLock);
631327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }
632327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    delete data;
633327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    }break;
634327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                case SET_PARAMETERS: {
635327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     ParametersData *data = (ParametersData *)command->mParam;
636327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     LOGV("AudioCommandThread() processing set parameters string %s, io %d", data->mKeyValuePairs.string(), data->mIO);
637327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
638327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     if (command->mWaitStatus) {
639327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                         command->mCond.signal();
640327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                         mWaitWorkCV.wait(mLock);
641327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     }
642327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     delete data;
643327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                     }break;
644415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                case SET_VOICE_VOLUME: {
645415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
646415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    LOGV("AudioCommandThread() processing set voice volume volume %f", data->mVolume);
647415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
648415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    if (command->mWaitStatus) {
649415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                        command->mCond.signal();
650415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                        mWaitWorkCV.wait(mLock);
651415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    }
652415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    delete data;
653415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent                    }break;
654327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                default:
655327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                    LOGW("AudioCommandThread() unknown command %d", command->mCommand);
656a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent                }
657327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                delete command;
658327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                waitTime = INT64_MAX;
659327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            } else {
660327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                waitTime = mAudioCommands[0]->mTime - curTime;
661327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                break;
662a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent            }
663a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        }
664cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        // release delayed commands wake lock
665cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        if (mName != "" && mAudioCommands.isEmpty()) {
666cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent            release_wake_lock(mName.string());
667cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        }
668a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGV("AudioCommandThread() going to sleep");
669327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        mWaitWorkCV.waitRelative(mLock, waitTime);
670a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        LOGV("AudioCommandThread() waking up");
671a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
672a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mLock.unlock();
673a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return false;
674a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
675a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
676f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::dump(int fd)
677f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
678f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    const size_t SIZE = 256;
679f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    char buffer[SIZE];
680f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    String8 result;
681f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
682f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
683f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result.append(buffer);
684f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    write(fd, result.string(), result.size());
685f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
686f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    bool locked = tryLock(mLock);
687f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    if (!locked) {
688f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        String8 result2(kCmdDeadlockedString);
689f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        write(fd, result2.string(), result2.size());
690f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    }
691f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
692f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    snprintf(buffer, SIZE, "- Commands:\n");
693f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    result = String8(buffer);
6943fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    result.append("   Command Time        Wait pParam\n");
695f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    for (int i = 0; i < (int)mAudioCommands.size(); i++) {
696f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        mAudioCommands[i]->dump(buffer, SIZE);
697f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent        result.append(buffer);
698f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    }
6993fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    result.append("  Last Command\n");
7003fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    mLastCommand.dump(buffer, SIZE);
7013fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    result.append(buffer);
7023fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent
703f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    write(fd, result.string(), result.size());
704f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
705f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    if (locked) mLock.unlock();
706f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
707f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent    return NO_ERROR;
708f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
709f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
710a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
711a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
712a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
713a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = START_TONE;
714a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    ToneData *data = new ToneData();
715a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mType = type;
716a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mStream = stream;
717a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = (void *)data;
718327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    command->mWaitStatus = false;
719415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
720327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command);
721a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
722a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
723a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
724a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
725a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::stopToneCommand()
726a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
727a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
728a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = STOP_TONE;
729a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = NULL;
730327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    command->mWaitStatus = false;
731415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
732327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command);
733a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("AudioCommandThread() adding tone stop");
734a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
735a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
736a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
737327c27be19ad333c4835c84397152a0b2cb33081Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float volume, int output, int delayMs)
738a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
739327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    status_t status = NO_ERROR;
740327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
741a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
742a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = SET_VOLUME;
743a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    VolumeData *data = new VolumeData();
744a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mStream = stream;
745a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mVolume = volume;
746a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mIO = output;
747a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = data;
748327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (delayMs == 0) {
749327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = true;
750327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    } else {
751327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = false;
752327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
753415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
754327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command, delayMs);
755ddb78e7753be03937ad57ce7c3c842c52bdad65eEric Laurent    LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", stream, volume, output);
756a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
757327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (command->mWaitStatus) {
758327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mCond.wait(mLock);
759327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        status =  command->mStatus;
760327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        mWaitWorkCV.signal();
761327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
762a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return status;
763a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
764a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
765327c27be19ad333c4835c84397152a0b2cb33081Eric Laurentstatus_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle, const String8& keyValuePairs, int delayMs)
766a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
767327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    status_t status = NO_ERROR;
768327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
769a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    AudioCommand *command = new AudioCommand();
770a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mCommand = SET_PARAMETERS;
771a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    ParametersData *data = new ParametersData();
772a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mIO = ioHandle;
773a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    data->mKeyValuePairs = keyValuePairs;
774a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    command->mParam = data;
775327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (delayMs == 0) {
776327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = true;
777327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    } else {
778327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mWaitStatus = false;
779327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
780415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
781327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    insertCommand_l(command, delayMs);
782327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", keyValuePairs.string(), ioHandle, delayMs);
783a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    mWaitWorkCV.signal();
784327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    if (command->mWaitStatus) {
785327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        command->mCond.wait(mLock);
786327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        status =  command->mStatus;
787327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        mWaitWorkCV.signal();
788327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
789a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    return status;
790a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
791a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
792415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurentstatus_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
793415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent{
794415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    status_t status = NO_ERROR;
795415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent
796415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    AudioCommand *command = new AudioCommand();
797415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    command->mCommand = SET_VOICE_VOLUME;
798415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    VoiceVolumeData *data = new VoiceVolumeData();
799415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    data->mVolume = volume;
800415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    command->mParam = data;
801415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    if (delayMs == 0) {
802415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        command->mWaitStatus = true;
803415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    } else {
804415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        command->mWaitStatus = false;
805415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    }
806415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    Mutex::Autolock _l(mLock);
807415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    insertCommand_l(command, delayMs);
808415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    LOGV("AudioCommandThread() adding set voice volume volume %f", volume);
809415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    mWaitWorkCV.signal();
810415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    if (command->mWaitStatus) {
811415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        command->mCond.wait(mLock);
812415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        status =  command->mStatus;
813415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent        mWaitWorkCV.signal();
814415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    }
815415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent    return status;
816415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent}
817415f3e2875b8b0b860d0dd6a69ff6868571c36bbEric Laurent
818327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent// insertCommand_l() must be called with mLock held
819327c27be19ad333c4835c84397152a0b2cb33081Eric Laurentvoid AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
820327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent{
821327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    ssize_t i;
822327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    Vector <AudioCommand *> removedCommands;
823327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
824327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    command->mTime = systemTime() + milliseconds(delayMs);
825327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
826cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    // acquire wake lock to make sure delayed commands are processed
827cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    if (mName != "" && mAudioCommands.isEmpty()) {
828cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
829cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    }
830cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent
831327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    // check same pending commands with later time stamps and eliminate them
832327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    for (i = mAudioCommands.size()-1; i >= 0; i--) {
833327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        AudioCommand *command2 = mAudioCommands[i];
834327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
835327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        if (command2->mTime <= command->mTime) break;
836327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        if (command2->mCommand != command->mCommand) continue;
837327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
838327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        switch (command->mCommand) {
839327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case SET_PARAMETERS: {
840327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            ParametersData *data = (ParametersData *)command->mParam;
841327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            ParametersData *data2 = (ParametersData *)command2->mParam;
842327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (data->mIO != data2->mIO) break;
843327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            LOGV("Comparing parameter command %s to new command %s", data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
844327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            AudioParameter param = AudioParameter(data->mKeyValuePairs);
845327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
846327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            for (size_t j = 0; j < param.size(); j++) {
847327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               String8 key;
848327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               String8 value;
849327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               param.getAt(j, key, value);
850327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               for (size_t k = 0; k < param2.size(); k++) {
851327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  String8 key2;
852327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  String8 value2;
853327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  param2.getAt(k, key2, value2);
854327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  if (key2 == key) {
855327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                      param2.remove(key2);
856327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                      LOGV("Filtering out parameter %s", key2.string());
857327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                      break;
858327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                  }
859327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent               }
860327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            }
861327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            // if all keys have been filtered out, remove the command.
862327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            // otherwise, update the key value pairs
863327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (param2.size() == 0) {
864327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                removedCommands.add(command2);
865327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            } else {
866327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                data2->mKeyValuePairs = param2.toString();
867327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            }
868327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        } break;
869327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
870327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case SET_VOLUME: {
871327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            VolumeData *data = (VolumeData *)command->mParam;
872327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            VolumeData *data2 = (VolumeData *)command2->mParam;
873327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (data->mIO != data2->mIO) break;
874327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (data->mStream != data2->mStream) break;
875327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            LOGV("Filtering out volume command on output %d for stream %d", data->mIO, data->mStream);
876327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            removedCommands.add(command2);
877327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        } break;
878327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case START_TONE:
879327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        case STOP_TONE:
880327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        default:
881327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            break;
882327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        }
883327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
884327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
885327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    // remove filtered commands
886327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    for (size_t j = 0; j < removedCommands.size(); j++) {
887327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        // removed commands always have time stamps greater than current command
888327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
889327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            if (mAudioCommands[k] == removedCommands[j]) {
890327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                LOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
891327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                mAudioCommands.removeAt(k);
892327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent                break;
893327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent            }
894327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent        }
895327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    }
896327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    removedCommands.clear();
897327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
898327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    // insert command at the right place according to its time stamp
899cef3cd79489fa7897ffbacbc4e435651fb04f10dEric Laurent    LOGV("inserting command: %d at index %d, num commands %d", command->mCommand, (int)i+1, mAudioCommands.size());
900327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent    mAudioCommands.insertAt(command, i + 1);
901327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent}
902327c27be19ad333c4835c84397152a0b2cb33081Eric Laurent
903a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurentvoid AudioPolicyService::AudioCommandThread::exit()
904a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent{
905a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    LOGV("AudioCommandThread::exit");
906a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    {
907a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        AutoMutex _l(mLock);
908a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        requestExit();
909a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent        mWaitWorkCV.signal();
910a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    }
911a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent    requestExitAndWait();
912a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}
913a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent
914f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurentvoid AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
915f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent{
9163fdb1267c1623773b4eb5e1b06d5859019275e40Eric Laurent    snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
917f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mCommand,
918f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            (int)ns2s(mTime),
919f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            (int)ns2ms(mTime)%1000,
920f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mWaitStatus,
921f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent            mParam);
922f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent}
923f4ee40e26ec43e17359ff5788565349a9aa71908Eric Laurent
924a553c25b33c99b345cf1c8688f8df0ed8df14e5aEric Laurent}; // namespace android
925