Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(283)

Unified Diff: device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java

Issue 1150833002: bluetooth: android: Initial Low Energy Discovery Sessions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bta-manifest-
Patch Set: Add tests Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java
index 5775b0073f0a72dc4c815a1db2f0d511c183baf9..4526d9dd5f6b2e95bb9e51d75b7ad1bce8a3cf81 100644
--- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java
+++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/ChromeBluetoothAdapter.java
@@ -4,30 +4,46 @@
package org.chromium.device.bluetooth;
+import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.le.ScanSettings;
+import android.os.Build;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.base.Log;
+import java.util.List;
+
/**
* Exposes android.bluetooth.BluetoothAdapter as necessary for C++
* device::BluetoothAdapterAndroid, which implements the cross platform
* device::BluetoothAdapter.
*/
@JNINamespace("device")
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
final class ChromeBluetoothAdapter {
private static final String TAG = "cr.Bluetooth";
+ private long mNativeBluetoothAdapterAndroid;
private Wrappers.BluetoothAdapterWrapper mAdapter;
+ private int mNumDiscoverySessions;
+ private ScanCallback mScanCallback;
+
+ // ---------------------------------------------------------------------------------------------
+ // Construction and handler for C++ object destruction.
/**
* Constructs a ChromeBluetoothAdapter.
+ * @param nativeBluetoothAdapterAndroid Is the paired C++
armansito 2015/06/30 20:37:22 I'd say "coupled" or "associated" rather than pair
scheib 2015/06/30 21:02:14 Done.
+ * BluetoothAdapterAndroid pointer value.
* @param adapterWrapper Wraps the default android.bluetooth.BluetoothAdapter,
* but may be either null if an adapter is not available
* or a fake for testing.
*/
- private ChromeBluetoothAdapter(Wrappers.BluetoothAdapterWrapper adapterWrapper) {
+ private ChromeBluetoothAdapter(
+ long nativeBluetoothAdapterAndroid, Wrappers.BluetoothAdapterWrapper adapterWrapper) {
+ mNativeBluetoothAdapterAndroid = nativeBluetoothAdapterAndroid;
mAdapter = adapterWrapper;
if (adapterWrapper == null) {
Log.i(TAG, "ChromeBluetoothAdapter created with no adapterWrapper.");
@@ -36,6 +52,15 @@ final class ChromeBluetoothAdapter {
}
}
+ /**
+ * Handles C++ object being destroyed.
+ */
+ @CalledByNative
+ private void onBluetoothAdapterAndroidDestruction() {
+ stopScan();
+ mNativeBluetoothAdapterAndroid = 0;
+ }
+
// ---------------------------------------------------------------------------------------------
// BluetoothAdapterAndroid methods implemented in java:
@@ -43,8 +68,10 @@ final class ChromeBluetoothAdapter {
// 'Object' type must be used because inner class Wrappers.BluetoothAdapterWrapper reference is
// not handled by jni_generator.py JavaToJni. http://crbug.com/505554
@CalledByNative
- public static ChromeBluetoothAdapter create(Object adapterWrapper) {
- return new ChromeBluetoothAdapter((Wrappers.BluetoothAdapterWrapper) adapterWrapper);
+ public static ChromeBluetoothAdapter create(
+ long nativeBluetoothAdapterAndroid, Object adapterWrapper) {
+ return new ChromeBluetoothAdapter(
+ nativeBluetoothAdapterAndroid, (Wrappers.BluetoothAdapterWrapper) adapterWrapper);
}
// Implements BluetoothAdapterAndroid::GetAddress.
@@ -89,6 +116,123 @@ final class ChromeBluetoothAdapter {
// Implements BluetoothAdapterAndroid::IsDiscovering.
@CalledByNative
private boolean isDiscovering() {
- return isPresent() && mAdapter.isDiscovering();
+ return isPresent() && (mAdapter.isDiscovering() || mScanCallback != null);
+ }
+
+ // Implements BluetoothAdapterAndroid::AddDiscoverySession.
+ @CalledByNative
+ private boolean addDiscoverySession() {
+ if (!isPowered()) {
+ Log.d(TAG, "addDiscoverySession: Fails: !isPowered");
+ return false;
+ }
+
+ mNumDiscoverySessions++;
+ Log.d(TAG, "addDiscoverySession: Now %d sessions.", mNumDiscoverySessions);
+ if (mNumDiscoverySessions > 1) {
+ return true;
+ }
+
+ if (startScan()) {
+ return true;
+ } else {
armansito 2015/06/30 20:37:22 No need for else since you have an early return
scheib 2015/06/30 21:02:14 Done.
+ mNumDiscoverySessions--;
+ return false;
+ }
+ }
+
+ // Implements BluetoothAdapterAndroid::RemoveDiscoverySession.
+ @CalledByNative
+ private boolean removeDiscoverySession() {
+ if (mNumDiscoverySessions == 0) {
+ assert false;
+ Log.w(TAG, "removeDiscoverySession: No scan in progress.");
+ return false;
+ }
+
+ --mNumDiscoverySessions;
+
+ if (mNumDiscoverySessions == 0) {
+ Log.d(TAG, "removeDiscoverySession: Now 0 sessions. Stopping scan.");
+ return stopScan();
armansito 2015/06/30 20:37:22 no need for else
scheib 2015/06/30 21:02:14 Done.
+ } else {
+ Log.d(TAG, "removeDiscoverySession: Now %d sessions.", mNumDiscoverySessions);
+ }
+ return true;
+ }
+
+ // ---------------------------------------------------------------------------------------------
+ // Implementation details:
+
+ /**
+ * Starts a Low Energy scan.
+ * @return True on success.
+ */
+ private boolean startScan() {
+ // ScanSettings Note: SCAN_FAILED_FEATURE_UNSUPPORTED is caused (at least on some devices)
+ // if setReportDelay() is used or if SCAN_MODE_LOW_LATENCY isn't used.
+ ScanSettings scanSettings =
+ new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
+
+ assert mScanCallback == null;
+ mScanCallback = new ScanCallback();
+
+ try {
+ mAdapter.getBluetoothLeScanner().startScan(
+ null /* filters */, scanSettings, mScanCallback);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Cannot start scan: " + e);
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Stops the Low Energy scan.
+ * @return True if a scan was in progress.
+ */
+ private boolean stopScan() {
+ if (mScanCallback == null) {
+ return false;
+ }
+ try {
+ mAdapter.getBluetoothLeScanner().stopScan(mScanCallback);
+ } catch (IllegalArgumentException e) {
+ Log.e(TAG, "Cannot stop scan: " + e);
+ mScanCallback = null;
+ return false;
+ }
+ mScanCallback = null;
+ return true;
}
+
+ /**
+ * Implements callbacks used during a Low Energy scan by notifying upon
+ * devices discovered or detecting a scan failure.
+ */
+ private class ScanCallback extends Wrappers.ScanCallbackWrapper {
+ @Override
+ public void onBatchScanResultWrappers(List<Wrappers.ScanResultWrapper> results) {
+ Log.v(TAG, "onBatchScanResults");
+ }
+
+ @Override
+ public void onScanResultWrapper(int callbackType, Wrappers.ScanResultWrapper result) {
+ Log.v(TAG, "onScanResult %d %s %s", callbackType, result.getDevice().getAddress(),
+ result.getDevice().getName());
+ }
+
+ @Override
+ public void onScanFailed(int errorCode) {
+ Log.w(TAG, "onScanFailed: %d", errorCode);
+ nativeOnScanFailed(mNativeBluetoothAdapterAndroid);
+ mNumDiscoverySessions = 0;
+ }
+ }
+
+ // ---------------------------------------------------------------------------------------------
+ // BluetoothAdapterAndroid C++ methods declared for access from java:
+
+ // Binds to BluetoothAdapterAndroid::OnScanFailed.
+ private native void nativeOnScanFailed(long nativeBluetoothAdapterAndroid);
}

Powered by Google App Engine
This is Rietveld 408576698