summaryrefslogtreecommitdiffstats
path: root/core/java/android/bluetooth
diff options
context:
space:
mode:
authorNitin Arora <niarora@codeaurora.org>2015-03-02 15:03:51 -0800
committerAndre Eisenbach <eisenbach@google.com>2015-04-15 23:45:30 -0700
commitd055adbe2c1c65d9346e65209fa8790190bc239e (patch)
treeab1f16a591fd857902c8d094360f31aac38cf305 /core/java/android/bluetooth
parentbd3af28fdc38cfe741badb86f9daa2fc6122eabc (diff)
downloadframeworks_base-d055adbe2c1c65d9346e65209fa8790190bc239e.zip
frameworks_base-d055adbe2c1c65d9346e65209fa8790190bc239e.tar.gz
frameworks_base-d055adbe2c1c65d9346e65209fa8790190bc239e.tar.bz2
Bluetooth LE background operation mode (2/2)
Changes include new framework APIs to enable and disable Bluetooth LE separately from Bluetooth Classic. Along with handling the new states in the Bluetooth manager service. Change-Id: Idf667981f48fcbcb6dfda1aa77ea8bab1b2361f0
Diffstat (limited to 'core/java/android/bluetooth')
-rw-r--r--core/java/android/bluetooth/BluetoothAdapter.java312
-rw-r--r--core/java/android/bluetooth/BluetoothDevice.java55
-rw-r--r--core/java/android/bluetooth/IBluetooth.aidl2
-rw-r--r--core/java/android/bluetooth/IBluetoothGatt.aidl2
-rw-r--r--core/java/android/bluetooth/IBluetoothManager.aidl2
-rw-r--r--core/java/android/bluetooth/IBluetoothManagerCallback.aidl3
-rw-r--r--core/java/android/bluetooth/le/BluetoothLeUtils.java2
7 files changed, 355 insertions, 23 deletions
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 87d5bb0..dd030f8 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -32,6 +32,9 @@ import android.os.IBinder;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.app.ActivityThread;
+import android.os.SystemProperties;
+import android.os.Binder;
import android.util.Log;
import android.util.Pair;
@@ -118,6 +121,9 @@ public final class BluetoothAdapter {
* {@link #STATE_TURNING_ON},
* {@link #STATE_ON},
* {@link #STATE_TURNING_OFF},
+ * {@link #STATE_BLE_TURNING_ON},
+ * {@link #STATE_BLE_ON},
+ * {@link #STATE_BLE_TURNING_OFF},
*/
public static final String EXTRA_STATE =
"android.bluetooth.adapter.extra.STATE";
@@ -128,6 +134,9 @@ public final class BluetoothAdapter {
* {@link #STATE_TURNING_ON},
* {@link #STATE_ON},
* {@link #STATE_TURNING_OFF},
+ * {@link #STATE_BLE_TURNING_ON},
+ * {@link #STATE_BLE_ON},
+ * {@link #STATE_BLE_TURNING_OFF},
*/
public static final String EXTRA_PREVIOUS_STATE =
"android.bluetooth.adapter.extra.PREVIOUS_STATE";
@@ -153,6 +162,24 @@ public final class BluetoothAdapter {
public static final int STATE_TURNING_OFF = 13;
/**
+ * Indicates the local Bluetooth adapter is turning Bluetooth LE mode on.
+ * @hide
+ */
+ public static final int STATE_BLE_TURNING_ON = 14;
+
+ /**
+ * Indicates the local Bluetooth adapter is in LE only mode.
+ * @hide
+ */
+ public static final int STATE_BLE_ON = 15;
+
+ /**
+ * Indicates the local Bluetooth adapter is turning off LE only mode.
+ * @hide
+ */
+ public static final int STATE_BLE_TURNING_OFF = 16;
+
+ /**
* Activity Action: Show a system activity that requests discoverable mode.
* This activity will also request the user to turn on Bluetooth if it
* is not currently enabled.
@@ -363,6 +390,39 @@ public final class BluetoothAdapter {
public static final String EXTRA_PREVIOUS_CONNECTION_STATE =
"android.bluetooth.adapter.extra.PREVIOUS_CONNECTION_STATE";
+ /**
+ * Broadcast Action: The Bluetooth adapter state has changed in LE only mode.
+ * @hide
+ */
+ public static final String ACTION_BLE_STATE_CHANGED =
+ "anrdoid.bluetooth.adapter.action.BLE_STATE_CHANGED";
+
+ /**
+ * Broadcast Action: The notifys Bluetooth ACL connected event. This will be
+ * by BLE Always on enabled application to know the ACL_CONNECTED event
+ * when Bluetooth state in STATE_BLE_ON. This denotes GATT connection
+ * as Bluetooth LE is the only feature available in STATE_BLE_ON
+ *
+ * This is counterpart of {@link BluetoothDevice#ACTION_ACL_CONNECTED} which
+ * works in Bluetooth state STATE_ON
+ * @hide
+ */
+ public static final String ACTION_BLE_ACL_CONNECTED =
+ "android.bluetooth.adapter.action.BLE_ACL_CONNECTED";
+
+ /**
+ * Broadcast Action: The notifys Bluetooth ACL connected event. This will be
+ * by BLE Always on enabled application to know the ACL_DISCONNECTED event
+ * when Bluetooth state in STATE_BLE_ON. This denotes GATT disconnection as Bluetooth
+ * LE is the only feature available in STATE_BLE_ON
+ *
+ * This is counterpart of {@link BluetoothDevice#ACTION_ACL_DISCONNECTED} which
+ * works in Bluetooth state STATE_ON
+ * @hide
+ */
+ public static final String ACTION_BLE_ACL_DISCONNECTED =
+ "android.bluetooth.adapter.action.BLE_ACL_DISCONNECTED";
+
/** The profile is in disconnected state */
public static final int STATE_DISCONNECTED = 0;
/** The profile is in connecting state */
@@ -374,6 +434,7 @@ public final class BluetoothAdapter {
/** @hide */
public static final String BLUETOOTH_MANAGER_SERVICE = "bluetooth_manager";
+ private final IBinder mToken;
/** When creating a ServerSocket using listenUsingRfcommOn() or
@@ -444,6 +505,7 @@ public final class BluetoothAdapter {
} catch (RemoteException e) {Log.e(TAG, "", e);}
mManagerService = managerService;
mLeScanClients = new HashMap<LeScanCallback, ScanCallback>();
+ mToken = new Binder();
}
/**
@@ -490,11 +552,9 @@ public final class BluetoothAdapter {
* on this device before calling this method.
*/
public BluetoothLeAdvertiser getBluetoothLeAdvertiser() {
- if (getState() != STATE_ON) {
- return null;
- }
+ if (!getLeAccess()) return null;
if (!isMultipleAdvertisementSupported() && !isPeripheralModeSupported()) {
- Log.e(TAG, "bluetooth le advertising not supported");
+ Log.e(TAG, "Bluetooth LE advertising not supported");
return null;
}
synchronized(mLock) {
@@ -509,9 +569,7 @@ public final class BluetoothAdapter {
* Returns a {@link BluetoothLeScanner} object for Bluetooth LE scan operations.
*/
public BluetoothLeScanner getBluetoothLeScanner() {
- if (getState() != STATE_ON) {
- return null;
- }
+ if (!getLeAccess()) return null;
synchronized(mLock) {
if (sBluetoothLeScanner == null) {
sBluetoothLeScanner = new BluetoothLeScanner(mManagerService);
@@ -529,7 +587,6 @@ public final class BluetoothAdapter {
* @return true if the local adapter is turned on
*/
public boolean isEnabled() {
-
try {
synchronized(mManagerCallback) {
if (mService != null) return mService.isEnabled();
@@ -539,6 +596,178 @@ public final class BluetoothAdapter {
}
/**
+ * Return true if Bluetooth LE(Always BLE On feature) is currently
+ * enabled and ready for use
+ * <p>This returns true if current state is either STATE_ON or STATE_BLE_ON
+ *
+ * @return true if the local Bluetooth LE adapter is turned on
+ * @hide
+ */
+ public boolean isLeEnabled() {
+ final int state = getLeState();
+ if (state == BluetoothAdapter.STATE_ON) {
+ if (DBG) Log.d (TAG, "STATE_ON");
+ } else if (state == BluetoothAdapter.STATE_BLE_ON) {
+ if (DBG) Log.d (TAG, "STATE_BLE_ON");
+ } else {
+ if (DBG) Log.d (TAG, "STATE_OFF");
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Performs action based on user action to turn BT ON
+ * or OFF if BT is in BLE_ON state
+ */
+ private void notifyUserAction(boolean enable) {
+ if (mService == null) {
+ Log.e(TAG, "mService is null");
+ return;
+ }
+
+ try {
+ if (enable) {
+ mService.onLeServiceUp(); //NA:TODO implementation pending
+ } else {
+ mService.onBrEdrDown(); //NA:TODO implementation pending
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ }
+
+ /**
+ * Returns true if LE only mode is enabled, that is apps
+ * have authorization to turn only BT ON and the calling
+ * app has privilage to do so
+ */
+ private boolean isLEAlwaysOnEnabled() {
+ boolean ret = false;
+ if (SystemProperties.getBoolean("ro.bluetooth.blealwayson", true) == true) {
+ Log.v(TAG, "LE always on mode is enabled");
+ // TODO: System API authorization check
+ ret = true;
+ } else {
+ Log.v(TAG, "LE always on mode is disabled");
+ ret = false;
+ }
+ return ret;
+ }
+
+ /**
+ * Turns off Bluetooth LE which was earlier turned on by calling EnableBLE().
+ *
+ * <p> If the internal Adapter state is STATE_BLE_ON, this would trigger the transition
+ * to STATE_OFF and completely shut-down Bluetooth
+ *
+ * <p> If the Adapter state is STATE_ON, This would unregister the existance of
+ * special Bluetooth LE application and hence the further turning off of Bluetooth
+ * from UI would ensure the complete turn-off of Bluetooth rather than staying back
+ * BLE only state
+ *
+ * <p>This is an asynchronous call: it will return immediately, and
+ * clients should listen for {@link #ACTION_BLE_STATE_CHANGED}
+ * to be notified of subsequent adapter state changes If this call returns
+ * true, then the adapter state will immediately transition from {@link
+ * #STATE_ON} to {@link #STATE_TURNING_OFF}, and some time
+ * later transition to either {@link #STATE_BLE_ON} or {@link
+ * #STATE_OFF} based on the existance of the further Always BLE ON enabled applications
+ * If this call returns false then there was an
+ * immediate problem that will prevent the QAdapter from being turned off -
+ * such as the QAadapter already being turned off.
+ *
+ * @return true to indicate success, or false on
+ * immediate error
+ * @hide
+ */
+ public boolean disableBLE() {
+ if (isLEAlwaysOnEnabled() != true) return false;
+
+ int state = getLeState();
+ if (state == BluetoothAdapter.STATE_ON) {
+ if (DBG) Log.d (TAG, "STATE_ON: shouldn't disable");
+ try {
+ mManagerService.updateBleAppCount(mToken, false);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ return true;
+
+ } else if (state == BluetoothAdapter.STATE_BLE_ON) {
+ if (DBG) Log.d (TAG, "STATE_BLE_ON");
+ int bleAppCnt = 0;
+ try {
+ bleAppCnt = mManagerService.updateBleAppCount(mToken, false);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ if (bleAppCnt == 0) {
+ // Disable only if there are no other clients
+ notifyUserAction(false);
+ }
+ return true;
+ }
+
+ if (DBG) Log.d (TAG, "STATE_OFF: Already disabled");
+ return false;
+ }
+
+ /**
+ * Special Applications who want to only turn on Bluetooth Low Energy (BLE) would
+ * EnableBLE, EnableBLE brings-up Bluetooth so that application can access
+ * only LE related feature (Bluetooth GATT layers interfaces using the respective class)
+ * EnableBLE in turn registers the existance of a special App which wants to
+ * turn on Bluetooth Low enrgy part without making it visible at the settings UI
+ * as Bluetooth ON.
+ * <p>Invoking EnableBLE when Bluetooth is already in ON state, would just registers
+ * the existance of special Application and doesn't do anything to current BT state.
+ * when user turn OFF Bluetooth from UI, if there is an existance of special app, Bluetooth
+ * would stay in BLE_ON state so that LE features are still acessible to the special
+ * Applications.
+ *
+ * <p>This is an asynchronous call: it will return immediately, and
+ * clients should listen for {@link #ACTION_BLE_STATE_CHANGED}
+ * to be notified of subsequent adapter state changes. If this call returns
+ * true, then the adapter state will immediately transition from {@link
+ * #STATE_OFF} to {@link #STATE_BLE_TURNING_ON}, and some time
+ * later transition to either {@link #STATE_OFF} or {@link
+ * #STATE_BLE_ON}. If this call returns false then there was an
+ * immediate problem that will prevent the adapter from being turned on -
+ * such as Airplane mode, or the adapter is already turned on.
+ * (@link #ACTION_BLE_STATE_CHANGED) returns the Bluetooth Adapter's various
+ * states, It includes all the classic Bluetooth Adapter states along with
+ * internal BLE only states
+ *
+ * @return true to indicate Bluetooth LE start-up has begun, or false on
+ * immediate error
+ * @hide
+ */
+ public boolean enableBLE() {
+ if (isLEAlwaysOnEnabled() != true) return false;
+
+ if (isLeEnabled() == true) {
+ if (DBG) Log.d(TAG, "enableBLE(): BT is already enabled..!");
+ try {
+ mManagerService.updateBleAppCount(mToken, true);
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ return true;
+ }
+
+ try {
+ if (DBG) Log.d(TAG, "Calling enableBLE");
+ mManagerService.updateBleAppCount(mToken, true);
+ return mManagerService.enable();
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+
+ return false;
+ }
+
+ /**
* Get the current state of the local Bluetooth adapter.
* <p>Possible return values are
* {@link #STATE_OFF},
@@ -556,6 +785,13 @@ public final class BluetoothAdapter {
{
int state= mService.getState();
if (VDBG) Log.d(TAG, "" + hashCode() + ": getState(). Returning " + state);
+ //consider all internal states as OFF
+ if (state == BluetoothAdapter.STATE_BLE_ON
+ || state == BluetoothAdapter.STATE_BLE_TURNING_ON
+ || state == BluetoothAdapter.STATE_BLE_TURNING_OFF) {
+ if (VDBG) Log.d(TAG, "Consider internal state as OFF");
+ state = BluetoothAdapter.STATE_OFF;
+ }
return state;
}
// TODO(BT) there might be a small gap during STATE_TURNING_ON that
@@ -567,6 +803,49 @@ public final class BluetoothAdapter {
}
/**
+ * Get the current state of the local Bluetooth adapter
+ * <p>This returns current internal state of Adapter including LE ON/OFF
+ *
+ * <p>Possible return values are
+ * {@link #STATE_OFF},
+ * {@link #STATE_BLE_TURNING_ON},
+ * {@link #STATE_BLE_ON},
+ * {@link #STATE_TURNING_ON},
+ * {@link #STATE_ON},
+ * {@link #STATE_TURNING_OFF},
+ * {@link #STATE_BLE_TURNING_OFF}.
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
+ *
+ * @return current state of Bluetooth adapter
+ * @hide
+ */
+ public int getLeState() {
+ try {
+ synchronized(mManagerCallback) {
+ if (mService != null)
+ {
+ int state= mService.getState();
+ if (VDBG) Log.d(TAG,"getLeState() returning " + state);
+ return state;
+ }
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "", e);
+ }
+ return BluetoothAdapter.STATE_OFF;
+ }
+
+ boolean getLeAccess() {
+ if(getLeState() == STATE_ON)
+ return true;
+
+ else if (getLeState() == STATE_BLE_ON)
+ return true; // TODO: FILTER SYSTEM APPS HERE <--
+
+ return false;
+ }
+
+ /**
* Turn on the local Bluetooth adapter&mdash;do not use without explicit
* user action to turn on Bluetooth.
* <p>This powers on the underlying Bluetooth hardware, and starts all
@@ -594,10 +873,23 @@ public final class BluetoothAdapter {
* immediate error
*/
public boolean enable() {
+ int state = STATE_OFF;
if (isEnabled() == true){
if (DBG) Log.d(TAG, "enable(): BT is already enabled..!");
return true;
}
+ //Use service interface to get the exact state
+ if (mService != null) {
+ try {
+ state = mService.getState();
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ }
+
+ if (state == BluetoothAdapter.STATE_BLE_ON) {
+ Log.e(TAG, "BT is in BLE_ON State");
+ notifyUserAction(true);
+ return true;
+ }
try {
return mManagerService.enable();
} catch (RemoteException e) {Log.e(TAG, "", e);}
@@ -1558,6 +1850,10 @@ public final class BluetoothAdapter {
}
}
}
+
+ public void onBrEdrDown() {
+ if (VDBG) Log.i(TAG, "on QBrEdrDown: ");
+ }
};
/**
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 1fdf9f4..1e82c03 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -606,7 +606,9 @@ public final class BluetoothDevice implements Parcelable {
public void onBluetoothServiceUp(IBluetooth bluetoothService)
throws RemoteException {
synchronized (BluetoothDevice.class) {
- sService = bluetoothService;
+ if (sService == null) {
+ sService = bluetoothService;
+ }
}
}
@@ -616,6 +618,11 @@ public final class BluetoothDevice implements Parcelable {
sService = null;
}
}
+
+ public void onBrEdrDown()
+ {
+ if (DBG) Log.d(TAG, "onBrEdrDown: reached BLE ON state");
+ }
};
/**
* Create a new BluetoothDevice
@@ -1030,7 +1037,7 @@ public final class BluetoothDevice implements Parcelable {
* or null on error
*/
public ParcelUuid[] getUuids() {
- if (sService == null) {
+ if (sService == null || isBluetoothEnabled() == false) {
Log.e(TAG, "BT not enabled. Cannot get remote device Uuids");
return null;
}
@@ -1057,7 +1064,7 @@ public final class BluetoothDevice implements Parcelable {
*/
public boolean fetchUuidsWithSdp() {
IBluetooth service = sService;
- if (service == null) {
+ if (service == null || isBluetoothEnabled() == false) {
Log.e(TAG, "BT not enabled. Cannot fetchUuidsWithSdp");
return false;
}
@@ -1099,16 +1106,6 @@ public final class BluetoothDevice implements Parcelable {
return false;
}
- /** @hide */
- public int getServiceChannel(ParcelUuid uuid) {
- //TODO(BT)
- /*
- try {
- return sService.getRemoteServiceChannel(this, uuid);
- } catch (RemoteException e) {Log.e(TAG, "", e);}*/
- return BluetoothDevice.ERROR;
- }
-
/**
* Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
* <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
@@ -1187,6 +1184,15 @@ public final class BluetoothDevice implements Parcelable {
return false;
}
+ boolean isBluetoothEnabled() {
+ boolean ret = false;
+ BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ if (adapter != null && adapter.isEnabled() == true) {
+ ret = true;
+ }
+ return ret;
+ }
+
/**
* Requires {@link android.Manifest.permission#BLUETOOTH}.
* @return Whether the phonebook access is allowed to this device. Can be
@@ -1289,6 +1295,10 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
public BluetoothSocket createRfcommSocket(int channel) throws IOException {
+ if (isBluetoothEnabled() == false) {
+ Log.e(TAG, "Bluetooth is not enabled");
+ throw new IOException();
+ }
return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel,
null);
}
@@ -1355,6 +1365,11 @@ public final class BluetoothDevice implements Parcelable {
* insufficient permissions
*/
public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
+ if (isBluetoothEnabled() == false) {
+ Log.e(TAG, "Bluetooth is not enabled");
+ throw new IOException();
+ }
+
return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, -1,
new ParcelUuid(uuid));
}
@@ -1388,6 +1403,10 @@ public final class BluetoothDevice implements Parcelable {
* insufficient permissions
*/
public BluetoothSocket createInsecureRfcommSocketToServiceRecord(UUID uuid) throws IOException {
+ if (isBluetoothEnabled() == false) {
+ Log.e(TAG, "Bluetooth is not enabled");
+ throw new IOException();
+ }
return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, -1,
new ParcelUuid(uuid));
}
@@ -1407,6 +1426,11 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
+
+ if (isBluetoothEnabled() == false) {
+ Log.e(TAG, "Bluetooth is not enabled");
+ throw new IOException();
+ }
return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port,
null);
}
@@ -1422,6 +1446,11 @@ public final class BluetoothDevice implements Parcelable {
* @hide
*/
public BluetoothSocket createScoSocket() throws IOException {
+
+ if (isBluetoothEnabled() == false) {
+ Log.e(TAG, "Bluetooth is not enabled");
+ throw new IOException();
+ }
return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1, null);
}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index af560df..90df198 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -102,4 +102,6 @@ interface IBluetooth
// for dumpsys support
String dump();
+ void onLeServiceUp();
+ void onBrEdrDown();
}
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index 7070bae..4ca57f8 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -101,4 +101,6 @@ interface IBluetoothGatt {
in int srvcInstanceId, in ParcelUuid srvcId,
in int charInstanceId, in ParcelUuid charId,
in boolean confirm, in byte[] value);
+ void disconnectAll();
+ void unregAll();
}
diff --git a/core/java/android/bluetooth/IBluetoothManager.aidl b/core/java/android/bluetooth/IBluetoothManager.aidl
index 7411d3f..8d1ce99 100644
--- a/core/java/android/bluetooth/IBluetoothManager.aidl
+++ b/core/java/android/bluetooth/IBluetoothManager.aidl
@@ -44,4 +44,6 @@ interface IBluetoothManager
String getAddress();
String getName();
+ int updateBleAppCount(IBinder b, boolean enable);
+ boolean isBleAppPresent();
}
diff --git a/core/java/android/bluetooth/IBluetoothManagerCallback.aidl b/core/java/android/bluetooth/IBluetoothManagerCallback.aidl
index 9551086..1385daf 100644
--- a/core/java/android/bluetooth/IBluetoothManagerCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothManagerCallback.aidl
@@ -26,4 +26,5 @@ import android.bluetooth.IBluetooth;
interface IBluetoothManagerCallback {
void onBluetoothServiceUp(in IBluetooth bluetoothService);
void onBluetoothServiceDown();
-} \ No newline at end of file
+ void onBrEdrDown();
+}
diff --git a/core/java/android/bluetooth/le/BluetoothLeUtils.java b/core/java/android/bluetooth/le/BluetoothLeUtils.java
index 4916bd9..c40256b 100644
--- a/core/java/android/bluetooth/le/BluetoothLeUtils.java
+++ b/core/java/android/bluetooth/le/BluetoothLeUtils.java
@@ -132,7 +132,7 @@ public class BluetoothLeUtils {
* {@link BluetoothAdapter#STATE_ON}.
*/
static void checkAdapterStateOn(BluetoothAdapter adapter) {
- if (adapter == null || adapter.getState() != BluetoothAdapter.STATE_ON) {
+ if (adapter == null || !adapter.isLeEnabled()) {//adapter.getState() != BluetoothAdapter.STATE_ON) {
throw new IllegalStateException("BT Adapter is not turned ON");
}
}