blob: cf9ab88cb10045bfe260be62382d9d886cb07158 [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) {
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)) {
227 return NULL;
228 }
229
230 return mHardwareOutput;
231}
232
233status_t AudioPolicyManagerGeneric::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
234{
235 LOGV("startOutput() output %p, stream %d", output, stream);
236 ssize_t index = mOutputs.indexOfKey(output);
237 if (index < 0) {
238 LOGW("startOutput() unknow output %p", output);
239 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{
256 LOGV("stopOutput() output %p, stream %d", output, stream);
257 ssize_t index = mOutputs.indexOfKey(output);
258 if (index < 0) {
259 LOGW("stopOutput() unknow output %p", output);
260 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 {
275 LOGW("stopOutput() refcount is already 0 for output %p", output);
276 return INVALID_OPERATION;
277 }
278}
279
280void AudioPolicyManagerGeneric::releaseOutput(audio_io_handle_t output)
281{
282 LOGV("releaseOutput() %p", output);
283 ssize_t index = mOutputs.indexOfKey(output);
284 if (index < 0) {
285 LOGW("releaseOutput() releasing unknown output %p", output);
286 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;
335 return NULL;
336 }
337 mInputs.add(input, inputDesc);
338 return input;
339}
340
341status_t AudioPolicyManagerGeneric::startInput(audio_io_handle_t input)
342{
343 LOGV("startInput() input %p", input);
344 ssize_t index = mInputs.indexOfKey(input);
345 if (index < 0) {
346 LOGW("startInput() unknow input %p", input);
347 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) {
358 LOGW("startInput() input %p, other input %p already started", input, mInputs.keyAt(i));
359 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{
370 LOGV("stopInput() input %p", input);
371 ssize_t index = mInputs.indexOfKey(input);
372 if (index < 0) {
373 LOGW("stopInput() unknow input %p", input);
374 return BAD_VALUE;
375 }
376 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
377
378 if (inputDesc->mRefCount == 0) {
379 LOGW("stopInput() input %p already stopped", input);
380 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{
389 LOGV("releaseInput() %p", input);
390 ssize_t index = mInputs.indexOfKey(input);
391 if (index < 0) {
392 LOGW("releaseInput() releasing unknown input %p", input);
393 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
441 LOGV("setStreamVolume() for output %p stream %d, volume %f", mOutputs.keyAt(i), stream, volume);
442 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
463
464extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
465{
466 return new AudioPolicyManagerGeneric(clientInterface);
467}
468
469extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
470{
471 delete interface;
472}
473
474AudioPolicyManagerGeneric::AudioPolicyManagerGeneric(AudioPolicyClientInterface *clientInterface)
475 :
476#ifdef AUDIO_POLICY_TEST
477 Thread(false),
478#endif //AUDIO_POLICY_TEST
479 mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0)
480{
481 mpClientInterface = clientInterface;
482
483 for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {
484 mForceUse[i] = AudioSystem::FORCE_NONE;
485 }
486
487 // devices available by default are speaker, ear piece and microphone
488 mAvailableOutputDevices = AudioSystem::DEVICE_OUT_SPEAKER;
489 mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC;
490
491 // open hardware output
492 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
493 outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
494 mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
495 &outputDesc->mSamplingRate,
496 &outputDesc->mFormat,
497 &outputDesc->mChannels,
498 &outputDesc->mLatency,
499 outputDesc->mFlags);
500
501 if (mHardwareOutput == 0) {
502 LOGE("Failed to initialize hardware output stream, samplingRate: %d, format %d, channels %d",
503 outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
504 } else {
505 mOutputs.add(mHardwareOutput, outputDesc);
506 }
507
508#ifdef AUDIO_POLICY_TEST
509 mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
510 mTestSamplingRate = 44100;
511 mTestFormat = AudioSystem::PCM_16_BIT;
512 mTestChannelcount = 2;
513 mTestLatencyMs = 0;
514 mCurOutput = 0;
515 mDirectOutput = false;
516 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
517 mTestOutputs[i] = 0;
518 }
519
520 const size_t SIZE = 256;
521 char buffer[SIZE];
522 snprintf(buffer, SIZE, "AudioPolicyManagerTest");
523 run(buffer, ANDROID_PRIORITY_AUDIO);
524#endif //AUDIO_POLICY_TEST
525}
526
527AudioPolicyManagerGeneric::~AudioPolicyManagerGeneric()
528{
529#ifdef AUDIO_POLICY_TEST
530 exit();
531#endif //AUDIO_POLICY_TEST
532
533 for (size_t i = 0; i < mOutputs.size(); i++) {
534 mpClientInterface->closeOutput(mOutputs.keyAt(i));
535 delete mOutputs.valueAt(i);
536 }
537 mOutputs.clear();
538 for (size_t i = 0; i < mInputs.size(); i++) {
539 mpClientInterface->closeInput(mInputs.keyAt(i));
540 delete mInputs.valueAt(i);
541 }
542 mInputs.clear();
543}
544
545#ifdef AUDIO_POLICY_TEST
546bool AudioPolicyManagerGeneric::threadLoop()
547{
548 LOGV("entering threadLoop()");
549 while (!exitPending())
550 {
551 Mutex::Autolock _l(mLock);
552 mWaitWorkCV.waitRelative(mLock, milliseconds(50));
553 String8 command;
554 command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
555 if (command != "") {
556 LOGV("Test command %s received", command.string());
557 AudioParameter param = AudioParameter(command);
558 int valueInt;
559 String8 value;
560 if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
561 param.remove(String8("test_cmd_policy_output"));
562 mCurOutput = valueInt;
563 }
564 if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
565 param.remove(String8("test_cmd_policy_direct"));
566 if (value == "false") {
567 mDirectOutput = false;
568 } else if (value == "true") {
569 mDirectOutput = true;
570 }
571 }
572 if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
573 param.remove(String8("test_cmd_policy_input"));
574 mTestInput = valueInt;
575 }
576
577 if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
578 param.remove(String8("test_cmd_policy_format"));
579 if (value == "PCM 16 bits") {
580 mTestFormat = AudioSystem::PCM_16_BIT;
581 } else if (value == "PCM 8 bits") {
582 mTestFormat = AudioSystem::PCM_8_BIT;
583 } else if (value == "Compressed MP3") {
584 mTestFormat = AudioSystem::MP3;
585 }
586 }
587 if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
588 param.remove(String8("test_cmd_policy_channels"));
589 if (value == "Channels Stereo") {
590 mTestChannelcount = 2;
591 } else if (value == "Channels Mono") {
592 mTestChannelcount = 1;
593 }
594 }
595 if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
596 param.remove(String8("test_cmd_policy_sampleRate"));
597 if (valueInt >= 0 && valueInt <= 96000) {
598 mTestSamplingRate = valueInt;
599 }
600 }
601 mpClientInterface->setParameters(0, String8("test_cmd_policy="));
602 }
603 }
604 return false;
605}
606
607void AudioPolicyManagerGeneric::exit()
608{
609 {
610 AutoMutex _l(mLock);
611 requestExit();
612 mWaitWorkCV.signal();
613 }
614 requestExitAndWait();
615}
616
617int AudioPolicyManagerGeneric::testOutputIndex(audio_io_handle_t output)
618{
619 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
620 if (output == mTestOutputs[i]) return i;
621 }
622 return 0;
623}
624#endif //AUDIO_POLICY_TEST
625
626// ---
627
628AudioPolicyManagerGeneric::routing_strategy AudioPolicyManagerGeneric::getStrategy(AudioSystem::stream_type stream)
629{
630 // stream to strategy mapping
631 switch (stream) {
632 case AudioSystem::VOICE_CALL:
633 case AudioSystem::BLUETOOTH_SCO:
634 return STRATEGY_PHONE;
635 case AudioSystem::RING:
636 case AudioSystem::NOTIFICATION:
637 case AudioSystem::ALARM:
638 case AudioSystem::ENFORCED_AUDIBLE:
639 return STRATEGY_SONIFICATION;
640 case AudioSystem::DTMF:
641 return STRATEGY_DTMF;
642 default:
643 LOGE("unknown stream type");
644 case AudioSystem::SYSTEM:
645 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
646 // while key clicks are played produces a poor result
647 case AudioSystem::TTS:
648 case AudioSystem::MUSIC:
649 return STRATEGY_MEDIA;
650 }
651}
652
653
654float AudioPolicyManagerGeneric::computeVolume(int stream, int index, uint32_t device)
655{
656 float volume = 1.0;
657
658 StreamDescriptor &streamDesc = mStreams[stream];
659
660 // Force max volume if stream cannot be muted
661 if (!streamDesc.mCanBeMuted) index = streamDesc.mIndexMax;
662
663 int volInt = (100 * (index - streamDesc.mIndexMin)) / (streamDesc.mIndexMax - streamDesc.mIndexMin);
664 volume = AudioSystem::linearToLog(volInt);
665
666 return volume;
667}
668
669void AudioPolicyManagerGeneric::setStreamMute(int stream, bool on, audio_io_handle_t output)
670{
671 LOGV("setStreamMute() stream %d, mute %d, output %p", stream, on, output);
672
673 StreamDescriptor &streamDesc = mStreams[stream];
674
675 if (on) {
676 if (streamDesc.mMuteCount++ == 0) {
677 if (streamDesc.mCanBeMuted) {
678 mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, 0, output);
679 }
680 }
681 } else {
682 if (streamDesc.mMuteCount == 0) {
683 LOGW("setStreamMute() unmuting non muted stream!");
684 return;
685 }
686 if (--streamDesc.mMuteCount == 0) {
687 uint32_t device = mOutputs.valueFor(output)->mDevice;
688 float volume = computeVolume(stream, streamDesc.mIndexCur, device);
689 mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output);
690 }
691 }
692}
693
694void AudioPolicyManagerGeneric::handleIncallSonification(int stream, bool starting)
695{
696 // if the stream pertains to sonification strategy and we are in call we must
697 // mute the stream if it is low visibility. If it is high visibility, we must play a tone
698 // in the device used for phone strategy and play the tone if the selected device does not
699 // interfere with the device used for phone strategy
700 if (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) {
701 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mHardwareOutput);
702 LOGV("handleIncallSonification() stream %d starting %d device %x", stream, starting, outputDesc->mDevice);
703 if (outputDesc->isUsedByStream((AudioSystem::stream_type)stream)) {
704 if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) {
705 LOGV("handleIncallSonification() low visibility");
706 setStreamMute(stream, starting, mHardwareOutput);
707 } else {
708 if (starting) {
709 mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL);
710 } else {
711 mpClientInterface->stopTone();
712 }
713 }
714 }
715 }
716}
717
718
719// --- AudioOutputDescriptor class implementation
720
721AudioPolicyManagerGeneric::AudioOutputDescriptor::AudioOutputDescriptor()
722 : mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0),
723 mFlags((AudioSystem::output_flags)0), mDevice(0)
724{
725 // clear usage count for all stream types
726 for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
727 mRefCount[i] = 0;
728 }
729}
730
731uint32_t AudioPolicyManagerGeneric::AudioOutputDescriptor::device()
732{
733 return mDevice;
734}
735
736void AudioPolicyManagerGeneric::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta)
737{
738 if ((delta + (int)mRefCount[stream]) < 0) {
739 LOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]);
740 mRefCount[stream] = 0;
741 return;
742 }
743 mRefCount[stream] += delta;
744 LOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
745}
746
747uint32_t AudioPolicyManagerGeneric::AudioOutputDescriptor::refCount()
748{
749 uint32_t refcount = 0;
750 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
751 refcount += mRefCount[i];
752 }
753 return refcount;
754}
755
756// --- AudioInputDescriptor class implementation
757
758AudioPolicyManagerGeneric::AudioInputDescriptor::AudioInputDescriptor()
759 : mSamplingRate(0), mFormat(0), mChannels(0),
760 mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0)
761{
762}
763
764}; // namespace android