Update code for new BT public APIs.
Change-Id: Id730fb6226db59f3a0416111c4790653c2fccb0b
This commit is contained in:
@@ -21,6 +21,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Message;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.server.BluetoothA2dpService;
|
||||
import android.server.BluetoothService;
|
||||
import android.util.Log;
|
||||
@@ -28,6 +29,8 @@ import android.util.Log;
|
||||
import com.android.internal.util.HierarchicalState;
|
||||
import com.android.internal.util.HierarchicalStateMachine;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class is the Profile connection state machine associated with a remote
|
||||
* device. When the device bonds an instance of this class is created.
|
||||
@@ -91,12 +94,11 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
||||
private BluetoothService mService;
|
||||
private BluetoothA2dpService mA2dpService;
|
||||
private BluetoothHeadset mHeadsetService;
|
||||
private boolean mHeadsetServiceConnected;
|
||||
|
||||
private BluetoothDevice mDevice;
|
||||
private int mHeadsetState;
|
||||
private int mA2dpState;
|
||||
private int mHidState;
|
||||
private int mHeadsetState = BluetoothProfile.STATE_DISCONNECTED;
|
||||
private int mA2dpState = BluetoothProfile.STATE_DISCONNECTED;
|
||||
private int mHidState = BluetoothProfile.STATE_DISCONNECTED;
|
||||
|
||||
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
@@ -105,32 +107,29 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
||||
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
if (!device.equals(mDevice)) return;
|
||||
|
||||
if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) {
|
||||
int newState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, 0);
|
||||
int oldState = intent.getIntExtra(BluetoothHeadset.EXTRA_PREVIOUS_STATE, 0);
|
||||
int initiator = intent.getIntExtra(
|
||||
BluetoothHeadset.EXTRA_DISCONNECT_INITIATOR,
|
||||
BluetoothHeadset.LOCAL_DISCONNECT);
|
||||
mHeadsetState = newState;
|
||||
if (newState == BluetoothHeadset.STATE_DISCONNECTED &&
|
||||
initiator == BluetoothHeadset.REMOTE_DISCONNECT) {
|
||||
sendMessage(DISCONNECT_HFP_INCOMING);
|
||||
}
|
||||
if (newState == BluetoothHeadset.STATE_CONNECTED ||
|
||||
newState == BluetoothHeadset.STATE_DISCONNECTED) {
|
||||
sendMessage(TRANSITION_TO_STABLE);
|
||||
}
|
||||
} else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
|
||||
int newState = intent.getIntExtra(BluetoothA2dp.EXTRA_SINK_STATE, 0);
|
||||
int oldState = intent.getIntExtra(BluetoothA2dp.EXTRA_PREVIOUS_SINK_STATE, 0);
|
||||
if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
|
||||
int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
|
||||
int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
|
||||
mA2dpState = newState;
|
||||
if ((oldState == BluetoothA2dp.STATE_CONNECTED ||
|
||||
oldState == BluetoothA2dp.STATE_PLAYING) &&
|
||||
newState == BluetoothA2dp.STATE_DISCONNECTED) {
|
||||
if (oldState == BluetoothA2dp.STATE_CONNECTED &&
|
||||
newState == BluetoothA2dp.STATE_DISCONNECTED) {
|
||||
sendMessage(DISCONNECT_A2DP_INCOMING);
|
||||
}
|
||||
if (newState == BluetoothA2dp.STATE_CONNECTED ||
|
||||
newState == BluetoothA2dp.STATE_DISCONNECTED) {
|
||||
if (newState == BluetoothProfile.STATE_CONNECTED ||
|
||||
newState == BluetoothProfile.STATE_DISCONNECTED) {
|
||||
sendMessage(TRANSITION_TO_STABLE);
|
||||
}
|
||||
} else if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
|
||||
int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
|
||||
int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
|
||||
|
||||
mHeadsetState = newState;
|
||||
if (oldState == BluetoothHeadset.STATE_CONNECTED &&
|
||||
newState == BluetoothHeadset.STATE_DISCONNECTED) {
|
||||
sendMessage(DISCONNECT_HFP_INCOMING);
|
||||
}
|
||||
if (newState == BluetoothProfile.STATE_CONNECTED ||
|
||||
newState == BluetoothProfile.STATE_DISCONNECTED) {
|
||||
sendMessage(TRANSITION_TO_STABLE);
|
||||
}
|
||||
} else if (action.equals(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED)) {
|
||||
@@ -192,31 +191,31 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
// Fine-grained state broadcasts
|
||||
filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
|
||||
filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
|
||||
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
|
||||
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
|
||||
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
|
||||
filter.addAction(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED);
|
||||
|
||||
mContext.registerReceiver(mBroadcastReceiver, filter);
|
||||
|
||||
HeadsetServiceListener l = new HeadsetServiceListener();
|
||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
|
||||
BluetoothProfile.HEADSET);
|
||||
}
|
||||
|
||||
private class HeadsetServiceListener implements BluetoothHeadset.ServiceListener {
|
||||
public HeadsetServiceListener() {
|
||||
mHeadsetService = new BluetoothHeadset(mContext, this);
|
||||
}
|
||||
public void onServiceConnected() {
|
||||
private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
|
||||
new BluetoothProfile.ServiceListener() {
|
||||
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
||||
synchronized(BluetoothDeviceProfileState.this) {
|
||||
mHeadsetServiceConnected = true;
|
||||
mHeadsetService = (BluetoothHeadset) proxy;
|
||||
}
|
||||
}
|
||||
public void onServiceDisconnected() {
|
||||
public void onServiceDisconnected(int profile) {
|
||||
synchronized(BluetoothDeviceProfileState.this) {
|
||||
mHeadsetServiceConnected = false;
|
||||
mHeadsetService = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private class BondedDevice extends HierarchicalState {
|
||||
@Override
|
||||
@@ -276,19 +275,25 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
||||
if (isPhoneDocked(mDevice)) {
|
||||
// Don't auto connect to docks.
|
||||
break;
|
||||
} else if (!mHeadsetServiceConnected) {
|
||||
} else if (mHeadsetService == null) {
|
||||
deferMessage(message);
|
||||
} else {
|
||||
if (mHeadsetService.getPriority(mDevice) ==
|
||||
BluetoothHeadset.PRIORITY_AUTO_CONNECT &&
|
||||
!mHeadsetService.isConnected(mDevice)) {
|
||||
mHeadsetService.connectHeadset(mDevice);
|
||||
mHeadsetService.getDevicesMatchingConnectionStates(
|
||||
new int[] {BluetoothProfile.STATE_CONNECTED,
|
||||
BluetoothProfile.STATE_CONNECTING,
|
||||
BluetoothProfile.STATE_DISCONNECTING}).size() == 0) {
|
||||
mHeadsetService.connect(mDevice);
|
||||
}
|
||||
if (mA2dpService != null &&
|
||||
mA2dpService.getSinkPriority(mDevice) ==
|
||||
mA2dpService.getPriority(mDevice) ==
|
||||
BluetoothA2dp.PRIORITY_AUTO_CONNECT &&
|
||||
mA2dpService.getConnectedSinks().length == 0) {
|
||||
mA2dpService.connectSink(mDevice);
|
||||
mA2dpService.getDevicesMatchingConnectionStates(
|
||||
new int[] {BluetoothA2dp.STATE_CONNECTED,
|
||||
BluetoothProfile.STATE_CONNECTING,
|
||||
BluetoothProfile.STATE_DISCONNECTING}).length == 0) {
|
||||
mA2dpService.connect(mDevice);
|
||||
}
|
||||
if (mService.getInputDevicePriority(mDevice) ==
|
||||
BluetoothInputDevice.PRIORITY_AUTO_CONNECT) {
|
||||
@@ -805,7 +810,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
||||
synchronized void cancelCommand(int command) {
|
||||
if (command == CONNECT_HFP_OUTGOING ) {
|
||||
// Cancel the outgoing thread.
|
||||
if (mHeadsetServiceConnected) {
|
||||
if (mHeadsetService != null) {
|
||||
mHeadsetService.cancelConnectThread();
|
||||
}
|
||||
// HeadsetService is down. Phone process most likely crashed.
|
||||
@@ -823,12 +828,14 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
||||
log("Processing command:" + command);
|
||||
switch(command) {
|
||||
case CONNECT_HFP_OUTGOING:
|
||||
if (mHeadsetService != null) {
|
||||
if (mHeadsetService == null) {
|
||||
deferHeadsetMessage(command);
|
||||
} else {
|
||||
return mHeadsetService.connectHeadsetInternal(mDevice);
|
||||
}
|
||||
break;
|
||||
case CONNECT_HFP_INCOMING:
|
||||
if (!mHeadsetServiceConnected) {
|
||||
if (mHeadsetService == null) {
|
||||
deferHeadsetMessage(command);
|
||||
} else if (mHeadsetState == BluetoothHeadset.STATE_CONNECTING) {
|
||||
return mHeadsetService.acceptIncomingConnect(mDevice);
|
||||
@@ -849,7 +856,7 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
||||
case CONNECT_HID_INCOMING:
|
||||
return true;
|
||||
case DISCONNECT_HFP_OUTGOING:
|
||||
if (!mHeadsetServiceConnected) {
|
||||
if (mHeadsetService == null) {
|
||||
deferHeadsetMessage(command);
|
||||
} else {
|
||||
if (mHeadsetService.getPriority(mDevice) ==
|
||||
@@ -867,9 +874,9 @@ public final class BluetoothDeviceProfileState extends HierarchicalStateMachine
|
||||
return true;
|
||||
case DISCONNECT_A2DP_OUTGOING:
|
||||
if (mA2dpService != null) {
|
||||
if (mA2dpService.getSinkPriority(mDevice) ==
|
||||
if (mA2dpService.getPriority(mDevice) ==
|
||||
BluetoothA2dp.PRIORITY_AUTO_CONNECT) {
|
||||
mA2dpService.setSinkPriority(mDevice, BluetoothHeadset.PRIORITY_ON);
|
||||
mA2dpService.setPriority(mDevice, BluetoothHeadset.PRIORITY_ON);
|
||||
}
|
||||
return mA2dpService.disconnectSinkInternal(mDevice);
|
||||
}
|
||||
|
||||
@@ -59,16 +59,16 @@ public class BluetoothProfileState extends HierarchicalStateMachine {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
|
||||
if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) {
|
||||
int newState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, 0);
|
||||
if (mProfile == HFP && (newState == BluetoothHeadset.STATE_CONNECTED ||
|
||||
newState == BluetoothHeadset.STATE_DISCONNECTED)) {
|
||||
if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
|
||||
int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
|
||||
if (mProfile == HFP && (newState == BluetoothProfile.STATE_CONNECTED ||
|
||||
newState == BluetoothProfile.STATE_DISCONNECTED)) {
|
||||
sendMessage(TRANSITION_TO_STABLE);
|
||||
}
|
||||
} else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) {
|
||||
int newState = intent.getIntExtra(BluetoothA2dp.EXTRA_SINK_STATE, 0);
|
||||
if (mProfile == A2DP && (newState == BluetoothA2dp.STATE_CONNECTED ||
|
||||
newState == BluetoothA2dp.STATE_DISCONNECTED)) {
|
||||
} else if (action.equals(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED)) {
|
||||
int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
|
||||
if (mProfile == A2DP && (newState == BluetoothProfile.STATE_CONNECTED ||
|
||||
newState == BluetoothProfile.STATE_DISCONNECTED)) {
|
||||
sendMessage(TRANSITION_TO_STABLE);
|
||||
}
|
||||
} else if (action.equals(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED)) {
|
||||
@@ -89,8 +89,8 @@ public class BluetoothProfileState extends HierarchicalStateMachine {
|
||||
setInitialState(mStableState);
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
|
||||
filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED);
|
||||
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
|
||||
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
|
||||
filter.addAction(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED);
|
||||
context.registerReceiver(mBroadcastReceiver, filter);
|
||||
}
|
||||
|
||||
@@ -19,21 +19,25 @@ package android.bluetooth;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
/**
|
||||
* System private API for Bluetooth A2DP service
|
||||
* APIs for Bluetooth A2DP service
|
||||
*
|
||||
* {@hide}
|
||||
* @hide
|
||||
*/
|
||||
interface IBluetoothA2dp {
|
||||
boolean connectSink(in BluetoothDevice device);
|
||||
boolean disconnectSink(in BluetoothDevice device);
|
||||
// Public API
|
||||
boolean connect(in BluetoothDevice device);
|
||||
boolean disconnect(in BluetoothDevice device);
|
||||
// change to Set<> once AIDL supports
|
||||
BluetoothDevice[] getConnectedDevices();
|
||||
BluetoothDevice[] getDevicesMatchingConnectionStates(in int[] states);
|
||||
int getConnectionState(in BluetoothDevice device);
|
||||
boolean setPriority(in BluetoothDevice device, int priority);
|
||||
int getPriority(in BluetoothDevice device);
|
||||
boolean isA2dpPlaying(in BluetoothDevice device);
|
||||
|
||||
// Internal APIs
|
||||
boolean suspendSink(in BluetoothDevice device);
|
||||
boolean resumeSink(in BluetoothDevice device);
|
||||
BluetoothDevice[] getConnectedSinks(); // change to Set<> once AIDL supports
|
||||
BluetoothDevice[] getNonDisconnectedSinks(); // change to Set<> once AIDL supports
|
||||
int getSinkState(in BluetoothDevice device);
|
||||
boolean setSinkPriority(in BluetoothDevice device, int priority);
|
||||
int getSinkPriority(in BluetoothDevice device);
|
||||
|
||||
boolean connectSinkInternal(in BluetoothDevice device);
|
||||
boolean disconnectSinkInternal(in BluetoothDevice device);
|
||||
}
|
||||
|
||||
@@ -19,25 +19,32 @@ package android.bluetooth;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
|
||||
/**
|
||||
* System private API for Bluetooth Headset service
|
||||
* API for Bluetooth Headset service
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
interface IBluetoothHeadset {
|
||||
int getState(in BluetoothDevice device);
|
||||
BluetoothDevice getCurrentHeadset();
|
||||
boolean connectHeadset(in BluetoothDevice device);
|
||||
void disconnectHeadset(in BluetoothDevice device);
|
||||
boolean isConnected(in BluetoothDevice device);
|
||||
boolean startVoiceRecognition();
|
||||
boolean stopVoiceRecognition();
|
||||
// Public API
|
||||
boolean connect(in BluetoothDevice device);
|
||||
boolean disconnect(in BluetoothDevice device);
|
||||
// Change to Set<> when AIDL supports
|
||||
BluetoothDevice[] getConnectedDevices();
|
||||
BluetoothDevice[] getDevicesMatchingConnectionStates(in int[] states);
|
||||
int getConnectionState(in BluetoothDevice device);
|
||||
boolean setPriority(in BluetoothDevice device, int priority);
|
||||
int getPriority(in BluetoothDevice device);
|
||||
int getBatteryUsageHint();
|
||||
boolean startVoiceRecognition(in BluetoothDevice device);
|
||||
boolean stopVoiceRecognition(in BluetoothDevice device);
|
||||
boolean isAudioConnected(in BluetoothDevice device);
|
||||
|
||||
// APIs that can be made public in future
|
||||
int getBatteryUsageHint(in BluetoothDevice device);
|
||||
|
||||
// Internal functions, not be made public
|
||||
boolean createIncomingConnect(in BluetoothDevice device);
|
||||
boolean acceptIncomingConnect(in BluetoothDevice device);
|
||||
boolean cancelConnectThread();
|
||||
boolean connectHeadsetInternal(in BluetoothDevice device);
|
||||
boolean disconnectHeadsetInternal(in BluetoothDevice device);
|
||||
boolean setAudioState(in BluetoothDevice device, int state);
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ package android.server;
|
||||
import android.bluetooth.BluetoothA2dp;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.bluetooth.BluetoothUuid;
|
||||
import android.bluetooth.IBluetoothA2dp;
|
||||
import android.content.BroadcastReceiver;
|
||||
@@ -32,17 +33,15 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.ParcelUuid;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
private static final String TAG = "BluetoothA2dpService";
|
||||
@@ -57,11 +56,6 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
|
||||
private static final String PROPERTY_STATE = "State";
|
||||
|
||||
private static final String SINK_STATE_DISCONNECTED = "disconnected";
|
||||
private static final String SINK_STATE_CONNECTING = "connecting";
|
||||
private static final String SINK_STATE_CONNECTED = "connected";
|
||||
private static final String SINK_STATE_PLAYING = "playing";
|
||||
|
||||
private static int mSinkCount;
|
||||
|
||||
private final Context mContext;
|
||||
@@ -72,6 +66,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
private final BluetoothAdapter mAdapter;
|
||||
private int mTargetA2dpState;
|
||||
private boolean mAdjustedPriority = false;
|
||||
private BluetoothDevice mPlayingA2dpDevice;
|
||||
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
@@ -95,12 +90,12 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
BluetoothDevice.ERROR);
|
||||
switch(bondState) {
|
||||
case BluetoothDevice.BOND_BONDED:
|
||||
if (getSinkPriority(device) == BluetoothA2dp.PRIORITY_UNDEFINED) {
|
||||
setSinkPriority(device, BluetoothA2dp.PRIORITY_ON);
|
||||
if (getPriority(device) == BluetoothA2dp.PRIORITY_UNDEFINED) {
|
||||
setPriority(device, BluetoothA2dp.PRIORITY_ON);
|
||||
}
|
||||
break;
|
||||
case BluetoothDevice.BOND_NONE:
|
||||
setSinkPriority(device, BluetoothA2dp.PRIORITY_UNDEFINED);
|
||||
setPriority(device, BluetoothA2dp.PRIORITY_UNDEFINED);
|
||||
break;
|
||||
}
|
||||
} else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
|
||||
@@ -113,7 +108,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
} else if (action.equals(AudioManager.VOLUME_CHANGED_ACTION)) {
|
||||
int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, -1);
|
||||
if (streamType == AudioManager.STREAM_MUSIC) {
|
||||
BluetoothDevice sinks[] = getConnectedSinks();
|
||||
BluetoothDevice sinks[] = getConnectedDevices();
|
||||
|
||||
if (sinks.length != 0 && isPhoneDocked(sinks[0])) {
|
||||
String address = sinks[0].getAddress();
|
||||
int newVolLevel =
|
||||
@@ -254,7 +250,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
BluetoothDevice[] devices = new BluetoothDevice[mAudioDevices.size()];
|
||||
devices = mAudioDevices.keySet().toArray(devices);
|
||||
for (BluetoothDevice device : devices) {
|
||||
int state = getSinkState(device);
|
||||
int state = getConnectionState(device);
|
||||
switch (state) {
|
||||
case BluetoothA2dp.STATE_CONNECTING:
|
||||
case BluetoothA2dp.STATE_CONNECTED:
|
||||
@@ -277,7 +273,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
|
||||
private synchronized boolean isConnectSinkFeasible(BluetoothDevice device) {
|
||||
if (!mBluetoothService.isEnabled() || !isSinkDevice(device) ||
|
||||
getSinkPriority(device) == BluetoothA2dp.PRIORITY_OFF) {
|
||||
getPriority(device) == BluetoothA2dp.PRIORITY_OFF) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -292,12 +288,26 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean connectSink(BluetoothDevice device) {
|
||||
public synchronized boolean isA2dpPlaying(BluetoothDevice device) {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
|
||||
"Need BLUETOOTH_ADMIN permission");
|
||||
if (DBG) log("isA2dpPlaying(" + device + ")");
|
||||
if (device.equals(mPlayingA2dpDevice)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public synchronized boolean connect(BluetoothDevice device) {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
|
||||
"Need BLUETOOTH_ADMIN permission");
|
||||
if (DBG) log("connectSink(" + device + ")");
|
||||
if (!isConnectSinkFeasible(device)) return false;
|
||||
|
||||
for (BluetoothDevice sinkDevice : mAudioDevices.keySet()) {
|
||||
if (getConnectionState(sinkDevice) != BluetoothProfile.STATE_DISCONNECTED) {
|
||||
disconnect(sinkDevice);
|
||||
}
|
||||
}
|
||||
|
||||
return mBluetoothService.connectSink(device.getAddress());
|
||||
}
|
||||
|
||||
@@ -307,17 +317,15 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
int state = mAudioDevices.get(device);
|
||||
|
||||
// ignore if there are any active sinks
|
||||
if (lookupSinksMatchingStates(new int[] {
|
||||
if (getDevicesMatchingConnectionStates(new int[] {
|
||||
BluetoothA2dp.STATE_CONNECTING,
|
||||
BluetoothA2dp.STATE_CONNECTED,
|
||||
BluetoothA2dp.STATE_PLAYING,
|
||||
BluetoothA2dp.STATE_DISCONNECTING}).size() != 0) {
|
||||
BluetoothA2dp.STATE_DISCONNECTING}).length != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (state) {
|
||||
case BluetoothA2dp.STATE_CONNECTED:
|
||||
case BluetoothA2dp.STATE_PLAYING:
|
||||
case BluetoothA2dp.STATE_DISCONNECTING:
|
||||
return false;
|
||||
case BluetoothA2dp.STATE_CONNECTING:
|
||||
@@ -343,17 +351,16 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
return false;
|
||||
}
|
||||
|
||||
int state = getSinkState(device);
|
||||
int state = getConnectionState(device);
|
||||
switch (state) {
|
||||
case BluetoothA2dp.STATE_DISCONNECTED:
|
||||
return false;
|
||||
case BluetoothA2dp.STATE_DISCONNECTING:
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public synchronized boolean disconnectSink(BluetoothDevice device) {
|
||||
public synchronized boolean disconnect(BluetoothDevice device) {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
|
||||
"Need BLUETOOTH_ADMIN permission");
|
||||
if (DBG) log("disconnectSink(" + device + ")");
|
||||
@@ -362,7 +369,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
}
|
||||
|
||||
public synchronized boolean disconnectSinkInternal(BluetoothDevice device) {
|
||||
int state = getSinkState(device);
|
||||
int state = getConnectionState(device);
|
||||
String path = mBluetoothService.getObjectPathFromAddress(device.getAddress());
|
||||
|
||||
// State is CONNECTING or CONNECTED or PLAYING
|
||||
@@ -408,24 +415,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
return checkSinkSuspendState(state.intValue());
|
||||
}
|
||||
|
||||
public synchronized BluetoothDevice[] getConnectedSinks() {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||
Set<BluetoothDevice> sinks = lookupSinksMatchingStates(
|
||||
new int[] {BluetoothA2dp.STATE_CONNECTED, BluetoothA2dp.STATE_PLAYING});
|
||||
return sinks.toArray(new BluetoothDevice[sinks.size()]);
|
||||
}
|
||||
|
||||
public synchronized BluetoothDevice[] getNonDisconnectedSinks() {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||
Set<BluetoothDevice> sinks = lookupSinksMatchingStates(
|
||||
new int[] {BluetoothA2dp.STATE_CONNECTED,
|
||||
BluetoothA2dp.STATE_PLAYING,
|
||||
BluetoothA2dp.STATE_CONNECTING,
|
||||
BluetoothA2dp.STATE_DISCONNECTING});
|
||||
return sinks.toArray(new BluetoothDevice[sinks.size()]);
|
||||
}
|
||||
|
||||
public synchronized int getSinkState(BluetoothDevice device) {
|
||||
public synchronized int getConnectionState(BluetoothDevice device) {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||
Integer state = mAudioDevices.get(device);
|
||||
if (state == null)
|
||||
@@ -433,19 +423,41 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
return state;
|
||||
}
|
||||
|
||||
public synchronized int getSinkPriority(BluetoothDevice device) {
|
||||
public synchronized BluetoothDevice[] getConnectedDevices() {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||
BluetoothDevice[] sinks = getDevicesMatchingConnectionStates(
|
||||
new int[] {BluetoothA2dp.STATE_CONNECTED});
|
||||
return sinks;
|
||||
}
|
||||
|
||||
public synchronized BluetoothDevice[] getDevicesMatchingConnectionStates(int[] states) {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||
ArrayList<BluetoothDevice> sinks = new ArrayList();
|
||||
if (mAudioDevices.isEmpty()) {
|
||||
return sinks.toArray(new BluetoothDevice[sinks.size()]);
|
||||
}
|
||||
for (BluetoothDevice device: mAudioDevices.keySet()) {
|
||||
int sinkState = getConnectionState(device);
|
||||
for (int state : states) {
|
||||
if (state == sinkState) {
|
||||
sinks.add(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sinks.toArray(new BluetoothDevice[sinks.size()]);
|
||||
}
|
||||
|
||||
public synchronized int getPriority(BluetoothDevice device) {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||
return Settings.Secure.getInt(mContext.getContentResolver(),
|
||||
Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()),
|
||||
BluetoothA2dp.PRIORITY_UNDEFINED);
|
||||
}
|
||||
|
||||
public synchronized boolean setSinkPriority(BluetoothDevice device, int priority) {
|
||||
public synchronized boolean setPriority(BluetoothDevice device, int priority) {
|
||||
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
|
||||
"Need BLUETOOTH_ADMIN permission");
|
||||
if (!BluetoothAdapter.checkBluetoothAddress(device.getAddress())) {
|
||||
return false;
|
||||
}
|
||||
return Settings.Secure.putInt(mContext.getContentResolver(),
|
||||
Settings.Secure.getBluetoothA2dpSinkPriorityKey(device.getAddress()), priority);
|
||||
}
|
||||
@@ -471,8 +483,17 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
// We have authorized it and bluez state has changed.
|
||||
addAudioSink(device);
|
||||
} else {
|
||||
int prevState = mAudioDevices.get(device);
|
||||
handleSinkStateChange(device, prevState, state);
|
||||
if (state == BluetoothA2dp.STATE_PLAYING && mPlayingA2dpDevice == null) {
|
||||
mPlayingA2dpDevice = device;
|
||||
handleSinkPlayingStateChange(device, state, BluetoothA2dp.STATE_NOT_PLAYING);
|
||||
} else if (state == BluetoothA2dp.STATE_CONNECTED && mPlayingA2dpDevice != null) {
|
||||
mPlayingA2dpDevice = null;
|
||||
handleSinkPlayingStateChange(device, BluetoothA2dp.STATE_NOT_PLAYING,
|
||||
BluetoothA2dp.STATE_PLAYING);
|
||||
} else {
|
||||
int prevState = mAudioDevices.get(device);
|
||||
handleSinkStateChange(device, prevState, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -484,18 +505,19 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
mSinkCount--;
|
||||
} else if (state == BluetoothA2dp.STATE_CONNECTED) {
|
||||
mSinkCount ++;
|
||||
mPlayingA2dpDevice = null;
|
||||
}
|
||||
mAudioDevices.put(device, state);
|
||||
|
||||
checkSinkSuspendState(state);
|
||||
mTargetA2dpState = -1;
|
||||
|
||||
if (getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF &&
|
||||
if (getPriority(device) > BluetoothA2dp.PRIORITY_OFF &&
|
||||
state == BluetoothA2dp.STATE_CONNECTING ||
|
||||
state == BluetoothA2dp.STATE_CONNECTED) {
|
||||
// We have connected or attempting to connect.
|
||||
// Bump priority
|
||||
setSinkPriority(device, BluetoothA2dp.PRIORITY_AUTO_CONNECT);
|
||||
setPriority(device, BluetoothA2dp.PRIORITY_AUTO_CONNECT);
|
||||
}
|
||||
|
||||
if (state == BluetoothA2dp.STATE_CONNECTED) {
|
||||
@@ -504,45 +526,38 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
adjustOtherSinkPriorities(device);
|
||||
}
|
||||
|
||||
Intent intent = new Intent(BluetoothA2dp.ACTION_SINK_STATE_CHANGED);
|
||||
Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
|
||||
intent.putExtra(BluetoothA2dp.EXTRA_PREVIOUS_SINK_STATE, prevState);
|
||||
intent.putExtra(BluetoothA2dp.EXTRA_SINK_STATE, state);
|
||||
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
|
||||
intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
|
||||
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
|
||||
|
||||
if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSinkPlayingStateChange(BluetoothDevice device, int state, int prevState) {
|
||||
Intent intent = new Intent(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED);
|
||||
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
|
||||
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
|
||||
intent.putExtra(BluetoothProfile.EXTRA_STATE, state);
|
||||
mContext.sendBroadcast(intent, BLUETOOTH_PERM);
|
||||
|
||||
if (DBG) log("A2DP Playing state : device: " + device + " State:" + prevState + "->" + state);
|
||||
}
|
||||
|
||||
private void adjustOtherSinkPriorities(BluetoothDevice connectedDevice) {
|
||||
if (!mAdjustedPriority) {
|
||||
for (BluetoothDevice device : mAdapter.getBondedDevices()) {
|
||||
if (getSinkPriority(device) >= BluetoothA2dp.PRIORITY_AUTO_CONNECT &&
|
||||
if (getPriority(device) >= BluetoothA2dp.PRIORITY_AUTO_CONNECT &&
|
||||
!device.equals(connectedDevice)) {
|
||||
setSinkPriority(device, BluetoothA2dp.PRIORITY_ON);
|
||||
setPriority(device, BluetoothA2dp.PRIORITY_ON);
|
||||
}
|
||||
}
|
||||
mAdjustedPriority = true;
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized Set<BluetoothDevice> lookupSinksMatchingStates(int[] states) {
|
||||
Set<BluetoothDevice> sinks = new HashSet<BluetoothDevice>();
|
||||
if (mAudioDevices.isEmpty()) {
|
||||
return sinks;
|
||||
}
|
||||
for (BluetoothDevice device: mAudioDevices.keySet()) {
|
||||
int sinkState = getSinkState(device);
|
||||
for (int state : states) {
|
||||
if (state == sinkState) {
|
||||
sinks.add(device);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sinks;
|
||||
}
|
||||
|
||||
private boolean checkSinkSuspendState(int state) {
|
||||
boolean result = true;
|
||||
|
||||
@@ -568,7 +583,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
||||
String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
|
||||
if (address == null) return;
|
||||
BluetoothDevice device = mAdapter.getRemoteDevice(address);
|
||||
int state = getSinkState(device);
|
||||
int state = getConnectionState(device);
|
||||
handleSinkStateChange(device, state, BluetoothA2dp.STATE_DISCONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.bluetooth.BluetoothClass;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothInputDevice;
|
||||
import android.bluetooth.BluetoothPan;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.bluetooth.BluetoothUuid;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -54,6 +55,7 @@ class BluetoothEventLoop {
|
||||
private final HashMap<String, Integer> mPasskeyAgentRequestData;
|
||||
private final BluetoothService mBluetoothService;
|
||||
private final BluetoothAdapter mAdapter;
|
||||
private BluetoothA2dp mA2dp;
|
||||
private final Context mContext;
|
||||
// The WakeLock is used for bringing up the LCD during a pairing request
|
||||
// from remote device when Android is in Suspend state.
|
||||
@@ -118,8 +120,21 @@ class BluetoothEventLoop {
|
||||
| PowerManager.ON_AFTER_RELEASE, TAG);
|
||||
mWakeLock.setReferenceCounted(false);
|
||||
initializeNativeDataNative();
|
||||
|
||||
mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.A2DP);
|
||||
}
|
||||
|
||||
private BluetoothProfile.ServiceListener mProfileServiceListener =
|
||||
new BluetoothProfile.ServiceListener() {
|
||||
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
||||
mA2dp = (BluetoothA2dp) proxy;
|
||||
}
|
||||
public void onServiceDisconnected(int profile) {
|
||||
mA2dp = null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
cleanupNativeDataNative();
|
||||
@@ -574,12 +589,11 @@ class BluetoothEventLoop {
|
||||
|
||||
// Bluez sends the UUID of the local service being accessed, _not_ the
|
||||
// remote service
|
||||
if ((BluetoothUuid.isAudioSource(uuid) || BluetoothUuid.isAvrcpTarget(uuid)
|
||||
if (mA2dp != null &&
|
||||
(BluetoothUuid.isAudioSource(uuid) || BluetoothUuid.isAvrcpTarget(uuid)
|
||||
|| BluetoothUuid.isAdvAudioDist(uuid)) &&
|
||||
!isOtherSinkInNonDisconnectingState(address)) {
|
||||
BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
|
||||
|
||||
authorized = a2dp.getSinkPriority(device) > BluetoothA2dp.PRIORITY_OFF;
|
||||
!isOtherSinkInNonDisconnectedState(address)) {
|
||||
authorized = mA2dp.getPriority(device) > BluetoothProfile.PRIORITY_OFF;
|
||||
if (authorized) {
|
||||
Log.i(TAG, "Allowing incoming A2DP / AVRCP connection from " + address);
|
||||
mBluetoothService.notifyIncomingA2dpConnection(address);
|
||||
@@ -630,9 +644,12 @@ class BluetoothEventLoop {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isOtherSinkInNonDisconnectingState(String address) {
|
||||
BluetoothA2dp a2dp = new BluetoothA2dp(mContext);
|
||||
Set<BluetoothDevice> devices = a2dp.getNonDisconnectedSinks();
|
||||
private boolean isOtherSinkInNonDisconnectedState(String address) {
|
||||
Set<BluetoothDevice> devices =
|
||||
mA2dp.getDevicesMatchingConnectionStates(new int[] {BluetoothA2dp.STATE_CONNECTED,
|
||||
BluetoothA2dp.STATE_CONNECTING,
|
||||
BluetoothA2dp.STATE_DISCONNECTING});
|
||||
|
||||
if (devices.size() == 0) return false;
|
||||
for(BluetoothDevice dev: devices) {
|
||||
if (!dev.getAddress().equals(address)) return true;
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
import android.bluetooth.BluetoothDeviceProfileState;
|
||||
import android.bluetooth.BluetoothPan;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.bluetooth.BluetoothProfileState;
|
||||
import android.bluetooth.BluetoothInputDevice;
|
||||
import android.bluetooth.BluetoothSocket;
|
||||
@@ -88,6 +89,7 @@ public class BluetoothService extends IBluetooth.Stub {
|
||||
|
||||
private int mNativeData;
|
||||
private BluetoothEventLoop mEventLoop;
|
||||
private BluetoothHeadset mBluetoothHeadset;
|
||||
private boolean mIsAirplaneSensitive;
|
||||
private boolean mIsAirplaneToggleable;
|
||||
private int mBluetoothState;
|
||||
@@ -2434,7 +2436,8 @@ public class BluetoothService extends IBluetooth.Stub {
|
||||
pw.println("Local name = " + getName());
|
||||
pw.println("isDiscovering() = " + isDiscovering());
|
||||
|
||||
BluetoothHeadset headset = new BluetoothHeadset(mContext, null);
|
||||
mAdapter.getProfileProxy(mContext,
|
||||
mBluetoothProfileServiceListener, BluetoothProfile.HEADSET);
|
||||
|
||||
pw.println("\n--Known devices--");
|
||||
for (String address : mDeviceProperties.keySet()) {
|
||||
@@ -2479,24 +2482,48 @@ public class BluetoothService extends IBluetooth.Stub {
|
||||
// Rather not do this from here, but no-where else and I need this
|
||||
// dump
|
||||
pw.println("\n--Headset Service--");
|
||||
switch (headset.getState(headset.getCurrentHeadset())) {
|
||||
case BluetoothHeadset.STATE_DISCONNECTED:
|
||||
pw.println("getState() = STATE_DISCONNECTED");
|
||||
break;
|
||||
case BluetoothHeadset.STATE_CONNECTING:
|
||||
pw.println("getState() = STATE_CONNECTING");
|
||||
break;
|
||||
case BluetoothHeadset.STATE_CONNECTED:
|
||||
pw.println("getState() = STATE_CONNECTED");
|
||||
break;
|
||||
case BluetoothHeadset.STATE_ERROR:
|
||||
pw.println("getState() = STATE_ERROR");
|
||||
break;
|
||||
if (mBluetoothHeadset != null) {
|
||||
Set<BluetoothDevice> deviceSet = mBluetoothHeadset.getConnectedDevices();
|
||||
if (deviceSet.size() == 0) {
|
||||
pw.println("\n--No headsets connected--");
|
||||
}
|
||||
BluetoothDevice device = (BluetoothDevice) deviceSet.toArray()[0];
|
||||
|
||||
switch (mBluetoothHeadset.getConnectionState(device)) {
|
||||
case BluetoothHeadset.STATE_DISCONNECTED:
|
||||
pw.println("getConnectionState() = STATE_DISCONNECTED");
|
||||
break;
|
||||
case BluetoothHeadset.STATE_CONNECTING:
|
||||
pw.println("getConnectionState() = STATE_CONNECTING");
|
||||
break;
|
||||
case BluetoothHeadset.STATE_CONNECTED:
|
||||
pw.println("getConnectionState() = STATE_CONNECTED");
|
||||
break;
|
||||
case BluetoothHeadset.STATE_DISCONNECTING:
|
||||
pw.println("getConnectionState() = STATE_DISCONNECTING");
|
||||
break;
|
||||
case BluetoothHeadset.STATE_AUDIO_CONNECTED:
|
||||
pw.println("getConnectionState() = STATE_AUDIO_CONNECTED");
|
||||
break;
|
||||
}
|
||||
|
||||
deviceSet.clear();
|
||||
deviceSet = mBluetoothHeadset.getDevicesMatchingConnectionStates(new int[] {
|
||||
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED});
|
||||
pw.println("\n--Connected and Disconnected Headsets");
|
||||
for (BluetoothDevice dev: deviceSet) {
|
||||
pw.println(device);
|
||||
if (mBluetoothHeadset.isAudioConnected(device)) {
|
||||
pw.println("SCO audio connected to device:" + device);
|
||||
}
|
||||
}
|
||||
|
||||
pw.println("\ngetCurrentHeadset() = " + device);
|
||||
pw.println("getBatteryUsageHint() = " +
|
||||
mBluetoothHeadset.getBatteryUsageHint(device));
|
||||
mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
|
||||
}
|
||||
|
||||
pw.println("\ngetCurrentHeadset() = " + headset.getCurrentHeadset());
|
||||
pw.println("getBatteryUsageHint() = " + headset.getBatteryUsageHint());
|
||||
headset.close();
|
||||
pw.println("\n--Application Service Records--");
|
||||
for (Integer handle : mServiceRecordToPid.keySet()) {
|
||||
Integer pid = mServiceRecordToPid.get(handle);
|
||||
@@ -2504,6 +2531,16 @@ public class BluetoothService extends IBluetooth.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
|
||||
new BluetoothProfile.ServiceListener() {
|
||||
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
||||
mBluetoothHeadset = (BluetoothHeadset) proxy;
|
||||
}
|
||||
public void onServiceDisconnected(int profile) {
|
||||
mBluetoothHeadset = null;
|
||||
}
|
||||
};
|
||||
|
||||
/* package */ static int bluezStringToScanMode(boolean pairable, boolean discoverable) {
|
||||
if (pairable && discoverable)
|
||||
return BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE;
|
||||
@@ -2563,6 +2600,8 @@ public class BluetoothService extends IBluetooth.Stub {
|
||||
}
|
||||
|
||||
public boolean connectHeadset(String address) {
|
||||
if (getBondState(address) != BluetoothDevice.BOND_BONDED) return false;
|
||||
|
||||
BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
|
||||
if (state != null) {
|
||||
Message msg = new Message();
|
||||
@@ -2575,6 +2614,8 @@ public class BluetoothService extends IBluetooth.Stub {
|
||||
}
|
||||
|
||||
public boolean disconnectHeadset(String address) {
|
||||
if (getBondState(address) != BluetoothDevice.BOND_BONDED) return false;
|
||||
|
||||
BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
|
||||
if (state != null) {
|
||||
Message msg = new Message();
|
||||
@@ -2587,6 +2628,8 @@ public class BluetoothService extends IBluetooth.Stub {
|
||||
}
|
||||
|
||||
public boolean connectSink(String address) {
|
||||
if (getBondState(address) != BluetoothDevice.BOND_BONDED) return false;
|
||||
|
||||
BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
|
||||
if (state != null) {
|
||||
Message msg = new Message();
|
||||
@@ -2599,6 +2642,8 @@ public class BluetoothService extends IBluetooth.Stub {
|
||||
}
|
||||
|
||||
public boolean disconnectSink(String address) {
|
||||
if (getBondState(address) != BluetoothDevice.BOND_BONDED) return false;
|
||||
|
||||
BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
|
||||
if (state != null) {
|
||||
Message msg = new Message();
|
||||
|
||||
Reference in New Issue
Block a user