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

Side by Side Diff: device/bluetooth/android/java/src/org/chromium/device/bluetooth/BluetoothAdapter.java

Issue 1150833002: bluetooth: android: Initial Low Energy Discovery Sessions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bta-manifest-
Patch Set: addressed tedchoc's comments Created 5 years, 7 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.device.bluetooth; 5 package org.chromium.device.bluetooth;
6 6
7 import android.Manifest; 7 import android.Manifest;
8 import android.annotation.TargetApi;
9 import android.bluetooth.le.ScanCallback;
10 import android.bluetooth.le.ScanResult;
11 import android.bluetooth.le.ScanSettings;
8 import android.content.Context; 12 import android.content.Context;
9 import android.content.ContextWrapper; 13 import android.content.ContextWrapper;
10 import android.content.pm.PackageManager; 14 import android.content.pm.PackageManager;
15 import android.os.Build;
11 16
12 import org.chromium.base.CalledByNative; 17 import org.chromium.base.CalledByNative;
13 import org.chromium.base.JNINamespace; 18 import org.chromium.base.JNINamespace;
14 import org.chromium.base.Log; 19 import org.chromium.base.Log;
15 20
21 import java.util.List;
22
16 /** 23 /**
17 * Exposes android.bluetooth.BluetoothAdapter as necessary for C++ 24 * Exposes android.bluetooth.BluetoothAdapter as necessary for C++
18 * device::BluetoothAdapterAndroid. 25 * device::BluetoothAdapterAndroid.
19 */ 26 */
20 @JNINamespace("device") 27 @JNINamespace("device")
28 @TargetApi(Build.VERSION_CODES.LOLLIPOP)
21 final class BluetoothAdapter { 29 final class BluetoothAdapter {
22 private static final String TAG = Log.makeTag("Bluetooth"); 30 private static final String TAG = Log.makeTag("Bluetooth");
23 31
24 private final boolean mHasBluetoothPermission; 32 private final long mNativeCPPObject;
Ted C 2015/05/27 01:13:39 Normally, we'd do mNativeBluetoothAdapter
scheib 2015/05/27 02:21:54 Done.
33 private final boolean mHasBluetoothCapability;
25 private android.bluetooth.BluetoothAdapter mAdapter; 34 private android.bluetooth.BluetoothAdapter mAdapter;
35 private int mNumDiscoverySessions;
36 private ScanCallback mLeScanCallback;
37
38 // ------------------------------------------------------------------------- --------------------
39 // Construction:
26 40
27 @CalledByNative 41 @CalledByNative
28 private static BluetoothAdapter create(Context context) { 42 private static BluetoothAdapter create(Context context, long nativeCPPObject ) {
29 return new BluetoothAdapter(context); 43 return new BluetoothAdapter(context, nativeCPPObject);
30 } 44 }
31 45
32 @CalledByNative 46 @CalledByNative
33 private static BluetoothAdapter createWithoutPermissionForTesting(Context co ntext) { 47 private static BluetoothAdapter createWithoutPermissionForTesting(
48 Context context, long nativeCPPObject) {
34 Context contextWithoutPermission = new ContextWrapper(context) { 49 Context contextWithoutPermission = new ContextWrapper(context) {
35 @Override 50 @Override
36 public int checkCallingOrSelfPermission(String permission) { 51 public int checkCallingOrSelfPermission(String permission) {
37 return PackageManager.PERMISSION_DENIED; 52 return PackageManager.PERMISSION_DENIED;
38 } 53 }
39 }; 54 };
40 return new BluetoothAdapter(contextWithoutPermission); 55 return new BluetoothAdapter(contextWithoutPermission, nativeCPPObject);
41 } 56 }
42 57
43 // Constructs a BluetoothAdapter. 58 // Constructs a BluetoothAdapter.
44 private BluetoothAdapter(Context context) { 59 private BluetoothAdapter(Context context, long nativeCPPObject) {
45 mHasBluetoothPermission = 60 mNativeCPPObject = nativeCPPObject;
61 final boolean hasMinAPI = Build.VERSION.SDK_INT >= Build.VERSION_CODES.L OLLIPOP;
62 final boolean hasPermissions =
46 context.checkCallingOrSelfPermission(Manifest.permission.BLUETOO TH) 63 context.checkCallingOrSelfPermission(Manifest.permission.BLUETOO TH)
47 == PackageManager.PERMISSION_GRANTED 64 == PackageManager.PERMISSION_GRANTED
48 && context.checkCallingOrSelfPermission(Manifest.permission.BLUE TOOTH_ADMIN) 65 && context.checkCallingOrSelfPermission(Manifest.permission.BLUE TOOTH_ADMIN)
49 == PackageManager.PERMISSION_GRANTED; 66 == PackageManager.PERMISSION_GRANTED;
50 if (!mHasBluetoothPermission) { 67 final boolean hasLowEnergyFeature =
51 Log.w(TAG, 68 Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2
52 "Bluetooth API disabled; BLUETOOTH and BLUETOOTH_ADMIN permi ssions required."); 69 && context.getPackageManager().hasSystemFeature(
70 PackageManager.FEATURE_BLUETOOTH_LE);
71 mHasBluetoothCapability = hasMinAPI && hasPermissions && hasLowEnergyFea ture;
72 if (!mHasBluetoothCapability) {
73 if (!hasMinAPI) {
74 Log.i(TAG, "Bluetooth API disabled; SDK version (%d) too low.",
75 Build.VERSION.SDK_INT);
76 } else if (!hasPermissions) {
77 Log.w(TAG, "Bluetooth API disabled; BLUETOOTH and BLUETOOTH_ADMI N permissions "
78 + "required.");
Ted C 2015/05/27 01:13:39 this is indented too much...should be 8
scheib 2015/05/27 02:21:54 This is enforced by 'git cl format', and reset if
79 } else if (!hasLowEnergyFeature) {
80 Log.i(TAG, "Bluetooth API disabled; Low Energy not supported on system.");
81 }
53 return; 82 return;
54 } 83 }
55 84
56 mAdapter = android.bluetooth.BluetoothAdapter.getDefaultAdapter(); 85 mAdapter = android.bluetooth.BluetoothAdapter.getDefaultAdapter();
57 if (mAdapter == null) Log.i(TAG, "No adapter found."); 86 if (mAdapter == null) {
58 } 87 Log.i(TAG, "No adapter found.");
59 88 } else {
60 @CalledByNative 89 Log.i(TAG, "BluetoothAdapter successfully constructed.");
61 private boolean hasBluetoothPermission() { 90 }
62 return mHasBluetoothPermission;
63 } 91 }
64 92
65 // ------------------------------------------------------------------------- -------------------- 93 // ------------------------------------------------------------------------- --------------------
66 // BluetoothAdapterAndroid.h interface: 94 // BluetoothAdapterAndroid C++ methods declared for access from java:
67 95
96 // Binds to BluetoothAdapterAndroid::OnScanFailed.
97 private native void nativeOnScanFailed(long nativeBluetoothAdapterAndroid);
Ted C 2015/05/27 01:13:39 We typically put native ones at the bottom since t
scheib 2015/05/27 02:21:54 Done.
98
99 // ------------------------------------------------------------------------- --------------------
100 // BluetoothAdapterAndroid methods implemented in java:
101
102 // Implements BluetoothAdapterAndroid::HasBluetoothCapability.
103 @CalledByNative
104 private boolean hasBluetoothCapability() {
105 return mHasBluetoothCapability;
106 }
107
108 // Implements BluetoothAdapterAndroid::GetAddress.
68 @CalledByNative 109 @CalledByNative
69 private String getAddress() { 110 private String getAddress() {
70 if (isPresent()) { 111 if (isPresent()) {
71 return mAdapter.getAddress(); 112 return mAdapter.getAddress();
72 } else { 113 } else {
73 return ""; 114 return "";
74 } 115 }
75 } 116 }
76 117
118 // Implements BluetoothAdapterAndroid::GetName.
77 @CalledByNative 119 @CalledByNative
78 private String getName() { 120 private String getName() {
79 if (isPresent()) { 121 if (isPresent()) {
80 return mAdapter.getName(); 122 return mAdapter.getName();
81 } else { 123 } else {
82 return ""; 124 return "";
83 } 125 }
84 } 126 }
85 127
128 // Implements BluetoothAdapterAndroid::IsPresent.
86 @CalledByNative 129 @CalledByNative
87 private boolean isPresent() { 130 private boolean isPresent() {
88 return mAdapter != null; 131 return mAdapter != null;
89 } 132 }
90 133
134 // Implements BluetoothAdapterAndroid::IsPowered.
91 @CalledByNative 135 @CalledByNative
92 private boolean isPowered() { 136 private boolean isPowered() {
93 return isPresent() && mAdapter.isEnabled(); 137 return isPresent() && mAdapter.isEnabled();
94 } 138 }
95 139
140 // Implements BluetoothAdapterAndroid::IsDiscoverable.
96 @CalledByNative 141 @CalledByNative
97 private boolean isDiscoverable() { 142 private boolean isDiscoverable() {
98 return isPresent() 143 return isPresent()
99 && mAdapter.getScanMode() 144 && mAdapter.getScanMode()
100 == android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISC OVERABLE; 145 == android.bluetooth.BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISC OVERABLE;
101 } 146 }
102 147
148 // Implements BluetoothAdapterAndroid::IsDiscovering.
103 @CalledByNative 149 @CalledByNative
104 private boolean isDiscovering() { 150 private boolean isDiscovering() {
105 return isPresent() && mAdapter.isDiscovering(); 151 return isPresent() && mAdapter.isDiscovering();
106 } 152 }
153
154 // Implements BluetoothAdapterAndroid::AddDiscoverySession.
155 @CalledByNative
156 private boolean addDiscoverySession() {
157 if (!isPowered()) {
158 Log.d(TAG, "addDiscoverySession: Fails: !isPowered");
159 return false;
160 }
161
162 mNumDiscoverySessions++;
163 Log.d(TAG, "addDiscoverySession: Now %d sessions", mNumDiscoverySessions );
164 if (mNumDiscoverySessions > 1) {
165 return true;
166 }
167
168 // ScanSettings Note: SCAN_FAILED_FEATURE_UNSUPPORTED is caused (at leas t on some devices)
169 // if setReportDelay() is used or if SCAN_MODE_LOW_LATENCY isn't used.
170 ScanSettings scanSettings =
171 new ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LO W_LATENCY).build();
172
173 if (mLeScanCallback == null) {
174 mLeScanCallback = new DiscoveryScanCallback();
175 }
176 mAdapter.getBluetoothLeScanner().startScan(
177 null /* filters */, scanSettings, mLeScanCallback);
178 return true;
179 }
180
181 // Implements BluetoothAdapterAndroid::RemoveDiscoverySession.
182 @CalledByNative
183 private boolean removeDiscoverySession() {
Ted C 2015/05/27 01:13:39 is this guaranteed to be called if during the dest
scheib 2015/05/27 02:21:54 Done. The scan will now be stopped upon C++ object
184 if (mNumDiscoverySessions == 0) {
185 assert false;
186 Log.w(TAG, "removeDiscoverySession: No scan in progress.");
187 return false;
188 }
189
190 --mNumDiscoverySessions;
191
192 if (mNumDiscoverySessions == 0) {
193 Log.d(TAG, "removeDiscoverySession: Stopping scan.");
194 mAdapter.getBluetoothLeScanner().stopScan(mLeScanCallback);
195 } else {
196 Log.d(TAG, "removeDiscoverySession: Now %d sessions", mNumDiscoveryS essions);
197 }
198
199 return true;
200 }
201
202 // ------------------------------------------------------------------------- --------------------
203 // Implementation details:
204
205 private class DiscoveryScanCallback extends ScanCallback {
206 @Override
207 public void onBatchScanResults(List<ScanResult> results) {
208 Log.v(TAG, "onBatchScanResults");
209 }
210
211 @Override
212 public void onScanResult(int callbackType, ScanResult result) {
213 Log.v(TAG, "onScanResult %s %s", result.getDevice().getAddress(),
214 result.getDevice().getName());
215 }
216
217 @Override
218 public void onScanFailed(int errorCode) {
219 Log.w(TAG, "onScanFailed: %d", errorCode);
220 // DISCUSS IN CODE REVIEW.
221 //
222 // TODO(scheib): Current device/bluetooth API doesn't support a way to communicate
223 // this asynchronous failure. If there was a way to communicate asyn chronous
224 // success, then the response to AddDiscoverySession would be delaye d until then or
225 // this error. But without only the error we must presume success.
226 //
227 //
228 // NEED ISSUE NUMBER.
229 nativeOnScanFailed(mNativeCPPObject);
230 }
231 }
107 } 232 }
OLDNEW
« no previous file with comments | « chrome/android/shell/java/AndroidManifest.xml.jinja2 ('k') | device/bluetooth/bluetooth_adapter_android.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698