blob: e3b5db1eefe1d13985ab89d1da101509f3850936 [file] [log] [blame]
Mathias Agopian65ab4712010-07-14 17:59:35 -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 "AudioPolicyManagerBase"
18//#define LOG_NDEBUG 0
19#include <utils/Log.h>
20#include <hardware_legacy/AudioPolicyManagerBase.h>
21#include <media/mediarecorder.h>
22
23namespace android {
24
25
26// ----------------------------------------------------------------------------
27// AudioPolicyInterface implementation
28// ----------------------------------------------------------------------------
29
30
31status_t AudioPolicyManagerBase::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
49#ifndef WITH_A2DP
50 if (AudioSystem::isA2dpDevice(device)) {
51 LOGE("setDeviceConnectionState() invalid device: %x", device);
52 return BAD_VALUE;
53 }
54#endif
55
56 switch (state)
57 {
58 // handle output device connection
59 case AudioSystem::DEVICE_STATE_AVAILABLE:
60 if (mAvailableOutputDevices & device) {
61 LOGW("setDeviceConnectionState() device already connected: %x", device);
62 return INVALID_OPERATION;
63 }
64 LOGV("setDeviceConnectionState() connecting device %x", device);
65
66 // register new device as available
67 mAvailableOutputDevices |= device;
68
69#ifdef WITH_A2DP
70 // handle A2DP device connection
71 if (AudioSystem::isA2dpDevice(device)) {
72 status_t status = handleA2dpConnection(device, device_address);
73 if (status != NO_ERROR) {
74 mAvailableOutputDevices &= ~device;
75 return status;
76 }
77 } else
78#endif
79 {
80 if (AudioSystem::isBluetoothScoDevice(device)) {
81 LOGV("setDeviceConnectionState() BT SCO device, address %s", device_address);
82 // keep track of SCO device address
83 mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
84#ifdef WITH_A2DP
85 if (mA2dpOutput != 0 &&
86 mPhoneState != AudioSystem::MODE_NORMAL) {
87 mpClientInterface->suspendOutput(mA2dpOutput);
88 }
89#endif
90 }
91 }
92 break;
93 // handle output device disconnection
94 case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
95 if (!(mAvailableOutputDevices & device)) {
96 LOGW("setDeviceConnectionState() device not connected: %x", device);
97 return INVALID_OPERATION;
98 }
99
100
101 LOGV("setDeviceConnectionState() disconnecting device %x", device);
102 // remove device from available output devices
103 mAvailableOutputDevices &= ~device;
104
105#ifdef WITH_A2DP
106 // handle A2DP device disconnection
107 if (AudioSystem::isA2dpDevice(device)) {
108 status_t status = handleA2dpDisconnection(device, device_address);
109 if (status != NO_ERROR) {
110 mAvailableOutputDevices |= device;
111 return status;
112 }
113 } else
114#endif
115 {
116 if (AudioSystem::isBluetoothScoDevice(device)) {
117 mScoDeviceAddress = "";
118#ifdef WITH_A2DP
119 if (mA2dpOutput != 0 &&
120 mPhoneState != AudioSystem::MODE_NORMAL) {
121 mpClientInterface->restoreOutput(mA2dpOutput);
122 }
123#endif
124 }
125 }
126 } break;
127
128 default:
129 LOGE("setDeviceConnectionState() invalid state: %x", state);
130 return BAD_VALUE;
131 }
132
133 // request routing change if necessary
134 uint32_t newDevice = getNewDevice(mHardwareOutput, false);
135#ifdef WITH_A2DP
Eric Laurentc1c88e22010-08-27 17:10:36 -0700136 checkOutputForAllStrategies();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700137 // A2DP outputs must be closed after checkOutputForAllStrategies() is executed
138 if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && AudioSystem::isA2dpDevice(device)) {
139 closeA2dpOutputs();
140 }
141#endif
142 updateDeviceForStrategy();
143 setOutputDevice(mHardwareOutput, newDevice);
144
145 if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) {
146 device = AudioSystem::DEVICE_IN_WIRED_HEADSET;
147 } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO ||
148 device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
149 device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
150 device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
151 } else {
152 return NO_ERROR;
153 }
154 }
155 // handle input devices
156 if (AudioSystem::isInputDevice(device)) {
157
158 switch (state)
159 {
160 // handle input device connection
161 case AudioSystem::DEVICE_STATE_AVAILABLE: {
162 if (mAvailableInputDevices & device) {
163 LOGW("setDeviceConnectionState() device already connected: %d", device);
164 return INVALID_OPERATION;
165 }
166 mAvailableInputDevices |= device;
167 }
168 break;
169
170 // handle input device disconnection
171 case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
172 if (!(mAvailableInputDevices & device)) {
173 LOGW("setDeviceConnectionState() device not connected: %d", device);
174 return INVALID_OPERATION;
175 }
176 mAvailableInputDevices &= ~device;
177 } break;
178
179 default:
180 LOGE("setDeviceConnectionState() invalid state: %x", state);
181 return BAD_VALUE;
182 }
183
184 audio_io_handle_t activeInput = getActiveInput();
185 if (activeInput != 0) {
186 AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
187 uint32_t newDevice = getDeviceForInputSource(inputDesc->mInputSource);
188 if (newDevice != inputDesc->mDevice) {
189 LOGV("setDeviceConnectionState() changing device from %x to %x for input %d",
190 inputDesc->mDevice, newDevice, activeInput);
191 inputDesc->mDevice = newDevice;
192 AudioParameter param = AudioParameter();
193 param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
194 mpClientInterface->setParameters(activeInput, param.toString());
195 }
196 }
197
198 return NO_ERROR;
199 }
200
201 LOGW("setDeviceConnectionState() invalid device: %x", device);
202 return BAD_VALUE;
203}
204
205AudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(AudioSystem::audio_devices device,
206 const char *device_address)
207{
208 AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE;
209 String8 address = String8(device_address);
210 if (AudioSystem::isOutputDevice(device)) {
211 if (device & mAvailableOutputDevices) {
212#ifdef WITH_A2DP
213 if (AudioSystem::isA2dpDevice(device) &&
214 address != "" && mA2dpDeviceAddress != address) {
215 return state;
216 }
217#endif
218 if (AudioSystem::isBluetoothScoDevice(device) &&
219 address != "" && mScoDeviceAddress != address) {
220 return state;
221 }
222 state = AudioSystem::DEVICE_STATE_AVAILABLE;
223 }
224 } else if (AudioSystem::isInputDevice(device)) {
225 if (device & mAvailableInputDevices) {
226 state = AudioSystem::DEVICE_STATE_AVAILABLE;
227 }
228 }
229
230 return state;
231}
232
233void AudioPolicyManagerBase::setPhoneState(int state)
234{
235 LOGV("setPhoneState() state %d", state);
236 uint32_t newDevice = 0;
237 if (state < 0 || state >= AudioSystem::NUM_MODES) {
238 LOGW("setPhoneState() invalid state %d", state);
239 return;
240 }
241
242 if (state == mPhoneState ) {
243 LOGW("setPhoneState() setting same state %d", state);
244 return;
245 }
246
247 // if leaving call state, handle special case of active streams
248 // pertaining to sonification strategy see handleIncallSonification()
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -0800249 if (isInCall()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700250 LOGV("setPhoneState() in call state management: new state is %d", state);
251 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
252 handleIncallSonification(stream, false, true);
253 }
254 }
255
256 // store previous phone state for management of sonification strategy below
257 int oldState = mPhoneState;
258 mPhoneState = state;
259 bool force = false;
260
261 // are we entering or starting a call
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -0800262 if (!isStateInCall(oldState) && isStateInCall(state)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700263 LOGV(" Entering call in setPhoneState()");
264 // force routing command to audio hardware when starting a call
265 // even if no device change is needed
266 force = true;
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -0800267 } else if (isStateInCall(oldState) && !isStateInCall(state)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700268 LOGV(" Exiting call in setPhoneState()");
269 // force routing command to audio hardware when exiting a call
270 // even if no device change is needed
271 force = true;
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -0800272 } else if (isStateInCall(state) && (state != oldState)) {
273 LOGV(" Switching between telephony and VoIP in setPhoneState()");
274 // force routing command to audio hardware when switching between telephony and VoIP
275 // even if no device change is needed
276 force = true;
Mathias Agopian65ab4712010-07-14 17:59:35 -0700277 }
278
279 // check for device and output changes triggered by new phone state
280 newDevice = getNewDevice(mHardwareOutput, false);
281#ifdef WITH_A2DP
Eric Laurentc1c88e22010-08-27 17:10:36 -0700282 checkOutputForAllStrategies();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700283 // suspend A2DP output if a SCO device is present.
284 if (mA2dpOutput != 0 && mScoDeviceAddress != "") {
285 if (oldState == AudioSystem::MODE_NORMAL) {
286 mpClientInterface->suspendOutput(mA2dpOutput);
287 } else if (state == AudioSystem::MODE_NORMAL) {
288 mpClientInterface->restoreOutput(mA2dpOutput);
289 }
290 }
291#endif
292 updateDeviceForStrategy();
293
294 AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
295
296 // force routing command to audio hardware when ending call
297 // even if no device change is needed
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -0800298 if (isStateInCall(oldState) && newDevice == 0) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700299 newDevice = hwOutputDesc->device();
300 }
301
302 // when changing from ring tone to in call mode, mute the ringing tone
303 // immediately and delay the route change to avoid sending the ring tone
304 // tail into the earpiece or headset.
305 int delayMs = 0;
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -0800306 if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700307 // delay the device change command by twice the output latency to have some margin
308 // and be sure that audio buffers not yet affected by the mute are out when
309 // we actually apply the route change
310 delayMs = hwOutputDesc->mLatency*2;
311 setStreamMute(AudioSystem::RING, true, mHardwareOutput);
312 }
313
314 // change routing is necessary
315 setOutputDevice(mHardwareOutput, newDevice, force, delayMs);
316
317 // if entering in call state, handle special case of active streams
318 // pertaining to sonification strategy see handleIncallSonification()
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -0800319 if (isStateInCall(state)) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700320 LOGV("setPhoneState() in call state management: new state is %d", state);
321 // unmute the ringing tone after a sufficient delay if it was muted before
322 // setting output device above
323 if (oldState == AudioSystem::MODE_RINGTONE) {
324 setStreamMute(AudioSystem::RING, false, mHardwareOutput, MUTE_TIME_MS);
325 }
326 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
327 handleIncallSonification(stream, true, true);
328 }
329 }
330
331 // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
332 if (state == AudioSystem::MODE_RINGTONE &&
333 (hwOutputDesc->mRefCount[AudioSystem::MUSIC] ||
334 (systemTime() - mMusicStopTime) < seconds(SONIFICATION_HEADSET_MUSIC_DELAY))) {
335 mLimitRingtoneVolume = true;
336 } else {
337 mLimitRingtoneVolume = false;
338 }
339}
340
341void AudioPolicyManagerBase::setRingerMode(uint32_t mode, uint32_t mask)
342{
343 LOGV("setRingerMode() mode %x, mask %x", mode, mask);
344
345 mRingerMode = mode;
346}
347
348void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
349{
350 LOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
351
352 bool forceVolumeReeval = false;
353 switch(usage) {
354 case AudioSystem::FOR_COMMUNICATION:
355 if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO &&
356 config != AudioSystem::FORCE_NONE) {
357 LOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
358 return;
359 }
360 mForceUse[usage] = config;
361 break;
362 case AudioSystem::FOR_MEDIA:
363 if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP &&
Praveen Bharathib235dee2010-10-06 15:23:14 -0500364 config != AudioSystem::FORCE_WIRED_ACCESSORY &&
365 config != AudioSystem::FORCE_ANALOG_DOCK &&
366 config != AudioSystem::FORCE_DIGITAL_DOCK && config != AudioSystem::FORCE_NONE) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700367 LOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
368 return;
369 }
370 mForceUse[usage] = config;
371 break;
372 case AudioSystem::FOR_RECORD:
373 if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY &&
374 config != AudioSystem::FORCE_NONE) {
375 LOGW("setForceUse() invalid config %d for FOR_RECORD", config);
376 return;
377 }
378 mForceUse[usage] = config;
379 break;
380 case AudioSystem::FOR_DOCK:
381 if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK &&
Praveen Bharathib235dee2010-10-06 15:23:14 -0500382 config != AudioSystem::FORCE_BT_DESK_DOCK &&
383 config != AudioSystem::FORCE_WIRED_ACCESSORY &&
384 config != AudioSystem::FORCE_ANALOG_DOCK &&
385 config != AudioSystem::FORCE_DIGITAL_DOCK) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700386 LOGW("setForceUse() invalid config %d for FOR_DOCK", config);
387 }
388 forceVolumeReeval = true;
389 mForceUse[usage] = config;
390 break;
391 default:
392 LOGW("setForceUse() invalid usage %d", usage);
393 break;
394 }
395
396 // check for device and output changes triggered by new phone state
397 uint32_t newDevice = getNewDevice(mHardwareOutput, false);
398#ifdef WITH_A2DP
Eric Laurentc1c88e22010-08-27 17:10:36 -0700399 checkOutputForAllStrategies();
Mathias Agopian65ab4712010-07-14 17:59:35 -0700400#endif
401 updateDeviceForStrategy();
402 setOutputDevice(mHardwareOutput, newDevice);
403 if (forceVolumeReeval) {
404 applyStreamVolumes(mHardwareOutput, newDevice);
405 }
Eric Laurentc1c88e22010-08-27 17:10:36 -0700406
407 audio_io_handle_t activeInput = getActiveInput();
408 if (activeInput != 0) {
409 AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
410 newDevice = getDeviceForInputSource(inputDesc->mInputSource);
411 if (newDevice != inputDesc->mDevice) {
412 LOGV("setForceUse() changing device from %x to %x for input %d",
413 inputDesc->mDevice, newDevice, activeInput);
414 inputDesc->mDevice = newDevice;
415 AudioParameter param = AudioParameter();
416 param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
417 mpClientInterface->setParameters(activeInput, param.toString());
418 }
419 }
420
Mathias Agopian65ab4712010-07-14 17:59:35 -0700421}
422
423AudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage)
424{
425 return mForceUse[usage];
426}
427
428void AudioPolicyManagerBase::setSystemProperty(const char* property, const char* value)
429{
430 LOGV("setSystemProperty() property %s, value %s", property, value);
431 if (strcmp(property, "ro.camera.sound.forced") == 0) {
432 if (atoi(value)) {
433 LOGV("ENFORCED_AUDIBLE cannot be muted");
434 mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = false;
435 } else {
436 LOGV("ENFORCED_AUDIBLE can be muted");
437 mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = true;
438 }
439 }
440}
441
442audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream,
443 uint32_t samplingRate,
444 uint32_t format,
445 uint32_t channels,
446 AudioSystem::output_flags flags)
447{
448 audio_io_handle_t output = 0;
449 uint32_t latency = 0;
450 routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
451 uint32_t device = getDeviceForStrategy(strategy);
452 LOGV("getOutput() stream %d, samplingRate %d, format %d, channels %x, flags %x", stream, samplingRate, format, channels, flags);
453
454#ifdef AUDIO_POLICY_TEST
455 if (mCurOutput != 0) {
456 LOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channels %x, mDirectOutput %d",
457 mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
458
459 if (mTestOutputs[mCurOutput] == 0) {
460 LOGV("getOutput() opening test output");
461 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
462 outputDesc->mDevice = mTestDevice;
463 outputDesc->mSamplingRate = mTestSamplingRate;
464 outputDesc->mFormat = mTestFormat;
465 outputDesc->mChannels = mTestChannels;
466 outputDesc->mLatency = mTestLatencyMs;
467 outputDesc->mFlags = (AudioSystem::output_flags)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0);
468 outputDesc->mRefCount[stream] = 0;
469 mTestOutputs[mCurOutput] = mpClientInterface->openOutput(&outputDesc->mDevice,
470 &outputDesc->mSamplingRate,
471 &outputDesc->mFormat,
472 &outputDesc->mChannels,
473 &outputDesc->mLatency,
474 outputDesc->mFlags);
475 if (mTestOutputs[mCurOutput]) {
476 AudioParameter outputCmd = AudioParameter();
477 outputCmd.addInt(String8("set_id"),mCurOutput);
478 mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
479 addOutput(mTestOutputs[mCurOutput], outputDesc);
480 }
481 }
482 return mTestOutputs[mCurOutput];
483 }
484#endif //AUDIO_POLICY_TEST
485
486 // open a direct output if required by specified parameters
487 if (needsDirectOuput(stream, samplingRate, format, channels, flags, device)) {
488
489 LOGV("getOutput() opening direct output device %x", device);
490 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
491 outputDesc->mDevice = device;
492 outputDesc->mSamplingRate = samplingRate;
493 outputDesc->mFormat = format;
494 outputDesc->mChannels = channels;
495 outputDesc->mLatency = 0;
496 outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT);
497 outputDesc->mRefCount[stream] = 0;
498 output = mpClientInterface->openOutput(&outputDesc->mDevice,
499 &outputDesc->mSamplingRate,
500 &outputDesc->mFormat,
501 &outputDesc->mChannels,
502 &outputDesc->mLatency,
503 outputDesc->mFlags);
504
505 // only accept an output with the requeted parameters
506 if (output == 0 ||
507 (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
508 (format != 0 && format != outputDesc->mFormat) ||
509 (channels != 0 && channels != outputDesc->mChannels)) {
510 LOGV("getOutput() failed opening direct output: samplingRate %d, format %d, channels %d",
511 samplingRate, format, channels);
512 if (output != 0) {
513 mpClientInterface->closeOutput(output);
514 }
515 delete outputDesc;
516 return 0;
517 }
518 addOutput(output, outputDesc);
519 return output;
520 }
521
522 if (channels != 0 && channels != AudioSystem::CHANNEL_OUT_MONO &&
523 channels != AudioSystem::CHANNEL_OUT_STEREO) {
524 return 0;
525 }
526 // open a non direct output
527
528 // get which output is suitable for the specified stream. The actual routing change will happen
529 // when startOutput() will be called
530 uint32_t a2dpDevice = device & AudioSystem::DEVICE_OUT_ALL_A2DP;
531 if (AudioSystem::popCount((AudioSystem::audio_devices)device) == 2) {
532#ifdef WITH_A2DP
533 if (a2dpUsedForSonification() && a2dpDevice != 0) {
534 // if playing on 2 devices among which one is A2DP, use duplicated output
535 LOGV("getOutput() using duplicated output");
536 LOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device in multiple %x selected but A2DP output not opened", device);
537 output = mDuplicatedOutput;
538 } else
539#endif
540 {
541 // if playing on 2 devices among which none is A2DP, use hardware output
542 output = mHardwareOutput;
543 }
544 LOGV("getOutput() using output %d for 2 devices %x", output, device);
545 } else {
546#ifdef WITH_A2DP
547 if (a2dpDevice != 0) {
548 // if playing on A2DP device, use a2dp output
549 LOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device %x selected but A2DP output not opened", device);
550 output = mA2dpOutput;
551 } else
552#endif
553 {
554 // if playing on not A2DP device, use hardware output
555 output = mHardwareOutput;
556 }
557 }
558
559
560 LOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d, format %d, channels %x, flags %x",
561 stream, samplingRate, format, channels, flags);
562
563 return output;
564}
565
Eric Laurentde070132010-07-13 04:45:46 -0700566status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output,
567 AudioSystem::stream_type stream,
568 int session)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700569{
Eric Laurentde070132010-07-13 04:45:46 -0700570 LOGV("startOutput() output %d, stream %d, session %d", output, stream, session);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700571 ssize_t index = mOutputs.indexOfKey(output);
572 if (index < 0) {
573 LOGW("startOutput() unknow output %d", output);
574 return BAD_VALUE;
575 }
576
577 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
578 routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
579
580#ifdef WITH_A2DP
581 if (mA2dpOutput != 0 && !a2dpUsedForSonification() && strategy == STRATEGY_SONIFICATION) {
582 setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput);
583 }
584#endif
585
586 // incremenent usage count for this stream on the requested output:
587 // NOTE that the usage count is the same for duplicated output and hardware output which is
588 // necassary for a correct control of hardware output routing by startOutput() and stopOutput()
589 outputDesc->changeRefCount(stream, 1);
590
591 setOutputDevice(output, getNewDevice(output));
592
593 // handle special case for sonification while in call
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -0800594 if (isInCall()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700595 handleIncallSonification(stream, true, false);
596 }
597
598 // apply volume rules for current stream and device if necessary
599 checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, outputDesc->device());
600
601 return NO_ERROR;
602}
603
Eric Laurentde070132010-07-13 04:45:46 -0700604status_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output,
605 AudioSystem::stream_type stream,
606 int session)
Mathias Agopian65ab4712010-07-14 17:59:35 -0700607{
Eric Laurentde070132010-07-13 04:45:46 -0700608 LOGV("stopOutput() output %d, stream %d, session %d", output, stream, session);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700609 ssize_t index = mOutputs.indexOfKey(output);
610 if (index < 0) {
611 LOGW("stopOutput() unknow output %d", output);
612 return BAD_VALUE;
613 }
614
615 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
616 routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
617
618 // handle special case for sonification while in call
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -0800619 if (isInCall()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -0700620 handleIncallSonification(stream, false, false);
621 }
622
623 if (outputDesc->mRefCount[stream] > 0) {
624 // decrement usage count of this stream on the output
625 outputDesc->changeRefCount(stream, -1);
626 // store time at which the last music track was stopped - see computeVolume()
627 if (stream == AudioSystem::MUSIC) {
628 mMusicStopTime = systemTime();
629 }
630
631 setOutputDevice(output, getNewDevice(output));
632
633#ifdef WITH_A2DP
Eric Laurentde070132010-07-13 04:45:46 -0700634 if (mA2dpOutput != 0 && !a2dpUsedForSonification() &&
635 strategy == STRATEGY_SONIFICATION) {
636 setStrategyMute(STRATEGY_MEDIA,
637 false,
638 mA2dpOutput,
639 mOutputs.valueFor(mHardwareOutput)->mLatency*2);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700640 }
641#endif
642 if (output != mHardwareOutput) {
643 setOutputDevice(mHardwareOutput, getNewDevice(mHardwareOutput), true);
644 }
645 return NO_ERROR;
646 } else {
647 LOGW("stopOutput() refcount is already 0 for output %d", output);
648 return INVALID_OPERATION;
649 }
650}
651
652void AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output)
653{
654 LOGV("releaseOutput() %d", output);
655 ssize_t index = mOutputs.indexOfKey(output);
656 if (index < 0) {
657 LOGW("releaseOutput() releasing unknown output %d", output);
658 return;
659 }
660
661#ifdef AUDIO_POLICY_TEST
662 int testIndex = testOutputIndex(output);
663 if (testIndex != 0) {
664 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
665 if (outputDesc->refCount() == 0) {
666 mpClientInterface->closeOutput(output);
667 delete mOutputs.valueAt(index);
668 mOutputs.removeItem(output);
669 mTestOutputs[testIndex] = 0;
670 }
671 return;
672 }
673#endif //AUDIO_POLICY_TEST
674
675 if (mOutputs.valueAt(index)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) {
676 mpClientInterface->closeOutput(output);
677 delete mOutputs.valueAt(index);
678 mOutputs.removeItem(output);
679 }
680}
681
682audio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource,
683 uint32_t samplingRate,
684 uint32_t format,
685 uint32_t channels,
686 AudioSystem::audio_in_acoustics acoustics)
687{
688 audio_io_handle_t input = 0;
689 uint32_t device = getDeviceForInputSource(inputSource);
690
691 LOGV("getInput() inputSource %d, samplingRate %d, format %d, channels %x, acoustics %x", inputSource, samplingRate, format, channels, acoustics);
692
693 if (device == 0) {
694 return 0;
695 }
696
697 // adapt channel selection to input source
698 switch(inputSource) {
699 case AUDIO_SOURCE_VOICE_UPLINK:
700 channels = AudioSystem::CHANNEL_IN_VOICE_UPLINK;
701 break;
702 case AUDIO_SOURCE_VOICE_DOWNLINK:
703 channels = AudioSystem::CHANNEL_IN_VOICE_DNLINK;
704 break;
705 case AUDIO_SOURCE_VOICE_CALL:
706 channels = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK);
707 break;
708 default:
709 break;
710 }
711
712 AudioInputDescriptor *inputDesc = new AudioInputDescriptor();
713
714 inputDesc->mInputSource = inputSource;
715 inputDesc->mDevice = device;
716 inputDesc->mSamplingRate = samplingRate;
717 inputDesc->mFormat = format;
718 inputDesc->mChannels = channels;
719 inputDesc->mAcoustics = acoustics;
720 inputDesc->mRefCount = 0;
721 input = mpClientInterface->openInput(&inputDesc->mDevice,
722 &inputDesc->mSamplingRate,
723 &inputDesc->mFormat,
724 &inputDesc->mChannels,
725 inputDesc->mAcoustics);
726
727 // only accept input with the exact requested set of parameters
728 if (input == 0 ||
729 (samplingRate != inputDesc->mSamplingRate) ||
730 (format != inputDesc->mFormat) ||
731 (channels != inputDesc->mChannels)) {
732 LOGV("getInput() failed opening input: samplingRate %d, format %d, channels %d",
733 samplingRate, format, channels);
734 if (input != 0) {
735 mpClientInterface->closeInput(input);
736 }
737 delete inputDesc;
738 return 0;
739 }
740 mInputs.add(input, inputDesc);
741 return input;
742}
743
744status_t AudioPolicyManagerBase::startInput(audio_io_handle_t input)
745{
746 LOGV("startInput() input %d", input);
747 ssize_t index = mInputs.indexOfKey(input);
748 if (index < 0) {
749 LOGW("startInput() unknow input %d", input);
750 return BAD_VALUE;
751 }
752 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
753
754#ifdef AUDIO_POLICY_TEST
755 if (mTestInput == 0)
756#endif //AUDIO_POLICY_TEST
757 {
758 // refuse 2 active AudioRecord clients at the same time
759 if (getActiveInput() != 0) {
760 LOGW("startInput() input %d failed: other input already started", input);
761 return INVALID_OPERATION;
762 }
763 }
764
765 AudioParameter param = AudioParameter();
766 param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
767
Jean-Michel Trivi56ecd202010-11-09 14:06:52 -0800768 param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource);
769 LOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource);
Mathias Agopian65ab4712010-07-14 17:59:35 -0700770
771 mpClientInterface->setParameters(input, param.toString());
772
773 inputDesc->mRefCount = 1;
774 return NO_ERROR;
775}
776
777status_t AudioPolicyManagerBase::stopInput(audio_io_handle_t input)
778{
779 LOGV("stopInput() input %d", input);
780 ssize_t index = mInputs.indexOfKey(input);
781 if (index < 0) {
782 LOGW("stopInput() unknow input %d", input);
783 return BAD_VALUE;
784 }
785 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
786
787 if (inputDesc->mRefCount == 0) {
788 LOGW("stopInput() input %d already stopped", input);
789 return INVALID_OPERATION;
790 } else {
791 AudioParameter param = AudioParameter();
792 param.addInt(String8(AudioParameter::keyRouting), 0);
793 mpClientInterface->setParameters(input, param.toString());
794 inputDesc->mRefCount = 0;
795 return NO_ERROR;
796 }
797}
798
799void AudioPolicyManagerBase::releaseInput(audio_io_handle_t input)
800{
801 LOGV("releaseInput() %d", input);
802 ssize_t index = mInputs.indexOfKey(input);
803 if (index < 0) {
804 LOGW("releaseInput() releasing unknown input %d", input);
805 return;
806 }
807 mpClientInterface->closeInput(input);
808 delete mInputs.valueAt(index);
809 mInputs.removeItem(input);
810 LOGV("releaseInput() exit");
811}
812
813void AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream,
814 int indexMin,
815 int indexMax)
816{
817 LOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
818 if (indexMin < 0 || indexMin >= indexMax) {
819 LOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax);
820 return;
821 }
822 mStreams[stream].mIndexMin = indexMin;
823 mStreams[stream].mIndexMax = indexMax;
824}
825
826status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
827{
828
829 if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
830 return BAD_VALUE;
831 }
832
833 // Force max volume if stream cannot be muted
834 if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
835
836 LOGV("setStreamVolumeIndex() stream %d, index %d", stream, index);
837 mStreams[stream].mIndexCur = index;
838
839 // compute and apply stream volume on all outputs according to connected device
840 status_t status = NO_ERROR;
841 for (size_t i = 0; i < mOutputs.size(); i++) {
842 status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), mOutputs.valueAt(i)->device());
843 if (volStatus != NO_ERROR) {
844 status = volStatus;
845 }
846 }
847 return status;
848}
849
850status_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
851{
852 if (index == 0) {
853 return BAD_VALUE;
854 }
855 LOGV("getStreamVolumeIndex() stream %d", stream);
856 *index = mStreams[stream].mIndexCur;
857 return NO_ERROR;
858}
859
Eric Laurentde070132010-07-13 04:45:46 -0700860audio_io_handle_t AudioPolicyManagerBase::getOutputForEffect(effect_descriptor_t *desc)
861{
862 LOGV("getOutputForEffect()");
863 // apply simple rule where global effects are attached to the same output as MUSIC streams
864 return getOutput(AudioSystem::MUSIC);
865}
866
867status_t AudioPolicyManagerBase::registerEffect(effect_descriptor_t *desc,
868 audio_io_handle_t output,
869 uint32_t strategy,
870 int session,
871 int id)
872{
873 ssize_t index = mOutputs.indexOfKey(output);
874 if (index < 0) {
875 LOGW("registerEffect() unknown output %d", output);
876 return INVALID_OPERATION;
877 }
878
879 if (mTotalEffectsCpuLoad + desc->cpuLoad > getMaxEffectsCpuLoad()) {
880 LOGW("registerEffect() CPU Load limit exceeded for Fx %s, CPU %f MIPS",
881 desc->name, (float)desc->cpuLoad/10);
882 return INVALID_OPERATION;
883 }
884 if (mTotalEffectsMemory + desc->memoryUsage > getMaxEffectsMemory()) {
885 LOGW("registerEffect() memory limit exceeded for Fx %s, Memory %d KB",
886 desc->name, desc->memoryUsage);
887 return INVALID_OPERATION;
888 }
889 mTotalEffectsCpuLoad += desc->cpuLoad;
890 mTotalEffectsMemory += desc->memoryUsage;
891 LOGV("registerEffect() effect %s, output %d, strategy %d session %d id %d",
892 desc->name, output, strategy, session, id);
893
894 LOGV("registerEffect() CPU %d, memory %d", desc->cpuLoad, desc->memoryUsage);
895 LOGV(" total CPU %d, total memory %d", mTotalEffectsCpuLoad, mTotalEffectsMemory);
896
897 EffectDescriptor *pDesc = new EffectDescriptor();
898 memcpy (&pDesc->mDesc, desc, sizeof(effect_descriptor_t));
899 pDesc->mOutput = output;
900 pDesc->mStrategy = (routing_strategy)strategy;
901 pDesc->mSession = session;
902 mEffects.add(id, pDesc);
903
904 return NO_ERROR;
905}
906
907status_t AudioPolicyManagerBase::unregisterEffect(int id)
908{
909 ssize_t index = mEffects.indexOfKey(id);
910 if (index < 0) {
911 LOGW("unregisterEffect() unknown effect ID %d", id);
912 return INVALID_OPERATION;
913 }
914
915 EffectDescriptor *pDesc = mEffects.valueAt(index);
916
917 if (mTotalEffectsCpuLoad < pDesc->mDesc.cpuLoad) {
918 LOGW("unregisterEffect() CPU load %d too high for total %d",
919 pDesc->mDesc.cpuLoad, mTotalEffectsCpuLoad);
920 pDesc->mDesc.cpuLoad = mTotalEffectsCpuLoad;
921 }
922 mTotalEffectsCpuLoad -= pDesc->mDesc.cpuLoad;
923 if (mTotalEffectsMemory < pDesc->mDesc.memoryUsage) {
924 LOGW("unregisterEffect() memory %d too big for total %d",
925 pDesc->mDesc.memoryUsage, mTotalEffectsMemory);
926 pDesc->mDesc.memoryUsage = mTotalEffectsMemory;
927 }
928 mTotalEffectsMemory -= pDesc->mDesc.memoryUsage;
929 LOGV("unregisterEffect() effect %s, ID %d, CPU %d, memory %d",
930 pDesc->mDesc.name, id, pDesc->mDesc.cpuLoad, pDesc->mDesc.memoryUsage);
931 LOGV(" total CPU %d, total memory %d", mTotalEffectsCpuLoad, mTotalEffectsMemory);
932
933 mEffects.removeItem(id);
934 delete pDesc;
935
936 return NO_ERROR;
937}
938
Mathias Agopian65ab4712010-07-14 17:59:35 -0700939status_t AudioPolicyManagerBase::dump(int fd)
940{
941 const size_t SIZE = 256;
942 char buffer[SIZE];
943 String8 result;
944
945 snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
946 result.append(buffer);
947 snprintf(buffer, SIZE, " Hardware Output: %d\n", mHardwareOutput);
948 result.append(buffer);
949#ifdef WITH_A2DP
950 snprintf(buffer, SIZE, " A2DP Output: %d\n", mA2dpOutput);
951 result.append(buffer);
952 snprintf(buffer, SIZE, " Duplicated Output: %d\n", mDuplicatedOutput);
953 result.append(buffer);
954 snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string());
955 result.append(buffer);
956#endif
957 snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string());
958 result.append(buffer);
959 snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices);
960 result.append(buffer);
961 snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices);
962 result.append(buffer);
963 snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
964 result.append(buffer);
965 snprintf(buffer, SIZE, " Ringer mode: %d\n", mRingerMode);
966 result.append(buffer);
967 snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]);
968 result.append(buffer);
969 snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]);
970 result.append(buffer);
971 snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]);
972 result.append(buffer);
973 snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AudioSystem::FOR_DOCK]);
974 result.append(buffer);
975 write(fd, result.string(), result.size());
976
977 snprintf(buffer, SIZE, "\nOutputs dump:\n");
978 write(fd, buffer, strlen(buffer));
979 for (size_t i = 0; i < mOutputs.size(); i++) {
980 snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
981 write(fd, buffer, strlen(buffer));
982 mOutputs.valueAt(i)->dump(fd);
983 }
984
985 snprintf(buffer, SIZE, "\nInputs dump:\n");
986 write(fd, buffer, strlen(buffer));
987 for (size_t i = 0; i < mInputs.size(); i++) {
988 snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
989 write(fd, buffer, strlen(buffer));
990 mInputs.valueAt(i)->dump(fd);
991 }
992
993 snprintf(buffer, SIZE, "\nStreams dump:\n");
994 write(fd, buffer, strlen(buffer));
995 snprintf(buffer, SIZE, " Stream Index Min Index Max Index Cur Can be muted\n");
996 write(fd, buffer, strlen(buffer));
997 for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
998 snprintf(buffer, SIZE, " %02d", i);
999 mStreams[i].dump(buffer + 3, SIZE);
1000 write(fd, buffer, strlen(buffer));
1001 }
1002
Eric Laurentde070132010-07-13 04:45:46 -07001003 snprintf(buffer, SIZE, "\nTotal Effects CPU: %f MIPS, Total Effects memory: %d KB\n",
1004 (float)mTotalEffectsCpuLoad/10, mTotalEffectsMemory);
1005 write(fd, buffer, strlen(buffer));
1006
1007 snprintf(buffer, SIZE, "Registered effects:\n");
1008 write(fd, buffer, strlen(buffer));
1009 for (size_t i = 0; i < mEffects.size(); i++) {
1010 snprintf(buffer, SIZE, "- Effect %d dump:\n", mEffects.keyAt(i));
1011 write(fd, buffer, strlen(buffer));
1012 mEffects.valueAt(i)->dump(fd);
1013 }
1014
1015
Mathias Agopian65ab4712010-07-14 17:59:35 -07001016 return NO_ERROR;
1017}
1018
1019// ----------------------------------------------------------------------------
1020// AudioPolicyManagerBase
1021// ----------------------------------------------------------------------------
1022
1023AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface)
1024 :
1025#ifdef AUDIO_POLICY_TEST
1026 Thread(false),
1027#endif //AUDIO_POLICY_TEST
Mathias Agopian094c96d2010-07-14 18:48:58 -07001028 mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0), mMusicStopTime(0), mLimitRingtoneVolume(false),
Eric Laurent8184a572010-07-20 13:37:19 -07001029 mLastVoiceVolume(-1.0f), mTotalEffectsCpuLoad(0), mTotalEffectsMemory(0)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001030{
1031 mpClientInterface = clientInterface;
1032
1033 for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {
1034 mForceUse[i] = AudioSystem::FORCE_NONE;
1035 }
1036
1037 // devices available by default are speaker, ear piece and microphone
1038 mAvailableOutputDevices = AudioSystem::DEVICE_OUT_EARPIECE |
1039 AudioSystem::DEVICE_OUT_SPEAKER;
1040 mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC;
1041
1042#ifdef WITH_A2DP
1043 mA2dpOutput = 0;
1044 mDuplicatedOutput = 0;
1045 mA2dpDeviceAddress = String8("");
1046#endif
1047 mScoDeviceAddress = String8("");
1048
1049 // open hardware output
1050 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
1051 outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
1052 mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
1053 &outputDesc->mSamplingRate,
1054 &outputDesc->mFormat,
1055 &outputDesc->mChannels,
1056 &outputDesc->mLatency,
1057 outputDesc->mFlags);
1058
1059 if (mHardwareOutput == 0) {
1060 LOGE("Failed to initialize hardware output stream, samplingRate: %d, format %d, channels %d",
1061 outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
1062 } else {
1063 addOutput(mHardwareOutput, outputDesc);
1064 setOutputDevice(mHardwareOutput, (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER, true);
Eric Laurentde070132010-07-13 04:45:46 -07001065 //TODO: configure audio effect output stage here
Mathias Agopian65ab4712010-07-14 17:59:35 -07001066 }
1067
1068 updateDeviceForStrategy();
1069#ifdef AUDIO_POLICY_TEST
1070 AudioParameter outputCmd = AudioParameter();
1071 outputCmd.addInt(String8("set_id"), 0);
1072 mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
1073
1074 mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
1075 mTestSamplingRate = 44100;
1076 mTestFormat = AudioSystem::PCM_16_BIT;
1077 mTestChannels = AudioSystem::CHANNEL_OUT_STEREO;
1078 mTestLatencyMs = 0;
1079 mCurOutput = 0;
1080 mDirectOutput = false;
1081 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
1082 mTestOutputs[i] = 0;
1083 }
1084
1085 const size_t SIZE = 256;
1086 char buffer[SIZE];
1087 snprintf(buffer, SIZE, "AudioPolicyManagerTest");
1088 run(buffer, ANDROID_PRIORITY_AUDIO);
1089#endif //AUDIO_POLICY_TEST
1090}
1091
1092AudioPolicyManagerBase::~AudioPolicyManagerBase()
1093{
1094#ifdef AUDIO_POLICY_TEST
1095 exit();
1096#endif //AUDIO_POLICY_TEST
1097 for (size_t i = 0; i < mOutputs.size(); i++) {
1098 mpClientInterface->closeOutput(mOutputs.keyAt(i));
1099 delete mOutputs.valueAt(i);
1100 }
1101 mOutputs.clear();
1102 for (size_t i = 0; i < mInputs.size(); i++) {
1103 mpClientInterface->closeInput(mInputs.keyAt(i));
1104 delete mInputs.valueAt(i);
1105 }
1106 mInputs.clear();
1107}
1108
1109#ifdef AUDIO_POLICY_TEST
1110bool AudioPolicyManagerBase::threadLoop()
1111{
1112 LOGV("entering threadLoop()");
1113 while (!exitPending())
1114 {
1115 String8 command;
1116 int valueInt;
1117 String8 value;
1118
1119 Mutex::Autolock _l(mLock);
1120 mWaitWorkCV.waitRelative(mLock, milliseconds(50));
1121
1122 command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
1123 AudioParameter param = AudioParameter(command);
1124
1125 if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
1126 valueInt != 0) {
1127 LOGV("Test command %s received", command.string());
1128 String8 target;
1129 if (param.get(String8("target"), target) != NO_ERROR) {
1130 target = "Manager";
1131 }
1132 if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
1133 param.remove(String8("test_cmd_policy_output"));
1134 mCurOutput = valueInt;
1135 }
1136 if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
1137 param.remove(String8("test_cmd_policy_direct"));
1138 if (value == "false") {
1139 mDirectOutput = false;
1140 } else if (value == "true") {
1141 mDirectOutput = true;
1142 }
1143 }
1144 if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
1145 param.remove(String8("test_cmd_policy_input"));
1146 mTestInput = valueInt;
1147 }
1148
1149 if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
1150 param.remove(String8("test_cmd_policy_format"));
1151 int format = AudioSystem::INVALID_FORMAT;
1152 if (value == "PCM 16 bits") {
1153 format = AudioSystem::PCM_16_BIT;
1154 } else if (value == "PCM 8 bits") {
1155 format = AudioSystem::PCM_8_BIT;
1156 } else if (value == "Compressed MP3") {
1157 format = AudioSystem::MP3;
1158 }
1159 if (format != AudioSystem::INVALID_FORMAT) {
1160 if (target == "Manager") {
1161 mTestFormat = format;
1162 } else if (mTestOutputs[mCurOutput] != 0) {
1163 AudioParameter outputParam = AudioParameter();
1164 outputParam.addInt(String8("format"), format);
1165 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
1166 }
1167 }
1168 }
1169 if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
1170 param.remove(String8("test_cmd_policy_channels"));
1171 int channels = 0;
1172
1173 if (value == "Channels Stereo") {
1174 channels = AudioSystem::CHANNEL_OUT_STEREO;
1175 } else if (value == "Channels Mono") {
1176 channels = AudioSystem::CHANNEL_OUT_MONO;
1177 }
1178 if (channels != 0) {
1179 if (target == "Manager") {
1180 mTestChannels = channels;
1181 } else if (mTestOutputs[mCurOutput] != 0) {
1182 AudioParameter outputParam = AudioParameter();
1183 outputParam.addInt(String8("channels"), channels);
1184 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
1185 }
1186 }
1187 }
1188 if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
1189 param.remove(String8("test_cmd_policy_sampleRate"));
1190 if (valueInt >= 0 && valueInt <= 96000) {
1191 int samplingRate = valueInt;
1192 if (target == "Manager") {
1193 mTestSamplingRate = samplingRate;
1194 } else if (mTestOutputs[mCurOutput] != 0) {
1195 AudioParameter outputParam = AudioParameter();
1196 outputParam.addInt(String8("sampling_rate"), samplingRate);
1197 mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
1198 }
1199 }
1200 }
1201
1202 if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
1203 param.remove(String8("test_cmd_policy_reopen"));
1204
1205 mpClientInterface->closeOutput(mHardwareOutput);
1206 delete mOutputs.valueFor(mHardwareOutput);
1207 mOutputs.removeItem(mHardwareOutput);
1208
1209 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
1210 outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
1211 mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
1212 &outputDesc->mSamplingRate,
1213 &outputDesc->mFormat,
1214 &outputDesc->mChannels,
1215 &outputDesc->mLatency,
1216 outputDesc->mFlags);
1217 if (mHardwareOutput == 0) {
1218 LOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d",
1219 outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
1220 } else {
1221 AudioParameter outputCmd = AudioParameter();
1222 outputCmd.addInt(String8("set_id"), 0);
1223 mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
1224 addOutput(mHardwareOutput, outputDesc);
1225 }
1226 }
1227
1228
1229 mpClientInterface->setParameters(0, String8("test_cmd_policy="));
1230 }
1231 }
1232 return false;
1233}
1234
1235void AudioPolicyManagerBase::exit()
1236{
1237 {
1238 AutoMutex _l(mLock);
1239 requestExit();
1240 mWaitWorkCV.signal();
1241 }
1242 requestExitAndWait();
1243}
1244
1245int AudioPolicyManagerBase::testOutputIndex(audio_io_handle_t output)
1246{
1247 for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
1248 if (output == mTestOutputs[i]) return i;
1249 }
1250 return 0;
1251}
1252#endif //AUDIO_POLICY_TEST
1253
1254// ---
1255
1256void AudioPolicyManagerBase::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc)
1257{
1258 outputDesc->mId = id;
1259 mOutputs.add(id, outputDesc);
1260}
1261
1262
1263#ifdef WITH_A2DP
1264status_t AudioPolicyManagerBase::handleA2dpConnection(AudioSystem::audio_devices device,
1265 const char *device_address)
1266{
1267 // when an A2DP device is connected, open an A2DP and a duplicated output
1268 LOGV("opening A2DP output for device %s", device_address);
1269 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
1270 outputDesc->mDevice = device;
1271 mA2dpOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
1272 &outputDesc->mSamplingRate,
1273 &outputDesc->mFormat,
1274 &outputDesc->mChannels,
1275 &outputDesc->mLatency,
1276 outputDesc->mFlags);
1277 if (mA2dpOutput) {
1278 // add A2DP output descriptor
1279 addOutput(mA2dpOutput, outputDesc);
Eric Laurentde070132010-07-13 04:45:46 -07001280
1281 //TODO: configure audio effect output stage here
1282
Mathias Agopian65ab4712010-07-14 17:59:35 -07001283 // set initial stream volume for A2DP device
1284 applyStreamVolumes(mA2dpOutput, device);
1285 if (a2dpUsedForSonification()) {
1286 mDuplicatedOutput = mpClientInterface->openDuplicateOutput(mA2dpOutput, mHardwareOutput);
1287 }
1288 if (mDuplicatedOutput != 0 ||
1289 !a2dpUsedForSonification()) {
1290 // If both A2DP and duplicated outputs are open, send device address to A2DP hardware
1291 // interface
1292 AudioParameter param;
1293 param.add(String8("a2dp_sink_address"), String8(device_address));
1294 mpClientInterface->setParameters(mA2dpOutput, param.toString());
1295 mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
1296
1297 if (a2dpUsedForSonification()) {
1298 // add duplicated output descriptor
1299 AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor();
1300 dupOutputDesc->mOutput1 = mOutputs.valueFor(mHardwareOutput);
1301 dupOutputDesc->mOutput2 = mOutputs.valueFor(mA2dpOutput);
1302 dupOutputDesc->mSamplingRate = outputDesc->mSamplingRate;
1303 dupOutputDesc->mFormat = outputDesc->mFormat;
1304 dupOutputDesc->mChannels = outputDesc->mChannels;
1305 dupOutputDesc->mLatency = outputDesc->mLatency;
1306 addOutput(mDuplicatedOutput, dupOutputDesc);
1307 applyStreamVolumes(mDuplicatedOutput, device);
1308 }
1309 } else {
1310 LOGW("getOutput() could not open duplicated output for %d and %d",
1311 mHardwareOutput, mA2dpOutput);
1312 mpClientInterface->closeOutput(mA2dpOutput);
1313 mOutputs.removeItem(mA2dpOutput);
1314 mA2dpOutput = 0;
1315 delete outputDesc;
1316 return NO_INIT;
1317 }
1318 } else {
1319 LOGW("setDeviceConnectionState() could not open A2DP output for device %x", device);
1320 delete outputDesc;
1321 return NO_INIT;
1322 }
1323 AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
1324
1325 if (mScoDeviceAddress != "") {
1326 // It is normal to suspend twice if we are both in call,
1327 // and have the hardware audio output routed to BT SCO
1328 if (mPhoneState != AudioSystem::MODE_NORMAL) {
1329 mpClientInterface->suspendOutput(mA2dpOutput);
1330 }
1331 if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)hwOutputDesc->device())) {
1332 mpClientInterface->suspendOutput(mA2dpOutput);
1333 }
1334 }
1335
1336 if (!a2dpUsedForSonification()) {
1337 // mute music on A2DP output if a notification or ringtone is playing
1338 uint32_t refCount = hwOutputDesc->strategyRefCount(STRATEGY_SONIFICATION);
1339 for (uint32_t i = 0; i < refCount; i++) {
1340 setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput);
1341 }
1342 }
1343 return NO_ERROR;
1344}
1345
1346status_t AudioPolicyManagerBase::handleA2dpDisconnection(AudioSystem::audio_devices device,
1347 const char *device_address)
1348{
1349 if (mA2dpOutput == 0) {
1350 LOGW("setDeviceConnectionState() disconnecting A2DP and no A2DP output!");
1351 return INVALID_OPERATION;
1352 }
1353
1354 if (mA2dpDeviceAddress != device_address) {
1355 LOGW("setDeviceConnectionState() disconnecting unknow A2DP sink address %s", device_address);
1356 return INVALID_OPERATION;
1357 }
1358
1359 // mute media strategy to avoid outputting sound on hardware output while music stream
1360 // is switched from A2DP output and before music is paused by music application
1361 setStrategyMute(STRATEGY_MEDIA, true, mHardwareOutput);
1362 setStrategyMute(STRATEGY_MEDIA, false, mHardwareOutput, MUTE_TIME_MS);
1363
1364 if (!a2dpUsedForSonification()) {
1365 // unmute music on A2DP output if a notification or ringtone is playing
1366 uint32_t refCount = mOutputs.valueFor(mHardwareOutput)->strategyRefCount(STRATEGY_SONIFICATION);
1367 for (uint32_t i = 0; i < refCount; i++) {
1368 setStrategyMute(STRATEGY_MEDIA, false, mA2dpOutput);
1369 }
1370 }
1371 mA2dpDeviceAddress = "";
1372 return NO_ERROR;
1373}
1374
1375void AudioPolicyManagerBase::closeA2dpOutputs()
1376{
Praveen Bharathib235dee2010-10-06 15:23:14 -05001377
Mathias Agopian65ab4712010-07-14 17:59:35 -07001378 LOGV("setDeviceConnectionState() closing A2DP and duplicated output!");
1379
1380 if (mDuplicatedOutput != 0) {
1381 AudioOutputDescriptor *dupOutputDesc = mOutputs.valueFor(mDuplicatedOutput);
1382 AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
1383 // As all active tracks on duplicated output will be deleted,
1384 // and as they were also referenced on hardware output, the reference
1385 // count for their stream type must be adjusted accordingly on
1386 // hardware output.
1387 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
1388 int refCount = dupOutputDesc->mRefCount[i];
1389 hwOutputDesc->changeRefCount((AudioSystem::stream_type)i,-refCount);
1390 }
1391
1392 mpClientInterface->closeOutput(mDuplicatedOutput);
1393 delete mOutputs.valueFor(mDuplicatedOutput);
1394 mOutputs.removeItem(mDuplicatedOutput);
1395 mDuplicatedOutput = 0;
1396 }
1397 if (mA2dpOutput != 0) {
1398 AudioParameter param;
1399 param.add(String8("closing"), String8("true"));
1400 mpClientInterface->setParameters(mA2dpOutput, param.toString());
Eric Laurentde070132010-07-13 04:45:46 -07001401
Mathias Agopian65ab4712010-07-14 17:59:35 -07001402 mpClientInterface->closeOutput(mA2dpOutput);
1403 delete mOutputs.valueFor(mA2dpOutput);
1404 mOutputs.removeItem(mA2dpOutput);
1405 mA2dpOutput = 0;
1406 }
1407}
1408
Eric Laurentc1c88e22010-08-27 17:10:36 -07001409void AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy)
Mathias Agopian65ab4712010-07-14 17:59:35 -07001410{
1411 uint32_t prevDevice = getDeviceForStrategy(strategy);
1412 uint32_t curDevice = getDeviceForStrategy(strategy, false);
1413 bool a2dpWasUsed = AudioSystem::isA2dpDevice((AudioSystem::audio_devices)(prevDevice & ~AudioSystem::DEVICE_OUT_SPEAKER));
1414 bool a2dpIsUsed = AudioSystem::isA2dpDevice((AudioSystem::audio_devices)(curDevice & ~AudioSystem::DEVICE_OUT_SPEAKER));
Eric Laurentde070132010-07-13 04:45:46 -07001415 audio_io_handle_t srcOutput = 0;
1416 audio_io_handle_t dstOutput = 0;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001417
1418 if (a2dpWasUsed && !a2dpIsUsed) {
1419 bool dupUsed = a2dpUsedForSonification() && a2dpWasUsed && (AudioSystem::popCount(prevDevice) == 2);
Eric Laurentde070132010-07-13 04:45:46 -07001420 dstOutput = mHardwareOutput;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001421 if (dupUsed) {
Eric Laurentde070132010-07-13 04:45:46 -07001422 LOGV("checkOutputForStrategy() moving strategy %d from duplicated", strategy);
1423 srcOutput = mDuplicatedOutput;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001424 } else {
Eric Laurentde070132010-07-13 04:45:46 -07001425 LOGV("checkOutputForStrategy() moving strategy %d from a2dp", strategy);
1426 srcOutput = mA2dpOutput;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001427 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001428 }
1429 if (a2dpIsUsed && !a2dpWasUsed) {
1430 bool dupUsed = a2dpUsedForSonification() && a2dpIsUsed && (AudioSystem::popCount(curDevice) == 2);
Eric Laurentde070132010-07-13 04:45:46 -07001431 srcOutput = mHardwareOutput;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001432 if (dupUsed) {
Eric Laurentde070132010-07-13 04:45:46 -07001433 LOGV("checkOutputForStrategy() moving strategy %d to duplicated", strategy);
1434 dstOutput = mDuplicatedOutput;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001435 } else {
Eric Laurentde070132010-07-13 04:45:46 -07001436 LOGV("checkOutputForStrategy() moving strategy %d to a2dp", strategy);
1437 dstOutput = mA2dpOutput;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001438 }
Eric Laurentde070132010-07-13 04:45:46 -07001439 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001440
Eric Laurentde070132010-07-13 04:45:46 -07001441 if (srcOutput != 0 && dstOutput != 0) {
1442 // Move effects associated to this strategy from previous output to new output
1443 for (size_t i = 0; i < mEffects.size(); i++) {
1444 EffectDescriptor *desc = mEffects.valueAt(i);
1445 if (desc->mSession != AudioSystem::SESSION_OUTPUT_STAGE &&
1446 desc->mStrategy == strategy &&
1447 desc->mOutput == srcOutput) {
1448 LOGV("checkOutputForStrategy() moving effect %d to output %d", mEffects.keyAt(i), dstOutput);
1449 mpClientInterface->moveEffects(desc->mSession, srcOutput, dstOutput);
1450 desc->mOutput = dstOutput;
1451 }
1452 }
1453 // Move tracks associated to this strategy from previous output to new output
Mathias Agopian65ab4712010-07-14 17:59:35 -07001454 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
1455 if (getStrategy((AudioSystem::stream_type)i) == strategy) {
Eric Laurentde070132010-07-13 04:45:46 -07001456 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, dstOutput);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001457 }
1458 }
1459 }
1460}
1461
Eric Laurentc1c88e22010-08-27 17:10:36 -07001462void AudioPolicyManagerBase::checkOutputForAllStrategies()
Mathias Agopian65ab4712010-07-14 17:59:35 -07001463{
Eric Laurentc1c88e22010-08-27 17:10:36 -07001464 checkOutputForStrategy(STRATEGY_PHONE);
1465 checkOutputForStrategy(STRATEGY_SONIFICATION);
1466 checkOutputForStrategy(STRATEGY_MEDIA);
1467 checkOutputForStrategy(STRATEGY_DTMF);
Mathias Agopian65ab4712010-07-14 17:59:35 -07001468}
1469
1470#endif
1471
1472uint32_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache)
1473{
1474 uint32_t device = 0;
1475
1476 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
1477 // check the following by order of priority to request a routing change if necessary:
1478 // 1: we are in call or the strategy phone is active on the hardware output:
1479 // use device for strategy phone
1480 // 2: the strategy sonification is active on the hardware output:
1481 // use device for strategy sonification
1482 // 3: the strategy media is active on the hardware output:
1483 // use device for strategy media
1484 // 4: the strategy DTMF is active on the hardware output:
1485 // use device for strategy DTMF
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -08001486 if (isInCall() ||
Mathias Agopian65ab4712010-07-14 17:59:35 -07001487 outputDesc->isUsedByStrategy(STRATEGY_PHONE)) {
1488 device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
1489 } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) {
1490 device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
1491 } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) {
1492 device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
1493 } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) {
1494 device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
1495 }
1496
1497 LOGV("getNewDevice() selected device %x", device);
1498 return device;
1499}
1500
Eric Laurentde070132010-07-13 04:45:46 -07001501uint32_t AudioPolicyManagerBase::getStrategyForStream(AudioSystem::stream_type stream) {
1502 return (uint32_t)getStrategy(stream);
1503}
1504
1505AudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy(
1506 AudioSystem::stream_type stream) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001507 // stream to strategy mapping
1508 switch (stream) {
1509 case AudioSystem::VOICE_CALL:
1510 case AudioSystem::BLUETOOTH_SCO:
1511 return STRATEGY_PHONE;
1512 case AudioSystem::RING:
1513 case AudioSystem::NOTIFICATION:
1514 case AudioSystem::ALARM:
1515 case AudioSystem::ENFORCED_AUDIBLE:
1516 return STRATEGY_SONIFICATION;
1517 case AudioSystem::DTMF:
1518 return STRATEGY_DTMF;
1519 default:
1520 LOGE("unknown stream type");
1521 case AudioSystem::SYSTEM:
1522 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
1523 // while key clicks are played produces a poor result
1524 case AudioSystem::TTS:
1525 case AudioSystem::MUSIC:
1526 return STRATEGY_MEDIA;
1527 }
1528}
1529
1530uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, bool fromCache)
1531{
1532 uint32_t device = 0;
1533
1534 if (fromCache) {
1535 LOGV("getDeviceForStrategy() from cache strategy %d, device %x", strategy, mDeviceForStrategy[strategy]);
1536 return mDeviceForStrategy[strategy];
1537 }
1538
1539 switch (strategy) {
1540 case STRATEGY_DTMF:
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -08001541 if (!isInCall()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001542 // when off call, DTMF strategy follows the same rules as MEDIA strategy
1543 device = getDeviceForStrategy(STRATEGY_MEDIA, false);
1544 break;
1545 }
1546 // when in call, DTMF and PHONE strategies follow the same rules
1547 // FALL THROUGH
1548
1549 case STRATEGY_PHONE:
1550 // for phone strategy, we first consider the forced use and then the available devices by order
1551 // of priority
1552 switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
1553 case AudioSystem::FORCE_BT_SCO:
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -08001554 if (!isInCall() || strategy != STRATEGY_DTMF) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001555 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
1556 if (device) break;
1557 }
1558 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
1559 if (device) break;
1560 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
1561 if (device) break;
1562 // if SCO device is requested but no SCO device is available, fall back to default case
1563 // FALL THROUGH
1564
1565 default: // FORCE_NONE
1566 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
1567 if (device) break;
1568 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
1569 if (device) break;
Praveen Bharathib235dee2010-10-06 15:23:14 -05001570 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET;
1571 if (device) break;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001572#ifdef WITH_A2DP
1573 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -08001574 if (!isInCall()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001575 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
1576 if (device) break;
1577 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
1578 if (device) break;
1579 }
1580#endif
1581 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
1582 if (device == 0) {
1583 LOGE("getDeviceForStrategy() earpiece device not found");
1584 }
1585 break;
1586
1587 case AudioSystem::FORCE_SPEAKER:
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -08001588 if (!isInCall() || strategy != STRATEGY_DTMF) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001589 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
1590 if (device) break;
1591 }
1592#ifdef WITH_A2DP
1593 // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
1594 // A2DP speaker when forcing to speaker output
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -08001595 if (!isInCall()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001596 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
1597 if (device) break;
1598 }
1599#endif
1600 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
1601 if (device == 0) {
1602 LOGE("getDeviceForStrategy() speaker device not found");
1603 }
1604 break;
1605 }
1606 break;
1607
1608 case STRATEGY_SONIFICATION:
1609
1610 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
1611 // handleIncallSonification().
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -08001612 if (isInCall()) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001613 device = getDeviceForStrategy(STRATEGY_PHONE, false);
1614 break;
1615 }
1616 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
1617 if (device == 0) {
1618 LOGE("getDeviceForStrategy() speaker device not found");
1619 }
1620 // The second device used for sonification is the same as the device used by media strategy
1621 // FALL THROUGH
1622
1623 case STRATEGY_MEDIA: {
1624 uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
1625 if (device2 == 0) {
1626 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
1627 }
1628 if (device2 == 0) {
1629 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
1630 }
Praveen Bharathib235dee2010-10-06 15:23:14 -05001631 if (device2 == 0) {
1632 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET;
1633 }
1634 if (device2 == 0) {
1635 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET;
1636 }
Mathias Agopian65ab4712010-07-14 17:59:35 -07001637#ifdef WITH_A2DP
1638 if (mA2dpOutput != 0) {
1639 if (strategy == STRATEGY_SONIFICATION && !a2dpUsedForSonification()) {
1640 break;
1641 }
1642 if (device2 == 0) {
1643 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
1644 }
1645 if (device2 == 0) {
1646 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
1647 }
1648 if (device2 == 0) {
1649 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
1650 }
1651 }
1652#endif
1653 if (device2 == 0) {
1654 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
1655 }
1656
1657 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION, 0 otherwise
1658 device |= device2;
1659 if (device == 0) {
1660 LOGE("getDeviceForStrategy() speaker device not found");
1661 }
1662 } break;
1663
1664 default:
1665 LOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
1666 break;
1667 }
1668
1669 LOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
1670 return device;
1671}
1672
1673void AudioPolicyManagerBase::updateDeviceForStrategy()
1674{
1675 for (int i = 0; i < NUM_STRATEGIES; i++) {
1676 mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false);
1677 }
1678}
1679
1680void AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, uint32_t device, bool force, int delayMs)
1681{
1682 LOGV("setOutputDevice() output %d device %x delayMs %d", output, device, delayMs);
1683 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
1684
1685
1686 if (outputDesc->isDuplicated()) {
1687 setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs);
1688 setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs);
1689 return;
1690 }
1691#ifdef WITH_A2DP
1692 // filter devices according to output selected
1693 if (output == mA2dpOutput) {
1694 device &= AudioSystem::DEVICE_OUT_ALL_A2DP;
1695 } else {
1696 device &= ~AudioSystem::DEVICE_OUT_ALL_A2DP;
1697 }
1698#endif
1699
1700 uint32_t prevDevice = (uint32_t)outputDesc->device();
1701 // Do not change the routing if:
1702 // - the requestede device is 0
1703 // - the requested device is the same as current device and force is not specified.
1704 // Doing this check here allows the caller to call setOutputDevice() without conditions
1705 if ((device == 0 || device == prevDevice) && !force) {
1706 LOGV("setOutputDevice() setting same device %x or null device for output %d", device, output);
1707 return;
1708 }
1709
1710 outputDesc->mDevice = device;
1711 // mute media streams if both speaker and headset are selected
1712 if (output == mHardwareOutput && AudioSystem::popCount(device) == 2) {
1713 setStrategyMute(STRATEGY_MEDIA, true, output);
1714 // wait for the PCM output buffers to empty before proceeding with the rest of the command
1715 usleep(outputDesc->mLatency*2*1000);
1716 }
1717#ifdef WITH_A2DP
1718 // suspend A2DP output if SCO device is selected
1719 if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)device)) {
1720 if (mA2dpOutput != 0) {
1721 mpClientInterface->suspendOutput(mA2dpOutput);
1722 }
1723 }
1724#endif
1725 // do the routing
1726 AudioParameter param = AudioParameter();
1727 param.addInt(String8(AudioParameter::keyRouting), (int)device);
1728 mpClientInterface->setParameters(mHardwareOutput, param.toString(), delayMs);
1729 // update stream volumes according to new device
1730 applyStreamVolumes(output, device, delayMs);
1731
1732#ifdef WITH_A2DP
1733 // if disconnecting SCO device, restore A2DP output
1734 if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)prevDevice)) {
1735 if (mA2dpOutput != 0) {
1736 LOGV("restore A2DP output");
1737 mpClientInterface->restoreOutput(mA2dpOutput);
1738 }
1739 }
1740#endif
1741 // if changing from a combined headset + speaker route, unmute media streams
1742 if (output == mHardwareOutput && AudioSystem::popCount(prevDevice) == 2) {
1743 setStrategyMute(STRATEGY_MEDIA, false, output, delayMs);
1744 }
1745}
1746
1747uint32_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource)
1748{
1749 uint32_t device;
1750
1751 switch(inputSource) {
1752 case AUDIO_SOURCE_DEFAULT:
1753 case AUDIO_SOURCE_MIC:
1754 case AUDIO_SOURCE_VOICE_RECOGNITION:
Jean-Michel Trivic643d772010-11-08 18:38:14 -08001755 case AUDIO_SOURCE_VOICE_COMMUNICATION:
Mathias Agopian65ab4712010-07-14 17:59:35 -07001756 if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO &&
1757 mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
1758 device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
1759 } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
1760 device = AudioSystem::DEVICE_IN_WIRED_HEADSET;
1761 } else {
1762 device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
1763 }
1764 break;
1765 case AUDIO_SOURCE_CAMCORDER:
1766 if (hasBackMicrophone()) {
1767 device = AudioSystem::DEVICE_IN_BACK_MIC;
1768 } else {
1769 device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
1770 }
1771 break;
1772 case AUDIO_SOURCE_VOICE_UPLINK:
1773 case AUDIO_SOURCE_VOICE_DOWNLINK:
1774 case AUDIO_SOURCE_VOICE_CALL:
1775 device = AudioSystem::DEVICE_IN_VOICE_CALL;
1776 break;
1777 default:
1778 LOGW("getInput() invalid input source %d", inputSource);
1779 device = 0;
1780 break;
1781 }
1782 LOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
1783 return device;
1784}
1785
1786audio_io_handle_t AudioPolicyManagerBase::getActiveInput()
1787{
1788 for (size_t i = 0; i < mInputs.size(); i++) {
1789 if (mInputs.valueAt(i)->mRefCount > 0) {
1790 return mInputs.keyAt(i);
1791 }
1792 }
1793 return 0;
1794}
1795
1796float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device)
1797{
1798 float volume = 1.0;
1799 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
1800 StreamDescriptor &streamDesc = mStreams[stream];
1801
1802 if (device == 0) {
1803 device = outputDesc->device();
1804 }
1805
1806 int volInt = (100 * (index - streamDesc.mIndexMin)) / (streamDesc.mIndexMax - streamDesc.mIndexMin);
1807 volume = AudioSystem::linearToLog(volInt);
1808
1809 // if a headset is connected, apply the following rules to ring tones and notifications
1810 // to avoid sound level bursts in user's ears:
1811 // - always attenuate ring tones and notifications volume by 6dB
1812 // - if music is playing, always limit the volume to current music volume,
1813 // with a minimum threshold at -36dB so that notification is always perceived.
1814 if ((device &
1815 (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP |
1816 AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
1817 AudioSystem::DEVICE_OUT_WIRED_HEADSET |
Praveen Bharathib235dee2010-10-06 15:23:14 -05001818 AudioSystem::DEVICE_OUT_WIRED_HEADPHONE |
1819 AudioSystem::DEVICE_OUT_ANLG_DOCK_HEADSET |
1820 AudioSystem::DEVICE_OUT_DGTL_DOCK_HEADSET)) &&
Mathias Agopian65ab4712010-07-14 17:59:35 -07001821 (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) &&
1822 streamDesc.mCanBeMuted) {
1823 volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
1824 // when the phone is ringing we must consider that music could have been paused just before
1825 // by the music application and behave as if music was active if the last music track was
1826 // just stopped
1827 if (outputDesc->mRefCount[AudioSystem::MUSIC] || mLimitRingtoneVolume) {
1828 float musicVol = computeVolume(AudioSystem::MUSIC, mStreams[AudioSystem::MUSIC].mIndexCur, output, device);
1829 float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
1830 if (volume > minVol) {
1831 volume = minVol;
1832 LOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
1833 }
1834 }
1835 }
1836
1837 return volume;
1838}
1839
1840status_t AudioPolicyManagerBase::checkAndSetVolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayMs, bool force)
1841{
1842
1843 // do not change actual stream volume if the stream is muted
1844 if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
1845 LOGV("checkAndSetVolume() stream %d muted count %d", stream, mOutputs.valueFor(output)->mMuteCount[stream]);
1846 return NO_ERROR;
1847 }
1848
1849 // do not change in call volume if bluetooth is connected and vice versa
1850 if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
1851 (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {
1852 LOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
1853 stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);
1854 return INVALID_OPERATION;
1855 }
1856
1857 float volume = computeVolume(stream, index, output, device);
Mathias Agopian094c96d2010-07-14 18:48:58 -07001858 // We actually change the volume if:
1859 // - the float value returned by computeVolume() changed
1860 // - the force flag is set
1861 if (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||
1862 force) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001863 mOutputs.valueFor(output)->mCurVolume[stream] = volume;
1864 LOGV("setStreamVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
1865 if (stream == AudioSystem::VOICE_CALL ||
1866 stream == AudioSystem::DTMF ||
1867 stream == AudioSystem::BLUETOOTH_SCO) {
Mathias Agopian65ab4712010-07-14 17:59:35 -07001868 // offset value to reflect actual hardware volume that never reaches 0
1869 // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java)
1870 volume = 0.01 + 0.99 * volume;
Mathias Agopian65ab4712010-07-14 17:59:35 -07001871 }
1872 mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
1873 }
1874
Mathias Agopian094c96d2010-07-14 18:48:58 -07001875 if (stream == AudioSystem::VOICE_CALL ||
1876 stream == AudioSystem::BLUETOOTH_SCO) {
1877 float voiceVolume;
1878 // Force voice volume to max for bluetooth SCO as volume is managed by the headset
1879 if (stream == AudioSystem::VOICE_CALL) {
1880 voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
1881 } else {
1882 voiceVolume = 1.0;
1883 }
1884 if (voiceVolume != mLastVoiceVolume && output == mHardwareOutput) {
1885 mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
1886 mLastVoiceVolume = voiceVolume;
1887 }
1888 }
1889
Mathias Agopian65ab4712010-07-14 17:59:35 -07001890 return NO_ERROR;
1891}
1892
1893void AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, uint32_t device, int delayMs)
1894{
1895 LOGV("applyStreamVolumes() for output %d and device %x", output, device);
1896
1897 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
1898 checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, device, delayMs);
1899 }
1900}
1901
1902void AudioPolicyManagerBase::setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output, int delayMs)
1903{
1904 LOGV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
1905 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
1906 if (getStrategy((AudioSystem::stream_type)stream) == strategy) {
1907 setStreamMute(stream, on, output, delayMs);
1908 }
1909 }
1910}
1911
1912void AudioPolicyManagerBase::setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs)
1913{
1914 StreamDescriptor &streamDesc = mStreams[stream];
1915 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
1916
1917 LOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d", stream, on, output, outputDesc->mMuteCount[stream]);
1918
1919 if (on) {
1920 if (outputDesc->mMuteCount[stream] == 0) {
1921 if (streamDesc.mCanBeMuted) {
1922 checkAndSetVolume(stream, 0, output, outputDesc->device(), delayMs);
1923 }
1924 }
1925 // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
1926 outputDesc->mMuteCount[stream]++;
1927 } else {
1928 if (outputDesc->mMuteCount[stream] == 0) {
1929 LOGW("setStreamMute() unmuting non muted stream!");
1930 return;
1931 }
1932 if (--outputDesc->mMuteCount[stream] == 0) {
1933 checkAndSetVolume(stream, streamDesc.mIndexCur, output, outputDesc->device(), delayMs);
1934 }
1935 }
1936}
1937
1938void AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, bool stateChange)
1939{
1940 // if the stream pertains to sonification strategy and we are in call we must
1941 // mute the stream if it is low visibility. If it is high visibility, we must play a tone
1942 // in the device used for phone strategy and play the tone if the selected device does not
1943 // interfere with the device used for phone strategy
1944 // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
1945 // many times as there are active tracks on the output
1946
1947 if (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) {
1948 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mHardwareOutput);
1949 LOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
1950 stream, starting, outputDesc->mDevice, stateChange);
1951 if (outputDesc->mRefCount[stream]) {
1952 int muteCount = 1;
1953 if (stateChange) {
1954 muteCount = outputDesc->mRefCount[stream];
1955 }
1956 if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) {
1957 LOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
1958 for (int i = 0; i < muteCount; i++) {
1959 setStreamMute(stream, starting, mHardwareOutput);
1960 }
1961 } else {
1962 LOGV("handleIncallSonification() high visibility");
1963 if (outputDesc->device() & getDeviceForStrategy(STRATEGY_PHONE)) {
1964 LOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
1965 for (int i = 0; i < muteCount; i++) {
1966 setStreamMute(stream, starting, mHardwareOutput);
1967 }
1968 }
1969 if (starting) {
1970 mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL);
1971 } else {
1972 mpClientInterface->stopTone();
1973 }
1974 }
1975 }
1976 }
1977}
1978
Jean-Michel Trivif1fb01a2010-11-15 12:11:32 -08001979bool AudioPolicyManagerBase::isInCall()
1980{
1981 return isStateInCall(mPhoneState);
1982}
1983
1984bool AudioPolicyManagerBase::isStateInCall(int state) {
1985 return ((state == AudioSystem::MODE_IN_CALL) ||
1986 (state == AudioSystem::MODE_IN_COMMUNICATION));
1987}
1988
Mathias Agopian65ab4712010-07-14 17:59:35 -07001989bool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream,
1990 uint32_t samplingRate,
1991 uint32_t format,
1992 uint32_t channels,
1993 AudioSystem::output_flags flags,
1994 uint32_t device)
1995{
1996 return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
1997 (format !=0 && !AudioSystem::isLinearPCM(format)));
1998}
1999
Eric Laurentde070132010-07-13 04:45:46 -07002000uint32_t AudioPolicyManagerBase::getMaxEffectsCpuLoad()
2001{
2002 return MAX_EFFECTS_CPU_LOAD;
2003}
2004
2005uint32_t AudioPolicyManagerBase::getMaxEffectsMemory()
2006{
2007 return MAX_EFFECTS_MEMORY;
2008}
2009
Mathias Agopian65ab4712010-07-14 17:59:35 -07002010// --- AudioOutputDescriptor class implementation
2011
2012AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor()
2013 : mId(0), mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0),
2014 mFlags((AudioSystem::output_flags)0), mDevice(0), mOutput1(0), mOutput2(0)
2015{
2016 // clear usage count for all stream types
2017 for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
2018 mRefCount[i] = 0;
2019 mCurVolume[i] = -1.0;
2020 mMuteCount[i] = 0;
2021 }
2022}
2023
2024uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::device()
2025{
2026 uint32_t device = 0;
2027 if (isDuplicated()) {
2028 device = mOutput1->mDevice | mOutput2->mDevice;
2029 } else {
2030 device = mDevice;
2031 }
2032 return device;
2033}
2034
2035void AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta)
2036{
2037 // forward usage count change to attached outputs
2038 if (isDuplicated()) {
2039 mOutput1->changeRefCount(stream, delta);
2040 mOutput2->changeRefCount(stream, delta);
2041 }
2042 if ((delta + (int)mRefCount[stream]) < 0) {
2043 LOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]);
2044 mRefCount[stream] = 0;
2045 return;
2046 }
2047 mRefCount[stream] += delta;
2048 LOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
2049}
2050
2051uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::refCount()
2052{
2053 uint32_t refcount = 0;
2054 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
2055 refcount += mRefCount[i];
2056 }
2057 return refcount;
2058}
2059
2060uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::strategyRefCount(routing_strategy strategy)
2061{
2062 uint32_t refCount = 0;
2063 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
2064 if (getStrategy((AudioSystem::stream_type)i) == strategy) {
2065 refCount += mRefCount[i];
2066 }
2067 }
2068 return refCount;
2069}
2070
2071
2072status_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd)
2073{
2074 const size_t SIZE = 256;
2075 char buffer[SIZE];
2076 String8 result;
2077
2078 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
2079 result.append(buffer);
2080 snprintf(buffer, SIZE, " Format: %d\n", mFormat);
2081 result.append(buffer);
2082 snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
2083 result.append(buffer);
2084 snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
2085 result.append(buffer);
2086 snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
2087 result.append(buffer);
2088 snprintf(buffer, SIZE, " Devices %08x\n", device());
2089 result.append(buffer);
2090 snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
2091 result.append(buffer);
2092 for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
2093 snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
2094 result.append(buffer);
2095 }
2096 write(fd, result.string(), result.size());
2097
2098 return NO_ERROR;
2099}
2100
2101// --- AudioInputDescriptor class implementation
2102
2103AudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor()
2104 : mSamplingRate(0), mFormat(0), mChannels(0),
2105 mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0)
2106{
2107}
2108
2109status_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd)
2110{
2111 const size_t SIZE = 256;
2112 char buffer[SIZE];
2113 String8 result;
2114
2115 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
2116 result.append(buffer);
2117 snprintf(buffer, SIZE, " Format: %d\n", mFormat);
2118 result.append(buffer);
2119 snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
2120 result.append(buffer);
2121 snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics);
2122 result.append(buffer);
2123 snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
2124 result.append(buffer);
2125 snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
2126 result.append(buffer);
2127 write(fd, result.string(), result.size());
2128
2129 return NO_ERROR;
2130}
2131
2132// --- StreamDescriptor class implementation
2133
2134void AudioPolicyManagerBase::StreamDescriptor::dump(char* buffer, size_t size)
2135{
2136 snprintf(buffer, size, " %02d %02d %02d %d\n",
2137 mIndexMin,
2138 mIndexMax,
2139 mIndexCur,
2140 mCanBeMuted);
2141}
2142
Eric Laurentde070132010-07-13 04:45:46 -07002143// --- EffectDescriptor class implementation
2144
2145status_t AudioPolicyManagerBase::EffectDescriptor::dump(int fd)
2146{
2147 const size_t SIZE = 256;
2148 char buffer[SIZE];
2149 String8 result;
2150
2151 snprintf(buffer, SIZE, " Output: %d\n", mOutput);
2152 result.append(buffer);
2153 snprintf(buffer, SIZE, " Strategy: %d\n", mStrategy);
2154 result.append(buffer);
2155 snprintf(buffer, SIZE, " Session: %d\n", mSession);
2156 result.append(buffer);
2157 snprintf(buffer, SIZE, " Name: %s\n", mDesc.name);
2158 result.append(buffer);
2159 write(fd, result.string(), result.size());
2160
2161 return NO_ERROR;
2162}
2163
2164
Mathias Agopian65ab4712010-07-14 17:59:35 -07002165
2166}; // namespace android