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

Unified Diff: device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.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/Wrappers.java
diff --git a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
index 36387f47c8f198db5f34bc93def243130375f5f1..4ae298d746a5e1732a78913396f455c55530c37b 100644
--- a/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
+++ b/device/bluetooth/android/java/src/org/chromium/device/bluetooth/Wrappers.java
@@ -5,14 +5,26 @@
package org.chromium.device.bluetooth;
import android.Manifest;
+import android.annotation.TargetApi;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.os.Build;
import org.chromium.base.CalledByNative;
import org.chromium.base.JNINamespace;
import org.chromium.base.Log;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
/**
* Wrapper classes around android.bluetooth.* classes that provide an
* indirection layer enabling fake implementations when running tests.
@@ -22,6 +34,7 @@ import org.chromium.base.Log;
* pass through to the Android object and instead provide fake implementations.
*/
@JNINamespace("device")
+@TargetApi(Build.VERSION_CODES.LOLLIPOP)
class Wrappers {
private static final String TAG = "cr.Bluetooth";
@@ -30,6 +43,7 @@ class Wrappers {
*/
static class BluetoothAdapterWrapper {
private final BluetoothAdapter mAdapter;
+ protected final BluetoothLeScannerWrapper mScanner;
/**
* Creates a BluetoothAdapterWrapper using the default
@@ -39,6 +53,13 @@ class Wrappers {
*/
@CalledByNative("BluetoothAdapterWrapper")
public static BluetoothAdapterWrapper createWithDefaultAdapter(Context context) {
+ final boolean hasMinAPI = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
+ if (!hasMinAPI) {
+ Log.i(TAG, "BluetoothAdapterWrapper.create failed: SDK version (%d) too low.",
+ Build.VERSION.SDK_INT);
+ return null;
+ }
+
final boolean hasPermissions =
context.checkCallingOrSelfPermission(Manifest.permission.BLUETOOTH)
== PackageManager.PERMISSION_GRANTED
@@ -49,17 +70,34 @@ class Wrappers {
return null;
}
+ // Only Low Energy currently supported, see BluetoothAdapterAndroid class note.
+ final boolean hasLowEnergyFeature =
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2
+ && context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_BLUETOOTH_LE);
+ if (!hasLowEnergyFeature) {
+ Log.i(TAG, "BluetoothAdapterWrapper.create failed: No Low Energy support.");
+ return null;
+ }
+
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter == null) {
Log.i(TAG, "BluetoothAdapterWrapper.create failed: Default adapter not found.");
return null;
} else {
- return new BluetoothAdapterWrapper(adapter);
+ return new BluetoothAdapterWrapper(
+ adapter, new BluetoothLeScannerWrapper(adapter.getBluetoothLeScanner()));
}
}
- public BluetoothAdapterWrapper(BluetoothAdapter adapter) {
+ public BluetoothAdapterWrapper(
+ BluetoothAdapter adapter, BluetoothLeScannerWrapper scanner) {
mAdapter = adapter;
+ mScanner = scanner;
+ }
+
+ public BluetoothLeScannerWrapper getBluetoothLeScanner() {
+ return mScanner;
}
public boolean isEnabled() {
@@ -82,4 +120,112 @@ class Wrappers {
return mAdapter.isDiscovering();
}
}
+
+ /**
+ * Wraps android.bluetooth.BluetoothLeScanner.
+ */
+ static class BluetoothLeScannerWrapper {
+ private final BluetoothLeScanner mScanner;
+ private final HashMap<ScanCallbackWrapper, ScanCallbackImpl> mCallbacks;
+
+ public BluetoothLeScannerWrapper(BluetoothLeScanner scanner) {
+ mScanner = scanner;
+ mCallbacks = new HashMap<ScanCallbackWrapper, ScanCallbackImpl>();
+ }
+
+ public void startScan(
+ List<ScanFilter> filters, int scanSettingsScanMode, ScanCallbackWrapper callback) {
+ ScanSettings settings =
+ new ScanSettings.Builder().setScanMode(scanSettingsScanMode).build();
+
+ ScanCallbackImpl callbackImpl = new ScanCallbackImpl(callback);
+ mCallbacks.put(callback, callbackImpl);
+
+ mScanner.startScan(filters, settings, callbackImpl);
+ }
+
+ public void stopScan(ScanCallbackWrapper callback) {
+ ScanCallbackImpl callbackImpl = mCallbacks.remove(callback);
+ mScanner.stopScan(callbackImpl);
+ }
+ }
+
+ /**
+ * Implements android.bluetooth.le.ScanCallback and passes calls through to a
+ * provided ScanCallbackWrapper instance.
+ *
+ * This class is required so that Fakes can use ScanCallbackWrapper without
+ * it extending from ScanCallback. Fakes must function even on Android
+ * versions where ScanCallback class is not defined.
+ */
+ static class ScanCallbackImpl extends ScanCallback {
+ final ScanCallbackWrapper mWrapperCallback;
+
+ ScanCallbackImpl(ScanCallbackWrapper wrapperCallback) {
+ mWrapperCallback = wrapperCallback;
+ }
+
+ @Override
+ public void onBatchScanResults(List<ScanResult> results) {
+ ArrayList<ScanResultWrapper> resultsWrapped =
+ new ArrayList<ScanResultWrapper>(results.size());
+ for (ScanResult result : results) {
+ resultsWrapped.add(new ScanResultWrapper(result));
+ }
+ mWrapperCallback.onBatchScanResult(resultsWrapped);
+ }
+
+ @Override
+ public void onScanResult(int callbackType, ScanResult result) {
+ mWrapperCallback.onScanResult(callbackType, new ScanResultWrapper(result));
+ }
+
+ @Override
+ public void onScanFailed(int errorCode) {
+ mWrapperCallback.onScanFailed(errorCode);
+ }
+ }
+
+ /**
+ * Wraps android.bluetooth.le.ScanCallback, being called by ScanCallbackImpl.
+ */
+ abstract static class ScanCallbackWrapper {
+ public abstract void onBatchScanResult(List<ScanResultWrapper> results);
+ public abstract void onScanResult(int callbackType, ScanResultWrapper result);
+ public abstract void onScanFailed(int errorCode);
+ }
+
+ /**
+ * Wraps android.bluetooth.le.ScanResult.
+ */
+ static class ScanResultWrapper {
+ private final ScanResult mScanResult;
+
+ public ScanResultWrapper(ScanResult scanResult) {
+ mScanResult = scanResult;
+ }
+
+ public BluetoothDeviceWrapper getDevice() {
+ return new BluetoothDeviceWrapper(mScanResult.getDevice());
+ }
+ }
+
+ /**
+ * Wraps android.bluetooth.BluetoothDevice.
+ */
+ static class BluetoothDeviceWrapper {
+ private final BluetoothDevice mDevice;
+
+ public BluetoothDeviceWrapper(BluetoothDevice device) {
+ mDevice = device;
+ }
+
+ public String getAddress() {
+ return mDevice.getAddress();
+ }
+
+ public String getName() {
+ return mDevice.getName();
+ }
+ }
}

Powered by Google App Engine
This is Rietveld 408576698