OLD | NEW |
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.annotation.TargetApi; | |
8 import android.bluetooth.BluetoothAdapter; | 7 import android.bluetooth.BluetoothAdapter; |
9 import android.bluetooth.le.ScanSettings; | |
10 import android.os.Build; | |
11 | 8 |
12 import org.chromium.base.CalledByNative; | 9 import org.chromium.base.CalledByNative; |
13 import org.chromium.base.JNINamespace; | 10 import org.chromium.base.JNINamespace; |
14 import org.chromium.base.Log; | 11 import org.chromium.base.Log; |
15 | 12 |
16 import java.util.List; | |
17 | |
18 /** | 13 /** |
19 * Exposes android.bluetooth.BluetoothAdapter as necessary for C++ | 14 * Exposes android.bluetooth.BluetoothAdapter as necessary for C++ |
20 * device::BluetoothAdapterAndroid, which implements the cross platform | 15 * device::BluetoothAdapterAndroid, which implements the cross platform |
21 * device::BluetoothAdapter. | 16 * device::BluetoothAdapter. |
22 */ | 17 */ |
23 @JNINamespace("device") | 18 @JNINamespace("device") |
24 @TargetApi(Build.VERSION_CODES.LOLLIPOP) | |
25 final class ChromeBluetoothAdapter { | 19 final class ChromeBluetoothAdapter { |
26 private static final String TAG = "cr.Bluetooth"; | 20 private static final String TAG = "cr.Bluetooth"; |
27 | 21 |
28 private long mNativeBluetoothAdapterAndroid; | |
29 private Wrappers.BluetoothAdapterWrapper mAdapter; | 22 private Wrappers.BluetoothAdapterWrapper mAdapter; |
30 private int mNumDiscoverySessions; | |
31 private ScanCallback mScanCallback; | |
32 | |
33 // -------------------------------------------------------------------------
-------------------- | |
34 // Construction and handler for C++ object destruction. | |
35 | 23 |
36 /** | 24 /** |
37 * Constructs a ChromeBluetoothAdapter. | 25 * Constructs a ChromeBluetoothAdapter. |
38 * @param nativeBluetoothAdapterAndroid Is the associated C++ | |
39 * BluetoothAdapterAndroid pointer valu
e. | |
40 * @param adapterWrapper Wraps the default android.bluetooth.BluetoothAdapte
r, | 26 * @param adapterWrapper Wraps the default android.bluetooth.BluetoothAdapte
r, |
41 * but may be either null if an adapter is not availab
le | 27 * but may be either null if an adapter is not availab
le |
42 * or a fake for testing. | 28 * or a fake for testing. |
43 */ | 29 */ |
44 public ChromeBluetoothAdapter( | 30 private ChromeBluetoothAdapter(Wrappers.BluetoothAdapterWrapper adapterWrapp
er) { |
45 long nativeBluetoothAdapterAndroid, Wrappers.BluetoothAdapterWrapper
adapterWrapper) { | |
46 mNativeBluetoothAdapterAndroid = nativeBluetoothAdapterAndroid; | |
47 mAdapter = adapterWrapper; | 31 mAdapter = adapterWrapper; |
48 if (adapterWrapper == null) { | 32 if (adapterWrapper == null) { |
49 Log.i(TAG, "ChromeBluetoothAdapter created with no adapterWrapper.")
; | 33 Log.i(TAG, "ChromeBluetoothAdapter created with no adapterWrapper.")
; |
50 } else { | 34 } else { |
51 Log.i(TAG, "ChromeBluetoothAdapter created with provided adapterWrap
per."); | 35 Log.i(TAG, "ChromeBluetoothAdapter created with provided adapterWrap
per."); |
52 } | 36 } |
53 } | 37 } |
54 | 38 |
55 /** | |
56 * Handles C++ object being destroyed. | |
57 */ | |
58 @CalledByNative | |
59 private void onBluetoothAdapterAndroidDestruction() { | |
60 stopScan(); | |
61 mNativeBluetoothAdapterAndroid = 0; | |
62 } | |
63 | |
64 // -------------------------------------------------------------------------
-------------------- | 39 // -------------------------------------------------------------------------
-------------------- |
65 // BluetoothAdapterAndroid methods implemented in java: | 40 // BluetoothAdapterAndroid methods implemented in java: |
66 | 41 |
67 // Implements BluetoothAdapterAndroid::Create. | 42 // Implements BluetoothAdapterAndroid::Create. |
68 // 'Object' type must be used because inner class Wrappers.BluetoothAdapterW
rapper reference is | 43 // 'Object' type must be used because inner class Wrappers.BluetoothAdapterW
rapper reference is |
69 // not handled by jni_generator.py JavaToJni. http://crbug.com/505554 | 44 // not handled by jni_generator.py JavaToJni. http://crbug.com/505554 |
70 @CalledByNative | 45 @CalledByNative |
71 private static ChromeBluetoothAdapter create( | 46 public static ChromeBluetoothAdapter create(Object adapterWrapper) { |
72 long nativeBluetoothAdapterAndroid, Object adapterWrapper) { | 47 return new ChromeBluetoothAdapter((Wrappers.BluetoothAdapterWrapper) ada
pterWrapper); |
73 return new ChromeBluetoothAdapter( | |
74 nativeBluetoothAdapterAndroid, (Wrappers.BluetoothAdapterWrapper
) adapterWrapper); | |
75 } | 48 } |
76 | 49 |
77 // Implements BluetoothAdapterAndroid::GetAddress. | 50 // Implements BluetoothAdapterAndroid::GetAddress. |
78 @CalledByNative | 51 @CalledByNative |
79 private String getAddress() { | 52 private String getAddress() { |
80 if (isPresent()) { | 53 if (isPresent()) { |
81 return mAdapter.getAddress(); | 54 return mAdapter.getAddress(); |
82 } else { | 55 } else { |
83 return ""; | 56 return ""; |
84 } | 57 } |
(...skipping 24 matching lines...) Expand all Loading... |
109 // Implements BluetoothAdapterAndroid::IsDiscoverable. | 82 // Implements BluetoothAdapterAndroid::IsDiscoverable. |
110 @CalledByNative | 83 @CalledByNative |
111 private boolean isDiscoverable() { | 84 private boolean isDiscoverable() { |
112 return isPresent() | 85 return isPresent() |
113 && mAdapter.getScanMode() == BluetoothAdapter.SCAN_MODE_CONNECTA
BLE_DISCOVERABLE; | 86 && mAdapter.getScanMode() == BluetoothAdapter.SCAN_MODE_CONNECTA
BLE_DISCOVERABLE; |
114 } | 87 } |
115 | 88 |
116 // Implements BluetoothAdapterAndroid::IsDiscovering. | 89 // Implements BluetoothAdapterAndroid::IsDiscovering. |
117 @CalledByNative | 90 @CalledByNative |
118 private boolean isDiscovering() { | 91 private boolean isDiscovering() { |
119 return isPresent() && (mAdapter.isDiscovering() || mScanCallback != null
); | 92 return isPresent() && mAdapter.isDiscovering(); |
120 } | 93 } |
121 | |
122 // Implements BluetoothAdapterAndroid::AddDiscoverySession. | |
123 @CalledByNative | |
124 private boolean addDiscoverySession() { | |
125 if (!isPowered()) { | |
126 Log.d(TAG, "addDiscoverySession: Fails: !isPowered"); | |
127 return false; | |
128 } | |
129 | |
130 mNumDiscoverySessions++; | |
131 Log.d(TAG, "addDiscoverySession: Now %d sessions.", mNumDiscoverySession
s); | |
132 if (mNumDiscoverySessions > 1) { | |
133 return true; | |
134 } | |
135 | |
136 if (!startScan()) { | |
137 mNumDiscoverySessions--; | |
138 return false; | |
139 } | |
140 return true; | |
141 } | |
142 | |
143 // Implements BluetoothAdapterAndroid::RemoveDiscoverySession. | |
144 @CalledByNative | |
145 private boolean removeDiscoverySession() { | |
146 if (mNumDiscoverySessions == 0) { | |
147 assert false; | |
148 Log.w(TAG, "removeDiscoverySession: No scan in progress."); | |
149 return false; | |
150 } | |
151 | |
152 --mNumDiscoverySessions; | |
153 | |
154 if (mNumDiscoverySessions == 0) { | |
155 Log.d(TAG, "removeDiscoverySession: Now 0 sessions. Stopping scan.")
; | |
156 return stopScan(); | |
157 } | |
158 | |
159 Log.d(TAG, "removeDiscoverySession: Now %d sessions.", mNumDiscoverySess
ions); | |
160 return true; | |
161 } | |
162 | |
163 // -------------------------------------------------------------------------
-------------------- | |
164 // Implementation details: | |
165 | |
166 /** | |
167 * Starts a Low Energy scan. | |
168 * @return True on success. | |
169 */ | |
170 private boolean startScan() { | |
171 // scanMode note: SCAN_FAILED_FEATURE_UNSUPPORTED is caused (at least on
some devices) if | |
172 // setReportDelay() is used or if SCAN_MODE_LOW_LATENCY isn't used. | |
173 int scanMode = ScanSettings.SCAN_MODE_LOW_LATENCY; | |
174 | |
175 assert mScanCallback == null; | |
176 mScanCallback = new ScanCallback(); | |
177 | |
178 try { | |
179 mAdapter.getBluetoothLeScanner().startScan(null /* filters */, scanM
ode, mScanCallback); | |
180 } catch (IllegalArgumentException e) { | |
181 Log.e(TAG, "Cannot start scan: " + e); | |
182 return false; | |
183 } | |
184 return true; | |
185 } | |
186 | |
187 /** | |
188 * Stops the Low Energy scan. | |
189 * @return True if a scan was in progress. | |
190 */ | |
191 private boolean stopScan() { | |
192 if (mScanCallback == null) { | |
193 return false; | |
194 } | |
195 try { | |
196 mAdapter.getBluetoothLeScanner().stopScan(mScanCallback); | |
197 } catch (IllegalArgumentException e) { | |
198 Log.e(TAG, "Cannot stop scan: " + e); | |
199 mScanCallback = null; | |
200 return false; | |
201 } | |
202 mScanCallback = null; | |
203 return true; | |
204 } | |
205 | |
206 /** | |
207 * Implements callbacks used during a Low Energy scan by notifying upon | |
208 * devices discovered or detecting a scan failure. | |
209 */ | |
210 private class ScanCallback extends Wrappers.ScanCallbackWrapper { | |
211 @Override | |
212 public void onBatchScanResult(List<Wrappers.ScanResultWrapper> results)
{ | |
213 Log.v(TAG, "onBatchScanResults"); | |
214 } | |
215 | |
216 @Override | |
217 public void onScanResult(int callbackType, Wrappers.ScanResultWrapper re
sult) { | |
218 Log.v(TAG, "onScanResult %d %s %s", callbackType, result.getDevice()
.getAddress(), | |
219 result.getDevice().getName()); | |
220 } | |
221 | |
222 @Override | |
223 public void onScanFailed(int errorCode) { | |
224 Log.w(TAG, "onScanFailed: %d", errorCode); | |
225 nativeOnScanFailed(mNativeBluetoothAdapterAndroid); | |
226 mNumDiscoverySessions = 0; | |
227 } | |
228 } | |
229 | |
230 // -------------------------------------------------------------------------
-------------------- | |
231 // BluetoothAdapterAndroid C++ methods declared for access from java: | |
232 | |
233 // Binds to BluetoothAdapterAndroid::OnScanFailed. | |
234 private native void nativeOnScanFailed(long nativeBluetoothAdapterAndroid); | |
235 } | 94 } |
OLD | NEW |