Allow enabling Bluetooth without auto-connecting.
This is a feature used for NFC-to-Bluetooth handover:
we want to enable BT for file transfer, and disconnect
it when we're done. During this period we don't want
to auto-connect other devices - it should be transparent
to the user that Bluetooth is used. Also, don't allow
A2DP/HSP incoming connections.
Change-Id: I0a03e8084c439b1271b6a80f4d9da5aacfe19c45
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 600ce6f..8e3df47 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1232,6 +1232,18 @@
}
/**
+ * Enable the Bluetooth Adapter, but don't auto-connect devices
+ * and don't persist state. Only for use by system applications.
+ * @hide
+ */
+ public boolean enableNoAutoConnect() {
+ try {
+ return mService.enableNoAutoConnect();
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return false;
+ }
+
+ /**
* Enable control of the Bluetooth Adapter for a single application.
*
* <p>Some applications need to use Bluetooth for short periods of time to
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index deea2b8..6075363 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -34,6 +34,7 @@
boolean isEnabled();
int getBluetoothState();
boolean enable();
+ boolean enableNoAutoConnect();
boolean disable(boolean persistSetting);
String getAddress();
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 36c0189..7a97455 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -165,6 +165,8 @@
private static String mDockAddress;
private String mDockPin;
+ private boolean mAllowConnect = true;
+
private int mAdapterConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
private BluetoothPanProfileHandler mBluetoothPanProfileHandler;
private BluetoothInputProfileHandler mBluetoothInputProfileHandler;
@@ -472,7 +474,7 @@
/** Bring up BT and persist BT on in settings */
public boolean enable() {
- return enable(true);
+ return enable(true, true);
}
/**
@@ -480,9 +482,11 @@
* This turns on/off the underlying hardware.
*
* @param saveSetting If true, persist the new state of BT in settings
+ * @param allowConnect If true, auto-connects device when BT is turned on
+ * and allows incoming A2DP/HSP connections
* @return True on success (so far)
*/
- public synchronized boolean enable(boolean saveSetting) {
+ public synchronized boolean enable(boolean saveSetting, boolean allowConnect) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
@@ -490,11 +494,29 @@
if (mIsAirplaneSensitive && isAirplaneModeOn() && !mIsAirplaneToggleable) {
return false;
}
+ mAllowConnect = allowConnect;
mBluetoothState.sendMessage(BluetoothAdapterStateMachine.USER_TURN_ON, saveSetting);
return true;
}
/**
+ * Enable this Bluetooth device, asynchronously, but does not
+ * auto-connect devices. In this state the Bluetooth adapter
+ * also does not allow incoming A2DP/HSP connections (that
+ * must go through this service), but does allow communication
+ * on RFCOMM sockets implemented outside of this service (ie BTOPP).
+ * This method is used to temporarily enable Bluetooth
+ * for data transfer, without changing
+ *
+ * This turns on/off the underlying hardware.
+ *
+ * @return True on success (so far)
+ */
+ public boolean enableNoAutoConnect() {
+ return enable(false, false);
+ }
+
+ /**
* Turn on Bluetooth Module, Load firmware, and do all the preparation
* needed to get the Bluetooth Module ready but keep it not discoverable
* and not connectable.
@@ -2441,6 +2463,13 @@
}
private void autoConnect() {
+ synchronized (this) {
+ if (!mAllowConnect) {
+ Log.d(TAG, "Not auto-connecting devices because of temporary BT on state.");
+ return;
+ }
+ }
+
String[] bonds = getKnownDevices();
if (bonds == null) {
return;
@@ -2457,6 +2486,12 @@
}
public boolean notifyIncomingConnection(String address, boolean rejected) {
+ synchronized (this) {
+ if (!mAllowConnect) {
+ Log.d(TAG, "Not allowing incoming connection because of temporary BT on state.");
+ return false;
+ }
+ }
BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
if (state != null) {
Message msg = new Message();
@@ -2478,6 +2513,13 @@
}
/*package*/ boolean notifyIncomingA2dpConnection(String address, boolean rejected) {
+ synchronized (this) {
+ if (!mAllowConnect) {
+ Log.d(TAG, "Not allowing a2dp connection because of temporary BT on state.");
+ return false;
+ }
+ }
+
BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
if (state != null) {
Message msg = new Message();