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

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: https://codereview.chromium.org/1231883004 fixs runtime error. Created 5 years, 5 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..a29c9d8c2515d0af3f7709e50ec581becd3218f2 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 associated C++
+ * 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) {
+ public 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);
+ private static ChromeBluetoothAdapter create(
+ long nativeBluetoothAdapterAndroid, Object adapterWrapper) {
+ return new ChromeBluetoothAdapter(
+ nativeBluetoothAdapterAndroid, (Wrappers.BluetoothAdapterWrapper) adapterWrapper);
}
// Implements BluetoothAdapterAndroid::GetAddress.
@@ -89,6 +116,120 @@ 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()) {
+ mNumDiscoverySessions--;
+ return false;
+ }
+ return true;
}
+
+ // 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();
+ }
+
+ Log.d(TAG, "removeDiscoverySession: Now %d sessions.", mNumDiscoverySessions);
+ return true;
+ }
+
+ // ---------------------------------------------------------------------------------------------
+ // Implementation details:
+
+ /**
+ * Starts a Low Energy scan.
+ * @return True on success.
+ */
+ private boolean startScan() {
+ // scanMode 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.
+ int scanMode = ScanSettings.SCAN_MODE_LOW_LATENCY;
+
+ assert mScanCallback == null;
+ mScanCallback = new ScanCallback();
+
+ try {
+ mAdapter.getBluetoothLeScanner().startScan(null /* filters */, scanMode, 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 onBatchScanResult(List<Wrappers.ScanResultWrapper> results) {
+ Log.v(TAG, "onBatchScanResults");
+ }
+
+ @Override
+ public void onScanResult(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