manual merge for b9c9d260f2

Merge commit 'b9c9d260f21b321527c4622a123af9767630d94d'
This commit is contained in:
The Android Open Source Project
2009-05-06 15:43:48 -07:00
3 changed files with 219 additions and 38 deletions

View File

@@ -65947,7 +65947,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<parameter name="mode" type="int">
@@ -66158,7 +66158,7 @@
synchronized="false"
static="false"
final="false"
deprecated="not deprecated"
deprecated="deprecated"
visibility="public"
>
<parameter name="mode" type="int">

View File

@@ -642,7 +642,9 @@ public class AudioManager {
* <var>false</var> to turn it off
*/
public void setSpeakerphoneOn(boolean on){
setRouting(MODE_IN_CALL, on ? ROUTE_SPEAKER : ROUTE_EARPIECE, ROUTE_ALL);
// Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
// MODE_INVALID indicates to AudioService that setRouting() was initiated by AudioManager
setRoutingP(MODE_INVALID, on ? ROUTE_SPEAKER: 0, ROUTE_SPEAKER);
}
/**
@@ -651,7 +653,7 @@ public class AudioManager {
* @return true if speakerphone is on, false if it's off
*/
public boolean isSpeakerphoneOn() {
return (getRouting(MODE_IN_CALL) & ROUTE_SPEAKER) == 0 ? false : true;
return (getRoutingP(MODE_IN_CALL) & ROUTE_SPEAKER) == 0 ? false : true;
}
/**
@@ -661,14 +663,9 @@ public class AudioManager {
* headset; <var>false</var> to route audio to/from phone earpiece
*/
public void setBluetoothScoOn(boolean on){
// Don't disable A2DP when turning off SCO.
// A2DP does not affect in-call routing.
setRouting(MODE_RINGTONE,
on ? ROUTE_BLUETOOTH_SCO: ROUTE_SPEAKER, ROUTE_ALL & ~ROUTE_BLUETOOTH_A2DP);
setRouting(MODE_NORMAL,
on ? ROUTE_BLUETOOTH_SCO: ROUTE_SPEAKER, ROUTE_ALL & ~ROUTE_BLUETOOTH_A2DP);
setRouting(MODE_IN_CALL,
on ? ROUTE_BLUETOOTH_SCO: ROUTE_EARPIECE, ROUTE_ALL);
// Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
// MODE_INVALID indicates to AudioService that setRouting() was initiated by AudioManager
setRoutingP(MODE_INVALID, on ? ROUTE_BLUETOOTH_SCO: 0, ROUTE_BLUETOOTH_SCO);
}
/**
@@ -678,7 +675,7 @@ public class AudioManager {
* false if otherwise
*/
public boolean isBluetoothScoOn() {
return (getRouting(MODE_IN_CALL) & ROUTE_BLUETOOTH_SCO) == 0 ? false : true;
return (getRoutingP(MODE_IN_CALL) & ROUTE_BLUETOOTH_SCO) == 0 ? false : true;
}
/**
@@ -688,12 +685,9 @@ public class AudioManager {
* headset; <var>false</var> disable A2DP audio
*/
public void setBluetoothA2dpOn(boolean on){
// the audio flinger chooses A2DP as a higher priority,
// so there is no need to disable other routes.
setRouting(MODE_RINGTONE,
on ? ROUTE_BLUETOOTH_A2DP: 0, ROUTE_BLUETOOTH_A2DP);
setRouting(MODE_NORMAL,
on ? ROUTE_BLUETOOTH_A2DP: 0, ROUTE_BLUETOOTH_A2DP);
// Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
// MODE_INVALID indicates to AudioService that setRouting() was initiated by AudioManager
setRoutingP(MODE_INVALID, on ? ROUTE_BLUETOOTH_A2DP: 0, ROUTE_BLUETOOTH_A2DP);
}
/**
@@ -703,7 +697,7 @@ public class AudioManager {
* false if otherwise
*/
public boolean isBluetoothA2dpOn() {
return (getRouting(MODE_NORMAL) & ROUTE_BLUETOOTH_A2DP) == 0 ? false : true;
return (getRoutingP(MODE_NORMAL) & ROUTE_BLUETOOTH_A2DP) == 0 ? false : true;
}
/**
@@ -714,14 +708,9 @@ public class AudioManager {
* @hide
*/
public void setWiredHeadsetOn(boolean on){
// A2DP has higher priority than wired headset, so headset connect/disconnect events
// should not affect A2DP routing
setRouting(MODE_NORMAL,
on ? ROUTE_HEADSET : ROUTE_SPEAKER, ROUTE_ALL & ~ROUTE_BLUETOOTH_A2DP);
setRouting(MODE_RINGTONE,
on ? ROUTE_HEADSET | ROUTE_SPEAKER : ROUTE_SPEAKER, ROUTE_ALL & ~ROUTE_BLUETOOTH_A2DP);
setRouting(MODE_IN_CALL,
on ? ROUTE_HEADSET : ROUTE_EARPIECE, ROUTE_ALL);
// Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
// MODE_INVALID indicates to AudioService that setRouting() was initiated by AudioManager
setRoutingP(MODE_INVALID, on ? ROUTE_HEADSET: 0, ROUTE_HEADSET);
}
/**
@@ -732,7 +721,7 @@ public class AudioManager {
* @hide
*/
public boolean isWiredHeadsetOn() {
return (getRouting(MODE_NORMAL) & ROUTE_HEADSET) == 0 ? false : true;
return (getRoutingP(MODE_NORMAL) & ROUTE_HEADSET) == 0 ? false : true;
}
/**
@@ -860,7 +849,11 @@ public class AudioManager {
* more of ROUTE_xxx types. Set bits indicate that route should be on
* @param mask bit vector of routes to change, created from one or more of
* ROUTE_xxx types. Unset bits indicate the route should be left unchanged
*
* @deprecated Do not set audio routing directly, use setSpeakerphoneOn(),
* setBluetoothScoOn(), setBluetoothA2dpOn() and setWiredHeadsetOn() methods instead.
*/
public void setRouting(int mode, int routes, int mask) {
IAudioService service = getService();
try {
@@ -876,7 +869,10 @@ public class AudioManager {
* @param mode audio mode to get route (e.g., MODE_RINGTONE)
* @return an audio route bit vector that can be compared with ROUTE_xxx
* bits
* @deprecated Do not query audio routing directly, use isSpeakerphoneOn(),
* isBluetoothScoOn(), isBluetoothA2dpOn() and isWiredHeadsetOn() methods instead.
*/
@Deprecated
public int getRouting(int mode) {
IAudioService service = getService();
try {
@@ -1076,4 +1072,31 @@ public class AudioManager {
* {@hide}
*/
private IBinder mICallBack = new Binder();
/**
* {@hide}
*/
private void setRoutingP(int mode, int routes, int mask) {
IAudioService service = getService();
try {
service.setRouting(mode, routes, mask);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in setRouting", e);
}
}
/**
* {@hide}
*/
private int getRoutingP(int mode) {
IAudioService service = getService();
try {
return service.getRouting(mode);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in getRouting", e);
return -1;
}
}
}

View File

@@ -100,6 +100,10 @@ public class AudioService extends IAudioService.Stub {
private int[] mRoutes = new int[AudioSystem.NUM_MODES];
private Object mSettingsLock = new Object();
private boolean mMediaServerOk;
private boolean mSpeakerIsOn;
private boolean mBluetoothScoIsConnected;
private boolean mHeadsetIsConnected;
private boolean mBluetoothA2dpIsConnected;
private SoundPool mSoundPool;
private Object mSoundEffectsLock = new Object();
@@ -189,6 +193,10 @@ public class AudioService extends IAudioService.Stub {
mMediaServerOk = true;
AudioSystem.setErrorCallback(mAudioSystemCallback);
loadSoundEffects();
mSpeakerIsOn = false;
mBluetoothScoIsConnected = false;
mHeadsetIsConnected = false;
mBluetoothA2dpIsConnected = false;
}
private void createAudioSystemThread() {
@@ -606,8 +614,9 @@ public class AudioService extends IAudioService.Stub {
}
synchronized (mSettingsLock) {
if (mode != mMode) {
AudioSystem.setMode(mode);
mMode = mode;
if (AudioSystem.setMode(mode) == AudioSystem.AUDIO_STATUS_OK) {
mMode = mode;
}
}
int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
int index = mStreamStates[streamType].mIndex;
@@ -623,18 +632,167 @@ public class AudioService extends IAudioService.Stub {
/** @see AudioManager#setRouting(int, int, int) */
public void setRouting(int mode, int routes, int mask) {
int incallMask = 0;
int ringtoneMask = 0;
int normalMask = 0;
if (!checkAudioSettingsPermission("setRouting()")) {
return;
}
synchronized (mSettingsLock) {
if ((mRoutes[mode] & mask) != (routes & mask)) {
AudioSystem.setRouting(mode, routes, mask);
mRoutes[mode] = (mRoutes[mode] & ~mask) | (routes & mask);
// Temporary fix for issue #1713090 until audio routing is refactored in eclair release.
// mode AudioSystem.MODE_INVALID is used only by the following AudioManager methods:
// setWiredHeadsetOn(), setBluetoothA2dpOn(), setBluetoothScoOn() and setSpeakerphoneOn().
// If applications are using AudioManager.setRouting() that is now deprecated, the routing
// command will be ignored.
if (mode == AudioSystem.MODE_INVALID) {
switch (mask) {
case AudioSystem.ROUTE_SPEAKER:
// handle setSpeakerphoneOn()
if (routes != 0 && !mSpeakerIsOn) {
mSpeakerIsOn = true;
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_SPEAKER;
incallMask = AudioSystem.ROUTE_ALL;
} else if (mSpeakerIsOn) {
mSpeakerIsOn = false;
if (mBluetoothScoIsConnected) {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_BLUETOOTH_SCO;
} else if (mHeadsetIsConnected) {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_HEADSET;
} else {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_EARPIECE;
}
incallMask = AudioSystem.ROUTE_ALL;
}
break;
case AudioSystem.ROUTE_BLUETOOTH_SCO:
// handle setBluetoothScoOn()
if (routes != 0 && !mBluetoothScoIsConnected) {
mBluetoothScoIsConnected = true;
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_BLUETOOTH_SCO;
mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
AudioSystem.ROUTE_BLUETOOTH_SCO;
mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
AudioSystem.ROUTE_BLUETOOTH_SCO;
incallMask = AudioSystem.ROUTE_ALL;
// A2DP has higher priority than SCO headset, so headset connect/disconnect events
// should not affect A2DP routing
ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
} else if (mBluetoothScoIsConnected) {
mBluetoothScoIsConnected = false;
if (mHeadsetIsConnected) {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_HEADSET;
mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
(AudioSystem.ROUTE_HEADSET|AudioSystem.ROUTE_SPEAKER);
mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
AudioSystem.ROUTE_HEADSET;
} else {
if (mSpeakerIsOn) {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_SPEAKER;
} else {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_EARPIECE;
}
mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
AudioSystem.ROUTE_SPEAKER;
mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
AudioSystem.ROUTE_SPEAKER;
}
incallMask = AudioSystem.ROUTE_ALL;
// A2DP has higher priority than SCO headset, so headset connect/disconnect events
// should not affect A2DP routing
ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
}
break;
case AudioSystem.ROUTE_HEADSET:
// handle setWiredHeadsetOn()
if (routes != 0 && !mHeadsetIsConnected) {
mHeadsetIsConnected = true;
// do not act upon headset connection if bluetooth SCO is connected to match phone app behavior
if (!mBluetoothScoIsConnected) {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_HEADSET;
mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
(AudioSystem.ROUTE_HEADSET|AudioSystem.ROUTE_SPEAKER);
mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
AudioSystem.ROUTE_HEADSET;
incallMask = AudioSystem.ROUTE_ALL;
// A2DP has higher priority than wired headset, so headset connect/disconnect events
// should not affect A2DP routing
ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
}
} else if (mHeadsetIsConnected) {
mHeadsetIsConnected = false;
// do not act upon headset disconnection if bluetooth SCO is connected to match phone app behavior
if (!mBluetoothScoIsConnected) {
if (mSpeakerIsOn) {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_SPEAKER;
} else {
mRoutes[AudioSystem.MODE_IN_CALL] = AudioSystem.ROUTE_EARPIECE;
}
mRoutes[AudioSystem.MODE_RINGTONE] = (mRoutes[AudioSystem.MODE_RINGTONE] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
AudioSystem.ROUTE_SPEAKER;
mRoutes[AudioSystem.MODE_NORMAL] = (mRoutes[AudioSystem.MODE_NORMAL] & AudioSystem.ROUTE_BLUETOOTH_A2DP) |
AudioSystem.ROUTE_SPEAKER;
incallMask = AudioSystem.ROUTE_ALL;
// A2DP has higher priority than wired headset, so headset connect/disconnect events
// should not affect A2DP routing
ringtoneMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
normalMask = AudioSystem.ROUTE_ALL & ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
}
}
break;
case AudioSystem.ROUTE_BLUETOOTH_A2DP:
// handle setBluetoothA2dpOn()
if (routes != 0 && !mBluetoothA2dpIsConnected) {
mBluetoothA2dpIsConnected = true;
mRoutes[AudioSystem.MODE_RINGTONE] |= AudioSystem.ROUTE_BLUETOOTH_A2DP;
mRoutes[AudioSystem.MODE_NORMAL] |= AudioSystem.ROUTE_BLUETOOTH_A2DP;
// the audio flinger chooses A2DP as a higher priority,
// so there is no need to disable other routes.
ringtoneMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
normalMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
} else if (mBluetoothA2dpIsConnected) {
mBluetoothA2dpIsConnected = false;
mRoutes[AudioSystem.MODE_RINGTONE] &= ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
mRoutes[AudioSystem.MODE_NORMAL] &= ~AudioSystem.ROUTE_BLUETOOTH_A2DP;
// the audio flinger chooses A2DP as a higher priority,
// so there is no need to disable other routes.
ringtoneMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
normalMask = AudioSystem.ROUTE_BLUETOOTH_A2DP;
}
break;
}
// incallMask is != 0 means we must apply ne routing to MODE_IN_CALL mode
if (incallMask != 0) {
AudioSystem.setRouting(AudioSystem.MODE_IN_CALL,
mRoutes[AudioSystem.MODE_IN_CALL],
incallMask);
}
// ringtoneMask is != 0 means we must apply ne routing to MODE_RINGTONE mode
if (ringtoneMask != 0) {
AudioSystem.setRouting(AudioSystem.MODE_RINGTONE,
mRoutes[AudioSystem.MODE_RINGTONE],
ringtoneMask);
}
// normalMask is != 0 means we must apply ne routing to MODE_NORMAL mode
if (normalMask != 0) {
AudioSystem.setRouting(AudioSystem.MODE_NORMAL,
mRoutes[AudioSystem.MODE_NORMAL],
normalMask);
}
int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
int index = mStreamStates[streamType].mIndex;
syncRingerAndNotificationStreamVolume(streamType, index, true);
setStreamVolumeInt(streamType, index, true);
}
int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
int index = mStreamStates[streamType].mIndex;
syncRingerAndNotificationStreamVolume(streamType, index, true);
setStreamVolumeInt(streamType, index, true);
}
}