Merge "Add Api to get profile connection state."
This commit is contained in:
committed by
Android (Google) Code Review
commit
cbf3e59590
@@ -773,6 +773,31 @@ public final class BluetoothAdapter {
|
|||||||
return BluetoothAdapter.STATE_DISCONNECTED;
|
return BluetoothAdapter.STATE_DISCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current connection state of a profile.
|
||||||
|
* This function can be used to check whether the local Bluetooth adapter
|
||||||
|
* is connected to any remote device for a specific profile.
|
||||||
|
* Profile can be one of {@link BluetoothProfile.HEADSET},
|
||||||
|
* {@link BluetoothProfile.A2DP}.
|
||||||
|
*
|
||||||
|
* <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
|
||||||
|
*
|
||||||
|
* <p> Return value can be one of
|
||||||
|
* {@link * BluetoothProfile.STATE_DISCONNECTED},
|
||||||
|
* {@link * BluetoothProfile.STATE_CONNECTING},
|
||||||
|
* {@link * BluetoothProfile.STATE_CONNECTED},
|
||||||
|
* {@link * BluetoothProfile.STATE_DISCONNECTING}
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public int getProfileConnectionState(int profile) {
|
||||||
|
if (getState() != STATE_ON) return BluetoothProfile.STATE_DISCONNECTED;
|
||||||
|
try {
|
||||||
|
return mService.getProfileConnectionState(profile);
|
||||||
|
} catch (RemoteException e) {Log.e(TAG, "getProfileConnectionState:", e);}
|
||||||
|
return BluetoothProfile.STATE_DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
/**
|
||||||
* Picks RFCOMM channels until none are left.
|
* Picks RFCOMM channels until none are left.
|
||||||
* Avoids reserved channels.
|
* Avoids reserved channels.
|
||||||
|
|||||||
@@ -82,6 +82,12 @@ public interface BluetoothProfile {
|
|||||||
*/
|
*/
|
||||||
public static final int PAN = 5;
|
public static final int PAN = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PBAP
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int PBAP = 6;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default priority for devices that we try to auto-connect to and
|
* Default priority for devices that we try to auto-connect to and
|
||||||
* and allow incoming connections for the profile
|
* and allow incoming connections for the profile
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ interface IBluetooth
|
|||||||
byte[] readOutOfBandData();
|
byte[] readOutOfBandData();
|
||||||
|
|
||||||
int getAdapterConnectionState();
|
int getAdapterConnectionState();
|
||||||
|
int getProfileConnectionState(int profile);
|
||||||
boolean changeApplicationBluetoothState(boolean on,
|
boolean changeApplicationBluetoothState(boolean on,
|
||||||
in IBluetoothStateChangeCallback callback, in
|
in IBluetoothStateChangeCallback callback, in
|
||||||
IBinder b);
|
IBinder b);
|
||||||
@@ -121,5 +122,5 @@ interface IBluetooth
|
|||||||
List<BluetoothDevice> getHealthDevicesMatchingConnectionStates(in int[] states);
|
List<BluetoothDevice> getHealthDevicesMatchingConnectionStates(in int[] states);
|
||||||
int getHealthDeviceConnectionState(in BluetoothDevice device);
|
int getHealthDeviceConnectionState(in BluetoothDevice device);
|
||||||
|
|
||||||
void sendConnectionStateChange(in BluetoothDevice device, int state, int prevState);
|
void sendConnectionStateChange(in BluetoothDevice device, int profile, int state, int prevState);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -523,7 +523,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
|
|||||||
|
|
||||||
if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state);
|
if (DBG) log("A2DP state : device: " + device + " State:" + prevState + "->" + state);
|
||||||
|
|
||||||
mBluetoothService.sendConnectionStateChange(device, state, prevState);
|
mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.A2DP, state,
|
||||||
|
prevState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothAdapter;
|
|||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.bluetooth.BluetoothHealth;
|
import android.bluetooth.BluetoothHealth;
|
||||||
import android.bluetooth.BluetoothHealthAppConfiguration;
|
import android.bluetooth.BluetoothHealthAppConfiguration;
|
||||||
|
import android.bluetooth.BluetoothProfile;
|
||||||
import android.bluetooth.IBluetoothHealthCallback;
|
import android.bluetooth.IBluetoothHealthCallback;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@@ -567,7 +568,8 @@ final class BluetoothHealthProfileHandler {
|
|||||||
private void updateAndSendIntent(BluetoothDevice device, int prevDeviceState,
|
private void updateAndSendIntent(BluetoothDevice device, int prevDeviceState,
|
||||||
int newDeviceState) {
|
int newDeviceState) {
|
||||||
mHealthDevices.put(device, newDeviceState);
|
mHealthDevices.put(device, newDeviceState);
|
||||||
mBluetoothService.sendConnectionStateChange(device, prevDeviceState, newDeviceState);
|
mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.HEALTH,
|
||||||
|
prevDeviceState, newDeviceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothAdapter;
|
|||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.bluetooth.BluetoothDeviceProfileState;
|
import android.bluetooth.BluetoothDeviceProfileState;
|
||||||
import android.bluetooth.BluetoothInputDevice;
|
import android.bluetooth.BluetoothInputDevice;
|
||||||
|
import android.bluetooth.BluetoothProfile;
|
||||||
import android.bluetooth.BluetoothProfileState;
|
import android.bluetooth.BluetoothProfileState;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@@ -191,7 +192,8 @@ final class BluetoothInputProfileHandler {
|
|||||||
mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
|
mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
|
||||||
|
|
||||||
debugLog("InputDevice state : device: " + device + " State:" + prevState + "->" + state);
|
debugLog("InputDevice state : device: " + device + " State:" + prevState + "->" + state);
|
||||||
mBluetoothService.sendConnectionStateChange(device, state, prevState);
|
mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.INPUT_DEVICE, state,
|
||||||
|
prevState);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleInputDevicePropertyChange(String address, boolean connected) {
|
void handleInputDevicePropertyChange(String address, boolean connected) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package android.server;
|
|||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.bluetooth.BluetoothPan;
|
import android.bluetooth.BluetoothPan;
|
||||||
|
import android.bluetooth.BluetoothProfile;
|
||||||
import android.bluetooth.BluetoothTetheringDataTracker;
|
import android.bluetooth.BluetoothTetheringDataTracker;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -303,7 +304,8 @@ final class BluetoothPanProfileHandler {
|
|||||||
mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
|
mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
|
||||||
|
|
||||||
debugLog("Pan Device state : device: " + device + " State:" + prevState + "->" + state);
|
debugLog("Pan Device state : device: " + device + " State:" + prevState + "->" + state);
|
||||||
mBluetoothService.sendConnectionStateChange(device, state, prevState);
|
mBluetoothService.sendConnectionStateChange(device, BluetoothProfile.PAN, state,
|
||||||
|
prevState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BluetoothPanDevice {
|
private class BluetoothPanDevice {
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
private static final String INCOMING_CONNECTION_FILE =
|
private static final String INCOMING_CONNECTION_FILE =
|
||||||
"/data/misc/bluetooth/incoming_connection.conf";
|
"/data/misc/bluetooth/incoming_connection.conf";
|
||||||
private HashMap<String, Pair<Integer, String>> mIncomingConnections;
|
private HashMap<String, Pair<Integer, String>> mIncomingConnections;
|
||||||
|
private HashMap<Integer, Pair<Integer, Integer>> mProfileConnectionState;
|
||||||
|
|
||||||
private static class RemoteService {
|
private static class RemoteService {
|
||||||
public String address;
|
public String address;
|
||||||
@@ -237,6 +238,7 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
mBluetoothPanProfileHandler = BluetoothPanProfileHandler.getInstance(mContext, this);
|
mBluetoothPanProfileHandler = BluetoothPanProfileHandler.getInstance(mContext, this);
|
||||||
mBluetoothHealthProfileHandler = BluetoothHealthProfileHandler.getInstance(mContext, this);
|
mBluetoothHealthProfileHandler = BluetoothHealthProfileHandler.getInstance(mContext, this);
|
||||||
mIncomingConnections = new HashMap<String, Pair<Integer, String>>();
|
mIncomingConnections = new HashMap<String, Pair<Integer, String>>();
|
||||||
|
mProfileConnectionState = new HashMap<Integer, Pair<Integer, Integer>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized String readDockBluetoothAddress() {
|
public static synchronized String readDockBluetoothAddress() {
|
||||||
@@ -1742,6 +1744,19 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
dumpInputDeviceProfile(pw);
|
dumpInputDeviceProfile(pw);
|
||||||
dumpPanProfile(pw);
|
dumpPanProfile(pw);
|
||||||
dumpApplicationServiceRecords(pw);
|
dumpApplicationServiceRecords(pw);
|
||||||
|
dumpProfileState(pw);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dumpProfileState(PrintWriter pw) {
|
||||||
|
pw.println("\n--Profile State dump--");
|
||||||
|
pw.println("\n Headset profile state:" +
|
||||||
|
mAdapter.getProfileConnectionState(BluetoothProfile.HEADSET));
|
||||||
|
pw.println("\n A2dp profile state:" +
|
||||||
|
mAdapter.getProfileConnectionState(BluetoothProfile.A2DP));
|
||||||
|
pw.println("\n HID profile state:" +
|
||||||
|
mAdapter.getProfileConnectionState(BluetoothProfile.INPUT_DEVICE));
|
||||||
|
pw.println("\n PAN profile state:" +
|
||||||
|
mAdapter.getProfileConnectionState(BluetoothProfile.PAN));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dumpHeadsetService(PrintWriter pw) {
|
private void dumpHeadsetService(PrintWriter pw) {
|
||||||
@@ -2443,23 +2458,85 @@ public class BluetoothService extends IBluetooth.Stub {
|
|||||||
return mAdapterConnectionState;
|
return mAdapterConnectionState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void sendConnectionStateChange(BluetoothDevice device, int state,
|
public int getProfileConnectionState(int profile) {
|
||||||
int prevState) {
|
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
|
||||||
|
|
||||||
|
Pair<Integer, Integer> state = mProfileConnectionState.get(profile);
|
||||||
|
if (state == null) return BluetoothProfile.STATE_DISCONNECTED;
|
||||||
|
|
||||||
|
return state.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateProfileConnectionState(int profile, int newState, int oldState) {
|
||||||
|
// mProfileConnectionState is a hashmap -
|
||||||
|
// <Integer, Pair<Integer, Integer>>
|
||||||
|
// The key is the profile, the value is a pair. first element
|
||||||
|
// is the state and the second element is the number of devices
|
||||||
|
// in that state.
|
||||||
|
int numDev = 1;
|
||||||
|
int newHashState = newState;
|
||||||
|
boolean update = true;
|
||||||
|
|
||||||
|
// The following conditions are considered in this function:
|
||||||
|
// 1. If there is no record of profile and state - update
|
||||||
|
// 2. If a new device's state is current hash state - increment
|
||||||
|
// number of devices in the state.
|
||||||
|
// 3. If a state change has happened to Connected or Connecting
|
||||||
|
// (if current state is not connected), update.
|
||||||
|
// 4. If numDevices is 1 and that device state is being updated, update
|
||||||
|
// 5. If numDevices is > 1 and one of the devices is changing state,
|
||||||
|
// decrement numDevices but maintain oldState if it is Connected or
|
||||||
|
// Connecting
|
||||||
|
Pair<Integer, Integer> stateNumDev = mProfileConnectionState.get(profile);
|
||||||
|
if (stateNumDev != null) {
|
||||||
|
int currHashState = stateNumDev.first;
|
||||||
|
numDev = stateNumDev.second;
|
||||||
|
|
||||||
|
if (newState == currHashState) {
|
||||||
|
numDev ++;
|
||||||
|
} else if (newState == BluetoothProfile.STATE_CONNECTED ||
|
||||||
|
(newState == BluetoothProfile.STATE_CONNECTING &&
|
||||||
|
currHashState != BluetoothProfile.STATE_CONNECTED)) {
|
||||||
|
numDev = 1;
|
||||||
|
} else if (numDev == 1 && oldState == currHashState) {
|
||||||
|
update = true;
|
||||||
|
} else if (numDev > 1 && oldState == currHashState) {
|
||||||
|
numDev --;
|
||||||
|
|
||||||
|
if (currHashState == BluetoothProfile.STATE_CONNECTED ||
|
||||||
|
currHashState == BluetoothProfile.STATE_CONNECTING) {
|
||||||
|
newHashState = currHashState;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
update = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (update) {
|
||||||
|
mProfileConnectionState.put(profile, new Pair<Integer, Integer>(newHashState,
|
||||||
|
numDev));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void sendConnectionStateChange(BluetoothDevice
|
||||||
|
device, int profile, int state, int prevState) {
|
||||||
// Since this is a binder call check if Bluetooth is on still
|
// Since this is a binder call check if Bluetooth is on still
|
||||||
if (getBluetoothStateInternal() == BluetoothAdapter.STATE_OFF) return;
|
if (getBluetoothStateInternal() == BluetoothAdapter.STATE_OFF) return;
|
||||||
|
|
||||||
if (updateCountersAndCheckForConnectionStateChange(state, prevState)) {
|
if (!validateProfileConnectionState(state) ||
|
||||||
if (!validateProfileConnectionState(state) ||
|
!validateProfileConnectionState(prevState)) {
|
||||||
!validateProfileConnectionState(prevState)) {
|
// Previously, an invalid state was broadcast anyway,
|
||||||
// Previously, an invalid state was broadcast anyway,
|
// with the invalid state converted to -1 in the intent.
|
||||||
// with the invalid state converted to -1 in the intent.
|
// Better to log an error and not send an intent with
|
||||||
// Better to log an error and not send an intent with
|
// invalid contents or set mAdapterConnectionState to -1.
|
||||||
// invalid contents or set mAdapterConnectionState to -1.
|
Log.e(TAG, "Error in sendConnectionStateChange: "
|
||||||
Log.e(TAG, "Error in sendConnectionStateChange: "
|
+ "prevState " + prevState + " state " + state);
|
||||||
+ "prevState " + prevState + " state " + state);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
updateProfileConnectionState(profile, state, prevState);
|
||||||
|
|
||||||
|
if (updateCountersAndCheckForConnectionStateChange(state, prevState)) {
|
||||||
mAdapterConnectionState = state;
|
mAdapterConnectionState = state;
|
||||||
|
|
||||||
if (state == BluetoothProfile.STATE_DISCONNECTED) {
|
if (state == BluetoothProfile.STATE_DISCONNECTED) {
|
||||||
|
|||||||
Reference in New Issue
Block a user