blob: 632385915a32cb5d1e5890335c172b9ceae9e2c5 [file] [log] [blame]
Eric Laurenta553c252009-07-17 12:17:14 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "AudioPolicyManagerGeneric"
18//#define LOG_NDEBUG 0
19#include <utils/Log.h>
20#include "AudioPolicyManagerGeneric.h"
21#include <media/mediarecorder.h>
22
23namespace android {
24
25
26// ----------------------------------------------------------------------------
27// AudioPolicyInterface implementation
28// ----------------------------------------------------------------------------
29
30
31status_t AudioPolicyManagerGeneric::setDeviceConnectionState(AudioSystem::audio_devices device,
32 AudioSystem::device_connection_state state,
33 const char *device_address)
34{
35
36 LOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address);
37
38 // connect/disconnect only 1 device at a time
39 if (AudioSystem::popCount(device) != 1) return BAD_VALUE;
40
41 if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) {
42 LOGE("setDeviceConnectionState() invalid address: %s", device_address);
43 return BAD_VALUE;
44 }
45
46 // handle output devices
47 if (AudioSystem::isOutputDevice(device)) {
48 switch (state)
49 {
50 // handle output device connection
51 case AudioSystem::DEVICE_STATE_AVAILABLE:
52 if (mAvailableOutputDevices & device) {
53 LOGW("setDeviceConnectionState() device already connected: %x", device);
54 return INVALID_OPERATION;
55 }
56 LOGV("setDeviceConnectionState() connecting device %x", device);
57
58 // register new device as available
59 mAvailableOutputDevices |= device;
60 break;
61 // handle output device disconnection
62 case AudioSystem::DEVICE_STATE_UNAVAILABLE:
63 if (!(mAvailableOutputDevices & device)) {
64 LOGW("setDeviceConnectionState() device not connected: %x", device);
65 return INVALID_OPERATION;
66 }
67 LOGV("setDeviceConnectionState() disconnecting device %x", device);
68 // remove device from available output devices
69 mAvailableOutputDevices &= ~device;
70 break;
71
72 default:
73 LOGE("setDeviceConnectionState() invalid state: %x", state);
74 return BAD_VALUE;
75 }
76 return NO_ERROR;
77 }
78 // handle input devices
79 if (AudioSystem::isInputDevice(device)) {
80 switch (state)
81 {
82 // handle input device connection
83 case AudioSystem::DEVICE_STATE_AVAILABLE:
84 if (mAvailableInputDevices & device) {
85 LOGW("setDeviceConnectionState() device already connected: %d", device);
86 return INVALID_OPERATION;
87 }
88 mAvailableInputDevices |= device;
89 break;
90
91 // handle input device disconnection
92 case AudioSystem::DEVICE_STATE_UNAVAILABLE:
93 if (!(mAvailableInputDevices & device)) {
94 LOGW("setDeviceConnectionState() device not connected: %d", device);
95 return INVALID_OPERATION;
96 }
97 mAvailableInputDevices &= ~device;
98 break;
99
100 default:
101 LOGE("setDeviceConnectionState() invalid state: %x", state);
102 return BAD_VALUE;
103 }
104 return NO_ERROR;
105 }
106
107 LOGW("setDeviceConnectionState() invalid device: %x", device);
108 return BAD_VALUE;
109}
110
111AudioSystem::device_connection_state AudioPolicyManagerGeneric::getDeviceConnectionState(AudioSystem::audio_devices device,
112 const char *device_address)
113{
114 AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE;
115 String8 address = String8(device_address);
116 if (AudioSystem::isOutputDevice(device)) {
117 if (device & mAvailableOutputDevices) {
118 state = AudioSystem::DEVICE_STATE_AVAILABLE;
119 }
120 } else if (AudioSystem::isInputDevice(device)) {
121 if (device & mAvailableInputDevices) {
122 state = AudioSystem::DEVICE_STATE_AVAILABLE;
123 }
124 }
125
126 return state;
127}
128
129void AudioPolicyManagerGeneric::setPhoneState(int state)
130{
131 LOGV("setPhoneState() state %d", state);
132 uint32_t newDevice = 0;
133 if (state < 0 || state >= AudioSystem::NUM_MODES) {
134 LOGW("setPhoneState() invalid state %d", state);
135 return;
136 }
137
138 if (state == mPhoneState ) {
139 LOGW("setPhoneState() setting same state %d", state);
140 return;
141 }
142 // store previous phone state for management of sonification strategy below
143 int oldState = mPhoneState;
144 mPhoneState = state;
145
146 // if leaving or entering in call state, handle special case of active streams
147 // pertaining to sonification strategy see handleIncallSonification()
148 if (state == AudioSystem::MODE_IN_CALL ||
149 oldState == AudioSystem::MODE_IN_CALL) {
150 bool starting = (state == AudioSystem::MODE_IN_CALL) ? true : false;
151 LOGV("setPhoneState() in call state management: new state is %d", state);
152 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
153 handleIncallSonification(stream, starting);
154 }
155 }
156}
157
158void AudioPolicyManagerGeneric::setRingerMode(uint32_t mode, uint32_t mask)
159{
160 LOGV("setRingerMode() mode %x, mask %x", mode, mask);
161
162 mRingerMode = mode;
163}
164
165void AudioPolicyManagerGeneric::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
166{
167 LOGV("setForceUse) usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
168 mForceUse[usage] = config;
169}
170
171AudioSystem::forced_config AudioPolicyManagerGeneric::getForceUse(AudioSystem::force_use usage)
172{
173 return mForceUse[usage];
174}
175
176void AudioPolicyManagerGeneric::setSystemProperty(const char* property, const char* value)
177{
178 LOGV("setSystemProperty() property %s, value %s", property, value);
179 if (strcmp(property, "ro.camera.sound.forced") == 0) {
180 if (atoi(value)) {
181 LOGV("ENFORCED_AUDIBLE cannot be muted");
182 mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = false;
183 } else {
184 LOGV("ENFORCED_AUDIBLE can be muted");
185 mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = true;
186 }
187 }
188}
189
190audio_io_handle_t AudioPolicyManagerGeneric::getOutput(AudioSystem::stream_type stream,
191 uint32_t samplingRate,
192 uint32_t format,
193 uint32_t channels,
194 AudioSystem::output_flags flags)
195{
196 LOGV("getOutput() stream %d, samplingRate %d, format %d, channels %x, flags %x", stream, samplingRate, format, channels, flags);
197
198#ifdef AUDIO_POLICY_TEST
199 if (mCurOutput != 0) {
Eric Laurent69682b42009-08-04 07:29:18 -0700200 LOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channels %x, mDirectOutput %d",
201 mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
Eric Laurenta553c252009-07-17 12:17:14 -0700202
203 if (mTestOutputs[mCurOutput] == 0) {
204 LOGV("getOutput() opening test output");
205 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
206 outputDesc->mDevice = mTestDevice;
207 outputDesc->mSamplingRate = mTestSamplingRate;
208 outputDesc->mFormat = mTestFormat;
Eric Laurent69682b42009-08-04 07:29:18 -0700209 outputDesc->mChannels = mTestChannels;
Eric Laurenta553c252009-07-17 12:17:14 -0700210 outputDesc->mLatency = mTestLatencyMs;
211 outputDesc->mFlags = (AudioSystem::output_flags)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0);
212 outputDesc->mRefCount[stream] = 0;
213 mTestOutputs[mCurOutput] = mpClientInterface->openOutput(&outputDesc->mDevice,
214 &outputDesc->mSamplingRate,
215 &outputDesc->mFormat,
216 &outputDesc->mChannels,
217 &outputDesc->mLatency,
218 outputDesc->mFlags);
Eric Laurent69682b42009-08-04 07:29:18 -0700219 if (mTestOutputs[mCurOutput]) {
220 AudioParameter outputCmd = AudioParameter();
221 outputCmd.addInt(String8("set_id"),mCurOutput);
222 mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
223 mOutputs.add(mTestOutputs[mCurOutput], outputDesc);
224 }
Eric Laurenta553c252009-07-17 12:17:14 -0700225 }
226 return mTestOutputs[mCurOutput];
227 }
228#endif //AUDIO_POLICY_TEST
229 if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
230 (format != 0 && !AudioSystem::isLinearPCM(format)) ||
231 (channels != 0 && channels != AudioSystem::CHANNEL_OUT_MONO && channels != AudioSystem::CHANNEL_OUT_STEREO)) {
Eric Laurentddb78e72009-07-28 08:44:33 -0700232 return 0;
Eric Laurenta553c252009-07-17 12:17:14 -0700233 }
234
235 return mHardwareOutput;
236}
237
238status_t AudioPolicyManagerGeneric::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
239{
Eric Laurentddb78e72009-07-28 08:44:33 -0700240 LOGV("startOutput() output %d, stream %d", output, stream);
Eric Laurenta553c252009-07-17 12:17:14 -0700241 ssize_t index = mOutputs.indexOfKey(output);
242 if (index < 0) {
Eric Laurentddb78e72009-07-28 08:44:33 -0700243 LOGW("startOutput() unknow output %d", output);
Eric Laurenta553c252009-07-17 12:17:14 -0700244 return BAD_VALUE;
245 }
246
247 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
248
249 // handle special case for sonification while in call
250 if (mPhoneState == AudioSystem::MODE_IN_CALL) {
251 handleIncallSonification(stream, true);
252 }
253
254 // incremenent usage count for this stream on the requested output:
255 outputDesc->changeRefCount(stream, 1);
256 return NO_ERROR;
257}
258
259status_t AudioPolicyManagerGeneric::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
260{
Eric Laurentddb78e72009-07-28 08:44:33 -0700261 LOGV("stopOutput() output %d, stream %d", output, stream);
Eric Laurenta553c252009-07-17 12:17:14 -0700262 ssize_t index = mOutputs.indexOfKey(output);
263 if (index < 0) {
Eric Laurentddb78e72009-07-28 08:44:33 -0700264 LOGW("stopOutput() unknow output %d", output);
Eric Laurenta553c252009-07-17 12:17:14 -0700265 return BAD_VALUE;
266 }
267
268 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
269
270 // handle special case for sonification while in call
271 if (mPhoneState == AudioSystem::MODE_IN_CALL) {
272 handleIncallSonification(stream, false);
273 }
274
275 if (outputDesc->isUsedByStream(stream)) {
276 // decrement usage count of this stream on the output
277 outputDesc->changeRefCount(stream, -1);
278 return NO_ERROR;
279 } else {
Eric Laurentddb78e72009-07-28 08:44:33 -0700280 LOGW("stopOutput() refcount is already 0 for output %d", output);
Eric Laurenta553c252009-07-17 12:17:14 -0700281 return INVALID_OPERATION;
282 }
283}
284
285void AudioPolicyManagerGeneric::releaseOutput(audio_io_handle_t output)
286{
Eric Laurentddb78e72009-07-28 08:44:33 -0700287 LOGV("releaseOutput() %d", output);
Eric Laurenta553c252009-07-17 12:17:14 -0700288 ssize_t index = mOutputs.indexOfKey(output);
289 if (index < 0) {
Eric Laurentddb78e72009-07-28 08:44:33 -0700290 LOGW("releaseOutput() releasing unknown output %d", output);
Eric Laurenta553c252009-07-17 12:17:14 -0700291 return;
292 }
293
294#ifdef AUDIO_POLICY_TEST
295 int testIndex = testOutputIndex(output);
296 if (testIndex != 0) {
297 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
298 if (outputDesc->refCount() == 0) {
299 mpClientInterface->closeOutput(output);
300 delete mOutputs.valueAt(index);
301 mOutputs.removeItem(output);
302 mTestOutputs[testIndex] = 0;
303 }
304 }
305#endif //AUDIO_POLICY_TEST
306}
307
308audio_io_handle_t AudioPolicyManagerGeneric::getInput(int inputSource,
309 uint32_t samplingRate,
310 uint32_t format,
311 uint32_t channels,
312 AudioSystem::audio_in_acoustics acoustics)
313{
314 audio_io_handle_t input = 0;
315 uint32_t device;
316
317 LOGV("getInput() inputSource %d, samplingRate %d, format %d, channels %x, acoustics %x", inputSource, samplingRate, format, channels, acoustics);
318
319 AudioInputDescriptor *inputDesc = new AudioInputDescriptor();
320 inputDesc->mDevice = AudioSystem::DEVICE_IN_BUILTIN_MIC;
321 inputDesc->mSamplingRate = samplingRate;
322 inputDesc->mFormat = format;
323 inputDesc->mChannels = channels;
324 inputDesc->mAcoustics = acoustics;
325 inputDesc->mRefCount = 0;
326 input = mpClientInterface->openInput(&inputDesc->mDevice,
327 &inputDesc->mSamplingRate,
328 &inputDesc->mFormat,
329 &inputDesc->mChannels,
330 inputDesc->mAcoustics);
331
332 // only accept input with the exact requested set of parameters
333 if ((samplingRate != inputDesc->mSamplingRate) ||
334 (format != inputDesc->mFormat) ||
335 (channels != inputDesc->mChannels)) {
336 LOGV("getOutput() failed opening input: samplingRate %d, format %d, channels %d",
337 samplingRate, format, channels);
338 mpClientInterface->closeInput(input);
339 delete inputDesc;
Eric Laurentddb78e72009-07-28 08:44:33 -0700340 return 0;
Eric Laurenta553c252009-07-17 12:17:14 -0700341 }
342 mInputs.add(input, inputDesc);
343 return input;
344}
345
346status_t AudioPolicyManagerGeneric::startInput(audio_io_handle_t input)
347{
Eric Laurentddb78e72009-07-28 08:44:33 -0700348 LOGV("startInput() input %d", input);
Eric Laurenta553c252009-07-17 12:17:14 -0700349 ssize_t index = mInputs.indexOfKey(input);
350 if (index < 0) {
Eric Laurentddb78e72009-07-28 08:44:33 -0700351 LOGW("startInput() unknow input %d", input);
Eric Laurenta553c252009-07-17 12:17:14 -0700352 return BAD_VALUE;
353 }
354 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
355
356#ifdef AUDIO_POLICY_TEST
357 if (mTestInput == 0)
358#endif //AUDIO_POLICY_TEST
359 {
360 // refuse 2 active AudioRecord clients at the same time
361 for (size_t i = 0; i < mInputs.size(); i++) {
362 if (mInputs.valueAt(i)->mRefCount > 0) {
Eric Laurentddb78e72009-07-28 08:44:33 -0700363 LOGW("startInput() input %d, other input %d already started", input, mInputs.keyAt(i));
Eric Laurenta553c252009-07-17 12:17:14 -0700364 return INVALID_OPERATION;
365 }
366 }
367 }
368
369 inputDesc->mRefCount = 1;
370 return NO_ERROR;
371}
372
373status_t AudioPolicyManagerGeneric::stopInput(audio_io_handle_t input)
374{
Eric Laurentddb78e72009-07-28 08:44:33 -0700375 LOGV("stopInput() input %d", input);
Eric Laurenta553c252009-07-17 12:17:14 -0700376 ssize_t index = mInputs.indexOfKey(input);
377 if (index < 0) {
Eric Laurentddb78e72009-07-28 08:44:33 -0700378 LOGW("stopInput() unknow input %d", input);
Eric Laurenta553c252009-07-17 12:17:14 -0700379 return BAD_VALUE;
380 }
381 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
382
383 if (inputDesc->mRefCount == 0) {
Eric Laurentddb78e72009-07-28 08:44:33 -0700384 LOGW("stopInput() input %d already stopped", input);
Eric Laurenta553c252009-07-17 12:17:14 -0700385 return INVALID_OPERATION;
386 } else {
387 inputDesc->mRefCount = 0;
388 return NO_ERROR;
389 }
390}
391
392void AudioPolicyManagerGeneric::releaseInput(audio_io_handle_t input)
393{
Eric Laurentddb78e72009-07-28 08:44:33 -0700394 LOGV("releaseInput() %d", input);
Eric Laurenta553c252009-07-17 12:17:14 -0700395 ssize_t index = mInputs.indexOfKey(input);
396 if (index < 0) {
Eric Laurentddb78e72009-07-28 08:44:33 -0700397 LOGW("releaseInput() releasing unknown input %d", input);
Eric Laurenta553c252009-07-17 12:17:14 -0700398 return;
399 }
400 mpClientInterface->closeInput(input);
401 delete mInputs.valueAt(index);
402 mInputs.removeItem(input);
403}
404
405
406
407void AudioPolicyManagerGeneric::initStreamVolume(AudioSystem::stream_type stream,
408 int indexMin,
409 int indexMax)
410{
411 LOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
412 mStreams[stream].mIndexMin = indexMin;
413 mStreams[stream].mIndexMax = indexMax;
414}
415
416status_t AudioPolicyManagerGeneric::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
417{
418
419 if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
420 return BAD_VALUE;
421 }
422
423 LOGV("setStreamVolumeIndex() stream %d, index %d", stream, index);
424 mStreams[stream].mIndexCur = index;
425
426 // do not change actual stream volume if the stream is muted
427 if (mStreams[stream].mMuteCount != 0) {
428 return NO_ERROR;
429 }
430
431 // Do not changed in call volume if bluetooth is connected and vice versa
432 if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
433 (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {
434 LOGV("setStreamVolumeIndex() cannot set stream %d volume with force use = %d for comm",
435 stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);
436 return INVALID_OPERATION;
437 }
438
439 // compute and apply stream volume on all outputs according to connected device
440 for (size_t i = 0; i < mOutputs.size(); i++) {
441 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
442 uint32_t device = outputDesc->device();
443
444 float volume = computeVolume((int)stream, index, device);
445
Eric Laurentddb78e72009-07-28 08:44:33 -0700446 LOGV("setStreamVolume() for output %d stream %d, volume %f", mOutputs.keyAt(i), stream, volume);
Eric Laurenta553c252009-07-17 12:17:14 -0700447 mpClientInterface->setStreamVolume(stream, volume, mOutputs.keyAt(i));
448 }
449 return NO_ERROR;
450}
451
452status_t AudioPolicyManagerGeneric::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
453{
454 if (index == 0) {
455 return BAD_VALUE;
456 }
457 LOGV("getStreamVolumeIndex() stream %d", stream);
458 *index = mStreams[stream].mIndexCur;
459 return NO_ERROR;
460}
461
462// ----------------------------------------------------------------------------
463// AudioPolicyManagerGeneric
464// ----------------------------------------------------------------------------
465
466// --- class factory
467
Eric Laurenta553c252009-07-17 12:17:14 -0700468AudioPolicyManagerGeneric::AudioPolicyManagerGeneric(AudioPolicyClientInterface *clientInterface)
469 :
470#ifdef AUDIO_POLICY_TEST
471 Thread(false),
472#endif //AUDIO_POLICY_TEST
473 mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0)
474{
475 mpClientInterface = clientInterface;
476
477 for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {
478 mForceUse[i] = AudioSystem::FORCE_NONE;
479 }
480
481 // devices available by default are speaker, ear piece and microphone
482 mAvailableOutputDevices = AudioSystem::DEVICE_OUT_SPEAKER;
483 mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC;
484
485 // open hardware output
486 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
487 outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
488 mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
489 &outputDesc->mSamplingRate,
490 &outputDesc->mFormat,
491 &outputDesc->mChannels,
492 &outputDesc->mLatency,
493 outputDesc->mFlags);
494
495 if (mHardwareOutput == 0) {
496 LOGE("Failed to initialize hardware output stream, samplingRate: %d, format %d, channels %d",
497 outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
498 } else {
499 mOutputs.add(mHardwareOutput, outputDesc);
500 }
501
502#ifdef AUDIO_POLICY_TEST
Eric Laurent69682b42009-08-04 07:29:18 -0700503 AudioParameter outputCmd = AudioParameter();
504 outputCmd.addInt(String8("set_id"), 0);
505 mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
506
Eric Laurenta553c252009-07-17 12:17:14 -0700507 mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
508 mTestSamplingRate = 44100;
509 mTestFormat = AudioSystem::PCM_16_BIT;
Eric Laurent69682b42009-08-04 07:29:18 -0700510 mTestChannels = AudioSystem::CHANNEL_OUT_STEREO;
Eric Laurenta553c252009-07-17 12:17:14 -0700511 mTestLatencyMs = 0;
512 mCurOutput = 0;
513 mDirectOutput = false;
514 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
515 mTestOutputs[i] = 0;
516 }
517
518 const size_t SIZE = 256;
519 char buffer[SIZE];
520 snprintf(buffer, SIZE, "AudioPolicyManagerTest");
521 run(buffer, ANDROID_PRIORITY_AUDIO);
522#endif //AUDIO_POLICY_TEST
523}
524
525AudioPolicyManagerGeneric::~AudioPolicyManagerGeneric()
526{
527#ifdef AUDIO_POLICY_TEST
528 exit();
529#endif //AUDIO_POLICY_TEST
530
531 for (size_t i = 0; i < mOutputs.size(); i++) {
532 mpClientInterface->closeOutput(mOutputs.keyAt(i));
533 delete mOutputs.valueAt(i);
534 }
535 mOutputs.clear();
536 for (size_t i = 0; i < mInputs.size(); i++) {
537 mpClientInterface->closeInput(mInputs.keyAt(i));
538 delete mInputs.valueAt(i);
539 }
540 mInputs.clear();
541}
542
543#ifdef AUDIO_POLICY_TEST
544bool AudioPolicyManagerGeneric::threadLoop()
545{
546 LOGV("entering threadLoop()");
547 while (!exitPending())
548 {
Eric Laurent69682b42009-08-04 07:29:18 -0700549 String8 command;
550 int valueInt;
551 String8 value;
552
Eric Laurenta553c252009-07-17 12:17:14 -0700553 Mutex::Autolock _l(mLock);
554 mWaitWorkCV.waitRelative(mLock, milliseconds(50));
Eric Laurent69682b42009-08-04 07:29:18 -0700555
Eric Laurenta553c252009-07-17 12:17:14 -0700556 command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
Eric Laurent69682b42009-08-04 07:29:18 -0700557 AudioParameter param = AudioParameter(command);
558
559 if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
560 valueInt != 0) {
Eric Laurenta553c252009-07-17 12:17:14 -0700561 LOGV("Test command %s received", command.string());
Eric Laurent69682b42009-08-04 07:29:18 -0700562 String8 target;
563 if (param.get(String8("target"), target) != NO_ERROR) {
564 target = "Manager";
565 }
Eric Laurenta553c252009-07-17 12:17:14 -0700566 if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
567 param.remove(String8("test_cmd_policy_output"));
568 mCurOutput = valueInt;
569 }
570 if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
571 param.remove(String8("test_cmd_policy_direct"));
572 if (value == "false") {
573 mDirectOutput = false;
574 } else if (value == "true") {
575 mDirectOutput = true;
576 }
577 }
578 if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
579 param.remove(String8("test_cmd_policy_input"));
580 mTestInput = valueInt;
581 }
582
583 if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
584 param.remove(String8("test_cmd_policy_format"));
Eric Laurent69682b42009-08-04 07:29:18 -0700585 int format = AudioSystem::INVALID_FORMAT;
Eric Laurenta553c252009-07-17 12:17:14 -0700586 if (value == "PCM 16 bits") {
Eric Laurent69682b42009-08-04 07:29:18 -0700587 format = AudioSystem::PCM_16_BIT;
Eric Laurenta553c252009-07-17 12:17:14 -0700588 } else if (value == "PCM 8 bits") {
Eric Laurent69682b42009-08-04 07:29:18 -0700589 format = AudioSystem::PCM_8_BIT;
Eric Laurenta553c252009-07-17 12:17:14 -0700590 } else if (value == "Compressed MP3") {
Eric Laurent69682b42009-08-04 07:29:18 -0700591 format = AudioSystem::MP3;
592 }
593 if (format != AudioSystem::INVALID_FORMAT) {
594 if (target == "Manager") {
595 mTestFormat = format;
596 } else if (mTestOutputs[mCurOutput] != 0) {
597 AudioParameter outputParam = AudioParameter();
598 outputParam.addInt(String8("format"), format);
599 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
600 }
Eric Laurenta553c252009-07-17 12:17:14 -0700601 }
602 }
603 if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
604 param.remove(String8("test_cmd_policy_channels"));
Eric Laurent69682b42009-08-04 07:29:18 -0700605 int channels = 0;
606
Eric Laurenta553c252009-07-17 12:17:14 -0700607 if (value == "Channels Stereo") {
Eric Laurent69682b42009-08-04 07:29:18 -0700608 channels = AudioSystem::CHANNEL_OUT_STEREO;
Eric Laurenta553c252009-07-17 12:17:14 -0700609 } else if (value == "Channels Mono") {
Eric Laurent69682b42009-08-04 07:29:18 -0700610 channels = AudioSystem::CHANNEL_OUT_MONO;
611 }
612 if (channels != 0) {
613 if (target == "Manager") {
614 mTestChannels = channels;
615 } else if (mTestOutputs[mCurOutput] != 0) {
616 AudioParameter outputParam = AudioParameter();
617 outputParam.addInt(String8("channels"), channels);
618 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
619 }
Eric Laurenta553c252009-07-17 12:17:14 -0700620 }
621 }
622 if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
623 param.remove(String8("test_cmd_policy_sampleRate"));
624 if (valueInt >= 0 && valueInt <= 96000) {
Eric Laurent69682b42009-08-04 07:29:18 -0700625 int samplingRate = valueInt;
626 if (target == "Manager") {
627 mTestSamplingRate = samplingRate;
628 } else if (mTestOutputs[mCurOutput] != 0) {
629 AudioParameter outputParam = AudioParameter();
630 outputParam.addInt(String8("sampling_rate"), samplingRate);
631 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
632 }
Eric Laurenta553c252009-07-17 12:17:14 -0700633 }
634 }
Eric Laurent69682b42009-08-04 07:29:18 -0700635
636 if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
637 param.remove(String8("test_cmd_policy_reopen"));
638
639 mpClientInterface->closeOutput(mHardwareOutput);
640 delete mOutputs.valueFor(mHardwareOutput);
641 mOutputs.removeItem(mHardwareOutput);
642
643 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
644 outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
645 mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
646 &outputDesc->mSamplingRate,
647 &outputDesc->mFormat,
648 &outputDesc->mChannels,
649 &outputDesc->mLatency,
650 outputDesc->mFlags);
651 if (mHardwareOutput == 0) {
652 LOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d",
653 outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
654 } else {
655 AudioParameter outputCmd = AudioParameter();
656 outputCmd.addInt(String8("set_id"), 0);
657 mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
658 mOutputs.add(mHardwareOutput, outputDesc);
659 }
660 }
661
662
Eric Laurenta553c252009-07-17 12:17:14 -0700663 mpClientInterface->setParameters(0, String8("test_cmd_policy="));
664 }
665 }
666 return false;
667}
668
669void AudioPolicyManagerGeneric::exit()
670{
671 {
672 AutoMutex _l(mLock);
673 requestExit();
674 mWaitWorkCV.signal();
675 }
676 requestExitAndWait();
677}
678
679int AudioPolicyManagerGeneric::testOutputIndex(audio_io_handle_t output)
680{
681 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
682 if (output == mTestOutputs[i]) return i;
683 }
684 return 0;
685}
686#endif //AUDIO_POLICY_TEST
687
688// ---
689
690AudioPolicyManagerGeneric::routing_strategy AudioPolicyManagerGeneric::getStrategy(AudioSystem::stream_type stream)
691{
692 // stream to strategy mapping
693 switch (stream) {
694 case AudioSystem::VOICE_CALL:
695 case AudioSystem::BLUETOOTH_SCO:
696 return STRATEGY_PHONE;
697 case AudioSystem::RING:
698 case AudioSystem::NOTIFICATION:
699 case AudioSystem::ALARM:
700 case AudioSystem::ENFORCED_AUDIBLE:
701 return STRATEGY_SONIFICATION;
702 case AudioSystem::DTMF:
703 return STRATEGY_DTMF;
704 default:
705 LOGE("unknown stream type");
706 case AudioSystem::SYSTEM:
707 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
708 // while key clicks are played produces a poor result
709 case AudioSystem::TTS:
710 case AudioSystem::MUSIC:
711 return STRATEGY_MEDIA;
712 }
713}
714
715
716float AudioPolicyManagerGeneric::computeVolume(int stream, int index, uint32_t device)
717{
718 float volume = 1.0;
719
720 StreamDescriptor &streamDesc = mStreams[stream];
721
722 // Force max volume if stream cannot be muted
723 if (!streamDesc.mCanBeMuted) index = streamDesc.mIndexMax;
724
725 int volInt = (100 * (index - streamDesc.mIndexMin)) / (streamDesc.mIndexMax - streamDesc.mIndexMin);
726 volume = AudioSystem::linearToLog(volInt);
727
728 return volume;
729}
730
731void AudioPolicyManagerGeneric::setStreamMute(int stream, bool on, audio_io_handle_t output)
732{
Eric Laurentddb78e72009-07-28 08:44:33 -0700733 LOGV("setStreamMute() stream %d, mute %d, output %d", stream, on, output);
Eric Laurenta553c252009-07-17 12:17:14 -0700734
735 StreamDescriptor &streamDesc = mStreams[stream];
736
737 if (on) {
738 if (streamDesc.mMuteCount++ == 0) {
739 if (streamDesc.mCanBeMuted) {
740 mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, 0, output);
741 }
742 }
743 } else {
744 if (streamDesc.mMuteCount == 0) {
745 LOGW("setStreamMute() unmuting non muted stream!");
746 return;
747 }
748 if (--streamDesc.mMuteCount == 0) {
749 uint32_t device = mOutputs.valueFor(output)->mDevice;
750 float volume = computeVolume(stream, streamDesc.mIndexCur, device);
751 mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output);
752 }
753 }
754}
755
756void AudioPolicyManagerGeneric::handleIncallSonification(int stream, bool starting)
757{
758 // if the stream pertains to sonification strategy and we are in call we must
759 // mute the stream if it is low visibility. If it is high visibility, we must play a tone
760 // in the device used for phone strategy and play the tone if the selected device does not
761 // interfere with the device used for phone strategy
762 if (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) {
763 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mHardwareOutput);
764 LOGV("handleIncallSonification() stream %d starting %d device %x", stream, starting, outputDesc->mDevice);
765 if (outputDesc->isUsedByStream((AudioSystem::stream_type)stream)) {
766 if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) {
767 LOGV("handleIncallSonification() low visibility");
768 setStreamMute(stream, starting, mHardwareOutput);
769 } else {
770 if (starting) {
771 mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL);
772 } else {
773 mpClientInterface->stopTone();
774 }
775 }
776 }
777 }
778}
779
780
781// --- AudioOutputDescriptor class implementation
782
783AudioPolicyManagerGeneric::AudioOutputDescriptor::AudioOutputDescriptor()
784 : mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0),
785 mFlags((AudioSystem::output_flags)0), mDevice(0)
786{
787 // clear usage count for all stream types
788 for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
789 mRefCount[i] = 0;
790 }
791}
792
793uint32_t AudioPolicyManagerGeneric::AudioOutputDescriptor::device()
794{
795 return mDevice;
796}
797
798void AudioPolicyManagerGeneric::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta)
799{
800 if ((delta + (int)mRefCount[stream]) < 0) {
801 LOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]);
802 mRefCount[stream] = 0;
803 return;
804 }
805 mRefCount[stream] += delta;
806 LOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
807}
808
809uint32_t AudioPolicyManagerGeneric::AudioOutputDescriptor::refCount()
810{
811 uint32_t refcount = 0;
812 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
813 refcount += mRefCount[i];
814 }
815 return refcount;
816}
817
818// --- AudioInputDescriptor class implementation
819
820AudioPolicyManagerGeneric::AudioInputDescriptor::AudioInputDescriptor()
821 : mSamplingRate(0), mFormat(0), mChannels(0),
822 mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0)
823{
824}
825
826}; // namespace android