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 #include "device/bluetooth/bluetooth_device_android.h" | 5 #include "device/bluetooth/bluetooth_device_android.h" |
6 | 6 |
7 #include "base/android/context_utils.h" | 7 #include "base/android/context_utils.h" |
8 #include "base/android/jni_android.h" | 8 #include "base/android/jni_android.h" |
9 #include "base/android/jni_array.h" | 9 #include "base/android/jni_array.h" |
10 #include "base/android/jni_string.h" | 10 #include "base/android/jni_string.h" |
11 #include "base/metrics/histogram_macros.h" | |
scheib
2016/01/15 01:39:45
Why is histogram_macros required? Seems to be a bu
ortuno
2016/01/15 21:34:41
Done.
| |
12 #include "base/metrics/sparse_histogram.h" | |
11 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
12 #include "device/bluetooth/bluetooth_adapter_android.h" | 14 #include "device/bluetooth/bluetooth_adapter_android.h" |
13 #include "device/bluetooth/bluetooth_remote_gatt_service_android.h" | 15 #include "device/bluetooth/bluetooth_remote_gatt_service_android.h" |
14 #include "jni/ChromeBluetoothDevice_jni.h" | 16 #include "jni/ChromeBluetoothDevice_jni.h" |
15 | 17 |
16 using base::android::AttachCurrentThread; | 18 using base::android::AttachCurrentThread; |
17 using base::android::AppendJavaStringArrayToStringVector; | 19 using base::android::AppendJavaStringArrayToStringVector; |
18 | 20 |
19 namespace device { | 21 namespace device { |
22 namespace { | |
23 void RecordConnectionSuccessResult(int32_t status) { | |
24 UMA_HISTOGRAM_SPARSE_SLOWLY("Bluetooth.Android.GATTConnection.Success.Result", | |
25 status); | |
26 } | |
27 void RecordConnectionFailureResult(int32_t status) { | |
28 UMA_HISTOGRAM_SPARSE_SLOWLY("Bluetooth.Android.GATTConnection.Failure.Result", | |
29 status); | |
30 } | |
31 void RecordConnectionTerminatedResult(int32_t status) { | |
32 UMA_HISTOGRAM_SPARSE_SLOWLY( | |
33 "Bluetooth.Android.GATTConnection.Terminated.Result", status); | |
34 } | |
35 } // namespace | |
20 | 36 |
21 BluetoothDeviceAndroid* BluetoothDeviceAndroid::Create( | 37 BluetoothDeviceAndroid* BluetoothDeviceAndroid::Create( |
22 BluetoothAdapterAndroid* adapter, | 38 BluetoothAdapterAndroid* adapter, |
23 jobject bluetooth_device_wrapper) { // Java Type: bluetoothDeviceWrapper | 39 jobject bluetooth_device_wrapper) { // Java Type: bluetoothDeviceWrapper |
24 BluetoothDeviceAndroid* device = new BluetoothDeviceAndroid(adapter); | 40 BluetoothDeviceAndroid* device = new BluetoothDeviceAndroid(adapter); |
25 | 41 |
26 device->j_device_.Reset(Java_ChromeBluetoothDevice_create( | 42 device->j_device_.Reset(Java_ChromeBluetoothDevice_create( |
27 AttachCurrentThread(), reinterpret_cast<intptr_t>(device), | 43 AttachCurrentThread(), reinterpret_cast<intptr_t>(device), |
28 bluetooth_device_wrapper)); | 44 bluetooth_device_wrapper)); |
29 | 45 |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
199 const ConnectToServiceCallback& callback, | 215 const ConnectToServiceCallback& callback, |
200 const ConnectToServiceErrorCallback& error_callback) { | 216 const ConnectToServiceErrorCallback& error_callback) { |
201 NOTIMPLEMENTED(); | 217 NOTIMPLEMENTED(); |
202 } | 218 } |
203 | 219 |
204 void BluetoothDeviceAndroid::OnConnectionStateChange( | 220 void BluetoothDeviceAndroid::OnConnectionStateChange( |
205 JNIEnv* env, | 221 JNIEnv* env, |
206 const JavaParamRef<jobject>& jcaller, | 222 const JavaParamRef<jobject>& jcaller, |
207 int32_t status, | 223 int32_t status, |
208 bool connected) { | 224 bool connected) { |
225 // There are many errors not present in the Android documentation that | |
226 // can be returned. We histogram these errors to better understand the | |
227 // cases in which they arise. | |
228 if (connected) { | |
229 RecordConnectionSuccessResult(status); | |
230 } else if (create_gatt_connection_error_callbacks_.size() > 0) { | |
231 // We assume that if there are any pending connection callbacks there | |
232 // was a failed connection attempt. | |
233 RecordConnectionFailureResult(status); | |
234 } else { | |
235 // Otherwise an existing connection was terminated. | |
236 RecordConnectionTerminatedResult(status); | |
237 } | |
238 | |
209 gatt_connected_ = connected; | 239 gatt_connected_ = connected; |
210 if (gatt_connected_) { | 240 if (gatt_connected_) { |
211 DidConnectGatt(); | 241 DidConnectGatt(); |
212 } else { | 242 } else { |
213 switch (status) { // Constants are from android.bluetooth.BluetoothGatt. | 243 switch (status) { // Constants are from android.bluetooth.BluetoothGatt. |
214 case 0x0000008f: // GATT_CONNECTION_CONGESTED | 244 case 0x0000008f: // GATT_CONNECTION_CONGESTED |
215 return DidFailToConnectGatt(ERROR_CONNECTION_CONGESTED); | 245 return DidFailToConnectGatt(ERROR_CONNECTION_CONGESTED); |
216 case 0x00000101: // GATT_FAILURE | 246 case 0x00000101: // GATT_FAILURE |
217 return DidFailToConnectGatt(ERROR_FAILED); | 247 return DidFailToConnectGatt(ERROR_FAILED); |
218 case 0x00000005: // GATT_INSUFFICIENT_AUTHENTICATION | 248 case 0x00000005: // GATT_INSUFFICIENT_AUTHENTICATION |
219 return DidFailToConnectGatt(ERROR_AUTH_FAILED); | 249 return DidFailToConnectGatt(ERROR_AUTH_FAILED); |
220 case 0x0000000f: // GATT_INSUFFICIENT_ENCRYPTION | 250 case 0x0000000f: // GATT_INSUFFICIENT_ENCRYPTION |
221 return DidFailToConnectGatt(ERROR_INSUFFICIENT_ENCRYPTION); | 251 return DidFailToConnectGatt(ERROR_INSUFFICIENT_ENCRYPTION); |
222 case 0x0000000d: // GATT_INVALID_ATTRIBUTE_LENGTH | 252 case 0x0000000d: // GATT_INVALID_ATTRIBUTE_LENGTH |
223 return DidFailToConnectGatt(ERROR_ATTRIBUTE_LENGTH_INVALID); | 253 return DidFailToConnectGatt(ERROR_ATTRIBUTE_LENGTH_INVALID); |
224 case 0x00000007: // GATT_INVALID_OFFSET | 254 case 0x00000007: // GATT_INVALID_OFFSET |
225 return DidFailToConnectGatt(ERROR_OFFSET_INVALID); | 255 return DidFailToConnectGatt(ERROR_OFFSET_INVALID); |
226 case 0x00000002: // GATT_READ_NOT_PERMITTED | 256 case 0x00000002: // GATT_READ_NOT_PERMITTED |
227 return DidFailToConnectGatt(ERROR_READ_NOT_PERMITTED); | 257 return DidFailToConnectGatt(ERROR_READ_NOT_PERMITTED); |
228 case 0x00000006: // GATT_REQUEST_NOT_SUPPORTED | 258 case 0x00000006: // GATT_REQUEST_NOT_SUPPORTED |
229 return DidFailToConnectGatt(ERROR_REQUEST_NOT_SUPPORTED); | 259 return DidFailToConnectGatt(ERROR_REQUEST_NOT_SUPPORTED); |
230 case 0x00000000: // GATT_SUCCESS | 260 case 0x00000000: // GATT_SUCCESS |
231 return DidDisconnectGatt(); | 261 return DidDisconnectGatt(); |
232 case 0x00000003: // GATT_WRITE_NOT_PERMITTED | 262 case 0x00000003: // GATT_WRITE_NOT_PERMITTED |
233 return DidFailToConnectGatt(ERROR_WRITE_NOT_PERMITTED); | 263 return DidFailToConnectGatt(ERROR_WRITE_NOT_PERMITTED); |
234 default: | 264 default: |
235 VLOG(1) << "Unhandled status: " << status; | 265 VLOG(1) << "Unhandled status: " << status; |
236 return DidFailToConnectGatt(ERROR_UNKNOWN); | 266 return DidFailToConnectGatt(ERROR_UNKNOWN); |
scheib
2016/01/15 01:39:45
Call DidFail or DidDisconnect based on the pending
ortuno
2016/01/15 21:34:42
Done.
| |
237 } | 267 } |
238 } | 268 } |
239 } | 269 } |
240 | 270 |
241 void BluetoothDeviceAndroid::OnGattServicesDiscovered( | 271 void BluetoothDeviceAndroid::OnGattServicesDiscovered( |
242 JNIEnv* env, | 272 JNIEnv* env, |
243 const JavaParamRef<jobject>& jcaller) { | 273 const JavaParamRef<jobject>& jcaller) { |
244 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, GetAdapter()->GetObservers(), | 274 FOR_EACH_OBSERVER(BluetoothAdapter::Observer, GetAdapter()->GetObservers(), |
245 GattServicesDiscovered(GetAdapter(), this)); | 275 GattServicesDiscovered(GetAdapter(), this)); |
246 } | 276 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
280 AttachCurrentThread(), j_device_.obj(), | 310 AttachCurrentThread(), j_device_.obj(), |
281 base::android::GetApplicationContext()); | 311 base::android::GetApplicationContext()); |
282 } | 312 } |
283 | 313 |
284 void BluetoothDeviceAndroid::DisconnectGatt() { | 314 void BluetoothDeviceAndroid::DisconnectGatt() { |
285 Java_ChromeBluetoothDevice_disconnectGatt(AttachCurrentThread(), | 315 Java_ChromeBluetoothDevice_disconnectGatt(AttachCurrentThread(), |
286 j_device_.obj()); | 316 j_device_.obj()); |
287 } | 317 } |
288 | 318 |
289 } // namespace device | 319 } // namespace device |
OLD | NEW |