blob: 6b17b872f9152aa7861177a9729a5edb204c7b58 [file] [log] [blame]
Eric Laurent9d91ad52009-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) {
200 LOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelcount %d, mDirectOutput %d",
201 mCurOutput, mTestSamplingRate, mTestFormat, mTestChannelcount, mDirectOutput);
202
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;
209 outputDesc->mChannels = (mTestChannelcount == 1) ? AudioSystem::CHANNEL_OUT_MONO : AudioSystem::CHANNEL_OUT_STEREO;
210 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);
219 mOutputs.add(mTestOutputs[mCurOutput], outputDesc);
220 }
221 return mTestOutputs[mCurOutput];
222 }
223#endif //AUDIO_POLICY_TEST
224 if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
225 (format != 0 && !AudioSystem::isLinearPCM(format)) ||
226 (channels != 0 && channels != AudioSystem::CHANNEL_OUT_MONO && channels != AudioSystem::CHANNEL_OUT_STEREO)) {
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700227 return 0;
Eric Laurent9d91ad52009-07-17 12:17:14 -0700228 }
229
230 return mHardwareOutput;
231}
232
233status_t AudioPolicyManagerGeneric::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
234{
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700235 LOGV("startOutput() output %d, stream %d", output, stream);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700236 ssize_t index = mOutputs.indexOfKey(output);
237 if (index < 0) {
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700238 LOGW("startOutput() unknow output %d", output);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700239 return BAD_VALUE;
240 }
241
242 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
243
244 // handle special case for sonification while in call
245 if (mPhoneState == AudioSystem::MODE_IN_CALL) {
246 handleIncallSonification(stream, true);
247 }
248
249 // incremenent usage count for this stream on the requested output:
250 outputDesc->changeRefCount(stream, 1);
251 return NO_ERROR;
252}
253
254status_t AudioPolicyManagerGeneric::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
255{
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700256 LOGV("stopOutput() output %d, stream %d", output, stream);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700257 ssize_t index = mOutputs.indexOfKey(output);
258 if (index < 0) {
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700259 LOGW("stopOutput() unknow output %d", output);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700260 return BAD_VALUE;
261 }
262
263 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
264
265 // handle special case for sonification while in call
266 if (mPhoneState == AudioSystem::MODE_IN_CALL) {
267 handleIncallSonification(stream, false);
268 }
269
270 if (outputDesc->isUsedByStream(stream)) {
271 // decrement usage count of this stream on the output
272 outputDesc->changeRefCount(stream, -1);
273 return NO_ERROR;
274 } else {
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700275 LOGW("stopOutput() refcount is already 0 for output %d", output);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700276 return INVALID_OPERATION;
277 }
278}
279
280void AudioPolicyManagerGeneric::releaseOutput(audio_io_handle_t output)
281{
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700282 LOGV("releaseOutput() %d", output);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700283 ssize_t index = mOutputs.indexOfKey(output);
284 if (index < 0) {
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700285 LOGW("releaseOutput() releasing unknown output %d", output);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700286 return;
287 }
288
289#ifdef AUDIO_POLICY_TEST
290 int testIndex = testOutputIndex(output);
291 if (testIndex != 0) {
292 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
293 if (outputDesc->refCount() == 0) {
294 mpClientInterface->closeOutput(output);
295 delete mOutputs.valueAt(index);
296 mOutputs.removeItem(output);
297 mTestOutputs[testIndex] = 0;
298 }
299 }
300#endif //AUDIO_POLICY_TEST
301}
302
303audio_io_handle_t AudioPolicyManagerGeneric::getInput(int inputSource,
304 uint32_t samplingRate,
305 uint32_t format,
306 uint32_t channels,
307 AudioSystem::audio_in_acoustics acoustics)
308{
309 audio_io_handle_t input = 0;
310 uint32_t device;
311
312 LOGV("getInput() inputSource %d, samplingRate %d, format %d, channels %x, acoustics %x", inputSource, samplingRate, format, channels, acoustics);
313
314 AudioInputDescriptor *inputDesc = new AudioInputDescriptor();
315 inputDesc->mDevice = AudioSystem::DEVICE_IN_BUILTIN_MIC;
316 inputDesc->mSamplingRate = samplingRate;
317 inputDesc->mFormat = format;
318 inputDesc->mChannels = channels;
319 inputDesc->mAcoustics = acoustics;
320 inputDesc->mRefCount = 0;
321 input = mpClientInterface->openInput(&inputDesc->mDevice,
322 &inputDesc->mSamplingRate,
323 &inputDesc->mFormat,
324 &inputDesc->mChannels,
325 inputDesc->mAcoustics);
326
327 // only accept input with the exact requested set of parameters
328 if ((samplingRate != inputDesc->mSamplingRate) ||
329 (format != inputDesc->mFormat) ||
330 (channels != inputDesc->mChannels)) {
331 LOGV("getOutput() failed opening input: samplingRate %d, format %d, channels %d",
332 samplingRate, format, channels);
333 mpClientInterface->closeInput(input);
334 delete inputDesc;
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700335 return 0;
Eric Laurent9d91ad52009-07-17 12:17:14 -0700336 }
337 mInputs.add(input, inputDesc);
338 return input;
339}
340
341status_t AudioPolicyManagerGeneric::startInput(audio_io_handle_t input)
342{
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700343 LOGV("startInput() input %d", input);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700344 ssize_t index = mInputs.indexOfKey(input);
345 if (index < 0) {
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700346 LOGW("startInput() unknow input %d", input);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700347 return BAD_VALUE;
348 }
349 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
350
351#ifdef AUDIO_POLICY_TEST
352 if (mTestInput == 0)
353#endif //AUDIO_POLICY_TEST
354 {
355 // refuse 2 active AudioRecord clients at the same time
356 for (size_t i = 0; i < mInputs.size(); i++) {
357 if (mInputs.valueAt(i)->mRefCount > 0) {
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700358 LOGW("startInput() input %d, other input %d already started", input, mInputs.keyAt(i));
Eric Laurent9d91ad52009-07-17 12:17:14 -0700359 return INVALID_OPERATION;
360 }
361 }
362 }
363
364 inputDesc->mRefCount = 1;
365 return NO_ERROR;
366}
367
368status_t AudioPolicyManagerGeneric::stopInput(audio_io_handle_t input)
369{
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700370 LOGV("stopInput() input %d", input);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700371 ssize_t index = mInputs.indexOfKey(input);
372 if (index < 0) {
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700373 LOGW("stopInput() unknow input %d", input);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700374 return BAD_VALUE;
375 }
376 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
377
378 if (inputDesc->mRefCount == 0) {
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700379 LOGW("stopInput() input %d already stopped", input);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700380 return INVALID_OPERATION;
381 } else {
382 inputDesc->mRefCount = 0;
383 return NO_ERROR;
384 }
385}
386
387void AudioPolicyManagerGeneric::releaseInput(audio_io_handle_t input)
388{
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700389 LOGV("releaseInput() %d", input);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700390 ssize_t index = mInputs.indexOfKey(input);
391 if (index < 0) {
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700392 LOGW("releaseInput() releasing unknown input %d", input);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700393 return;
394 }
395 mpClientInterface->closeInput(input);
396 delete mInputs.valueAt(index);
397 mInputs.removeItem(input);
398}
399
400
401
402void AudioPolicyManagerGeneric::initStreamVolume(AudioSystem::stream_type stream,
403 int indexMin,
404 int indexMax)
405{
406 LOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
407 mStreams[stream].mIndexMin = indexMin;
408 mStreams[stream].mIndexMax = indexMax;
409}
410
411status_t AudioPolicyManagerGeneric::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
412{
413
414 if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
415 return BAD_VALUE;
416 }
417
418 LOGV("setStreamVolumeIndex() stream %d, index %d", stream, index);
419 mStreams[stream].mIndexCur = index;
420
421 // do not change actual stream volume if the stream is muted
422 if (mStreams[stream].mMuteCount != 0) {
423 return NO_ERROR;
424 }
425
426 // Do not changed in call volume if bluetooth is connected and vice versa
427 if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
428 (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {
429 LOGV("setStreamVolumeIndex() cannot set stream %d volume with force use = %d for comm",
430 stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);
431 return INVALID_OPERATION;
432 }
433
434 // compute and apply stream volume on all outputs according to connected device
435 for (size_t i = 0; i < mOutputs.size(); i++) {
436 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(i);
437 uint32_t device = outputDesc->device();
438
439 float volume = computeVolume((int)stream, index, device);
440
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700441 LOGV("setStreamVolume() for output %d stream %d, volume %f", mOutputs.keyAt(i), stream, volume);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700442 mpClientInterface->setStreamVolume(stream, volume, mOutputs.keyAt(i));
443 }
444 return NO_ERROR;
445}
446
447status_t AudioPolicyManagerGeneric::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
448{
449 if (index == 0) {
450 return BAD_VALUE;
451 }
452 LOGV("getStreamVolumeIndex() stream %d", stream);
453 *index = mStreams[stream].mIndexCur;
454 return NO_ERROR;
455}
456
457// ----------------------------------------------------------------------------
458// AudioPolicyManagerGeneric
459// ----------------------------------------------------------------------------
460
461// --- class factory
462
Eric Laurent9d91ad52009-07-17 12:17:14 -0700463AudioPolicyManagerGeneric::AudioPolicyManagerGeneric(AudioPolicyClientInterface *clientInterface)
464 :
465#ifdef AUDIO_POLICY_TEST
466 Thread(false),
467#endif //AUDIO_POLICY_TEST
468 mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0)
469{
470 mpClientInterface = clientInterface;
471
472 for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {
473 mForceUse[i] = AudioSystem::FORCE_NONE;
474 }
475
476 // devices available by default are speaker, ear piece and microphone
477 mAvailableOutputDevices = AudioSystem::DEVICE_OUT_SPEAKER;
478 mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC;
479
480 // open hardware output
481 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
482 outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
483 mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
484 &outputDesc->mSamplingRate,
485 &outputDesc->mFormat,
486 &outputDesc->mChannels,
487 &outputDesc->mLatency,
488 outputDesc->mFlags);
489
490 if (mHardwareOutput == 0) {
491 LOGE("Failed to initialize hardware output stream, samplingRate: %d, format %d, channels %d",
492 outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
493 } else {
494 mOutputs.add(mHardwareOutput, outputDesc);
495 }
496
497#ifdef AUDIO_POLICY_TEST
498 mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
499 mTestSamplingRate = 44100;
500 mTestFormat = AudioSystem::PCM_16_BIT;
501 mTestChannelcount = 2;
502 mTestLatencyMs = 0;
503 mCurOutput = 0;
504 mDirectOutput = false;
505 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
506 mTestOutputs[i] = 0;
507 }
508
509 const size_t SIZE = 256;
510 char buffer[SIZE];
511 snprintf(buffer, SIZE, "AudioPolicyManagerTest");
512 run(buffer, ANDROID_PRIORITY_AUDIO);
513#endif //AUDIO_POLICY_TEST
514}
515
516AudioPolicyManagerGeneric::~AudioPolicyManagerGeneric()
517{
518#ifdef AUDIO_POLICY_TEST
519 exit();
520#endif //AUDIO_POLICY_TEST
521
522 for (size_t i = 0; i < mOutputs.size(); i++) {
523 mpClientInterface->closeOutput(mOutputs.keyAt(i));
524 delete mOutputs.valueAt(i);
525 }
526 mOutputs.clear();
527 for (size_t i = 0; i < mInputs.size(); i++) {
528 mpClientInterface->closeInput(mInputs.keyAt(i));
529 delete mInputs.valueAt(i);
530 }
531 mInputs.clear();
532}
533
534#ifdef AUDIO_POLICY_TEST
535bool AudioPolicyManagerGeneric::threadLoop()
536{
537 LOGV("entering threadLoop()");
538 while (!exitPending())
539 {
540 Mutex::Autolock _l(mLock);
541 mWaitWorkCV.waitRelative(mLock, milliseconds(50));
542 String8 command;
543 command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
544 if (command != "") {
545 LOGV("Test command %s received", command.string());
546 AudioParameter param = AudioParameter(command);
547 int valueInt;
548 String8 value;
549 if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
550 param.remove(String8("test_cmd_policy_output"));
551 mCurOutput = valueInt;
552 }
553 if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
554 param.remove(String8("test_cmd_policy_direct"));
555 if (value == "false") {
556 mDirectOutput = false;
557 } else if (value == "true") {
558 mDirectOutput = true;
559 }
560 }
561 if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
562 param.remove(String8("test_cmd_policy_input"));
563 mTestInput = valueInt;
564 }
565
566 if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
567 param.remove(String8("test_cmd_policy_format"));
568 if (value == "PCM 16 bits") {
569 mTestFormat = AudioSystem::PCM_16_BIT;
570 } else if (value == "PCM 8 bits") {
571 mTestFormat = AudioSystem::PCM_8_BIT;
572 } else if (value == "Compressed MP3") {
573 mTestFormat = AudioSystem::MP3;
574 }
575 }
576 if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
577 param.remove(String8("test_cmd_policy_channels"));
578 if (value == "Channels Stereo") {
579 mTestChannelcount = 2;
580 } else if (value == "Channels Mono") {
581 mTestChannelcount = 1;
582 }
583 }
584 if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
585 param.remove(String8("test_cmd_policy_sampleRate"));
586 if (valueInt >= 0 && valueInt <= 96000) {
587 mTestSamplingRate = valueInt;
588 }
589 }
590 mpClientInterface->setParameters(0, String8("test_cmd_policy="));
591 }
592 }
593 return false;
594}
595
596void AudioPolicyManagerGeneric::exit()
597{
598 {
599 AutoMutex _l(mLock);
600 requestExit();
601 mWaitWorkCV.signal();
602 }
603 requestExitAndWait();
604}
605
606int AudioPolicyManagerGeneric::testOutputIndex(audio_io_handle_t output)
607{
608 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
609 if (output == mTestOutputs[i]) return i;
610 }
611 return 0;
612}
613#endif //AUDIO_POLICY_TEST
614
615// ---
616
617AudioPolicyManagerGeneric::routing_strategy AudioPolicyManagerGeneric::getStrategy(AudioSystem::stream_type stream)
618{
619 // stream to strategy mapping
620 switch (stream) {
621 case AudioSystem::VOICE_CALL:
622 case AudioSystem::BLUETOOTH_SCO:
623 return STRATEGY_PHONE;
624 case AudioSystem::RING:
625 case AudioSystem::NOTIFICATION:
626 case AudioSystem::ALARM:
627 case AudioSystem::ENFORCED_AUDIBLE:
628 return STRATEGY_SONIFICATION;
629 case AudioSystem::DTMF:
630 return STRATEGY_DTMF;
631 default:
632 LOGE("unknown stream type");
633 case AudioSystem::SYSTEM:
634 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
635 // while key clicks are played produces a poor result
636 case AudioSystem::TTS:
637 case AudioSystem::MUSIC:
638 return STRATEGY_MEDIA;
639 }
640}
641
642
643float AudioPolicyManagerGeneric::computeVolume(int stream, int index, uint32_t device)
644{
645 float volume = 1.0;
646
647 StreamDescriptor &streamDesc = mStreams[stream];
648
649 // Force max volume if stream cannot be muted
650 if (!streamDesc.mCanBeMuted) index = streamDesc.mIndexMax;
651
652 int volInt = (100 * (index - streamDesc.mIndexMin)) / (streamDesc.mIndexMax - streamDesc.mIndexMin);
653 volume = AudioSystem::linearToLog(volInt);
654
655 return volume;
656}
657
658void AudioPolicyManagerGeneric::setStreamMute(int stream, bool on, audio_io_handle_t output)
659{
Eric Laurente0e9ecc2009-07-28 08:44:33 -0700660 LOGV("setStreamMute() stream %d, mute %d, output %d", stream, on, output);
Eric Laurent9d91ad52009-07-17 12:17:14 -0700661
662 StreamDescriptor &streamDesc = mStreams[stream];
663
664 if (on) {
665 if (streamDesc.mMuteCount++ == 0) {
666 if (streamDesc.mCanBeMuted) {
667 mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, 0, output);
668 }
669 }
670 } else {
671 if (streamDesc.mMuteCount == 0) {
672 LOGW("setStreamMute() unmuting non muted stream!");
673 return;
674 }
675 if (--streamDesc.mMuteCount == 0) {
676 uint32_t device = mOutputs.valueFor(output)->mDevice;
677 float volume = computeVolume(stream, streamDesc.mIndexCur, device);
678 mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output);
679 }
680 }
681}
682
683void AudioPolicyManagerGeneric::handleIncallSonification(int stream, bool starting)
684{
685 // if the stream pertains to sonification strategy and we are in call we must
686 // mute the stream if it is low visibility. If it is high visibility, we must play a tone
687 // in the device used for phone strategy and play the tone if the selected device does not
688 // interfere with the device used for phone strategy
689 if (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) {
690 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mHardwareOutput);
691 LOGV("handleIncallSonification() stream %d starting %d device %x", stream, starting, outputDesc->mDevice);
692 if (outputDesc->isUsedByStream((AudioSystem::stream_type)stream)) {
693 if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) {
694 LOGV("handleIncallSonification() low visibility");
695 setStreamMute(stream, starting, mHardwareOutput);
696 } else {
697 if (starting) {
698 mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL);
699 } else {
700 mpClientInterface->stopTone();
701 }
702 }
703 }
704 }
705}
706
707
708// --- AudioOutputDescriptor class implementation
709
710AudioPolicyManagerGeneric::AudioOutputDescriptor::AudioOutputDescriptor()
711 : mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0),
712 mFlags((AudioSystem::output_flags)0), mDevice(0)
713{
714 // clear usage count for all stream types
715 for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
716 mRefCount[i] = 0;
717 }
718}
719
720uint32_t AudioPolicyManagerGeneric::AudioOutputDescriptor::device()
721{
722 return mDevice;
723}
724
725void AudioPolicyManagerGeneric::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta)
726{
727 if ((delta + (int)mRefCount[stream]) < 0) {
728 LOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]);
729 mRefCount[stream] = 0;
730 return;
731 }
732 mRefCount[stream] += delta;
733 LOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
734}
735
736uint32_t AudioPolicyManagerGeneric::AudioOutputDescriptor::refCount()
737{
738 uint32_t refcount = 0;
739 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
740 refcount += mRefCount[i];
741 }
742 return refcount;
743}
744
745// --- AudioInputDescriptor class implementation
746
747AudioPolicyManagerGeneric::AudioInputDescriptor::AudioInputDescriptor()
748 : mSamplingRate(0), mFormat(0), mChannels(0),
749 mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0)
750{
751}
752
753}; // namespace android