Skip to content

Commit 90fb2dd

Browse files
Eric LaurentAndroid (Google) Code Review
authored andcommitted
Merge "AudioManager: restore setBluetoothA2dpOn() method" into jb-dev
2 parents 6385ff5 + 7847211 commit 90fb2dd

File tree

4 files changed

+80
-10
lines changed

4 files changed

+80
-10
lines changed

media/java/android/media/AudioManager.java

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,25 +1270,42 @@ public boolean isBluetoothScoOn() {
12701270
}
12711271

12721272
/**
1273-
* @param on set <var>true</var> to route A2DP audio to/from Bluetooth
1274-
* headset; <var>false</var> disable A2DP audio
1273+
* Allow or disallow use of Bluetooth A2DP for media.
1274+
* <p>The default behavior of the system is to use A2DP for media playback whenever an A2DP sink
1275+
* is connected. Applications can use this method to override this behavior.
1276+
* Note that the request will not persist after a wired headset or an A2DP sink is connected or
1277+
* disconnected:
1278+
* - Connection of an A2DP sink automatically enables use of A2DP.
1279+
* - Connection of a wired headset automatically disables use of A2DP.
1280+
* - Disconnection of a wired headset automatically enables use of A2DP if an A2DP sink is
1281+
* connected.
1282+
* <p>Requires Permission:
1283+
* {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
1284+
* @param on set <var>true</var> to allow use of A2DP for media (default).
1285+
* <var>false</var> to disallow use of A2DP for media.
12751286
* @deprecated Do not use.
12761287
*/
12771288
@Deprecated public void setBluetoothA2dpOn(boolean on){
1289+
IAudioService service = getService();
1290+
try {
1291+
service.setBluetoothA2dpOn(on);
1292+
} catch (RemoteException e) {
1293+
Log.e(TAG, "Dead object in setBluetoothA2dpOn", e);
1294+
}
12781295
}
12791296

12801297
/**
1281-
* Checks whether A2DP audio routing to the Bluetooth headset is on or off.
1298+
* Checks whether use of A2DP sinks is enabled for media.
12821299
*
1283-
* @return true if A2DP audio is being routed to/from Bluetooth headset;
1284-
* false if otherwise
1300+
* @return true if use of A2DP is enabled for media, false otherwise.
12851301
*/
12861302
public boolean isBluetoothA2dpOn() {
1287-
if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_BLUETOOTH_A2DP,"")
1288-
== AudioSystem.DEVICE_STATE_UNAVAILABLE) {
1303+
IAudioService service = getService();
1304+
try {
1305+
return service.isBluetoothA2dpOn();
1306+
} catch (RemoteException e) {
1307+
Log.e(TAG, "Dead object in isBluetoothA2dpOn", e);
12891308
return false;
1290-
} else {
1291-
return true;
12921309
}
12931310
}
12941311

