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 #ifdef SUPPORT_DEVICE_OUT_TTY
218 } else if (device == AudioSystem::DEVICE_OUT_TTY) {
219 LOGV("setDeviceConnectionState() tty device");
220 // if connecting a wired headset, we check the following by order of priority
221 // to request a routing change if necessary:
222 // 1: we are in call or the strategy phone is active on the hardware output:
223 // use device for strategy phone
224 if (getDeviceForStrategy(STRATEGY_PHONE) == device &&
225 (mPhoneState == AudioSystem::MODE_IN_CALL ||
226 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_PHONE))) {
229 #endif // SUPPORT_DEVICE_OUT_TTY
232 // request routing change if necessary
233 setOutputDevice(mHardwareOutput, newDevice);
236 // handle output device disconnection
237 case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
238 if (!(mAvailableOutputDevices & device)) {
239 LOGW("setDeviceConnectionState() device not connected: %x", device);
240 return INVALID_OPERATION;
243 uint32_t newDevice = 0;
244 // get usage of disconnected device by all strategies
245 bool wasUsedForMedia = (getDeviceForStrategy(STRATEGY_MEDIA) & device) != 0;
246 bool wasUsedForSonification = (getDeviceForStrategy(STRATEGY_SONIFICATION) & device) != 0;
247 bool wasUsedforPhone = (getDeviceForStrategy(STRATEGY_PHONE) & device) != 0;
248 bool wasUsedforDtmf = (getDeviceForStrategy(STRATEGY_DTMF) & device) != 0;
249 LOGV("setDeviceConnectionState() disconnecting device %x used by media %d, sonification %d, phone %d",
250 device, wasUsedForMedia, wasUsedForSonification, wasUsedforPhone);
251 // remove device from available output devices
252 mAvailableOutputDevices &= ~device;
255 // handle A2DP device disconnection
256 if (AudioSystem::isA2dpDevice(device)) {
257 if (mA2dpOutput == 0 || mDuplicatedOutput == 0) {
258 LOGW("setDeviceConnectionState() disconnecting A2DP and no A2DP output!");
259 mAvailableOutputDevices |= device;
260 return INVALID_OPERATION;
263 if (mA2dpDeviceAddress != device_address) {
264 LOGW("setDeviceConnectionState() disconnecting unknow A2DP sink address %s", device_address);
265 mAvailableOutputDevices |= device;
266 return INVALID_OPERATION;
269 AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
270 AudioOutputDescriptor *a2dpOutputDesc = mOutputs.valueFor(mA2dpOutput);
272 // mute media during 2 seconds to avoid outputing sound on hardware output while music stream
273 // is switched from A2DP output and before music is paused by music application
274 setStrategyMute(STRATEGY_MEDIA, true, mHardwareOutput);
275 setStrategyMute(STRATEGY_MEDIA, false, mHardwareOutput, 2000);
277 // If the A2DP device was used by DTMF strategy, move all streams pertaining to DTMF strategy to
279 if (wasUsedforDtmf) {
280 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
281 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_DTMF) {
282 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mHardwareOutput);
283 hwOutputDesc->changeRefCount((AudioSystem::stream_type)i,
284 a2dpOutputDesc->mRefCount[i]);
287 if (a2dpOutputDesc->isUsedByStrategy(STRATEGY_DTMF)) {
288 newDevice = getDeviceForStrategy(STRATEGY_DTMF);
292 // If the A2DP device was used by media strategy, move all streams pertaining to media strategy to
294 if (wasUsedForMedia) {
295 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
296 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_MEDIA) {
297 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mHardwareOutput);
298 hwOutputDesc->changeRefCount((AudioSystem::stream_type)i,
299 a2dpOutputDesc->mRefCount[i]);
302 if (a2dpOutputDesc->isUsedByStrategy(STRATEGY_MEDIA)) {
303 newDevice = getDeviceForStrategy(STRATEGY_MEDIA);
307 // If the A2DP device was used by sonification strategy, move all streams pertaining to
308 // sonification strategy to hardware output.
309 // Note that newDevice is overwritten here giving sonification strategy a higher priority than
311 if (wasUsedForSonification) {
312 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
313 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_SONIFICATION) {
314 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mHardwareOutput);
317 if (a2dpOutputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) {
318 newDevice = getDeviceForStrategy(STRATEGY_SONIFICATION);
322 // close A2DP and duplicated outputs
323 AudioParameter param;
324 param.add(String8("closing"), String8("true"));
325 mpClientInterface->setParameters(mA2dpOutput, param.toString());
327 LOGW("setDeviceConnectionState() closing A2DP and duplicated output!");
328 mpClientInterface->closeOutput(mDuplicatedOutput);
329 delete mOutputs.valueFor(mDuplicatedOutput);
330 mOutputs.removeItem(mDuplicatedOutput);
331 mDuplicatedOutput = 0;
332 mpClientInterface->closeOutput(mA2dpOutput);
333 delete mOutputs.valueFor(mA2dpOutput);
334 mOutputs.removeItem(mA2dpOutput);
339 if (AudioSystem::isBluetoothScoDevice(device)) {
340 // handle SCO device disconnection
341 if (wasUsedforPhone &&
342 mPhoneState == AudioSystem::MODE_IN_CALL) {
343 // if in call, find new suitable device for phone strategy
344 newDevice = getDeviceForStrategy(STRATEGY_PHONE);
345 } else if (wasUsedforDtmf &&
346 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_DTMF)) {
347 newDevice = getDeviceForStrategy(STRATEGY_DTMF);
349 if ((mA2dpDeviceAddress == mScoDeviceAddress) &&
350 (mPhoneState != AudioSystem::MODE_NORMAL)) {
351 mpClientInterface->restoreOutput(mA2dpOutput);
353 } else if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET ||
354 device == AudioSystem::DEVICE_OUT_WIRED_HEADPHONE) {
355 // if disconnecting a wired headset, we check the following by order of priority
356 // to request a routing change if necessary:
357 // 1: we are in call or the strategy phone is active on the hardware output:
358 // use device for strategy phone
359 // 2: the strategy sonification is active on the hardware output:
360 // use device for strategy sonification
361 // 3: the strategy media is active on the hardware output:
362 // use device for strategy media
363 // 4: the strategy DTMF is active on the hardware output:
364 // use device for strategy DTMF
365 if (wasUsedforPhone &&
366 (mPhoneState == AudioSystem::MODE_IN_CALL ||
367 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_PHONE))) {
368 newDevice = getDeviceForStrategy(STRATEGY_PHONE);
369 } else if (wasUsedForSonification &&
370 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_SONIFICATION)){
371 newDevice = getDeviceForStrategy(STRATEGY_SONIFICATION);
372 } else if (wasUsedForMedia &&
373 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_MEDIA)){
374 newDevice = getDeviceForStrategy(STRATEGY_MEDIA);
375 } else if (wasUsedforDtmf &&
376 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_DTMF)){
377 newDevice = getDeviceForStrategy(STRATEGY_DTMF);
379 #ifdef SUPPORT_DEVICE_OUT_TTY
380 } else if (device == AudioSystem::DEVICE_OUT_TTY) {
381 LOGV("setDeviceConnectionState() tty device");
382 if (wasUsedforPhone &&
383 (mPhoneState == AudioSystem::MODE_IN_CALL ||
384 mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_PHONE))) {
385 newDevice = getDeviceForStrategy(STRATEGY_PHONE);
387 #endif // SUPPORT_DEVICE_OUT_TTY
391 // request routing change if necessary
392 setOutputDevice(mHardwareOutput, newDevice);
394 // clear A2DP and SCO device address if necessary
396 if (AudioSystem::isA2dpDevice(device)) {
397 mA2dpDeviceAddress = "";
400 if (AudioSystem::isBluetoothScoDevice(device)) {
401 mScoDeviceAddress = "";
406 LOGE("setDeviceConnectionState() invalid state: %x", state);
410 if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) {
411 device = AudioSystem::DEVICE_IN_WIRED_HEADSET;
412 } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO ||
413 device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
414 device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
415 device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
420 // handle input devices
421 if (AudioSystem::isInputDevice(device)) {
425 // handle input device connection
426 case AudioSystem::DEVICE_STATE_AVAILABLE: {
427 if (mAvailableInputDevices & device) {
428 LOGW("setDeviceConnectionState() device already connected: %d", device);
429 return INVALID_OPERATION;
431 mAvailableInputDevices |= device;
435 // handle input device disconnection
436 case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
437 if (!(mAvailableInputDevices & device)) {
438 LOGW("setDeviceConnectionState() device not connected: %d", device);
439 return INVALID_OPERATION;
441 mAvailableInputDevices &= ~device;
445 LOGE("setDeviceConnectionState() invalid state: %x", state);
449 audio_io_handle_t activeInput = getActiveInput();
450 if (activeInput != 0) {
451 AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
452 uint32_t newDevice = getDeviceForInputSource(inputDesc->mInputSource);
453 if (newDevice != inputDesc->mDevice) {
454 LOGV("setDeviceConnectionState() changing device from %x to %x for input %d",
455 inputDesc->mDevice, newDevice, activeInput);
456 inputDesc->mDevice = newDevice;
457 AudioParameter param = AudioParameter();
458 param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
459 mpClientInterface->setParameters(activeInput, param.toString());
466 LOGW("setDeviceConnectionState() invalid device: %x", device);
470 AudioSystem::device_connection_state AudioPolicyManagerALSA::getDeviceConnectionState(AudioSystem::audio_devices device,
471 const char *device_address)
473 AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE;
474 String8 address = String8(device_address);
475 if (AudioSystem::isOutputDevice(device)) {
476 if (device & mAvailableOutputDevices) {
478 if (AudioSystem::isA2dpDevice(device) &&
479 address != "" && mA2dpDeviceAddress != address) {
483 if (AudioSystem::isBluetoothScoDevice(device) &&
484 address != "" && mScoDeviceAddress != address) {
487 state = AudioSystem::DEVICE_STATE_AVAILABLE;
489 } else if (AudioSystem::isInputDevice(device)) {
490 if (device & mAvailableInputDevices) {
491 state = AudioSystem::DEVICE_STATE_AVAILABLE;
498 void AudioPolicyManagerALSA::setPhoneState(int state)
500 LOGV("setPhoneState() state %d", state);
501 uint32_t newDevice = 0;
502 if (state < 0 || state >= AudioSystem::NUM_MODES) {
503 LOGW("setPhoneState() invalid state %d", state);
507 if (state == mPhoneState ) {
508 LOGW("setPhoneState() setting same state %d", state);
512 // if leaving call state, handle special case of active streams
513 // pertaining to sonification strategy see handleIncallSonification()
514 if (mPhoneState == AudioSystem::MODE_IN_CALL) {
515 LOGV("setPhoneState() in call state management: new state is %d", state);
516 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
517 handleIncallSonification(stream, false, true);
521 // store previous phone state for management of sonification strategy below
522 int oldState = mPhoneState;
523 uint32_t oldDtmfDevice = getDeviceForStrategy(STRATEGY_DTMF);
524 uint32_t oldSonificationDevice = getDeviceForStrategy(STRATEGY_SONIFICATION) & ~AudioSystem::DEVICE_OUT_SPEAKER;
527 // check if a routing change is required for hardware output in the following
528 // order of priority:
529 // 1: a stream pertaining to sonification strategy is active
530 // 2: new state is incall
531 // 3: a stream pertaining to media strategy is active
532 // 4: a stream pertaining to DTMF strategy is active
533 if (mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_SONIFICATION)) {
534 newDevice = getDeviceForStrategy(STRATEGY_SONIFICATION);
535 } else if (mPhoneState == AudioSystem::MODE_IN_CALL) {
536 newDevice = getDeviceForStrategy(STRATEGY_PHONE);
537 // force routing command to audio hardware when starting call
538 // even if no device change is needed
540 } else if (mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_MEDIA)) {
541 newDevice = getDeviceForStrategy(STRATEGY_MEDIA);
542 } else if (mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_DTMF)) {
543 newDevice = getDeviceForStrategy(STRATEGY_DTMF);
547 if (mA2dpOutput != 0) {
548 // If entering or exiting in call state, switch DTMF streams to/from A2DP output
550 uint32_t newDtmfDevice = getDeviceForStrategy(STRATEGY_DTMF);
551 uint32_t newSonificationDevice = getDeviceForStrategy(STRATEGY_SONIFICATION) & ~AudioSystem::DEVICE_OUT_SPEAKER;
552 if (state == AudioSystem::MODE_IN_CALL) { // entering in call mode
553 // move DTMF streams from A2DP output to hardware output if necessary
554 if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)oldDtmfDevice) &&
555 !AudioSystem::isA2dpDevice((AudioSystem::audio_devices)newDtmfDevice)) {
556 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
557 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_DTMF) {
558 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mHardwareOutput);
559 int refCount = mOutputs.valueFor(mA2dpOutput)->mRefCount[i];
560 mOutputs.valueFor(mHardwareOutput)->changeRefCount((AudioSystem::stream_type)i,
562 mOutputs.valueFor(mA2dpOutput)->changeRefCount((AudioSystem::stream_type)i,-refCount);
565 if (newDevice == 0 && mOutputs.valueFor(mA2dpOutput)->isUsedByStrategy(STRATEGY_DTMF)) {
566 newDevice = newDtmfDevice;
569 // move SONIFICATION streams from duplicated output to hardware output if necessary
570 if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)oldSonificationDevice) &&
571 !AudioSystem::isA2dpDevice((AudioSystem::audio_devices)newSonificationDevice)) {
572 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
573 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_SONIFICATION) {
574 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mHardwareOutput);
575 int refCount = mOutputs.valueFor(mDuplicatedOutput)->mRefCount[i];
576 mOutputs.valueFor(mHardwareOutput)->changeRefCount((AudioSystem::stream_type)i,
578 mOutputs.valueFor(mDuplicatedOutput)->changeRefCount((AudioSystem::stream_type)i,-refCount);
582 } else { // exiting in call mode
583 // move DTMF streams from hardware output to A2DP output if necessary
584 if (!AudioSystem::isA2dpDevice((AudioSystem::audio_devices)oldDtmfDevice) &&
585 AudioSystem::isA2dpDevice((AudioSystem::audio_devices)newDtmfDevice)) {
586 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
587 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_DTMF) {
588 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mA2dpOutput);
589 int refCount = mOutputs.valueFor(mHardwareOutput)->mRefCount[i];
590 mOutputs.valueFor(mA2dpOutput)->changeRefCount((AudioSystem::stream_type)i, refCount);
591 mOutputs.valueFor(mHardwareOutput)->changeRefCount((AudioSystem::stream_type)i, -refCount);
595 // move SONIFICATION streams from hardware output to A2DP output if necessary
596 if (!AudioSystem::isA2dpDevice((AudioSystem::audio_devices)oldSonificationDevice) &&
597 AudioSystem::isA2dpDevice((AudioSystem::audio_devices)newSonificationDevice)) {
598 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
599 if (getStrategy((AudioSystem::stream_type)i) == STRATEGY_SONIFICATION) {
600 mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mDuplicatedOutput);
601 int refCount = mOutputs.valueFor(mHardwareOutput)->mRefCount[i];
602 mOutputs.valueFor(mDuplicatedOutput)->changeRefCount((AudioSystem::stream_type)i, refCount);
603 mOutputs.valueFor(mHardwareOutput)->changeRefCount((AudioSystem::stream_type)i, -refCount);
608 // suspend A2DP output if SCO device address is the same as A2DP device address.
609 // no need to check that a SCO device is actually connected as mScoDeviceAddress == ""
610 // if none is connected and the test below will fail.
611 if (mA2dpDeviceAddress == mScoDeviceAddress) {
612 if (oldState == AudioSystem::MODE_NORMAL) {
613 mpClientInterface->suspendOutput(mA2dpOutput);
614 } else if (state == AudioSystem::MODE_NORMAL) {
615 mpClientInterface->restoreOutput(mA2dpOutput);
620 // force routing command to audio hardware when ending call
621 // even if no device change is needed
622 if (oldState == AudioSystem::MODE_IN_CALL) {
623 if (newDevice == 0) {
624 newDevice = mOutputs.valueFor(mHardwareOutput)->device();
628 // change routing is necessary
629 setOutputDevice(mHardwareOutput, newDevice, force);
631 // if entering in call state, handle special case of active streams
632 // pertaining to sonification strategy see handleIncallSonification()
633 if (state == AudioSystem::MODE_IN_CALL) {
634 LOGV("setPhoneState() in call state management: new state is %d", state);
635 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
636 handleIncallSonification(stream, true, true);
641 void AudioPolicyManagerALSA::setRingerMode(uint32_t mode, uint32_t mask)
643 LOGV("setRingerMode() mode %x, mask %x", mode, mask);
648 void AudioPolicyManagerALSA::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
650 LOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
653 case AudioSystem::FOR_COMMUNICATION:
654 if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO &&
655 config != AudioSystem::FORCE_NONE) {
656 LOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
659 mForceUse[usage] = config;
660 // update hardware output routing immediately if in call, or if there is an active
661 // VOICE_CALL stream, as would be the case with an application that uses this stream
662 // for it to behave like in a telephony app (e.g. voicemail app that plays audio files
663 // streamed or downloaded to the device)
664 if ((mPhoneState == AudioSystem::MODE_IN_CALL) ||
665 (mOutputs.valueFor(mHardwareOutput)->isUsedByStream(AudioSystem::VOICE_CALL))) {
666 uint32_t device = getDeviceForStrategy(STRATEGY_PHONE);
667 setOutputDevice(mHardwareOutput, device);
670 case AudioSystem::FOR_MEDIA:
671 if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP &&
672 config != AudioSystem::FORCE_WIRED_ACCESSORY && config != AudioSystem::FORCE_NONE) {
673 LOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
676 mForceUse[usage] = config;
678 case AudioSystem::FOR_RECORD:
679 if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY &&
680 config != AudioSystem::FORCE_NONE) {
681 LOGW("setForceUse() invalid config %d for FOR_RECORD", config);
684 mForceUse[usage] = config;
687 LOGW("setForceUse() invalid usage %d", usage);
692 AudioSystem::forced_config AudioPolicyManagerALSA::getForceUse(AudioSystem::force_use usage)
694 return mForceUse[usage];
697 void AudioPolicyManagerALSA::setSystemProperty(const char* property, const char* value)
699 LOGV("setSystemProperty() property %s, value %s", property, value);
700 if (strcmp(property, "ro.camera.sound.forced") == 0) {
702 LOGV("ENFORCED_AUDIBLE cannot be muted");
703 mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = false;
705 LOGV("ENFORCED_AUDIBLE can be muted");
706 mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = true;
711 audio_io_handle_t AudioPolicyManagerALSA::getOutput(AudioSystem::stream_type stream,
712 uint32_t samplingRate,
715 AudioSystem::output_flags flags)
717 audio_io_handle_t output = 0;
718 uint32_t latency = 0;
719 routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
720 uint32_t device = getDeviceForStrategy(strategy);
721 LOGV("getOutput() stream %d, samplingRate %d, format %d, channels %x, flags %x", stream, samplingRate, format, channels, flags);
724 // open a direct output if:
725 // 1 a direct output is explicitely requested
726 // 2 the audio format is compressed
727 if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
728 (format !=0 && !AudioSystem::isLinearPCM(format))) {
730 LOGV("getOutput() opening direct output device %x", device);
731 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
732 outputDesc->mDevice = device;
733 outputDesc->mSamplingRate = samplingRate;
734 outputDesc->mFormat = format;
735 outputDesc->mChannels = channels;
736 outputDesc->mLatency = 0;
737 outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT);
738 outputDesc->mRefCount[stream] = 1;
739 output = mpClientInterface->openOutput(&outputDesc->mDevice,
740 &outputDesc->mSamplingRate,
741 &outputDesc->mFormat,
742 &outputDesc->mChannels,
743 &outputDesc->mLatency,
746 // only accept an output with the requeted parameters
747 if ((samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
748 (format != 0 && format != outputDesc->mFormat) ||
749 (channels != 0 && channels != outputDesc->mChannels)) {
750 LOGV("getOutput() failed opening direct output: samplingRate %d, format %d, channels %d",
751 samplingRate, format, channels);
752 mpClientInterface->closeOutput(output);
756 mOutputs.add(output, outputDesc);
760 if (channels != 0 && channels != AudioSystem::CHANNEL_OUT_MONO &&
761 channels != AudioSystem::CHANNEL_OUT_STEREO) {
764 // open a non direct output
766 // get which output is suitable for the specified stream. The actual routing change will happen
767 // when startOutput() will be called
768 uint32_t device2 = device & ~AudioSystem::DEVICE_OUT_SPEAKER;
769 if (AudioSystem::popCount((AudioSystem::audio_devices)device) == 2) {
771 if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device2)) {
772 // if playing on 2 devices among which one is A2DP, use duplicated output
773 LOGV("getOutput() using duplicated output");
774 LOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device in multiple %x selected but A2DP output not opened", device);
775 output = mDuplicatedOutput;
779 // if playing on 2 devices among which none is A2DP, use hardware output
780 output = mHardwareOutput;
782 LOGV("getOutput() using output %d for 2 devices %x", output, device);
785 if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device2)) {
786 // if playing on A2DP device, use a2dp output
787 LOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device %x selected but A2DP output not opened", device);
788 output = mA2dpOutput;
792 // if playing on not A2DP device, use hardware output
793 output = mHardwareOutput;
798 LOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d, format %d, channels %x, flags %x",
799 stream, samplingRate, format, channels, flags);
804 status_t AudioPolicyManagerALSA::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
806 LOGV("startOutput() output %d, stream %d", output, stream);
807 ssize_t index = mOutputs.indexOfKey(output);
809 LOGW("startOutput() unknow output %d", output);
813 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
814 routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
815 uint32_t device = getDeviceForStrategy(strategy);
817 if (!outputDesc->isUsedByStrategy(strategy)) {
818 // if the stream started is the first active stream in its strategy, check if routing change
819 // must be done on hardware output
820 uint32_t newDevice = 0;
821 if (AudioSystem::popCount((AudioSystem::audio_devices)device) == 2) {
823 uint32_t device2 = device & ~AudioSystem::DEVICE_OUT_SPEAKER;
824 if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device2)) {
825 // if one device is A2DP, selected the second device for hardware output
830 // we only support speaker + headset and speaker + headphone combinations on hardware output.
831 // other combinations will leave device = 0 and no routing will happen.
832 if (device != (AudioSystem::DEVICE_OUT_SPEAKER | AudioSystem::DEVICE_OUT_WIRED_HEADSET) &&
833 device != (AudioSystem::DEVICE_OUT_SPEAKER | AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
834 device = AudioSystem::DEVICE_OUT_SPEAKER;
839 // By order of priority
840 // 1 apply routing for phone strategy in any case
841 // 2 apply routing for notification strategy if no stream pertaining to
842 // phone strategies is playing
843 // 3 apply routing for media strategy is not incall and neither phone nor sonification
844 // strategies is active.
845 // 4 apply routing for DTMF strategy if no stream pertaining to
846 // neither phone, sonification nor media strategy is playing
847 if (strategy == STRATEGY_PHONE) {
849 } else if (!mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_PHONE)) {
850 if (strategy == STRATEGY_SONIFICATION) {
852 } else if (!mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_SONIFICATION)) {
853 if (strategy == STRATEGY_MEDIA) {
855 } else if (!mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_MEDIA)) {
856 // strategy == STRATEGY_DTMF
862 // TODO: maybe mute stream is selected device was refused
863 setOutputDevice(mHardwareOutput, newDevice);
866 // incremenent usage count for this stream on the requested output:
867 // NOTE that the usage count is the same for duplicated output and hardware output which is
868 // necassary for a correct control of hardware output routing by startOutput() and stopOutput()
869 outputDesc->changeRefCount(stream, 1);
871 // handle special case for sonification while in call
872 if (mPhoneState == AudioSystem::MODE_IN_CALL) {
873 handleIncallSonification(stream, true, false);
876 // apply volume rules for current stream and device if necessary
877 checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, outputDesc->device());
882 status_t AudioPolicyManagerALSA::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
884 LOGV("stopOutput() output %d, stream %d", output, stream);
885 ssize_t index = mOutputs.indexOfKey(output);
887 LOGW("stopOutput() unknow output %d", output);
891 AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
892 routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
894 // handle special case for sonification while in call
895 if (mPhoneState == AudioSystem::MODE_IN_CALL) {
896 handleIncallSonification(stream, false, false);
899 if (outputDesc->isUsedByStrategy(strategy)) {
900 // decrement usage count of this stream on the output
901 outputDesc->changeRefCount(stream, -1);
902 if (!outputDesc->isUsedByStrategy(strategy)) {
903 // if the stream is the last of its strategy to use this output, change routing
904 // in the following order or priority:
905 // PHONE > SONIFICATION > MEDIA > DTMF
906 uint32_t newDevice = 0;
907 if (outputDesc->isUsedByStrategy(STRATEGY_PHONE)) {
908 newDevice = getDeviceForStrategy(STRATEGY_PHONE);
909 } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) {
910 newDevice = getDeviceForStrategy(STRATEGY_SONIFICATION);
911 } else if (mPhoneState == AudioSystem::MODE_IN_CALL) {
912 newDevice = getDeviceForStrategy(STRATEGY_PHONE);
913 } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) {
914 newDevice = getDeviceForStrategy(STRATEGY_MEDIA);
915 } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) {
916 newDevice = getDeviceForStrategy(STRATEGY_DTMF);
919 // apply routing change if necessary.
920 // insert a delay of 2 times the audio hardware latency to ensure PCM
921 // buffers in audio flinger and audio hardware are emptied before the
922 // routing change is executed.
923 setOutputDevice(mHardwareOutput, newDevice, false, mOutputs.valueFor(mHardwareOutput)->mLatency*2);
925 // store time at which the last music track was stopped - see computeVolume()
926 if (stream == AudioSystem::MUSIC) {
927 mMusicStopTime = systemTime();
931 LOGW("stopOutput() refcount is already 0 for output %d", output);
932 return INVALID_OPERATION;
936 void AudioPolicyManagerALSA::releaseOutput(audio_io_handle_t output)
938 LOGV("releaseOutput() %d", output);
939 ssize_t index = mOutputs.indexOfKey(output);
941 LOGW("releaseOutput() releasing unknown output %d", output);
944 if (mOutputs.valueAt(index)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) {
945 mpClientInterface->closeOutput(output);
946 delete mOutputs.valueAt(index);
947 mOutputs.removeItem(output);
951 audio_io_handle_t AudioPolicyManagerALSA::getInput(int inputSource,
952 uint32_t samplingRate,
955 AudioSystem::audio_in_acoustics acoustics)
957 audio_io_handle_t input = 0;
958 uint32_t device = getDeviceForInputSource(inputSource);
960 LOGV("getInput() inputSource %d, samplingRate %d, format %d, channels %x, acoustics %x", inputSource, samplingRate, format, channels, acoustics);
966 // adapt channel selection to input source
967 switch(inputSource) {
968 case AUDIO_SOURCE_VOICE_UPLINK:
969 channels = AudioSystem::CHANNEL_IN_VOICE_UPLINK;
971 case AUDIO_SOURCE_VOICE_DOWNLINK:
972 channels = AudioSystem::CHANNEL_IN_VOICE_DNLINK;
974 case AUDIO_SOURCE_VOICE_CALL:
975 channels = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK);
981 AudioInputDescriptor *inputDesc = new AudioInputDescriptor();
983 inputDesc->mInputSource = inputSource;
984 inputDesc->mDevice = device;
985 inputDesc->mSamplingRate = samplingRate;
986 inputDesc->mFormat = format;
987 inputDesc->mChannels = channels;
988 inputDesc->mAcoustics = acoustics;
989 inputDesc->mRefCount = 0;
990 input = mpClientInterface->openInput(&inputDesc->mDevice,
991 &inputDesc->mSamplingRate,
993 &inputDesc->mChannels,
994 inputDesc->mAcoustics);
996 // only accept input with the exact requested set of parameters
997 if ((samplingRate != inputDesc->mSamplingRate) ||
998 (format != inputDesc->mFormat) ||
999 (channels != inputDesc->mChannels)) {
1000 LOGV("getOutput() failed opening input: samplingRate %d, format %d, channels %d",
1001 samplingRate, format, channels);
1002 mpClientInterface->closeInput(input);
1006 mInputs.add(input, inputDesc);
1010 status_t AudioPolicyManagerALSA::startInput(audio_io_handle_t input)
1012 LOGV("startInput() input %d", input);
1013 ssize_t index = mInputs.indexOfKey(input);
1015 LOGW("startInput() unknow input %d", input);
1018 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
1020 // refuse 2 active AudioRecord clients at the same time
1021 if (getActiveInput() != 0) {
1022 LOGW("startInput() input %d failed: other input already started", input);
1023 return INVALID_OPERATION;
1026 AudioParameter param = AudioParameter();
1027 param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
1028 mpClientInterface->setParameters(input, param.toString());
1030 inputDesc->mRefCount = 1;
1034 status_t AudioPolicyManagerALSA::stopInput(audio_io_handle_t input)
1036 LOGV("stopInput() input %d", input);
1037 ssize_t index = mInputs.indexOfKey(input);
1039 LOGW("stopInput() unknow input %d", input);
1042 AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
1044 if (inputDesc->mRefCount == 0) {
1045 LOGW("stopInput() input %d already stopped", input);
1046 return INVALID_OPERATION;
1048 AudioParameter param = AudioParameter();
1049 param.addInt(String8(AudioParameter::keyRouting), 0);
1050 mpClientInterface->setParameters(input, param.toString());
1051 inputDesc->mRefCount = 0;
1056 void AudioPolicyManagerALSA::releaseInput(audio_io_handle_t input)
1058 LOGV("releaseInput() %d", input);
1059 ssize_t index = mInputs.indexOfKey(input);
1061 LOGW("releaseInput() releasing unknown input %d", input);
1064 mpClientInterface->closeInput(input);
1065 delete mInputs.valueAt(index);
1066 mInputs.removeItem(input);
1067 LOGV("releaseInput() exit");
1072 void AudioPolicyManagerALSA::initStreamVolume(AudioSystem::stream_type stream,
1076 LOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
1077 if (indexMin < 0 || indexMin >= indexMax) {
1078 LOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax);
1081 mStreams[stream].mIndexMin = indexMin;
1082 mStreams[stream].mIndexMax = indexMax;
1085 status_t AudioPolicyManagerALSA::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
1088 if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
1092 LOGV("setStreamVolumeIndex() stream %d, index %d", stream, index);
1093 mStreams[stream].mIndexCur = index;
1095 // compute and apply stream volume on all outputs according to connected device
1096 status_t status = NO_ERROR;
1097 for (size_t i = 0; i < mOutputs.size(); i++) {
1098 status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), mOutputs.valueAt(i)->device());
1099 if (volStatus != NO_ERROR) {
1106 status_t AudioPolicyManagerALSA::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
1111 LOGV("getStreamVolumeIndex() stream %d", stream);
1112 *index = mStreams[stream].mIndexCur;
1116 status_t AudioPolicyManagerALSA::dump(int fd)
1118 const size_t SIZE = 256;
1122 snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
1123 result.append(buffer);
1124 snprintf(buffer, SIZE, " Hardware Output: %d\n", mHardwareOutput);
1125 result.append(buffer);
1126 snprintf(buffer, SIZE, " A2DP Output: %d\n", mA2dpOutput);
1127 result.append(buffer);
1128 snprintf(buffer, SIZE, " Duplicated Output: %d\n", mDuplicatedOutput);
1129 result.append(buffer);
1130 snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices);
1131 result.append(buffer);
1132 snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices);
1133 result.append(buffer);
1134 snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string());
1135 result.append(buffer);
1136 snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string());
1137 result.append(buffer);
1138 snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
1139 result.append(buffer);
1140 snprintf(buffer, SIZE, " Ringer mode: %d\n", mRingerMode);
1141 result.append(buffer);
1142 snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]);
1143 result.append(buffer);
1144 snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]);
1145 result.append(buffer);
1146 snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]);
1147 result.append(buffer);
1148 write(fd, result.string(), result.size());
1150 snprintf(buffer, SIZE, "\nOutputs dump:\n");
1151 write(fd, buffer, strlen(buffer));
1152 for (size_t i = 0; i < mOutputs.size(); i++) {
1153 snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
1154 write(fd, buffer, strlen(buffer));
1155 mOutputs.valueAt(i)->dump(fd);
1158 snprintf(buffer, SIZE, "\nInputs dump:\n");
1159 write(fd, buffer, strlen(buffer));
1160 for (size_t i = 0; i < mInputs.size(); i++) {
1161 snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
1162 write(fd, buffer, strlen(buffer));
1163 mInputs.valueAt(i)->dump(fd);
1166 snprintf(buffer, SIZE, "\nStreams dump:\n");
1167 write(fd, buffer, strlen(buffer));
1168 snprintf(buffer, SIZE, " Stream Index Min Index Max Index Cur Mute Count Can be muted\n");
1169 write(fd, buffer, strlen(buffer));
1170 for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
1171 snprintf(buffer, SIZE, " %02d", i);
1172 mStreams[i].dump(buffer + 3, SIZE);
1173 write(fd, buffer, strlen(buffer));
1179 // ----------------------------------------------------------------------------
1180 // AudioPolicyManagerALSA
1181 // ----------------------------------------------------------------------------
1183 // --- class factory
1186 extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
1188 return new AudioPolicyManagerALSA(clientInterface);
1191 extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
1196 AudioPolicyManagerALSA::AudioPolicyManagerALSA(AudioPolicyClientInterface *clientInterface)
1197 : mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0), mMusicStopTime(0)
1199 mpClientInterface = clientInterface;
1201 for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {
1202 mForceUse[i] = AudioSystem::FORCE_NONE;
1205 // devices available by default are speaker, ear piece and microphone
1206 mAvailableOutputDevices = AudioSystem::DEVICE_OUT_EARPIECE |
1207 AudioSystem::DEVICE_OUT_SPEAKER;
1208 mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC;
1210 mA2dpDeviceAddress = String8("");
1211 mScoDeviceAddress = String8("");
1213 // open hardware output
1214 AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
1215 outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
1216 mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
1217 &outputDesc->mSamplingRate,
1218 &outputDesc->mFormat,
1219 &outputDesc->mChannels,
1220 &outputDesc->mLatency,
1221 outputDesc->mFlags);
1223 if (mHardwareOutput == 0) {
1224 LOGE("Failed to initialize hardware output stream, samplingRate: %d, format %d, channels %d",
1225 outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
1227 mOutputs.add(mHardwareOutput, outputDesc);
1228 setOutputDevice(mHardwareOutput, (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER, true);
1232 mDuplicatedOutput = 0;
1235 AudioPolicyManagerALSA::~AudioPolicyManagerALSA()
1237 for (size_t i = 0; i < mOutputs.size(); i++) {
1238 mpClientInterface->closeOutput(mOutputs.keyAt(i));
1239 delete mOutputs.valueAt(i);
1242 for (size_t i = 0; i < mInputs.size(); i++) {
1243 mpClientInterface->closeInput(mInputs.keyAt(i));
1244 delete mInputs.valueAt(i);
1251 audio_io_handle_t AudioPolicyManagerALSA::getOutputForDevice(uint32_t device)
1253 audio_io_handle_t output = 0;
1256 for (size_t i = 0; i < mOutputs.size(); i++) {
1257 lDevice = mOutputs.valueAt(i)->device();
1258 LOGV("getOutputForDevice() output %d devices %x", mOutputs.keyAt(i), lDevice);
1260 // We are only considering outputs connected to a mixer here => exclude direct outputs
1261 if ((lDevice == device) &&
1262 !(mOutputs.valueAt(i)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT)) {
1263 output = mOutputs.keyAt(i);
1264 LOGV("getOutputForDevice() found output %d for device %x", output, device);
1271 AudioPolicyManagerALSA::routing_strategy AudioPolicyManagerALSA::getStrategy(AudioSystem::stream_type stream)
1273 // stream to strategy mapping
1275 case AudioSystem::VOICE_CALL:
1276 case AudioSystem::BLUETOOTH_SCO:
1277 return STRATEGY_PHONE;
1278 case AudioSystem::RING:
1279 case AudioSystem::NOTIFICATION:
1280 case AudioSystem::ALARM:
1281 case AudioSystem::ENFORCED_AUDIBLE:
1282 return STRATEGY_SONIFICATION;
1283 case AudioSystem::DTMF:
1284 return STRATEGY_DTMF;
1286 LOGE("unknown stream type");
1287 case AudioSystem::SYSTEM:
1288 // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
1289 // while key clicks are played produces a poor result
1290 case AudioSystem::TTS:
1291 case AudioSystem::MUSIC:
1292 return STRATEGY_MEDIA;
1296 uint32_t AudioPolicyManagerALSA::getDeviceForStrategy(routing_strategy strategy)
1298 uint32_t device = 0;
1302 if (mPhoneState != AudioSystem::MODE_IN_CALL) {
1303 // when off call, DTMF strategy follows the same rules as MEDIA strategy
1304 device = getDeviceForStrategy(STRATEGY_MEDIA);
1307 // when in call, DTMF and PHONE strategies follow the same rules
1310 case STRATEGY_PHONE:
1311 // for phone strategy, we first consider the forced use and then the available devices by order
1313 switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
1314 case AudioSystem::FORCE_BT_SCO:
1315 if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
1316 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
1319 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
1321 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
1323 // if SCO device is requested but no SCO device is available, fall back to default case
1326 default: // FORCE_NONE
1327 #ifdef SUPPORT_DEVICE_OUT_TTY
1328 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_TTY;
1330 #endif // SUPPORT_DEVICE_OUT_TTY
1331 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
1333 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
1335 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
1337 LOGE("getDeviceForStrategy() earpiece device not found");
1341 case AudioSystem::FORCE_SPEAKER:
1342 if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
1343 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
1346 device = mAvailableOutputDevices;
1348 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
1350 LOGE("getDeviceForStrategy() speaker device not found");
1356 case STRATEGY_SONIFICATION:
1358 // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
1359 // handleIncallSonification().
1360 if (mPhoneState == AudioSystem::MODE_IN_CALL) {
1361 device = getDeviceForStrategy(STRATEGY_PHONE);
1364 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
1366 LOGE("getDeviceForStrategy() speaker device not found");
1368 // The second device used for sonification is the same as the device used by media strategy
1371 case STRATEGY_MEDIA: {
1372 uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
1374 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
1376 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
1378 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
1380 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
1382 device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
1384 device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
1386 LOGE("getDeviceForStrategy() speaker device not found");
1394 // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION, 0 otherwise
1396 // Do not play media stream if in call and the requested device would change the hardware
1398 if (mPhoneState == AudioSystem::MODE_IN_CALL &&
1399 !AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device) &&
1400 device != getDeviceForStrategy(STRATEGY_PHONE)) {
1402 LOGV("getDeviceForStrategy() incompatible media and phone devices");
1407 LOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
1411 LOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
1415 void AudioPolicyManagerALSA::setOutputDevice(audio_io_handle_t output, uint32_t device, bool force, int delayMs)
1417 LOGV("setOutputDevice() output %d device %x delayMs %d", output, device, delayMs);
1418 if (mOutputs.indexOfKey(output) < 0) {
1419 LOGW("setOutputDevice() unknown output %d", output);
1423 if (output == mHardwareOutput) {
1424 // clear A2DP devices from device bit field here so that the caller does not have to
1425 // do it in case of multiple device selections
1426 uint32_t device2 = device & ~AudioSystem::DEVICE_OUT_SPEAKER;
1427 if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device2)) {
1428 LOGV("setOutputDevice() removing A2DP device");
1431 } else if (output == mA2dpOutput) {
1432 // clear hardware devices from device bit field here so that the caller does not have to
1433 // do it in case of multiple device selections (the second device is always DEVICE_OUT_SPEAKER)
1435 device &= ~AudioSystem::DEVICE_OUT_SPEAKER;
1439 // doing this check here allows the caller to call setOutputDevice() without conditions
1440 if (device == 0) return;
1442 uint32_t oldDevice = (uint32_t)mOutputs.valueFor(output)->device();
1443 // Do not change the routing if the requested device is the same as current device. Doing this check
1444 // here allows the caller to call setOutputDevice() without conditions
1445 if (device == oldDevice && !force) {
1446 LOGV("setOutputDevice() setting same device %x for output %d", device, output);
1450 mOutputs.valueFor(output)->mDevice = device;
1451 // mute media streams if both speaker and headset are selected
1452 if (device == (AudioSystem::DEVICE_OUT_SPEAKER | AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1453 device == (AudioSystem::DEVICE_OUT_SPEAKER | AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
1454 setStrategyMute(STRATEGY_MEDIA, true, output);
1455 // wait for the PCM output buffers to empty before proceeding with the rest of the command
1456 usleep(mOutputs.valueFor(output)->mLatency*2*1000);
1458 // suspend A2D output if SCO device is selected
1459 if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)device)) {
1460 if (mA2dpOutput && mScoDeviceAddress == mA2dpDeviceAddress) {
1461 mpClientInterface->suspendOutput(mA2dpOutput);
1465 AudioParameter param = AudioParameter();
1466 param.addInt(String8(AudioParameter::keyRouting), (int)device);
1467 mpClientInterface->setParameters(mHardwareOutput, param.toString(), delayMs);
1468 // update stream volumes according to new device
1469 applyStreamVolumes(output, device, delayMs);
1471 // if disconnecting SCO device, restore A2DP output
1472 if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)oldDevice)) {
1473 if (mA2dpOutput && mScoDeviceAddress == mA2dpDeviceAddress) {
1474 LOGV("restore A2DP output");
1475 mpClientInterface->restoreOutput(mA2dpOutput);
1478 // if changing from a combined headset + speaker route, unmute media streams
1479 if (oldDevice == (AudioSystem::DEVICE_OUT_SPEAKER | AudioSystem::DEVICE_OUT_WIRED_HEADSET) ||
1480 oldDevice == (AudioSystem::DEVICE_OUT_SPEAKER | AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) {
1481 setStrategyMute(STRATEGY_MEDIA, false, output, delayMs);
1485 uint32_t AudioPolicyManagerALSA::getDeviceForInputSource(int inputSource)
1489 switch(inputSource) {
1490 case AUDIO_SOURCE_DEFAULT:
1491 case AUDIO_SOURCE_MIC:
1492 case AUDIO_SOURCE_VOICE_RECOGNITION:
1493 if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO &&
1494 mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
1495 device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
1496 } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
1497 device = AudioSystem::DEVICE_IN_WIRED_HEADSET;
1499 device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
1502 case AUDIO_SOURCE_CAMCORDER:
1503 device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
1505 case AUDIO_SOURCE_VOICE_UPLINK:
1506 case AUDIO_SOURCE_VOICE_DOWNLINK:
1507 case AUDIO_SOURCE_VOICE_CALL:
1508 device = AudioSystem::DEVICE_IN_VOICE_CALL;
1511 LOGW("getInput() invalid input source %d", inputSource);
1518 audio_io_handle_t AudioPolicyManagerALSA::getActiveInput()
1520 for (size_t i = 0; i < mInputs.size(); i++) {
1521 if (mInputs.valueAt(i)->mRefCount > 0) {
1522 return mInputs.keyAt(i);
1528 float AudioPolicyManagerALSA::computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device)
1531 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
1532 StreamDescriptor &streamDesc = mStreams[stream];
1534 // Force max volume if stream cannot be muted
1535 if (!streamDesc.mCanBeMuted) index = streamDesc.mIndexMax;
1538 device = outputDesc->device();
1541 int volInt = (100 * (index - streamDesc.mIndexMin)) / (streamDesc.mIndexMax - streamDesc.mIndexMin);
1542 volume = AudioSystem::linearToLog(volInt);
1544 // if a heaset is connected, apply the following rules to ring tones and notifications
1545 // to avoid sound level bursts in user's ears:
1546 // - always attenuate ring tones and notifications volume by 6dB
1547 // - if music is playing, always limit the volume to current music volume,
1548 // with a minimum threshold at -36dB so that notification is always perceived.
1550 (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP |
1551 AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
1552 AudioSystem::DEVICE_OUT_WIRED_HEADSET |
1553 AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) &&
1554 (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION)) {
1555 volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
1556 // when the phone is ringing we must consider that music could have been paused just before
1557 // by the music application and behave as if music was active if the last music track was
1559 if (outputDesc->isUsedByStream(AudioSystem::MUSIC) ||
1560 ((mPhoneState == AudioSystem::MODE_RINGTONE) &&
1561 (systemTime() - mMusicStopTime < seconds(SONIFICATION_HEADSET_MUSIC_DELAY)))) {
1562 float musicVol = computeVolume(AudioSystem::MUSIC, mStreams[AudioSystem::MUSIC].mIndexCur, output, device);
1563 float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
1564 if (volume > minVol) {
1566 LOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
1574 status_t AudioPolicyManagerALSA::checkAndSetVolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayMs, bool force)
1577 // do not change actual stream volume if the stream is muted
1578 if (mStreams[stream].mMuteCount != 0) {
1579 LOGV("checkAndSetVolume() stream %d muted count %d", stream, mStreams[stream].mMuteCount);
1583 // do not change in call volume if bluetooth is connected and vice versa
1584 if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
1585 (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {
1586 LOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
1587 stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);
1588 return INVALID_OPERATION;
1591 float volume = computeVolume(stream, index, output, device || force);
1592 // do not set volume if the float value did not change
1593 if (volume != mOutputs.valueFor(output)->mCurVolume[stream]) {
1594 mOutputs.valueFor(output)->mCurVolume[stream] = volume;
1595 LOGV("setStreamVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
1596 if (stream == AudioSystem::VOICE_CALL ||
1597 stream == AudioSystem::DTMF ||
1598 stream == AudioSystem::BLUETOOTH_SCO) {
1599 float voiceVolume = -1.0;
1600 // offset value to reflect actual hardware volume that never reaches 0
1601 // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java)
1602 volume = 0.01 + 0.99 * volume;
1603 if (stream == AudioSystem::VOICE_CALL) {
1604 voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
1605 } else if (stream == AudioSystem::BLUETOOTH_SCO) {
1608 if (voiceVolume >= 0 && output == mHardwareOutput) {
1609 mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
1612 mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
1618 void AudioPolicyManagerALSA::applyStreamVolumes(audio_io_handle_t output, uint32_t device, int delayMs)
1620 LOGV("applyStreamVolumes() for output %d and device %x", output, device);
1622 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
1623 checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, device, delayMs);
1627 void AudioPolicyManagerALSA::setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output, int delayMs)
1629 LOGV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
1630 for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
1631 if (getStrategy((AudioSystem::stream_type)stream) == strategy) {
1632 setStreamMute(stream, on, output, delayMs);
1637 void AudioPolicyManagerALSA::setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs)
1639 StreamDescriptor &streamDesc = mStreams[stream];
1640 uint32_t device = mOutputs.valueFor(output)->mDevice;
1642 LOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d", stream, on, output, streamDesc.mMuteCount);
1645 if (streamDesc.mMuteCount == 0) {
1646 if (streamDesc.mCanBeMuted) {
1647 checkAndSetVolume(stream, 0, output, device, delayMs);
1650 // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
1651 streamDesc.mMuteCount++;
1653 if (streamDesc.mMuteCount == 0) {
1654 LOGW("setStreamMute() unmuting non muted stream!");
1657 if (--streamDesc.mMuteCount == 0) {
1658 checkAndSetVolume(stream, streamDesc.mIndexCur, output, device, delayMs);
1663 void AudioPolicyManagerALSA::handleIncallSonification(int stream, bool starting, bool stateChange)
1665 // if the stream pertains to sonification strategy and we are in call we must
1666 // mute the stream if it is low visibility. If it is high visibility, we must play a tone
1667 // in the device used for phone strategy and play the tone if the selected device does not
1668 // interfere with the device used for phone strategy
1669 // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
1670 // many times as there are active tracks on the output
1672 if (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) {
1673 AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mHardwareOutput);
1674 LOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
1675 stream, starting, outputDesc->mDevice, stateChange);
1676 if (outputDesc->isUsedByStream((AudioSystem::stream_type)stream)) {
1679 muteCount = outputDesc->mRefCount[stream];
1681 if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) {
1682 LOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
1683 for (int i = 0; i < muteCount; i++) {
1684 setStreamMute(stream, starting, mHardwareOutput);
1687 LOGV("handleIncallSonification() high visibility ");
1688 if (outputDesc->mDevice & getDeviceForStrategy(STRATEGY_PHONE)) {
1689 LOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
1690 for (int i = 0; i < muteCount; i++) {
1691 setStreamMute(stream, starting, mHardwareOutput);
1695 mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL);
1697 mpClientInterface->stopTone();
1705 // --- AudioOutputDescriptor class implementation
1707 AudioPolicyManagerALSA::AudioOutputDescriptor::AudioOutputDescriptor()
1708 : mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0),
1709 mFlags((AudioSystem::output_flags)0), mDevice(0), mOutput1(0), mOutput2(0)
1711 // clear usage count for all stream types
1712 for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
1714 mCurVolume[i] = -1.0;
1718 uint32_t AudioPolicyManagerALSA::AudioOutputDescriptor::device()
1720 uint32_t device = 0;
1721 if (isDuplicated()) {
1722 device = mOutput1->mDevice | mOutput2->mDevice;
1729 void AudioPolicyManagerALSA::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta)
1731 // forward usage count change to attached outputs
1732 if (isDuplicated()) {
1733 mOutput1->changeRefCount(stream, delta);
1734 mOutput2->changeRefCount(stream, delta);
1736 if ((delta + (int)mRefCount[stream]) < 0) {
1737 LOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]);
1738 mRefCount[stream] = 0;
1741 mRefCount[stream] += delta;
1742 LOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
1745 bool AudioPolicyManagerALSA::AudioOutputDescriptor::isUsedByStrategy(routing_strategy strategy)
1747 for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
1748 if (AudioPolicyManagerALSA::getStrategy((AudioSystem::stream_type)i) == strategy &&
1749 isUsedByStream((AudioSystem::stream_type)i)) {
1756 status_t AudioPolicyManagerALSA::AudioOutputDescriptor::dump(int fd)
1758 const size_t SIZE = 256;
1762 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
1763 result.append(buffer);
1764 snprintf(buffer, SIZE, " Format: %d\n", mFormat);
1765 result.append(buffer);
1766 snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
1767 result.append(buffer);
1768 snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
1769 result.append(buffer);
1770 snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
1771 result.append(buffer);
1772 snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
1773 result.append(buffer);
1774 snprintf(buffer, SIZE, " Stream volume refCount\n");
1775 result.append(buffer);
1776 for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
1777 snprintf(buffer, SIZE, " %02d %.03f %d\n", i, mCurVolume[i], mRefCount[i]);
1778 result.append(buffer);
1780 write(fd, result.string(), result.size());
1785 // --- AudioInputDescriptor class implementation
1787 AudioPolicyManagerALSA::AudioInputDescriptor::AudioInputDescriptor()
1788 : mSamplingRate(0), mFormat(0), mChannels(0),
1789 mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0)
1793 status_t AudioPolicyManagerALSA::AudioInputDescriptor::dump(int fd)
1795 const size_t SIZE = 256;
1799 snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
1800 result.append(buffer);
1801 snprintf(buffer, SIZE, " Format: %d\n", mFormat);
1802 result.append(buffer);
1803 snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
1804 result.append(buffer);
1805 snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics);
1806 result.append(buffer);
1807 snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
1808 result.append(buffer);
1809 snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
1810 result.append(buffer);
1811 write(fd, result.string(), result.size());
1816 // --- StreamDescriptor class implementation
1818 void AudioPolicyManagerALSA::StreamDescriptor::dump(char* buffer, size_t size)
1820 snprintf(buffer, size, " %02d %02d %02d %02d %d\n",
1829 }; // namespace android