Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

hardware-alsa_sound: 提交

hardware/alsa_sound


Commit MetaInfo

修订版621bc21b12d0c4fb2f0f90ebf64b2f34d5233d38 (tree)
时间2010-06-25 17:51:47
作者Sean McNeil <sean.mcneil@wind...>
CommiterSean McNeil

Log Message

Reduce common code.

Make AudioPolicyManagerBase the parent class of AudioPolicyManagerALSA.
Remove what is common code. If necessary, we can implement any changes
when we find them.

更改概述

差异

--- a/AudioPolicyManagerALSA.cpp
+++ b/AudioPolicyManagerALSA.cpp
@@ -22,1167 +22,12 @@
2222
2323 namespace android {
2424
25-
26-// ----------------------------------------------------------------------------
27-// AudioPolicyInterface implementation
28-// ----------------------------------------------------------------------------
29-
30-
31-status_t AudioPolicyManagerALSA::setDeviceConnectionState(AudioSystem::audio_devices device,
32- AudioSystem::device_connection_state state,
33- const char *device_address)
34-{
35-
36- LOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address);
37-
38- // connect/disconnect only 1 device at a time
39- if (AudioSystem::popCount(device) != 1) return BAD_VALUE;
40-
41- if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) {
42- LOGE("setDeviceConnectionState() invalid address: %s", device_address);
43- return BAD_VALUE;
44- }
45-
46- // handle output devices
47- if (AudioSystem::isOutputDevice(device)) {
48-
49-#ifndef WITH_A2DP
50- if (AudioSystem::isA2dpDevice(device)) {
51- LOGE("setDeviceConnectionState() invalid device: %x", device);
52- return BAD_VALUE;
53- }
54-#endif
55-
56- switch (state)
57- {
58- // handle output device connection
59- case AudioSystem::DEVICE_STATE_AVAILABLE:
60- if (mAvailableOutputDevices & device) {
61- LOGW("setDeviceConnectionState() device already connected: %x", device);
62- return INVALID_OPERATION;
63- }
64- LOGW_IF((getOutputForDevice((uint32_t)device) != 0), "setDeviceConnectionState(): output using unconnected device %x", device);
65-
66- LOGV("setDeviceConnectionState() connecting device %x", device);
67-
68- // register new device as available
69- mAvailableOutputDevices |= device;
70-
71-#ifdef WITH_A2DP
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,
80- &outputDesc->mFormat,
81- &outputDesc->mChannels,
82- &outputDesc->mLatency,
83- outputDesc->mFlags);
84- if (mA2dpOutput) {
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
92- // interface
93- AudioParameter param;
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);
97-
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);
108- } else {
109- LOGW("getOutput() could not open duplicated output for %d and %d",
110- mHardwareOutput, mA2dpOutput);
111- mAvailableOutputDevices &= ~device;
112- delete outputDesc;
113- return NO_INIT;
114- }
115- } else {
116- LOGW("setDeviceConnectionState() could not open A2DP output for device %x", device);
117- mAvailableOutputDevices &= ~device;
118- delete outputDesc;
119- return NO_INIT;
120- }
121- AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
122-
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);
128- }
129- if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)hwOutputDesc->device())) {
130- mpClientInterface->suspendOutput(mA2dpOutput);
131- }
132- }
133-
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;
141- }
142- }
143-
144- }
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;
152- }
153- }
154-
155- }
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];
165- }
166- }
167- }
168- } else
169-#endif
170- // handle wired and SCO device connection (accessed via hardware output)
171- {
172-
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) {
181- newDevice = device;
182- } else if (mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_DTMF) &&
183- getDeviceForStrategy(STRATEGY_DTMF) == device) {
184- newDevice = device;
185- }
186- if ((mA2dpDeviceAddress == mScoDeviceAddress) &&
187- (mPhoneState != AudioSystem::MODE_NORMAL)) {
188- mpClientInterface->suspendOutput(mA2dpOutput);
189- }
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))) {
206- newDevice = device;
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)){
212- newDevice = device;
213- } else if (getDeviceForStrategy(STRATEGY_DTMF) == device &&
214- mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_DTMF)) {
215- newDevice = device;
216- }
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))) {
227- newDevice = device;
228- }
229-#endif // SUPPORT_DEVICE_OUT_TTY
230- }
231-
232- // request routing change if necessary
233- setOutputDevice(mHardwareOutput, newDevice);
234- }
235- break;
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;
241- }
242-
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;
253-
254-#ifdef WITH_A2DP
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;
261- }
262-
263- if (mA2dpDeviceAddress != device_address) {
264- LOGW("setDeviceConnectionState() disconnecting unknow A2DP sink address %s", device_address);
265- mAvailableOutputDevices |= device;
266- return INVALID_OPERATION;
267- }
268-
269- AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
270- AudioOutputDescriptor *a2dpOutputDesc = mOutputs.valueFor(mA2dpOutput);
271-
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);
276-
277- // If the A2DP device was used by DTMF strategy, move all streams pertaining to DTMF strategy to
278- // hardware output
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]);
285- }
286- }
287- if (a2dpOutputDesc->isUsedByStrategy(STRATEGY_DTMF)) {
288- newDevice = getDeviceForStrategy(STRATEGY_DTMF);
289- }
290- }
291-
292- // If the A2DP device was used by media strategy, move all streams pertaining to media strategy to
293- // hardware output
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]);
300- }
301- }
302- if (a2dpOutputDesc->isUsedByStrategy(STRATEGY_MEDIA)) {
303- newDevice = getDeviceForStrategy(STRATEGY_MEDIA);
304- }
305- }
306-
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
310- // media strategy.
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);
315- }
316- }
317- if (a2dpOutputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) {
318- newDevice = getDeviceForStrategy(STRATEGY_SONIFICATION);
319- }
320- }
321-
322- // close A2DP and duplicated outputs
323- AudioParameter param;
324- param.add(String8("closing"), String8("true"));
325- mpClientInterface->setParameters(mA2dpOutput, param.toString());
326-
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);
335- mA2dpOutput = 0;
336- } else
337-#endif
338- {
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);
348- }
349- if ((mA2dpDeviceAddress == mScoDeviceAddress) &&
350- (mPhoneState != AudioSystem::MODE_NORMAL)) {
351- mpClientInterface->restoreOutput(mA2dpOutput);
352- }
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);
378- }
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);
386- }
387-#endif // SUPPORT_DEVICE_OUT_TTY
388- }
389- }
390-
391- // request routing change if necessary
392- setOutputDevice(mHardwareOutput, newDevice);
393-
394- // clear A2DP and SCO device address if necessary
395-#ifdef WITH_A2DP
396- if (AudioSystem::isA2dpDevice(device)) {
397- mA2dpDeviceAddress = "";
398- }
399-#endif
400- if (AudioSystem::isBluetoothScoDevice(device)) {
401- mScoDeviceAddress = "";
402- }
403- } break;
404-
405- default:
406- LOGE("setDeviceConnectionState() invalid state: %x", state);
407- return BAD_VALUE;
408- }
409-
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;
416- } else {
417- return NO_ERROR;
418- }
419- }
420- // handle input devices
421- if (AudioSystem::isInputDevice(device)) {
422-
423- switch (state)
424- {
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;
430- }
431- mAvailableInputDevices |= device;
432- }
433- break;
434-
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;
440- }
441- mAvailableInputDevices &= ~device;
442- } break;
443-
444- default:
445- LOGE("setDeviceConnectionState() invalid state: %x", state);
446- return BAD_VALUE;
447- }
448-
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());
460- }
461- }
462-
463- return NO_ERROR;
464- }
465-
466- LOGW("setDeviceConnectionState() invalid device: %x", device);
467- return BAD_VALUE;
468-}
469-
470-AudioSystem::device_connection_state AudioPolicyManagerALSA::getDeviceConnectionState(AudioSystem::audio_devices device,
471- const char *device_address)
472-{
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) {
477-#ifdef WITH_A2DP
478- if (AudioSystem::isA2dpDevice(device) &&
479- address != "" && mA2dpDeviceAddress != address) {
480- return state;
481- }
482-#endif
483- if (AudioSystem::isBluetoothScoDevice(device) &&
484- address != "" && mScoDeviceAddress != address) {
485- return state;
486- }
487- state = AudioSystem::DEVICE_STATE_AVAILABLE;
488- }
489- } else if (AudioSystem::isInputDevice(device)) {
490- if (device & mAvailableInputDevices) {
491- state = AudioSystem::DEVICE_STATE_AVAILABLE;
492- }
493- }
494-
495- return state;
496-}
497-
498-void AudioPolicyManagerALSA::setPhoneState(int state)
499-{
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);
504- return;
505- }
506-
507- if (state == mPhoneState ) {
508- LOGW("setPhoneState() setting same state %d", state);
509- return;
510- }
511-
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);
518- }
519- }
520-
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;
525- mPhoneState = state;
526- bool force = false;
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
539- force = true;
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);
544- }
545-
546-
547- if (mA2dpOutput != 0) {
548- // If entering or exiting in call state, switch DTMF streams to/from A2DP output
549- // if necessary
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,
561- refCount);
562- mOutputs.valueFor(mA2dpOutput)->changeRefCount((AudioSystem::stream_type)i,-refCount);
563- }
564- }
565- if (newDevice == 0 && mOutputs.valueFor(mA2dpOutput)->isUsedByStrategy(STRATEGY_DTMF)) {
566- newDevice = newDtmfDevice;
567- }
568- }
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,
577- refCount);
578- mOutputs.valueFor(mDuplicatedOutput)->changeRefCount((AudioSystem::stream_type)i,-refCount);
579- }
580- }
581- }
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);
592- }
593- }
594- }
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);
604- }
605- }
606- }
607- }
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);
616- }
617- }
618- }
619-
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();
625- }
626- force = true;
627- }
628- // change routing is necessary
629- setOutputDevice(mHardwareOutput, newDevice, force);
630-
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);
637- }
638- }
639-}
640-
641-void AudioPolicyManagerALSA::setRingerMode(uint32_t mode, uint32_t mask)
642-{
643- LOGV("setRingerMode() mode %x, mask %x", mode, mask);
644-
645- mRingerMode = mode;
646-}
647-
648-void AudioPolicyManagerALSA::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
649-{
650- LOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
651-
652- switch(usage) {
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);
657- return;
658- }
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);
668- }
669- break;
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);
674- return;
675- }
676- mForceUse[usage] = config;
677- break;
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);
682- return;
683- }
684- mForceUse[usage] = config;
685- break;
686- default:
687- LOGW("setForceUse() invalid usage %d", usage);
688- break;
689- }
690-}
691-
692-AudioSystem::forced_config AudioPolicyManagerALSA::getForceUse(AudioSystem::force_use usage)
693-{
694- return mForceUse[usage];
695-}
696-
697-void AudioPolicyManagerALSA::setSystemProperty(const char* property, const char* value)
698-{
699- LOGV("setSystemProperty() property %s, value %s", property, value);
700- if (strcmp(property, "ro.camera.sound.forced") == 0) {
701- if (atoi(value)) {
702- LOGV("ENFORCED_AUDIBLE cannot be muted");
703- mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = false;
704- } else {
705- LOGV("ENFORCED_AUDIBLE can be muted");
706- mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = true;
707- }
708- }
709-}
710-
711-audio_io_handle_t AudioPolicyManagerALSA::getOutput(AudioSystem::stream_type stream,
712- uint32_t samplingRate,
713- uint32_t format,
714- uint32_t channels,
715- AudioSystem::output_flags flags)
716-{
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);
722-
723-
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))) {
729-
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,
744- outputDesc->mFlags);
745-
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);
753- delete outputDesc;
754- return 0;
755- }
756- mOutputs.add(output, outputDesc);
757- return output;
758- }
759-
760- if (channels != 0 && channels != AudioSystem::CHANNEL_OUT_MONO &&
761- channels != AudioSystem::CHANNEL_OUT_STEREO) {
762- return 0;
763- }
764- // open a non direct output
765-
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) {
770-#ifdef WITH_A2DP
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;
776- } else
777-#endif
778- {
779- // if playing on 2 devices among which none is A2DP, use hardware output
780- output = mHardwareOutput;
781- }
782- LOGV("getOutput() using output %d for 2 devices %x", output, device);
783- } else {
784-#ifdef WITH_A2DP
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;
789- } else
790-#endif
791- {
792- // if playing on not A2DP device, use hardware output
793- output = mHardwareOutput;
794- }
795- }
796-
797-
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);
800-
801- return output;
802-}
803-
804-status_t AudioPolicyManagerALSA::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
805-{
806- LOGV("startOutput() output %d, stream %d", output, stream);
807- ssize_t index = mOutputs.indexOfKey(output);
808- if (index < 0) {
809- LOGW("startOutput() unknow output %d", output);
810- return BAD_VALUE;
811- }
812-
813- AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
814- routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
815- uint32_t device = getDeviceForStrategy(strategy);
816-
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) {
822-#ifdef WITH_A2DP
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
826- device &= ~device2;
827- } else
828-#endif
829- {
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;
835- }
836- }
837- }
838-
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) {
848- newDevice = device;
849- } else if (!mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_PHONE)) {
850- if (strategy == STRATEGY_SONIFICATION) {
851- newDevice = device;
852- } else if (!mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_SONIFICATION)) {
853- if (strategy == STRATEGY_MEDIA) {
854- newDevice = device;
855- } else if (!mOutputs.valueFor(mHardwareOutput)->isUsedByStrategy(STRATEGY_MEDIA)) {
856- // strategy == STRATEGY_DTMF
857- newDevice = device;
858- }
859- }
860- }
861-
862- // TODO: maybe mute stream is selected device was refused
863- setOutputDevice(mHardwareOutput, newDevice);
864- }
865-
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);
870-
871- // handle special case for sonification while in call
872- if (mPhoneState == AudioSystem::MODE_IN_CALL) {
873- handleIncallSonification(stream, true, false);
874- }
875-
876- // apply volume rules for current stream and device if necessary
877- checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, outputDesc->device());
878-
879- return NO_ERROR;
880-}
881-
882-status_t AudioPolicyManagerALSA::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
883-{
884- LOGV("stopOutput() output %d, stream %d", output, stream);
885- ssize_t index = mOutputs.indexOfKey(output);
886- if (index < 0) {
887- LOGW("stopOutput() unknow output %d", output);
888- return BAD_VALUE;
889- }
890-
891- AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
892- routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
893-
894- // handle special case for sonification while in call
895- if (mPhoneState == AudioSystem::MODE_IN_CALL) {
896- handleIncallSonification(stream, false, false);
897- }
898-
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);
917- }
918-
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);
924- }
925- // store time at which the last music track was stopped - see computeVolume()
926- if (stream == AudioSystem::MUSIC) {
927- mMusicStopTime = systemTime();
928- }
929- return NO_ERROR;
930- } else {
931- LOGW("stopOutput() refcount is already 0 for output %d", output);
932- return INVALID_OPERATION;
933- }
934-}
935-
936-void AudioPolicyManagerALSA::releaseOutput(audio_io_handle_t output)
937-{
938- LOGV("releaseOutput() %d", output);
939- ssize_t index = mOutputs.indexOfKey(output);
940- if (index < 0) {
941- LOGW("releaseOutput() releasing unknown output %d", output);
942- return;
943- }
944- if (mOutputs.valueAt(index)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) {
945- mpClientInterface->closeOutput(output);
946- delete mOutputs.valueAt(index);
947- mOutputs.removeItem(output);
948- }
949-}
950-
951-audio_io_handle_t AudioPolicyManagerALSA::getInput(int inputSource,
952- uint32_t samplingRate,
953- uint32_t format,
954- uint32_t channels,
955- AudioSystem::audio_in_acoustics acoustics)
956-{
957- audio_io_handle_t input = 0;
958- uint32_t device = getDeviceForInputSource(inputSource);
959-
960- LOGV("getInput() inputSource %d, samplingRate %d, format %d, channels %x, acoustics %x", inputSource, samplingRate, format, channels, acoustics);
961-
962- if (device == 0) {
963- return 0;
964- }
965-
966- // adapt channel selection to input source
967- switch(inputSource) {
968- case AUDIO_SOURCE_VOICE_UPLINK:
969- channels = AudioSystem::CHANNEL_IN_VOICE_UPLINK;
970- break;
971- case AUDIO_SOURCE_VOICE_DOWNLINK:
972- channels = AudioSystem::CHANNEL_IN_VOICE_DNLINK;
973- break;
974- case AUDIO_SOURCE_VOICE_CALL:
975- channels = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK);
976- break;
977- default:
978- break;
979- }
980-
981- AudioInputDescriptor *inputDesc = new AudioInputDescriptor();
982-
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,
992- &inputDesc->mFormat,
993- &inputDesc->mChannels,
994- inputDesc->mAcoustics);
995-
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);
1003- delete inputDesc;
1004- return 0;
1005- }
1006- mInputs.add(input, inputDesc);
1007- return input;
1008-}
1009-
1010-status_t AudioPolicyManagerALSA::startInput(audio_io_handle_t input)
1011-{
1012- LOGV("startInput() input %d", input);
1013- ssize_t index = mInputs.indexOfKey(input);
1014- if (index < 0) {
1015- LOGW("startInput() unknow input %d", input);
1016- return BAD_VALUE;
1017- }
1018- AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
1019-
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;
1024- }
1025-
1026- AudioParameter param = AudioParameter();
1027- param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
1028- mpClientInterface->setParameters(input, param.toString());
1029-
1030- inputDesc->mRefCount = 1;
1031- return NO_ERROR;
1032-}
1033-
1034-status_t AudioPolicyManagerALSA::stopInput(audio_io_handle_t input)
1035-{
1036- LOGV("stopInput() input %d", input);
1037- ssize_t index = mInputs.indexOfKey(input);
1038- if (index < 0) {
1039- LOGW("stopInput() unknow input %d", input);
1040- return BAD_VALUE;
1041- }
1042- AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
1043-
1044- if (inputDesc->mRefCount == 0) {
1045- LOGW("stopInput() input %d already stopped", input);
1046- return INVALID_OPERATION;
1047- } else {
1048- AudioParameter param = AudioParameter();
1049- param.addInt(String8(AudioParameter::keyRouting), 0);
1050- mpClientInterface->setParameters(input, param.toString());
1051- inputDesc->mRefCount = 0;
1052- return NO_ERROR;
1053- }
1054-}
1055-
1056-void AudioPolicyManagerALSA::releaseInput(audio_io_handle_t input)
1057-{
1058- LOGV("releaseInput() %d", input);
1059- ssize_t index = mInputs.indexOfKey(input);
1060- if (index < 0) {
1061- LOGW("releaseInput() releasing unknown input %d", input);
1062- return;
1063- }
1064- mpClientInterface->closeInput(input);
1065- delete mInputs.valueAt(index);
1066- mInputs.removeItem(input);
1067- LOGV("releaseInput() exit");
1068-}
1069-
1070-
1071-
1072-void AudioPolicyManagerALSA::initStreamVolume(AudioSystem::stream_type stream,
1073- int indexMin,
1074- int indexMax)
1075-{
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);
1079- return;
1080- }
1081- mStreams[stream].mIndexMin = indexMin;
1082- mStreams[stream].mIndexMax = indexMax;
1083-}
1084-
1085-status_t AudioPolicyManagerALSA::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
1086-{
1087-
1088- if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
1089- return BAD_VALUE;
1090- }
1091-
1092- LOGV("setStreamVolumeIndex() stream %d, index %d", stream, index);
1093- mStreams[stream].mIndexCur = index;
1094-
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) {
1100- status = volStatus;
1101- }
1102- }
1103- return status;
1104-}
1105-
1106-status_t AudioPolicyManagerALSA::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
1107-{
1108- if (index == 0) {
1109- return BAD_VALUE;
1110- }
1111- LOGV("getStreamVolumeIndex() stream %d", stream);
1112- *index = mStreams[stream].mIndexCur;
1113- return NO_ERROR;
1114-}
1115-
1116-status_t AudioPolicyManagerALSA::dump(int fd)
1117-{
1118- const size_t SIZE = 256;
1119- char buffer[SIZE];
1120- String8 result;
1121-
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());
1149-
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);
1156- }
1157-
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);
1164- }
1165-
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));
1174- }
1175-
1176- return NO_ERROR;
1177-}
1178-
117925 // ----------------------------------------------------------------------------
118026 // AudioPolicyManagerALSA
118127 // ----------------------------------------------------------------------------
118228
118329 // --- class factory
118430
1185-
118631 extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
118732 {
118833 return new AudioPolicyManagerALSA(clientInterface);
@@ -1193,637 +38,15 @@ extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
119338 delete interface;
119439 }
119540
41+// Nothing currently different between the Base implementation.
42+
119643 AudioPolicyManagerALSA::AudioPolicyManagerALSA(AudioPolicyClientInterface *clientInterface)
1197-: mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0), mMusicStopTime(0)
44+ : AudioPolicyManagerBase(clientInterface)
119845 {
1199- mpClientInterface = clientInterface;
1200-
1201- for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {
1202- mForceUse[i] = AudioSystem::FORCE_NONE;
1203- }
1204-
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;
1209-
1210- mA2dpDeviceAddress = String8("");
1211- mScoDeviceAddress = String8("");
1212-
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);
1222-
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);
1226- } else {
1227- mOutputs.add(mHardwareOutput, outputDesc);
1228- setOutputDevice(mHardwareOutput, (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER, true);
1229- }
1230-
1231- mA2dpOutput = 0;
1232- mDuplicatedOutput = 0;
123346 }
123447
123548 AudioPolicyManagerALSA::~AudioPolicyManagerALSA()
123649 {
1237- for (size_t i = 0; i < mOutputs.size(); i++) {
1238- mpClientInterface->closeOutput(mOutputs.keyAt(i));
1239- delete mOutputs.valueAt(i);
1240- }
1241- mOutputs.clear();
1242- for (size_t i = 0; i < mInputs.size(); i++) {
1243- mpClientInterface->closeInput(mInputs.keyAt(i));
1244- delete mInputs.valueAt(i);
1245- }
1246- mInputs.clear();
1247-}
1248-
1249-// ---
1250-
1251-audio_io_handle_t AudioPolicyManagerALSA::getOutputForDevice(uint32_t device)
1252-{
1253- audio_io_handle_t output = 0;
1254- uint32_t lDevice;
1255-
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);
1259-
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);
1265- break;
1266- }
1267- }
1268- return output;
1269-}
1270-
1271-AudioPolicyManagerALSA::routing_strategy AudioPolicyManagerALSA::getStrategy(AudioSystem::stream_type stream)
1272-{
1273- // stream to strategy mapping
1274- switch (stream) {
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;
1285- default:
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;
1293- }
1294-}
1295-
1296-uint32_t AudioPolicyManagerALSA::getDeviceForStrategy(routing_strategy strategy)
1297-{
1298- uint32_t device = 0;
1299-
1300- switch (strategy) {
1301- case STRATEGY_DTMF:
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);
1305- break;
1306- }
1307- // when in call, DTMF and PHONE strategies follow the same rules
1308- // FALL THROUGH
1309-
1310- case STRATEGY_PHONE:
1311- // for phone strategy, we first consider the forced use and then the available devices by order
1312- // of priority
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;
1317- if (device) break;
1318- }
1319- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
1320- if (device) break;
1321- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
1322- if (device) break;
1323- // if SCO device is requested but no SCO device is available, fall back to default case
1324- // FALL THROUGH
1325-
1326- default: // FORCE_NONE
1327-#ifdef SUPPORT_DEVICE_OUT_TTY
1328- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_TTY;
1329- if (device) break;
1330-#endif // SUPPORT_DEVICE_OUT_TTY
1331- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
1332- if (device) break;
1333- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
1334- if (device) break;
1335- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
1336- if (device == 0) {
1337- LOGE("getDeviceForStrategy() earpiece device not found");
1338- }
1339- break;
1340-
1341- case AudioSystem::FORCE_SPEAKER:
1342- if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
1343- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
1344- if (device) break;
1345- }
1346- device = mAvailableOutputDevices;
1347- if (device) break;
1348- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
1349- if (device == 0) {
1350- LOGE("getDeviceForStrategy() speaker device not found");
1351- }
1352- break;
1353- }
1354- break;
1355-
1356- case STRATEGY_SONIFICATION:
1357-
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);
1362- break;
1363- }
1364- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
1365- if (device == 0) {
1366- LOGE("getDeviceForStrategy() speaker device not found");
1367- }
1368- // The second device used for sonification is the same as the device used by media strategy
1369- // FALL THROUGH
1370-
1371- case STRATEGY_MEDIA: {
1372- uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
1373- if (device2 == 0) {
1374- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
1375- if (device2 == 0) {
1376- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
1377- if (device2 == 0) {
1378- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
1379- if (device2 == 0) {
1380- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
1381- if (device2 == 0) {
1382- device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
1383- if (device2 == 0) {
1384- device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
1385- if (device == 0) {
1386- LOGE("getDeviceForStrategy() speaker device not found");
1387- }
1388- }
1389- }
1390- }
1391- }
1392- }
1393- }
1394- // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION, 0 otherwise
1395- device |= device2;
1396- // Do not play media stream if in call and the requested device would change the hardware
1397- // output routing
1398- if (mPhoneState == AudioSystem::MODE_IN_CALL &&
1399- !AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device) &&
1400- device != getDeviceForStrategy(STRATEGY_PHONE)) {
1401- device = 0;
1402- LOGV("getDeviceForStrategy() incompatible media and phone devices");
1403- }
1404- } break;
1405-
1406- default:
1407- LOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
1408- break;
1409- }
1410-
1411- LOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
1412- return device;
1413-}
1414-
1415-void AudioPolicyManagerALSA::setOutputDevice(audio_io_handle_t output, uint32_t device, bool force, int delayMs)
1416-{
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);
1420- return;
1421- }
1422-#ifdef WITH_A2DP
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");
1429- device &= ~device2;
1430- }
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)
1434- // in this case
1435- device &= ~AudioSystem::DEVICE_OUT_SPEAKER;
1436- }
1437-#endif
1438-
1439- // doing this check here allows the caller to call setOutputDevice() without conditions
1440- if (device == 0) return;
1441-
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);
1447- return;
1448- }
1449-
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);
1457- }
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);
1462- }
1463- }
1464- // do the routing
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);
1470-
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);
1476- }
1477- }
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);
1482- }
1483-}
1484-
1485-uint32_t AudioPolicyManagerALSA::getDeviceForInputSource(int inputSource)
1486-{
1487- uint32_t device;
1488-
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;
1498- } else {
1499- device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
1500- }
1501- break;
1502- case AUDIO_SOURCE_CAMCORDER:
1503- device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
1504- break;
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;
1509- break;
1510- default:
1511- LOGW("getInput() invalid input source %d", inputSource);
1512- device = 0;
1513- break;
1514- }
1515- return device;
1516-}
1517-
1518-audio_io_handle_t AudioPolicyManagerALSA::getActiveInput()
1519-{
1520- for (size_t i = 0; i < mInputs.size(); i++) {
1521- if (mInputs.valueAt(i)->mRefCount > 0) {
1522- return mInputs.keyAt(i);
1523- }
1524- }
1525- return 0;
152650 }
152751
1528-float AudioPolicyManagerALSA::computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device)
1529-{
1530- float volume = 1.0;
1531- AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
1532- StreamDescriptor &streamDesc = mStreams[stream];
1533-
1534- // Force max volume if stream cannot be muted
1535- if (!streamDesc.mCanBeMuted) index = streamDesc.mIndexMax;
1536-
1537- if (device == 0) {
1538- device = outputDesc->device();
1539- }
1540-
1541- int volInt = (100 * (index - streamDesc.mIndexMin)) / (streamDesc.mIndexMax - streamDesc.mIndexMin);
1542- volume = AudioSystem::linearToLog(volInt);
1543-
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.
1549- if ((device &
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
1558- // just stopped
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) {
1565- volume = minVol;
1566- LOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
1567- }
1568- }
1569- }
1570-
1571- return volume;
1572-}
1573-
1574-status_t AudioPolicyManagerALSA::checkAndSetVolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayMs, bool force)
1575-{
1576-
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);
1580- return NO_ERROR;
1581- }
1582-
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;
1589- }
1590-
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) {
1606- voiceVolume = 1.0;
1607- }
1608- if (voiceVolume >= 0 && output == mHardwareOutput) {
1609- mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
1610- }
1611- }
1612- mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
1613- }
1614-
1615- return NO_ERROR;
1616-}
1617-
1618-void AudioPolicyManagerALSA::applyStreamVolumes(audio_io_handle_t output, uint32_t device, int delayMs)
1619-{
1620- LOGV("applyStreamVolumes() for output %d and device %x", output, device);
1621-
1622- for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
1623- checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, device, delayMs);
1624- }
1625-}
1626-
1627-void AudioPolicyManagerALSA::setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output, int delayMs)
1628-{
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);
1633- }
1634- }
1635-}
1636-
1637-void AudioPolicyManagerALSA::setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs)
1638-{
1639- StreamDescriptor &streamDesc = mStreams[stream];
1640- uint32_t device = mOutputs.valueFor(output)->mDevice;
1641-
1642- LOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d", stream, on, output, streamDesc.mMuteCount);
1643-
1644- if (on) {
1645- if (streamDesc.mMuteCount == 0) {
1646- if (streamDesc.mCanBeMuted) {
1647- checkAndSetVolume(stream, 0, output, device, delayMs);
1648- }
1649- }
1650- // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
1651- streamDesc.mMuteCount++;
1652- } else {
1653- if (streamDesc.mMuteCount == 0) {
1654- LOGW("setStreamMute() unmuting non muted stream!");
1655- return;
1656- }
1657- if (--streamDesc.mMuteCount == 0) {
1658- checkAndSetVolume(stream, streamDesc.mIndexCur, output, device, delayMs);
1659- }
1660- }
1661-}
1662-
1663-void AudioPolicyManagerALSA::handleIncallSonification(int stream, bool starting, bool stateChange)
1664-{
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
1671-
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)) {
1677- int muteCount = 1;
1678- if (stateChange) {
1679- muteCount = outputDesc->mRefCount[stream];
1680- }
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);
1685- }
1686- } else {
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);
1692- }
1693- }
1694- if (starting) {
1695- mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL);
1696- } else {
1697- mpClientInterface->stopTone();
1698- }
1699- }
1700- }
1701- }
1702-}
1703-
1704-
1705-// --- AudioOutputDescriptor class implementation
1706-
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)
1710-{
1711- // clear usage count for all stream types
1712- for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
1713- mRefCount[i] = 0;
1714- mCurVolume[i] = -1.0;
1715- }
1716-}
1717-
1718-uint32_t AudioPolicyManagerALSA::AudioOutputDescriptor::device()
1719-{
1720- uint32_t device = 0;
1721- if (isDuplicated()) {
1722- device = mOutput1->mDevice | mOutput2->mDevice;
1723- } else {
1724- device = mDevice;
1725- }
1726- return device;
1727-}
1728-
1729-void AudioPolicyManagerALSA::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta)
1730-{
1731- // forward usage count change to attached outputs
1732- if (isDuplicated()) {
1733- mOutput1->changeRefCount(stream, delta);
1734- mOutput2->changeRefCount(stream, delta);
1735- }
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;
1739- return;
1740- }
1741- mRefCount[stream] += delta;
1742- LOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
1743-}
1744-
1745-bool AudioPolicyManagerALSA::AudioOutputDescriptor::isUsedByStrategy(routing_strategy strategy)
1746-{
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)) {
1750- return true;
1751- }
1752- }
1753- return false;
1754-}
1755-
1756-status_t AudioPolicyManagerALSA::AudioOutputDescriptor::dump(int fd)
1757-{
1758- const size_t SIZE = 256;
1759- char buffer[SIZE];
1760- String8 result;
1761-
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);
1779- }
1780- write(fd, result.string(), result.size());
1781-
1782- return NO_ERROR;
1783-}
1784-
1785-// --- AudioInputDescriptor class implementation
1786-
1787-AudioPolicyManagerALSA::AudioInputDescriptor::AudioInputDescriptor()
1788- : mSamplingRate(0), mFormat(0), mChannels(0),
1789- mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0)
1790-{
1791-}
1792-
1793-status_t AudioPolicyManagerALSA::AudioInputDescriptor::dump(int fd)
1794-{
1795- const size_t SIZE = 256;
1796- char buffer[SIZE];
1797- String8 result;
1798-
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());
1812-
1813- return NO_ERROR;
1814-}
1815-
1816-// --- StreamDescriptor class implementation
1817-
1818-void AudioPolicyManagerALSA::StreamDescriptor::dump(char* buffer, size_t size)
1819-{
1820- snprintf(buffer, size, " %02d %02d %02d %02d %d\n",
1821- mIndexMin,
1822- mIndexMax,
1823- mIndexCur,
1824- mMuteCount,
1825- mCanBeMuted);
1826-}
1827-
1828-
182952 }; // namespace android
--- a/AudioPolicyManagerALSA.h
+++ b/AudioPolicyManagerALSA.h
@@ -20,7 +20,7 @@
2020 #include <utils/Timers.h>
2121 #include <utils/Errors.h>
2222 #include <utils/KeyedVector.h>
23-#include <hardware_legacy/AudioPolicyInterface.h>
23+#include <hardware_legacy/AudioPolicyManagerBase.h>
2424
2525
2626 namespace android {
@@ -35,167 +35,14 @@ namespace android {
3535 // Time in seconds during which we consider that music is still active after a music
3636 // track was stopped - see computeVolume()
3737 #define SONIFICATION_HEADSET_MUSIC_DELAY 5
38-class AudioPolicyManagerALSA: public AudioPolicyInterface
38+class AudioPolicyManagerALSA: public AudioPolicyManagerBase
3939 {
4040
4141 public:
4242 AudioPolicyManagerALSA(AudioPolicyClientInterface *clientInterface);
4343 virtual ~AudioPolicyManagerALSA();
4444
45- // AudioPolicyInterface
46- virtual status_t setDeviceConnectionState(AudioSystem::audio_devices device,
47- AudioSystem::device_connection_state state,
48- const char *device_address);
49- virtual AudioSystem::device_connection_state getDeviceConnectionState(AudioSystem::audio_devices device,
50- const char *device_address);
51- virtual void setPhoneState(int state);
52- virtual void setRingerMode(uint32_t mode, uint32_t mask);
53- virtual void setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config);
54- virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage);
55- virtual void setSystemProperty(const char* property, const char* value);
56- virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream,
57- uint32_t samplingRate,
58- uint32_t format,
59- uint32_t channels,
60- AudioSystem::output_flags flags);
61- virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream);
62- virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream);
63- virtual void releaseOutput(audio_io_handle_t output);
64- virtual audio_io_handle_t getInput(int inputSource,
65- uint32_t samplingRate,
66- uint32_t format,
67- uint32_t channels,
68- AudioSystem::audio_in_acoustics acoustics);
69- // indicates to the audio policy manager that the input starts being used.
70- virtual status_t startInput(audio_io_handle_t input);
71- // indicates to the audio policy manager that the input stops being used.
72- virtual status_t stopInput(audio_io_handle_t input);
73- virtual void releaseInput(audio_io_handle_t input);
74- virtual void initStreamVolume(AudioSystem::stream_type stream,
75- int indexMin,
76- int indexMax);
77- virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index);
78- virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index);
79-
80- virtual status_t dump(int fd);
81-
82-private:
83-
84- enum routing_strategy {
85- STRATEGY_MEDIA,
86- STRATEGY_PHONE,
87- STRATEGY_SONIFICATION,
88- STRATEGY_DTMF,
89- NUM_STRATEGIES
90- };
91-
92- // descriptor for audio outputs. Used to maintain current configuration of each opened audio output
93- // and keep track of the usage of this output by each audio stream type.
94- class AudioOutputDescriptor
95- {
96- public:
97- AudioOutputDescriptor();
98-
99- status_t dump(int fd);
100-
101- uint32_t device();
102- void changeRefCount(AudioSystem::stream_type, int delta);
103- bool isUsedByStrategy(routing_strategy strategy);
104- bool isUsedByStream(AudioSystem::stream_type stream) { return mRefCount[stream] > 0 ? true : false; }
105- bool isDuplicated() { return (mDevice == 0); } // by convention mDevice is 0 for duplicated outputs
106-
107- uint32_t mSamplingRate; //
108- uint32_t mFormat; //
109- uint32_t mChannels; // output configuration
110- uint32_t mLatency; //
111- AudioSystem::output_flags mFlags; //
112- uint32_t mDevice; // current device this output is routed to
113- uint32_t mRefCount[AudioSystem::NUM_STREAM_TYPES]; // number of streams of each type using this output
114- AudioOutputDescriptor *mOutput1; // used by duplicated outputs: first output
115- AudioOutputDescriptor *mOutput2; // used by duplicated outputs: second output
116- float mCurVolume[AudioSystem::NUM_STREAM_TYPES]; // current stream volume
117- };
118-
119- // descriptor for audio inputs. Used to maintain current configuration of each opened audio input
120- // and keep track of the usage of this input.
121- class AudioInputDescriptor
122- {
123- public:
124- AudioInputDescriptor();
125-
126- status_t dump(int fd);
127-
128- uint32_t mSamplingRate; //
129- uint32_t mFormat; // input configuration
130- uint32_t mChannels; //
131- AudioSystem::audio_in_acoustics mAcoustics; //
132- uint32_t mDevice; // current device this input is routed to
133- uint32_t mRefCount; // number of AudioRecord clients using this output
134- int mInputSource; // input source selected by application (mediarecorder.h)
135- };
136-
137- // stream descriptor used for volume control
138- class StreamDescriptor
139- {
140- public:
141- StreamDescriptor()
142- : mIndexMin(0), mIndexMax(1), mIndexCur(1), mMuteCount(0), mCanBeMuted(true) {}
143-
144- void dump(char* buffer, size_t size);
145-
146- int mIndexMin; // min volume index
147- int mIndexMax; // max volume index
148- int mIndexCur; // current volume index
149- int mMuteCount; // mute request counter
150- bool mCanBeMuted; // true is the stream can be muted
151- };
152-
153- // return the strategy corresponding to a given stream type
154- static routing_strategy getStrategy(AudioSystem::stream_type stream);
155- // return the output handle of an output routed to the specified device, 0 if no output
156- // is routed to the device
157- audio_io_handle_t getOutputForDevice(uint32_t device);
158- // return appropriate device for streams handled by the specified strategy according to current
159- // phone state, connected devices...
160- uint32_t getDeviceForStrategy(routing_strategy strategy);
161- // change the route of the specified output
162- void setOutputDevice(audio_io_handle_t output, uint32_t device, bool force = false, int delayMs = 0);
163- // select input device corresponding to requested audio source
164- uint32_t getDeviceForInputSource(int inputSource);
165- // return io handle of active input or 0 if no input is active
166- audio_io_handle_t getActiveInput();
167- // compute the actual volume for a given stream according to the requested index and a particular
168- // device
169- float computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device);
170- // check that volume change is permitted, compute and send new volume to audio hardware
171- status_t checkAndSetVolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayMs = 0, bool force = false);
172- // apply all stream volumes to the specified output and device
173- void applyStreamVolumes(audio_io_handle_t output, uint32_t device, int delayMs = 0);
174- // Mute or unmute all streams handled by the specified strategy on the specified output
175- void setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output, int delayMs = 0);
176- // Mute or unmute the stream on the specified output
177- void setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs = 0);
178- // handle special cases for sonification strategy while in call: mute streams or replace by
179- // a special tone in the device used for communication
180- void handleIncallSonification(int stream, bool starting, bool stateChange);
181-
182- AudioPolicyClientInterface *mpClientInterface; // audio policy client interface
183- audio_io_handle_t mHardwareOutput; // hardware output handler
184- audio_io_handle_t mA2dpOutput; // A2DP output handler
185- audio_io_handle_t mDuplicatedOutput; // duplicated output handler: outputs to hardware and A2DP.
186-
187- KeyedVector<audio_io_handle_t, AudioOutputDescriptor *> mOutputs; // list of output descriptors
188- KeyedVector<audio_io_handle_t, AudioInputDescriptor *> mInputs; // list of input descriptors
189- uint32_t mAvailableOutputDevices; // bit field of all available output devices
190- uint32_t mAvailableInputDevices; // bit field of all available input devices
191- int mPhoneState; // current phone state
192- uint32_t mRingerMode; // current ringer mode
193- AudioSystem::forced_config mForceUse[AudioSystem::NUM_FORCE_USE]; // current forced use configuration
194-
195- StreamDescriptor mStreams[AudioSystem::NUM_STREAM_TYPES]; // stream descriptors for volume control
196- String8 mA2dpDeviceAddress; // A2DP device MAC address
197- String8 mScoDeviceAddress; // SCO device MAC address
198- nsecs_t mMusicStopTime; // time when last music stream was stopped
45+ // Nothing currently different between the Base implementation.
19946 };
20047
20148 };
Show on old repository browser