media/java/android/media/AudioService.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,10 @@ public void onError(int error) {
392392

393393
private int mDeviceOrientation = Configuration.ORIENTATION_UNDEFINED;
394394

395+
// Request to override default use of A2DP for media.
396+
private boolean mBluetoothA2dpEnabled;
397+
private final Object mBluetoothA2dpEnabledLock = new Object();
398+
395399
///////////////////////////////////////////////////////////////////////////
396400
// Construction
397401
///////////////////////////////////////////////////////////////////////////
@@ -481,6 +485,7 @@ public AudioService(Context context) {
481485

482486
mMasterVolumeRamp = context.getResources().getIntArray(
483487
com.android.internal.R.array.config_masterVolumeRamp);
488+
484489
}
485490

486491
private void createAudioSystemThread() {
@@ -1651,6 +1656,21 @@ public boolean isBluetoothScoOn() {
16511656
return (mForcedUseForComm == AudioSystem.FORCE_BT_SCO);
16521657
}
16531658

1659+
/** @see AudioManager#setBluetoothA2dpOn() */
1660+
public void setBluetoothA2dpOn(boolean on) {
1661+
if (!checkAudioSettingsPermission("setBluetoothA2dpOn()")) {
1662+
return;
1663+
}
1664+
setBluetoothA2dpOnInt(on);
1665+
}
1666+
1667+
/** @see AudioManager#isBluetoothA2dpOn() */
1668+
public boolean isBluetoothA2dpOn() {
1669+
synchronized (mBluetoothA2dpEnabledLock) {
1670+
return mBluetoothA2dpEnabled;
1671+
}
1672+
}
1673+
16541674
/** @see AudioManager#startBluetoothSco() */
16551675
public void startBluetoothSco(IBinder cb){
16561676
if (!checkAudioSettingsPermission("startBluetoothSco()") ||
@@ -1673,6 +1693,7 @@ public void stopBluetoothSco(IBinder cb){
16731693
}
16741694
}
16751695

1696+
16761697
private class ScoClient implements IBinder.DeathRecipient {
16771698
private IBinder mCb; // To be notified of client's death
16781699
private int mCreatorPid;
@@ -2894,6 +2915,11 @@ public void handleMessage(Message msg) {
28942915
setOrientationForAudioSystem();
28952916
}
28962917

2918+
synchronized (mBluetoothA2dpEnabledLock) {
2919+
AudioSystem.setForceUse(AudioSystem.FOR_MEDIA,
2920+
mBluetoothA2dpEnabled ?
2921+
AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP);
2922+
}
28972923
// indicate the end of reconfiguration phase to audio HAL
28982924
AudioSystem.setParameters("restarting=false");
28992925
break;
@@ -2976,6 +3002,9 @@ public void onChange(boolean selfChange) {
29763002

29773003
// must be called synchronized on mConnectedDevices
29783004
private void makeA2dpDeviceAvailable(String address) {
3005+
// enable A2DP before notifying A2DP connection to avoid unecessary processing in
3006+
// audio policy manager
3007+
setBluetoothA2dpOnInt(true);
29793008
AudioSystem.setDeviceConnectionState(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
29803009
AudioSystem.DEVICE_STATE_AVAILABLE,
29813010
address);
@@ -3177,7 +3206,15 @@ public void onReceive(Context context, Intent intent) {
31773206
} else {
31783207
device = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
31793208
}
3209+
// enable A2DP before notifying headset disconnection to avoid glitches
3210+
if (state == 0) {
3211+
setBluetoothA2dpOnInt(true);
3212+
}
31803213
handleDeviceConnection((state == 1), device, "");
3214+
// disable A2DP after notifying headset connection to avoid glitches
3215+
if (state != 0) {
3216+
setBluetoothA2dpOnInt(false);
3217+
}
31813218
} else if (action.equals(Intent.ACTION_ANALOG_AUDIO_DOCK_PLUG)) {
31823219
state = intent.getIntExtra("state", 0);
31833220
Log.v(TAG, "Broadcast Receiver: Got ACTION_ANALOG_AUDIO_DOCK_PLUG, state = "+state);
@@ -4655,6 +4692,17 @@ private void setOrientationForAudioSystem() {
46554692
}
46564693

46574694

4695+
// Handles request to override default use of A2DP for media.
4696+
public void setBluetoothA2dpOnInt(boolean on) {
4697+
synchronized (mBluetoothA2dpEnabledLock) {
4698+
mBluetoothA2dpEnabled = on;
4699+
sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE,
4700+
AudioSystem.FOR_MEDIA,
4701+
mBluetoothA2dpEnabled ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP,
4702+
null, 0);
4703+
}
4704+
}
4705+
46584706
@Override
46594707
public void setRingtonePlayer(IRingtonePlayer player) {
46604708
mContext.enforceCallingOrSelfPermission(REMOTE_AUDIO_PLAYBACK, null);

media/java/android/media/AudioSystem.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,8 @@ public static String getDeviceName(int device)
318318
public static final int FORCE_BT_DESK_DOCK = 7;
319319
public static final int FORCE_ANALOG_DOCK = 8;
320320
public static final int FORCE_DIGITAL_DOCK = 9;
321-
private static final int NUM_FORCE_CONFIG = 10;
321+
public static final int FORCE_NO_BT_A2DP = 10;
322+
private static final int NUM_FORCE_CONFIG = 11;
322323
public static final int FORCE_DEFAULT = FORCE_NONE;
323324

324325
// usage for setForceUse, must match AudioSystem::force_use

media/java/android/media/IAudioService.aidl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ interface IAudioService {
9696

9797
boolean isBluetoothScoOn();
9898

99+
oneway void setBluetoothA2dpOn(boolean on);
100+
101+
boolean isBluetoothA2dpOn();
102+
99103
int requestAudioFocus(int mainStreamType, int durationHint, IBinder cb, IAudioFocusDispatcher l,
100104
String clientId, String callingPackageName);
101105

0 commit comments

Comments
 (0)