2 * Copyright (C) 2009 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #define LOG_TAG "AudioPolicyManagerALSA"
18 //#define LOG_NDEBUG 0
19 #include <utils/Log.h>
20 #include "AudioPolicyManagerALSA.h"
21 #include <media/mediarecorder.h>
26 // ----------------------------------------------------------------------------
27 // AudioPolicyInterface implementation
28 // ----------------------------------------------------------------------------
31 status_t AudioPolicyManagerALSA::setDeviceConnectionState(AudioSystem::audio_devices device,
32 AudioSystem::device_connection_state state,
33 const char *device_address)
36 LOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address);
38 // connect/disconnect only 1 device at a time
39 if (AudioSystem::popCount(device) != 1) return BAD_VALUE;
41 if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) {
42 LOGE("setDeviceConnectionState() invalid address: %s", device_address);
46 // handle output devices
47 if (AudioSystem::isOutputDevice(device)) {
50 if (AudioSystem::isA2dpDevice(device)) {
51 LOGE("setDeviceConnectionState() invalid device: %x", device);
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;
64 LOGW_IF((getOutputForDevice((uint32_t)device) != 0), "setDeviceConnectionState(): output using unconnected device %x", device);
66 LOGV("setDeviceConnectionState() connecting device %x", device);
68 // register new device as available
69 mAvailableOutputDevices |= device;
72 // handle A2DP device connection
73 if (AudioSystem::isA2dpDevice(device)) {
74 // when an A2DP device is connected, open an A2DP and a duplicated output
75 LOGV("opening A2DP output for device %s", device_address);
76 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
77 outputDesc->mDevice = device;
78 mA2dpOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
79 &outputDesc->mSamplingRate,
81 &outputDesc->mChannels,
82 &outputDesc->mLatency,
85 // add A2DP output descriptor
86 mOutputs.add(mA2dpOutput, outputDesc);
87 // set initial stream volume for A2DP device
88 applyStreamVolumes(mA2dpOutput, device);
89 mDuplicatedOutput = mpClientInterface->openDuplicateOutput(mA2dpOutput, mHardwareOutput);
90 if (mDuplicatedOutput != 0) {
91 // If both A2DP and duplicated outputs are open, send device address to A2DP hardware
94 param.add(String8("a2dp_sink_address"), String8(device_address));
95 mpClientInterface->setParameters(mA2dpOutput, param.toString());
96 mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
98 // add duplicated output descriptor
99 AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor();
100 dupOutputDesc->mOutput1 = mOutputs.valueFor(mHardwareOutput);
101 dupOutputDesc->mOutput2 = mOutputs.valueFor(mA2dpOutput);
102 dupOutputDesc->mSamplingRate = outputDesc->mSamplingRate;
103 dupOutputDesc->mFormat = outputDesc->mFormat;
104 dupOutputDesc->mChannels = outputDesc->mChannels;
105 dupOutputDesc->mLatency = outputDesc->mLatency;
106 mOutputs.add(mDuplicatedOutput, dupOutputDesc);
107 applyStreamVolumes(mDuplicatedOutput, device);
109 LOGW("getOutput() could not open duplicated output for %d and %d",
110 mHardwareOutput, mA2dpOutput);
111 mAvailableOutputDevices &= ~device;
116 LOGW("setDeviceConnectionState() could not open A2DP output for device %x", device);
117 mAvailableOutputDevices &= ~device;
121 AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
123 if (mA2dpDeviceAddress == mScoDeviceAddress) {
124 // It is normal to suspend twice if we are both in call,
125 // and have the hardware audio output routed to BT SCO
126 if (mPhoneState != AudioSystem::MODE_NORMAL) {
127 mpClientInterface->suspendOutput(mA2dpOutput);
129 if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)hwOutputDesc->device())) {
130 mpClientInterface->suspendOutput(mA2dpOutput);
134 // move streams pertaining to STRATEGY_MEDIA to the newly opened A2DP output
135 if (getDeviceForStrategy(STRATEGY_MEDIA) & device) {
136 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
137 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_MEDIA) {
138 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mA2dpOutput);
139 outputDesc->mRefCount[i] = hwOutputDesc->mRefCount[i];
140 hwOutputDesc->mRefCount[i] = 0;
145 // move streams pertaining to STRATEGY_DTMF to the newly opened A2DP output
146 if (getDeviceForStrategy(STRATEGY_DTMF) & device) {
147 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
148 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_DTMF) {
149 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mA2dpOutput);
150 outputDesc->mRefCount[i] = hwOutputDesc->mRefCount[i];
151 hwOutputDesc->mRefCount[i] = 0;
156 // move streams pertaining to STRATEGY_SONIFICATION to the newly opened duplicated output
157 if (getDeviceForStrategy(STRATEGY_SONIFICATION) & device) {
158 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
159 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_SONIFICATION) {
160 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mDuplicatedOutput);
161 outputDesc->mRefCount[i] =
162 hwOutputDesc->mRefCount[i];
163 mOutputs.valueFor(mDuplicatedOutput)->mRefCount[i] =
164 hwOutputDesc->mRefCount[i];
170 // handle wired and SCO device connection (accessed via hardware output)
173 uint32_t newDevice = 0;
174 if (AudioSystem::isBluetoothScoDevice(device)) {
175 LOGV("setDeviceConnectionState() BT SCO device, address %s", device_address);
176 // keep track of SCO device address
177 mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
178 // if in call and connecting SCO device, check if we must reroute hardware output
179 if (mPhoneState == AudioSystem::MODE_IN_CALL &&
180 getDeviceForStrategy(STRATEGY_PHONE) == device) {
182 } else if (mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_DTMF) &&
183 getDeviceForStrategy(STRATEGY_DTMF) == device) {
186 if ((mA2dpDeviceAddress == mScoDeviceAddress) &&
187 (mPhoneState != AudioSystem::MODE_NORMAL)) {
188 mpClientInterface->suspendOutput(mA2dpOutput);
190 } else if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET ||
191 device == AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
192 LOGV("setDeviceConnectionState() wired headset device");
193 // if connecting a wired headset, we check the following by order of priority
194 // to request a routing change if necessary:
195 // 1: we are in call or the strategy phone is active on the hardware output:
196 // use device for strategy phone
197 // 2: the strategy sonification is active on the hardware output:
198 // use device for strategy sonification
199 // 3: the strategy media is active on the hardware output:
200 // use device for strategy media
201 // 4: the strategy DTMF is active on the hardware output:
202 // use device for strategy DTMF
203 if (getDeviceForStrategy(STRATEGY_PHONE) == device &&
204 (mPhoneState == AudioSystem::MODE_IN_CALL ||
205 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_PHONE))) {
207 } else if ((getDeviceForStrategy(STRATEGY_SONIFICATION) & device) &&
208 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_SONIFICATION)){
209 newDevice = getDeviceForStrategy(STRATEGY_SONIFICATION);
210 } else if ((getDeviceForStrategy(STRATEGY_MEDIA) == device) &&
211 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_MEDIA)){
213 } else if (getDeviceForStrategy(STRATEGY_DTMF) == device &&
214 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_DTMF)) {
217 } else if (device == AudioSystem::DEVICE_OUT_TTY) {
218 LOGV("setDeviceConnectionState() tty device");
219 // if connecting a wired headset, we check the following by order of priority
220 // to request a routing change if necessary:
221 // 1: we are in call or the strategy phone is active on the hardware output:
222 // use device for strategy phone
223 if (getDeviceForStrategy(STRATEGY_PHONE) == device &&
224 (mPhoneState == AudioSystem::MODE_IN_CALL ||
225 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_PHONE))) {
228 } else if (device == AudioSystem::DEVICE_OUT_FM_SPEAKER ||
229 device == AudioSystem::DEVICE_OUT_FM_HEADPHONE) {
230 LOGV("setDeviceConnectionState() no mic headphone device");
231 // if connecting a wired headset, we check the following by order of priority
232 // to request a routing change if necessary:
233 // 1: the strategy sonification is active on the hardware output:
234 // use device for strategy sonification
235 // 2: the strategy media is active on the hardware output:
236 // use device for strategy media
237 if ((getDeviceForStrategy(STRATEGY_SONIFICATION) & device) &&
238 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_SONIFICATION)){
239 newDevice = getDeviceForStrategy(STRATEGY_SONIFICATION);
240 } else if ((getDeviceForStrategy(STRATEGY_MEDIA) == device) &&
241 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_MEDIA)){
246 // request routing change if necessary
247 setOutputDevice(mHardwareOutput, newDevice);
250 // handle output device disconnection
251 case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
252 if (!(mAvailableOutputDevices & device)) {
253 LOGW("setDeviceConnectionState() device not connected: %x", device);
254 return INVALID_OPERATION;
257 uint32_t newDevice = 0;
258 // get usage of disconnected device by all strategies
259 bool wasUsedForMedia = (getDeviceForStrategy(STRATEGY_MEDIA) & device) != 0;
260 bool wasUsedForSonification = (getDeviceForStrategy(STRATEGY_SONIFICATION) & device) != 0;
261 bool wasUsedforPhone = (getDeviceForStrategy(STRATEGY_PHONE) & device) != 0;
262 bool wasUsedforDtmf = (getDeviceForStrategy(STRATEGY_DTMF) & device) != 0;
263 LOGV("setDeviceConnectionState() disconnecting device %x used by media %d, sonification %d, phone %d",
264 device, wasUsedForMedia, wasUsedForSonification, wasUsedforPhone);
265 // remove device from available output devices
266 mAvailableOutputDevices &= ~device;
269 // handle A2DP device disconnection
270 if (AudioSystem::isA2dpDevice(device)) {
271 if (mA2dpOutput == 0 || mDuplicatedOutput == 0) {
272 LOGW("setDeviceConnectionState() disconnecting A2DP and no A2DP output!");
273 mAvailableOutputDevices |= device;
274 return INVALID_OPERATION;
277 if (mA2dpDeviceAddress != device_address) {
278 LOGW("setDeviceConnectionState() disconnecting unknow A2DP sink address %s", device_address);
279 mAvailableOutputDevices |= device;
280 return INVALID_OPERATION;
283 AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
284 AudioOutputDescriptor *a2dpOutputDesc = mOutputs.valueFor(mA2dpOutput);
286 // mute media during 2 seconds to avoid outputing sound on hardware output while music stream
287 // is switched from A2DP output and before music is paused by music application
288 setStrategyMute(STRATEGY_MEDIA, true, mHardwareOutput);
289 setStrategyMute(STRATEGY_MEDIA, false, mHardwareOutput, 2000);
291 // If the A2DP device was used by DTMF strategy, move all streams pertaining to DTMF strategy to
293 if (wasUsedforDtmf) {
294 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
295 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_DTMF) {
296 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mHardwareOutput);
297 hwOutputDesc->changeRefCount((AudioSystem::stream_type)i,
298 a2dpOutputDesc->mRefCount[i]);
301 if (a2dpOutputDesc->isUsedByStrategy(STRATEGY_DTMF)) {
302 newDevice = getDeviceForStrategy(STRATEGY_DTMF);
306 // If the A2DP device was used by media strategy, move all streams pertaining to media strategy to
308 if (wasUsedForMedia) {
309 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
310 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_MEDIA) {
311 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mHardwareOutput);
312 hwOutputDesc->changeRefCount((AudioSystem::stream_type)i,
313 a2dpOutputDesc->mRefCount[i]);
316 if (a2dpOutputDesc->isUsedByStrategy(STRATEGY_MEDIA)) {
317 newDevice = getDeviceForStrategy(STRATEGY_MEDIA);
321 // If the A2DP device was used by sonification strategy, move all streams pertaining to
322 // sonification strategy to hardware output.
323 // Note that newDevice is overwritten here giving sonification strategy a higher priority than
325 if (wasUsedForSonification) {
326 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
327 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_SONIFICATION) {
328 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mHardwareOutput);
331 if (a2dpOutputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) {
332 newDevice = getDeviceForStrategy(STRATEGY_SONIFICATION);
336 // close A2DP and duplicated outputs
337 AudioParameter param;
338 param.add(String8("closing"), String8("true"));
339 mpClientInterface->setParameters(mA2dpOutput, param.toString());
341 LOGW("setDeviceConnectionState() closing A2DP and duplicated output!");
342 mpClientInterface->closeOutput(mDuplicatedOutput);
343 delete mOutputs.valueFor(mDuplicatedOutput);
344 mOutputs.removeItem(mDuplicatedOutput);
345 mDuplicatedOutput = 0;
346 mpClientInterface->closeOutput(mA2dpOutput);
347 delete mOutputs.valueFor(mA2dpOutput);
348 mOutputs.removeItem(mA2dpOutput);
353 if (AudioSystem::isBluetoothScoDevice(device)) {
354 // handle SCO device disconnection
355 if (wasUsedforPhone &&
356 mPhoneState == AudioSystem::MODE_IN_CALL) {
357 // if in call, find new suitable device for phone strategy
358 newDevice = getDeviceForStrategy(STRATEGY_PHONE);
359 } else if (wasUsedforDtmf &&
360 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_DTMF)) {
361 newDevice = getDeviceForStrategy(STRATEGY_DTMF);
363 if ((mA2dpDeviceAddress == mScoDeviceAddress) &&
364 (mPhoneState != AudioSystem::MODE_NORMAL)) {
365 mpClientInterface->restoreOutput(mA2dpOutput);
367 } else if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET ||
368 device == AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
369 // if disconnecting a wired headset, we check the following by order of priority
370 // to request a routing change if necessary:
371 // 1: we are in call or the strategy phone is active on the hardware output:
372 // use device for strategy phone
373 // 2: the strategy sonification is active on the hardware output:
374 // use device for strategy sonification
375 // 3: the strategy media is active on the hardware output:
376 // use device for strategy media
377 // 4: the strategy DTMF is active on the hardware output:
378 // use device for strategy DTMF
379 if (wasUsedforPhone &&
380 (mPhoneState == AudioSystem::MODE_IN_CALL ||
381 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_PHONE))) {
382 newDevice = getDeviceForStrategy(STRATEGY_PHONE);
383 } else if (wasUsedForSonification &&
384 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_SONIFICATION)){
385 newDevice = getDeviceForStrategy(STRATEGY_SONIFICATION);
386 } else if (wasUsedForMedia &&
387 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_MEDIA)){
388 newDevice = getDeviceForStrategy(STRATEGY_MEDIA);
389 } else if (wasUsedforDtmf &&
390 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_DTMF)){
391 newDevice = getDeviceForStrategy(STRATEGY_DTMF);
393 } else if (device == AudioSystem::DEVICE_OUT_TTY) {
394 LOGV("setDeviceConnectionState() tty device");
395 if (wasUsedforPhone &&
396 (mPhoneState == AudioSystem::MODE_IN_CALL ||
397 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_PHONE))) {
398 newDevice = getDeviceForStrategy(STRATEGY_PHONE);
400 } else if (device == AudioSystem::DEVICE_OUT_FM_SPEAKER ||
401 device == AudioSystem::DEVICE_OUT_FM_HEADPHONE) {
402 LOGV("setDeviceConnectionState() no mic headphone device");
403 if (wasUsedForSonification &&
404 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_SONIFICATION)){
405 newDevice = getDeviceForStrategy(STRATEGY_SONIFICATION);
406 } else if (wasUsedForMedia &&
407 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_MEDIA)){
408 newDevice = getDeviceForStrategy(STRATEGY_MEDIA);
412 // request routing change if necessary
413 setOutputDevice(mHardwareOutput, newDevice);
415 // clear A2DP and SCO device address if necessary
417 if (AudioSystem::isA2dpDevice(device)) {
418 mA2dpDeviceAddress = "";
421 if (AudioSystem::isBluetoothScoDevice(device)) {
422 mScoDeviceAddress = "";
427 LOGE("setDeviceConnectionState() invalid state: %x", state);
431 if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) {
432 device = AudioSystem::DEVICE_IN_WIRED_HEADSET;
433 } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO ||
434 device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
435 device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
436 device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
441 // handle input devices
442 if (AudioSystem::isInputDevice(device)) {
446 // handle input device connection
447 case AudioSystem::DEVICE_STATE_AVAILABLE: {
448 if (mAvailableInputDevices & device) {
449 LOGW("setDeviceConnectionState() device already connected: %d", device);
450 return INVALID_OPERATION;
452 mAvailableInputDevices |= device;
456 // handle input device disconnection
457 case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
458 if (!(mAvailableInputDevices & device)) {
459 LOGW("setDeviceConnectionState() device not connected: %d", device);
460 return INVALID_OPERATION;
462 mAvailableInputDevices &= ~device;
466 LOGE("setDeviceConnectionState() invalid state: %x", state);
470 audio_io_handle_t activeInput = getActiveInput();
471 if (activeInput != 0) {
472 AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
473 uint32_t newDevice = getDeviceForInputSource(inputDesc->mInputSource);
474 if (newDevice != inputDesc->mDevice) {
475 LOGV("setDeviceConnectionState() changing device from %x to %x for input %d",
476 inputDesc->mDevice, newDevice, activeInput);
477 inputDesc->mDevice = newDevice;
478 AudioParameter param = AudioParameter();
479 param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
480 mpClientInterface->setParameters(activeInput, param.toString());
487 LOGW("setDeviceConnectionState() invalid device: %x", device);
491 AudioSystem::device_connection_state AudioPolicyManagerALSA::getDeviceConnectionState(AudioSystem::audio_devices device,
492 const char *device_address)
494 AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE;
495 String8 address = String8(device_address);
496 if (AudioSystem::isOutputDevice(device)) {
497 if (device & mAvailableOutputDevices) {
499 if (AudioSystem::isA2dpDevice(device) &&
500 address != "" && mA2dpDeviceAddress != address) {
504 if (AudioSystem::isBluetoothScoDevice(device) &&
505 address != "" && mScoDeviceAddress != address) {
508 state = AudioSystem::DEVICE_STATE_AVAILABLE;
510 } else if (AudioSystem::isInputDevice(device)) {
511 if (device & mAvailableInputDevices) {
512 state = AudioSystem::DEVICE_STATE_AVAILABLE;
519 void AudioPolicyManagerALSA::setPhoneState(int state)
521 LOGV("setPhoneState() state %d", state);
522 uint32_t newDevice = 0;
523 if (state < 0 || state >= AudioSystem::NUM_MODES) {
524 LOGW("setPhoneState() invalid state %d", state);
528 if (state == mPhoneState ) {
529 LOGW("setPhoneState() setting same state %d", state);
533 // if leaving call state, handle special case of active streams
534 // pertaining to sonification strategy see handleIncallSonification()
535 if (mPhoneState == AudioSystem::MODE_IN_CALL) {
536 LOGV("setPhoneState() in call state management: new state is %d", state);
537 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
538 handleIncallSonification(stream, false, true);
542 // store previous phone state for management of sonification strategy below
543 int oldState = mPhoneState;
544 uint32_t oldDtmfDevice = getDeviceForStrategy(STRATEGY_DTMF);
545 uint32_t oldSonificationDevice = getDeviceForStrategy(STRATEGY_SONIFICATION) & ~AudioSystem::DEVICE_OUT_SPEAKER;
548 // check if a routing change is required for hardware output in the following
549 // order of priority:
550 // 1: a stream pertaining to sonification strategy is active
551 // 2: new state is incall
552 // 3: a stream pertaining to media strategy is active
553 // 4: a stream pertaining to DTMF strategy is active
554 if (mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_SONIFICATION)) {
555 newDevice = getDeviceForStrategy(STRATEGY_SONIFICATION);
556 } else if (mPhoneState == AudioSystem::MODE_IN_CALL) {
557 newDevice = getDeviceForStrategy(STRATEGY_PHONE);
558 // force routing command to audio hardware when starting call
559 // even if no device change is needed
561 } else if (mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_MEDIA)) {
562 newDevice = getDeviceForStrategy(STRATEGY_MEDIA);
563 } else if (mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_DTMF)) {
564 newDevice = getDeviceForStrategy(STRATEGY_DTMF);
568 if (mA2dpOutput != 0) {
569 // If entering or exiting in call state, switch DTMF streams to/from A2DP output
571 uint32_t newDtmfDevice = getDeviceForStrategy(STRATEGY_DTMF);
572 uint32_t newSonificationDevice = getDeviceForStrategy(STRATEGY_SONIFICATION) & ~AudioSystem::DEVICE_OUT_SPEAKER;
573 if (state == AudioSystem::MODE_IN_CALL) { // entering in call mode
574 // move DTMF streams from A2DP output to hardware output if necessary
575 if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)oldDtmfDevice) &&
576 !AudioSystem::isA2dpDevice((AudioSystem::audio_devices)newDtmfDevice)) {
577 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
578 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_DTMF) {
579 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mHardwareOutput);
580 int refCount = mOutputs.valueFor(mA2dpOutput)->mRefCount[i];
581 mOutputs.valueFor(mHardwareOutput)->changeRefCount((AudioSystem::stream_type)i,
583 mOutputs.valueFor(mA2dpOutput)->changeRefCount((AudioSystem::stream_type)i,-refCount);
586 if (newDevice == 0 && mOutputs.valueFor(mA2dpOutput)->isUsedByStrategy(STRATEGY_DTMF)) {
587 newDevice = newDtmfDevice;
590 // move SONIFICATION streams from duplicated output to hardware output if necessary
591 if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)oldSonificationDevice) &&
592 !AudioSystem::isA2dpDevice((AudioSystem::audio_devices)newSonificationDevice)) {
593 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
594 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_SONIFICATION) {
595 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mHardwareOutput);
596 int refCount = mOutputs.valueFor(mDuplicatedOutput)->mRefCount[i];
597 mOutputs.valueFor(mHardwareOutput)->changeRefCount((AudioSystem::stream_type)i,
599 mOutputs.valueFor(mDuplicatedOutput)->changeRefCount((AudioSystem::stream_type)i,-refCount);
603 } else { // exiting in call mode
604 // move DTMF streams from hardware output to A2DP output if necessary
605 if (!AudioSystem::isA2dpDevice((AudioSystem::audio_devices)oldDtmfDevice) &&
606 AudioSystem::isA2dpDevice((AudioSystem::audio_devices)newDtmfDevice)) {
607 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
608 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_DTMF) {
609 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mA2dpOutput);
610 int refCount = mOutputs.valueFor(mHardwareOutput)->mRefCount[i];
611 mOutputs.valueFor(mA2dpOutput)->changeRefCount((AudioSystem::stream_type)i, refCount);
612 mOutputs.valueFor(mHardwareOutput)->changeRefCount((AudioSystem::stream_type)i, -refCount);
616 // move SONIFICATION streams from hardware output to A2DP output if necessary
617 if (!AudioSystem::isA2dpDevice((AudioSystem::audio_devices)oldSonificationDevice) &&
618 AudioSystem::isA2dpDevice((AudioSystem::audio_devices)newSonificationDevice)) {
619 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
620 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_SONIFICATION) {
621 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mDuplicatedOutput);
622 int refCount = mOutputs.valueFor(mHardwareOutput)->mRefCount[i];
623 mOutputs.valueFor(mDuplicatedOutput)->changeRefCount((AudioSystem::stream_type)i, refCount);
624 mOutputs.valueFor(mHardwareOutput)->changeRefCount((AudioSystem::stream_type)i, -refCount);
629 // suspend A2DP output if SCO device address is the same as A2DP device address.
630 // no need to check that a SCO device is actually connected as mScoDeviceAddress == ""
631 // if none is connected and the test below will fail.
632 if (mA2dpDeviceAddress == mScoDeviceAddress) {
633 if (oldState == AudioSystem::MODE_NORMAL) {
634 mpClientInterface->suspendOutput(mA2dpOutput);
635 } else if (state == AudioSystem::MODE_NORMAL) {
636 mpClientInterface->restoreOutput(mA2dpOutput);
641 // force routing command to audio hardware when ending call
642 // even if no device change is needed
643 if (oldState == AudioSystem::MODE_IN_CALL) {
644 if (newDevice == 0) {
645 newDevice = mOutputs.valueFor(mHardwareOutput)->device();
649 // change routing is necessary
650 setOutputDevice(mHardwareOutput, newDevice, force);
652 // if entering in call state, handle special case of active streams
653 // pertaining to sonification strategy see handleIncallSonification()
654 if (state == AudioSystem::MODE_IN_CALL) {
655 LOGV("setPhoneState() in call state management: new state is %d", state);
656 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
657 handleIncallSonification(stream, true, true);
662 void AudioPolicyManagerALSA::setRingerMode(uint32_t mode, uint32_t mask)
664 LOGV("setRingerMode() mode %x, mask %x", mode, mask);
669 void AudioPolicyManagerALSA::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
671 LOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
674 case AudioSystem::FOR_COMMUNICATION:
675 if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO &&
676 config != AudioSystem::FORCE_NONE) {
677 LOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
680 mForceUse[usage] = config;
681 // update hardware output routing immediately if in call, or if there is an active
682 // VOICE_CALL stream, as would be the case with an application that uses this stream
683 // for it to behave like in a telephony app (e.g. voicemail app that plays audio files
684 // streamed or downloaded to the device)
685 if ((mPhoneState == AudioSystem::MODE_IN_CALL) ||
686 (mOutputs.valueFor(mHardwareOutput)->isUsedByStream(AudioSystem::VOICE_CALL))) {
687 uint32_t device = getDeviceForStrategy(STRATEGY_PHONE);
688 setOutputDevice(mHardwareOutput, device);
691 case AudioSystem::FOR_MEDIA:
692 if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP &&
693 config != AudioSystem::FORCE_WIRED_ACCESSORY && config != AudioSystem::FORCE_NONE) {
694 LOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
697 mForceUse[usage] = config;
699 case AudioSystem::FOR_RECORD:
700 if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY &&
701 config != AudioSystem::FORCE_NONE) {
702 LOGW("setForceUse() invalid config %d for FOR_RECORD", config);
705 mForceUse[usage] = config;
708 LOGW("setForceUse() invalid usage %d", usage);
713 AudioSystem::forced_config AudioPolicyManagerALSA::getForceUse(AudioSystem::force_use usage)
715 return mForceUse[usage];
718 void AudioPolicyManagerALSA::setSystemProperty(const char* property, const char* value)
720 LOGV("setSystemProperty() property %s, value %s", property, value);
721 if (strcmp(property, "ro.camera.sound.forced") == 0) {
723 LOGV("ENFORCED_AUDIBLE cannot be muted");
724 mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = false;
726 LOGV("ENFORCED_AUDIBLE can be muted");
727 mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = true;
732 audio_io_handle_t AudioPolicyManagerALSA::getOutput(AudioSystem::stream_type stream,
733 uint32_t samplingRate,
736 AudioSystem::output_flags flags)
738 audio_io_handle_t output = 0;
739 uint32_t latency = 0;
740 routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
741 uint32_t device = getDeviceForStrategy(strategy);
742 LOGV("getOutput() stream %d, samplingRate %d, format %d, channels %x, flags %x", stream, samplingRate, format, channels, flags);
745 // open a direct output if:
746 // 1 a direct output is explicitely requested
747 // 2 the audio format is compressed
748 if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
749 (format !=0 && !AudioSystem::isLinearPCM(format))) {
751 LOGV("getOutput() opening direct output device %x", device);
752 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
753 outputDesc->mDevice = device;
754 outputDesc->mSamplingRate = samplingRate;
755 outputDesc->mFormat = format;
756 outputDesc->mChannels = channels;
757 outputDesc->mLatency = 0;
758 outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT);
759 outputDesc->mRefCount[stream] = 1;
760 output = mpClientInterface->openOutput(&outputDesc->mDevice,
761 &outputDesc->mSamplingRate,
762 &outputDesc->mFormat,
763 &outputDesc->mChannels,
764 &outputDesc->mLatency,
767 // only accept an output with the requeted parameters
768 if ((samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
769 (format != 0 && format != outputDesc->mFormat) ||
770 (channels != 0 && channels != outputDesc->mChannels)) {
771 LOGV("getOutput() failed opening direct output: samplingRate %d, format %d, channels %d",
772 samplingRate, format, channels);
773 mpClientInterface->closeOutput(output);
777 mOutputs.add(output, outputDesc);
781 if (channels != 0 && channels != AudioSystem::CHANNEL_OUT_MONO &&
782 channels != AudioSystem::CHANNEL_OUT_STEREO) {
785 // open a non direct output
787 // get which output is suitable for the specified stream. The actual routing change will happen
788 // when startOutput() will be called
789 uint32_t device2 = device & ~AudioSystem::DEVICE_OUT_SPEAKER;
790 if (AudioSystem::popCount((AudioSystem::audio_devices)device) == 2) {
792 if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device2)) {
793 // if playing on 2 devices among which one is A2DP, use duplicated output
794 LOGV("getOutput() using duplicated output");
795 LOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device in multiple %x selected but A2DP output not opened", device);
796 output = mDuplicatedOutput;
800 // if playing on 2 devices among which none is A2DP, use hardware output
801 output = mHardwareOutput;
803 LOGV("getOutput() using output %d for 2 devices %x", output, device);
806 if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device2)) {
807 // if playing on A2DP device, use a2dp output
808 LOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device %x selected but A2DP output not opened", device);
809 output = mA2dpOutput;
813 // if playing on not A2DP device, use hardware output
814 output = mHardwareOutput;
819 LOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d, format %d, channels %x, flags %x",
820 stream, samplingRate, format, channels, flags);
825 status_t AudioPolicyManagerALSA::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
827 LOGV("startOutput() output %d, stream %d", output, stream);
828 ssize_t index = mOutputs.indexOfKey(output);
830 LOGW("startOutput() unknow output %d", output);
834 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
835 routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
836 uint32_t device = getDeviceForStrategy(strategy);
838 if (!outputDesc->isUsedByStrategy(strategy)) {
839 // if the stream started is the first active stream in its strategy, check if routing change
840 // must be done on hardware output
841 uint32_t newDevice = 0;
842 if (AudioSystem::popCount((AudioSystem::audio_devices)device) == 2) {
844 uint32_t device2 = device & ~AudioSystem::DEVICE_OUT_SPEAKER;
845 if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device2)) {
846 // if one device is A2DP, selected the second device for hardware output
851 // we only support speaker + headset and speaker + headphone combinations on hardware output.
852 // other combinations will leave device = 0 and no routing will happen.
853 if (device != (AudioSystem::DEVICE_OUT_SPEAKER | AudioSystem::DEVICE_OUT_WIRED_HEADSET) &&
854 device != (AudioSystem::DEVICE_OUT_SPEAKER | AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
855 device = AudioSystem::DEVICE_OUT_SPEAKER;
860 // By order of priority
861 // 1 apply routing for phone strategy in any case
862 // 2 apply routing for notification strategy if no stream pertaining to
863 // phone strategies is playing
864 // 3 apply routing for media strategy is not incall and neither phone nor sonification
865 // strategies is active.
866 // 4 apply routing for DTMF strategy if no stream pertaining to
867 // neither phone, sonification nor media strategy is playing
868 if (strategy == STRATEGY_PHONE) {
870 } else if (!mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_PHONE)) {
871 if (strategy == STRATEGY_SONIFICATION) {
873 } else if (!mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_SONIFICATION)) {
874 if (strategy == STRATEGY_MEDIA) {
876 } else if (!mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_MEDIA)) {
877 // strategy == STRATEGY_DTMF
883 // TODO: maybe mute stream is selected device was refused
884 setOutputDevice(mHardwareOutput, newDevice);
887 // incremenent usage count for this stream on the requested output:
888 // NOTE that the usage count is the same for duplicated output and hardware output which is
889 // necassary for a correct control of hardware output routing by startOutput() and stopOutput()
890 outputDesc->changeRefCount(stream, 1);
892 // handle special case for sonification while in call
893 if (mPhoneState == AudioSystem::MODE_IN_CALL) {
894 handleIncallSonification(stream, true, false);
897 // apply volume rules for current stream and device if necessary
898 checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, outputDesc->device());
903 status_t AudioPolicyManagerALSA::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
905 LOGV("stopOutput() output %d, stream %d", output, stream);
906 ssize_t index = mOutputs.indexOfKey(output);
908 LOGW("stopOutput() unknow output %d", output);
912 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
913 routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
915 // handle special case for sonification while in call
916 if (mPhoneState == AudioSystem::MODE_IN_CALL) {
917 handleIncallSonification(stream, false, false);
920 if (outputDesc->isUsedByStrategy(strategy)) {
921 // decrement usage count of this stream on the output
922 outputDesc->changeRefCount(stream, -1);
923 if (!outputDesc->isUsedByStrategy(strategy)) {
924 // if the stream is the last of its strategy to use this output, change routing
925 // in the following order or priority:
926 // PHONE > SONIFICATION > MEDIA > DTMF
927 uint32_t newDevice = 0;
928 if (outputDesc->isUsedByStrategy(STRATEGY_PHONE)) {
929 newDevice = getDeviceForStrategy(STRATEGY_PHONE);
930 } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) {
931 newDevice = getDeviceForStrategy(STRATEGY_SONIFICATION);
932 } else if (mPhoneState == AudioSystem::MODE_IN_CALL) {
933 newDevice = getDeviceForStrategy(STRATEGY_PHONE);
934 } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) {
935 newDevice = getDeviceForStrategy(STRATEGY_MEDIA);
936 } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) {
937 newDevice = getDeviceForStrategy(STRATEGY_DTMF);
940 // apply routing change if necessary.
941 // insert a delay of 2 times the audio hardware latency to ensure PCM
942 // buffers in audio flinger and audio hardware are emptied before the
943 // routing change is executed.
944 setOutputDevice(mHardwareOutput, newDevice, false, mOutputs.valueFor(mHardwareOutput)->mLatency*2);
946 // store time at which the last music track was stopped - see computeVolume()
947 if (stream == AudioSystem::MUSIC) {
948 mMusicStopTime = systemTime();
952 LOGW("stopOutput() refcount is already 0 for output %d", output);
953 return INVALID_OPERATION;
957 void AudioPolicyManagerALSA::releaseOutput(audio_io_handle_t output)
959 LOGV("releaseOutput() %d", output);
960 ssize_t index = mOutputs.indexOfKey(output);
962 LOGW("releaseOutput() releasing unknown output %d", output);
965 if (mOutputs.valueAt(index)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) {
966 mpClientInterface->closeOutput(output);
967 delete mOutputs.valueAt(index);
968 mOutputs.removeItem(output);
972 audio_io_handle_t AudioPolicyManagerALSA::getInput(int inputSource,
973 uint32_t samplingRate,
976 AudioSystem::audio_in_acoustics acoustics)
978 audio_io_handle_t input = 0;
979 uint32_t device = getDeviceForInputSource(inputSource);
981 LOGV("getInput() inputSource %d, samplingRate %d, format %d, channels %x, acoustics %x", inputSource, samplingRate, format, channels, acoustics);
987 // adapt channel selection to input source
988 switch(inputSource) {
989 case AUDIO_SOURCE_VOICE_UPLINK:
990 channels = AudioSystem::CHANNEL_IN_VOICE_UPLINK;
992 case AUDIO_SOURCE_VOICE_DOWNLINK:
993 channels = AudioSystem::CHANNEL_IN_VOICE_DNLINK;
995 case AUDIO_SOURCE_VOICE_CALL:
996 channels = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK);
1002 AudioInputDescriptor *inputDesc = new AudioInputDescriptor();
1004 inputDesc->mInputSource = inputSource;
1005 inputDesc->mDevice = device;
1006 inputDesc->mSamplingRate = samplingRate;
1007 inputDesc->mFormat = format;
1008 inputDesc->mChannels = channels;
1009 inputDesc->mAcoustics = acoustics;
1010 inputDesc->mRefCount = 0;
1011 input = mpClientInterface->openInput(&inputDesc->mDevice,
1012 &inputDesc->mSamplingRate,
1013 &inputDesc->mFormat,
1014 &inputDesc->mChannels,
1015 inputDesc->mAcoustics);
1017 // only accept input with the exact requested set of parameters
1018 if ((samplingRate != inputDesc->mSamplingRate) ||
1019 (format != inputDesc->mFormat) ||
1020 (channels != inputDesc->mChannels)) {
1021 LOGV("getOutput() failed opening input: samplingRate %d, format %d, channels %d",
1022 samplingRate, format, channels);
1023 mpClientInterface->closeInput(input);
1027 mInputs.add(input, inputDesc);
1031 status_t AudioPolicyManagerALSA::startInput(audio_io_handle_t input)
1033 LOGV("startInput() input %d", input);
1034 ssize_t index = mInputs.indexOfKey(input);
1036 LOGW("startInput() unknow input %d", input);
1039 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
1041 // refuse 2 active AudioRecord clients at the same time
1042 if (getActiveInput() != 0) {
1043 LOGW("startInput() input %d failed: other input already started", input);
1044 return INVALID_OPERATION;
1047 AudioParameter param = AudioParameter();
1048 param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
1049 mpClientInterface->setParameters(input, param.toString());
1051 inputDesc->mRefCount = 1;
1055 status_t AudioPolicyManagerALSA::stopInput(audio_io_handle_t input)
1057 LOGV("stopInput() input %d", input);
1058 ssize_t index = mInputs.indexOfKey(input);
1060 LOGW("stopInput() unknow input %d", input);
1063 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
1065 if (inputDesc->mRefCount == 0) {
1066 LOGW("stopInput() input %d already stopped", input);
1067 return INVALID_OPERATION;
1069 AudioParameter param = AudioParameter();
1070 param.addInt(String8(AudioParameter::keyRouting), 0);
1071 mpClientInterface->setParameters(input, param.toString());
1072 inputDesc->mRefCount = 0;
1077 void AudioPolicyManagerALSA::releaseInput(audio_io_handle_t input)
1079 LOGV("releaseInput() %d", input);
1080 ssize_t index = mInputs.indexOfKey(input);
1082 LOGW("releaseInput() releasing unknown input %d", input);
1085 mpClientInterface->closeInput(input);
1086 delete mInputs.valueAt(index);
1087 mInputs.removeItem(input);
1088 LOGV("releaseInput() exit");
1093 void AudioPolicyManagerALSA::initStreamVolume(AudioSystem::stream_type stream,
1097 LOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
1098 if (indexMin < 0 || indexMin >= indexMax) {
1099 LOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax);
1102 mStreams[stream].mIndexMin = indexMin;
1103 mStreams[stream].mIndexMax = indexMax;
1106 status_t AudioPolicyManagerALSA::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
1109 if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
1113 LOGV("setStreamVolumeIndex() stream %d, index %d", stream, index);
1114 mStreams[stream].mIndexCur = index;
1116 // compute and apply stream volume on all outputs according to connected device
1117 status_t status = NO_ERROR;
1118 for (size_t i = 0; i < mOutputs.size(); i++) {
1119 status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), mOutputs.valueAt(i)->device());
1120 if (volStatus != NO_ERROR) {
1127 status_t AudioPolicyManagerALSA::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
1132 LOGV("getStreamVolumeIndex() stream %d", stream);
1133 *index = mStreams[stream].mIndexCur;
1137 status_t AudioPolicyManagerALSA::dump(int fd)
1139 const size_t SIZE = 256;
1143 snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
1144 result.append(buffer);
1145 snprintf(buffer, SIZE, " Hardware Output: %d\n", mHardwareOutput);
1146 result.append(buffer);
1147 snprintf(buffer, SIZE, " A2DP Output: %d\n", mA2dpOutput);
1148 result.append(buffer);
1149 snprintf(buffer, SIZE, " Duplicated Output: %d\n", mDuplicatedOutput);
1150 result.append(buffer);
1151 snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices);
1152 result.append(buffer);
1153 snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices);
1154 result.append(buffer);
1155 snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string());
1156 result.append(buffer);
1157 snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string());
1158 result.append(buffer);
1159 snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
1160 result.append(buffer);
1161 snprintf(buffer, SIZE, " Ringer mode: %d\n", mRingerMode);
1162 result.append(buffer);
1163 snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]);
1164 result.append(buffer);
1165 snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]);
1166 result.append(buffer);
1167 snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]);
1168 result.append(buffer);
1169 write(fd, result.string(), result.size());
1171 snprintf(buffer, SIZE, "\nOutputs dump:\n");
1172 write(fd, buffer, strlen(buffer));
1173 for (size_t i = 0; i < mOutputs.size(); i++) {
1174 snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
1175 write(fd, buffer, strlen(buffer));
1176 mOutputs.valueAt(i)->dump(fd);
1179 snprintf(buffer, SIZE, "\nInputs dump:\n");
1180 write(fd, buffer, strlen(buffer));
1181 for (size_t i = 0; i < mInputs.size(); i++) {
1182 snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
1183 write(fd, buffer, strlen(buffer));
1184 mInputs.valueAt(i)->dump(fd);
1187 snprintf(buffer, SIZE, "\nStreams dump:\n");
1188 write(fd, buffer, strlen(buffer));
1189 snprintf(buffer, SIZE, " Stream Index Min Index Max Index Cur Mute Count Can be muted\n");
1190 write(fd, buffer, strlen(buffer));
1191 for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
1192 snprintf(buffer, SIZE, " %02d", i);
1193 mStreams[i].dump(buffer + 3, SIZE);
1194 write(fd, buffer, strlen(buffer));
1200 // ----------------------------------------------------------------------------
1201 // AudioPolicyManagerALSA
1202 // ----------------------------------------------------------------------------
1204 // --- class factory
1207 extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
1209 return new AudioPolicyManagerALSA(clientInterface);
1212 extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
1217 AudioPolicyManagerALSA::AudioPolicyManagerALSA(AudioPolicyClientInterface *clientInterface)
1218 : mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0), mMusicStopTime(0)
1220 mpClientInterface = clientInterface;
1222 for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {
1223 mForceUse[i] = AudioSystem::FORCE_NONE;
1226 // devices available by default are speaker, ear piece and microphone
1227 mAvailableOutputDevices = AudioSystem::DEVICE_OUT_EARPIECE |
1228 AudioSystem::DEVICE_OUT_SPEAKER;
1229 mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC;
1231 mA2dpDeviceAddress = String8("");
1232 mScoDeviceAddress = String8("");
1234 // open hardware output
1235 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
1236 outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
1237 mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
1238 &outputDesc->mSamplingRate,
1239 &outputDesc->mFormat,
1240 &outputDesc->mChannels,
1241 &outputDesc->mLatency,
1242 outputDesc->mFlags);
1244 if (mHardwareOutput == 0) {
1245 LOGE("Failed to initialize hardware output stream, samplingRate: %d, format %d, channels %d",
1246 outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
1248 mOutputs.add(mHardwareOutput, outputDesc);
1249 setOutputDevice(mHardwareOutput, (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER, true);
1253 mDuplicatedOutput = 0;
1256 AudioPolicyManagerALSA::~AudioPolicyManagerALSA()
1258 for (size_t i = 0; i < mOutputs.size(); i++) {
1259 mpClientInterface->closeOutput(mOutputs.keyAt(i));
1260 delete mOutputs.valueAt(i);
1263 for (size_t i = 0; i < mInputs.size(); i++) {
1264 mpClientInterface->closeInput(mInputs.keyAt(i));
1265 delete mInputs.valueAt(i);
1272 audio_io_handle_t AudioPolicyManagerALSA::getOutputForDevice(uint32_t device)
1274 audio_io_handle_t output = 0;
1277 for (size_t i = 0; i < mOutputs.size(); i++) {
1278 lDevice = mOutputs.valueAt(i)->device();
1279 LOGV("getOutputForDevice() output %d devices %x", mOutputs.keyAt(i), lDevice);
1281 // We are only considering outputs connected to a mixer here => exclude direct outputs
1282 if ((lDevice == device) &&
1283 !(mOutputs.valueAt(i)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT)) {
1284 output = mOutputs.keyAt(i);
1285 LOGV("getOutputForDevice() found output %d for device %x", output, device);
1292 AudioPolicyManagerALSA::routing_strategy AudioPolicyManagerALSA::getStrategy(AudioSystem::stream_type stream)
1294 // stream to strategy mapping
1296 case AudioSystem::VOICE_CALL:
1297 case AudioSystem::BLUETOOTH_SCO:
1298 return STRATEGY_PHONE;
1299 case AudioSystem::RING:
1300 case AudioSystem::NOTIFICATION:
1301 case AudioSystem::ALARM:
1302 case AudioSystem::ENFORCED_AUDIBLE:
1303 return STRATEGY_SONIFICATION;
1304 case AudioSystem::DTMF:
1305 return STRATEGY_DTMF;
1307 LOGE("unknown stream type");
1308 case AudioSystem::SYSTEM:
1309 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
1310 // while key clicks are played produces a poor result
1311 case AudioSystem::TTS:
1312 case AudioSystem::MUSIC:
1313 return STRATEGY_MEDIA;
1317 uint32_t AudioPolicyManagerALSA::getDeviceForStrategy(routing_strategy strategy)
1319 uint32_t device = 0;
1323 if (mPhoneState != AudioSystem::MODE_IN_CALL) {
1324 // when off call, DTMF strategy follows the same rules as MEDIA strategy
1325 device = getDeviceForStrategy(STRATEGY_MEDIA);
1328 // when in call, DTMF and PHONE strategies follow the same rules
1331 case STRATEGY_PHONE:
1332 // for phone strategy, we first consider the forced use and then the available devices by order
1334 switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
1335 case AudioSystem::FORCE_BT_SCO:
1336 if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
1337 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
1340 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
1342 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
1344 // if SCO device is requested but no SCO device is available, fall back to default case
1347 default: // FORCE_NONE
1348 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_TTY;
1350 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
1352 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
1354 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
1356 LOGE("getDeviceForStrategy() earpiece device not found");
1360 case AudioSystem::FORCE_SPEAKER:
1361 if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
1362 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
1365 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_FM_SPEAKER;
1367 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
1369 LOGE("getDeviceForStrategy() speaker device not found");
1375 case STRATEGY_SONIFICATION:
1377 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
1378 // handleIncallSonification().
1379 if (mPhoneState == AudioSystem::MODE_IN_CALL) {
1380 device = getDeviceForStrategy(STRATEGY_PHONE);
1383 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
1385 LOGE("getDeviceForStrategy() speaker device not found");
1387 // The second device used for sonification is the same as the device used by media strategy
1390 case STRATEGY_MEDIA: {
1391 uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
1393 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
1395 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
1397 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
1399 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_FM_HEADPHONE;
1401 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_FM_SPEAKER;
1403 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
1405 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
1407 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
1409 LOGE("getDeviceForStrategy() speaker device not found");
1419 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION, 0 otherwise
1421 // Do not play media stream if in call and the requested device would change the hardware
1423 if (mPhoneState == AudioSystem::MODE_IN_CALL &&
1424 !AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device) &&
1425 device != getDeviceForStrategy(STRATEGY_PHONE)) {
1427 LOGV("getDeviceForStrategy() incompatible media and phone devices");
1432 LOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
1436 LOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
1440 void AudioPolicyManagerALSA::setOutputDevice(audio_io_handle_t output, uint32_t device, bool force, int delayMs)
1442 LOGV("setOutputDevice() output %d device %x delayMs %d", output, device, delayMs);
1443 if (mOutputs.indexOfKey(output) < 0) {
1444 LOGW("setOutputDevice() unknown output %d", output);
1448 if (output == mHardwareOutput) {
1449 // clear A2DP devices from device bit field here so that the caller does not have to
1450 // do it in case of multiple device selections
1451 uint32_t device2 = device & ~AudioSystem::DEVICE_OUT_SPEAKER;
1452 if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device2)) {
1453 LOGV("setOutputDevice() removing A2DP device");
1456 } else if (output == mA2dpOutput) {
1457 // clear hardware devices from device bit field here so that the caller does not have to
1458 // do it in case of multiple device selections (the second device is always DEVICE_OUT_SPEAKER)
1460 device &= ~AudioSystem::DEVICE_OUT_SPEAKER;
1464 // doing this check here allows the caller to call setOutputDevice() without conditions
1465 if (device == 0) return;
1467 uint32_t oldDevice = (uint32_t)mOutputs.valueFor(output)->device();
1468 // Do not change the routing if the requested device is the same as current device. Doing this check
1469 // here allows the caller to call setOutputDevice() without conditions
1470 if (device == oldDevice && !force) {
1471 LOGV("setOutputDevice() setting same device %x for output %d", device, output);
1475 mOutputs.valueFor(output)->mDevice = device;
1476 // mute media streams if both speaker and headset are selected
1477 if (device == (AudioSystem::DEVICE_OUT_SPEAKER | AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1478 device == (AudioSystem::DEVICE_OUT_SPEAKER | AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
1479 setStrategyMute(STRATEGY_MEDIA, true, output);
1480 // wait for the PCM output buffers to empty before proceeding with the rest of the command
1481 usleep(mOutputs.valueFor(output)->mLatency*2*1000);
1483 // suspend A2D output if SCO device is selected
1484 if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)device)) {
1485 if (mA2dpOutput && mScoDeviceAddress == mA2dpDeviceAddress) {
1486 mpClientInterface->suspendOutput(mA2dpOutput);
1490 AudioParameter param = AudioParameter();
1491 param.addInt(String8(AudioParameter::keyRouting), (int)device);
1492 mpClientInterface->setParameters(mHardwareOutput, param.toString(), delayMs);
1493 // update stream volumes according to new device
1494 applyStreamVolumes(output, device, delayMs);
1496 // if disconnecting SCO device, restore A2DP output
1497 if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)oldDevice)) {
1498 if (mA2dpOutput && mScoDeviceAddress == mA2dpDeviceAddress) {
1499 LOGV("restore A2DP output");
1500 mpClientInterface->restoreOutput(mA2dpOutput);
1503 // if changing from a combined headset + speaker route, unmute media streams
1504 if (oldDevice == (AudioSystem::DEVICE_OUT_SPEAKER | AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1505 oldDevice == (AudioSystem::DEVICE_OUT_SPEAKER | AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
1506 setStrategyMute(STRATEGY_MEDIA, false, output, delayMs);
1510 uint32_t AudioPolicyManagerALSA::getDeviceForInputSource(int inputSource)
1514 switch(inputSource) {
1515 case AUDIO_SOURCE_DEFAULT:
1516 case AUDIO_SOURCE_MIC:
1517 case AUDIO_SOURCE_VOICE_RECOGNITION:
1518 if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO &&
1519 mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
1520 device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
1521 } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
1522 device = AudioSystem::DEVICE_IN_WIRED_HEADSET;
1524 device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
1527 case AUDIO_SOURCE_CAMCORDER:
1528 device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
1530 case AUDIO_SOURCE_VOICE_UPLINK:
1531 case AUDIO_SOURCE_VOICE_DOWNLINK:
1532 case AUDIO_SOURCE_VOICE_CALL:
1533 device = AudioSystem::DEVICE_IN_VOICE_CALL;
1536 LOGW("getInput() invalid input source %d", inputSource);
1543 audio_io_handle_t AudioPolicyManagerALSA::getActiveInput()
1545 for (size_t i = 0; i < mInputs.size(); i++) {
1546 if (mInputs.valueAt(i)->mRefCount > 0) {
1547 return mInputs.keyAt(i);
1553 float AudioPolicyManagerALSA::computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device)
1556 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
1557 StreamDescriptor &streamDesc = mStreams[stream];
1559 // Force max volume if stream cannot be muted
1560 if (!streamDesc.mCanBeMuted) index = streamDesc.mIndexMax;
1563 device = outputDesc->device();
1566 int volInt = (100 * (index - streamDesc.mIndexMin)) / (streamDesc.mIndexMax - streamDesc.mIndexMin);
1567 volume = AudioSystem::linearToLog(volInt);
1569 // if a heaset is connected, apply the following rules to ring tones and notifications
1570 // to avoid sound level bursts in user's ears:
1571 // - always attenuate ring tones and notifications volume by 6dB
1572 // - if music is playing, always limit the volume to current music volume,
1573 // with a minimum threshold at -36dB so that notification is always perceived.
1575 (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP |
1576 AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
1577 AudioSystem::DEVICE_OUT_WIRED_HEADSET |
1578 AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) &&
1579 (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION)) {
1580 volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
1581 // when the phone is ringing we must consider that music could have been paused just before
1582 // by the music application and behave as if music was active if the last music track was
1584 if (outputDesc->isUsedByStream(AudioSystem::MUSIC) ||
1585 ((mPhoneState == AudioSystem::MODE_RINGTONE) &&
1586 (systemTime() - mMusicStopTime < seconds(SONIFICATION_HEADSET_MUSIC_DELAY)))) {
1587 float musicVol = computeVolume(AudioSystem::MUSIC, mStreams[AudioSystem::MUSIC].mIndexCur, output, device);
1588 float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
1589 if (volume > minVol) {
1591 LOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
1599 status_t AudioPolicyManagerALSA::checkAndSetVolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayMs, bool force)
1602 // do not change actual stream volume if the stream is muted
1603 if (mStreams[stream].mMuteCount != 0) {
1604 LOGV("checkAndSetVolume() stream %d muted count %d", stream, mStreams[stream].mMuteCount);
1608 // do not change in call volume if bluetooth is connected and vice versa
1609 if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
1610 (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {
1611 LOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
1612 stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);
1613 return INVALID_OPERATION;
1616 float volume = computeVolume(stream, index, output, device || force);
1617 // do not set volume if the float value did not change
1618 if (volume != mOutputs.valueFor(output)->mCurVolume[stream]) {
1619 mOutputs.valueFor(output)->mCurVolume[stream] = volume;
1620 LOGV("setStreamVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
1621 if (stream == AudioSystem::VOICE_CALL ||
1622 stream == AudioSystem::DTMF ||
1623 stream == AudioSystem::BLUETOOTH_SCO) {
1624 float voiceVolume = -1.0;
1625 // offset value to reflect actual hardware volume that never reaches 0
1626 // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java)
1627 volume = 0.01 + 0.99 * volume;
1628 if (stream == AudioSystem::VOICE_CALL) {
1629 voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
1630 } else if (stream == AudioSystem::BLUETOOTH_SCO) {
1633 if (voiceVolume >= 0 && output == mHardwareOutput) {
1634 mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
1637 mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
1643 void AudioPolicyManagerALSA::applyStreamVolumes(audio_io_handle_t output, uint32_t device, int delayMs)
1645 LOGV("applyStreamVolumes() for output %d and device %x", output, device);
1647 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
1648 checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, device, delayMs);
1652 void AudioPolicyManagerALSA::setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output, int delayMs)
1654 LOGV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
1655 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
1656 if (getStrategy((AudioSystem::stream_type)stream) == strategy) {
1657 setStreamMute(stream, on, output, delayMs);
1662 void AudioPolicyManagerALSA::setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs)
1664 StreamDescriptor &streamDesc = mStreams[stream];
1665 uint32_t device = mOutputs.valueFor(output)->mDevice;
1667 LOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d", stream, on, output, streamDesc.mMuteCount);
1670 if (streamDesc.mMuteCount == 0) {
1671 if (streamDesc.mCanBeMuted) {
1672 checkAndSetVolume(stream, 0, output, device, delayMs);
1675 // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
1676 streamDesc.mMuteCount++;
1678 if (streamDesc.mMuteCount == 0) {
1679 LOGW("setStreamMute() unmuting non muted stream!");
1682 if (--streamDesc.mMuteCount == 0) {
1683 checkAndSetVolume(stream, streamDesc.mIndexCur, output, device, delayMs);
1688 void AudioPolicyManagerALSA::handleIncallSonification(int stream, bool starting, bool stateChange)
1690 // if the stream pertains to sonification strategy and we are in call we must
1691 // mute the stream if it is low visibility. If it is high visibility, we must play a tone
1692 // in the device used for phone strategy and play the tone if the selected device does not
1693 // interfere with the device used for phone strategy
1694 // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
1695 // many times as there are active tracks on the output
1697 if (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) {
1698 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mHardwareOutput);
1699 LOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
1700 stream, starting, outputDesc->mDevice, stateChange);
1701 if (outputDesc->isUsedByStream((AudioSystem::stream_type)stream)) {
1704 muteCount = outputDesc->mRefCount[stream];
1706 if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) {
1707 LOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
1708 for (int i = 0; i < muteCount; i++) {
1709 setStreamMute(stream, starting, mHardwareOutput);
1712 LOGV("handleIncallSonification() high visibility ");
1713 if (outputDesc->mDevice & getDeviceForStrategy(STRATEGY_PHONE)) {
1714 LOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
1715 for (int i = 0; i < muteCount; i++) {
1716 setStreamMute(stream, starting, mHardwareOutput);
1720 mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL);
1722 mpClientInterface->stopTone();
1730 // --- AudioOutputDescriptor class implementation
1732 AudioPolicyManagerALSA::AudioOutputDescriptor::AudioOutputDescriptor()
1733 : mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0),
1734 mFlags((AudioSystem::output_flags)0), mDevice(0), mOutput1(0), mOutput2(0)
1736 // clear usage count for all stream types
1737 for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
1739 mCurVolume[i] = -1.0;
1743 uint32_t AudioPolicyManagerALSA::AudioOutputDescriptor::device()
1745 uint32_t device = 0;
1746 if (isDuplicated()) {
1747 device = mOutput1->mDevice | mOutput2->mDevice;
1754 void AudioPolicyManagerALSA::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta)
1756 // forward usage count change to attached outputs
1757 if (isDuplicated()) {
1758 mOutput1->changeRefCount(stream, delta);
1759 mOutput2->changeRefCount(stream, delta);
1761 if ((delta + (int)mRefCount[stream]) < 0) {
1762 LOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]);
1763 mRefCount[stream] = 0;
1766 mRefCount[stream] += delta;
1767 LOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
1770 bool AudioPolicyManagerALSA::AudioOutputDescriptor::isUsedByStrategy(routing_strategy strategy)
1772 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
1773 if (AudioPolicyManagerALSA::getStrategy((AudioSystem::stream_type)i) == strategy &&
1774 isUsedByStream((AudioSystem::stream_type)i)) {
1781 status_t AudioPolicyManagerALSA::AudioOutputDescriptor::dump(int fd)
1783 const size_t SIZE = 256;
1787 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
1788 result.append(buffer);
1789 snprintf(buffer, SIZE, " Format: %d\n", mFormat);
1790 result.append(buffer);
1791 snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
1792 result.append(buffer);
1793 snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
1794 result.append(buffer);
1795 snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
1796 result.append(buffer);
1797 snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
1798 result.append(buffer);
1799 snprintf(buffer, SIZE, " Stream volume refCount\n");
1800 result.append(buffer);
1801 for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
1802 snprintf(buffer, SIZE, " %02d %.03f %d\n", i, mCurVolume[i], mRefCount[i]);
1803 result.append(buffer);
1805 write(fd, result.string(), result.size());
1810 // --- AudioInputDescriptor class implementation
1812 AudioPolicyManagerALSA::AudioInputDescriptor::AudioInputDescriptor()
1813 : mSamplingRate(0), mFormat(0), mChannels(0),
1814 mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0)
1818 status_t AudioPolicyManagerALSA::AudioInputDescriptor::dump(int fd)
1820 const size_t SIZE = 256;
1824 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
1825 result.append(buffer);
1826 snprintf(buffer, SIZE, " Format: %d\n", mFormat);
1827 result.append(buffer);
1828 snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
1829 result.append(buffer);
1830 snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics);
1831 result.append(buffer);
1832 snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
1833 result.append(buffer);
1834 snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
1835 result.append(buffer);
1836 write(fd, result.string(), result.size());
1841 // --- StreamDescriptor class implementation
1843 void AudioPolicyManagerALSA::StreamDescriptor::dump(char* buffer, size_t size)
1845 snprintf(buffer, size, " %02d %02d %02d %02d %d\n",
1854 }; // namespace android