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

Side by Side Diff: content/browser/bluetooth/bluetooth_dispatcher_host.cc

Issue 1261593004: bluetooth: Add histograms and logging for requestDevice() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bluetooth-adapter-ff
Patch Set: Address asvitkine comments. Created 5 years, 4 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 // NETWORK_ERROR Note: 5 // NETWORK_ERROR Note:
6 // When a device can't be found in the BluetoothAdapter, that generally 6 // When a device can't be found in the BluetoothAdapter, that generally
7 // indicates that it's gone out of range. We reject with a NetworkError in that 7 // indicates that it's gone out of range. We reject with a NetworkError in that
8 // case. 8 // case.
9 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-conne ctgatt 9 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothdevice-conne ctgatt
10 10
11 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h" 11 #include "content/browser/bluetooth/bluetooth_dispatcher_host.h"
12 12
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
15 #include "content/browser/bad_message.h" 16 #include "content/browser/bad_message.h"
16 #include "content/browser/frame_host/render_frame_host_impl.h" 17 #include "content/browser/frame_host/render_frame_host_impl.h"
17 #include "content/common/bluetooth/bluetooth_messages.h" 18 #include "content/common/bluetooth/bluetooth_messages.h"
18 #include "device/bluetooth/bluetooth_adapter.h" 19 #include "device/bluetooth/bluetooth_adapter.h"
19 #include "device/bluetooth/bluetooth_adapter_factory.h" 20 #include "device/bluetooth/bluetooth_adapter_factory.h"
20 #include "device/bluetooth/bluetooth_device.h" 21 #include "device/bluetooth/bluetooth_device.h"
21 #include "device/bluetooth/bluetooth_discovery_session.h" 22 #include "device/bluetooth/bluetooth_discovery_session.h"
22 #include "device/bluetooth/bluetooth_gatt_characteristic.h" 23 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
23 #include "device/bluetooth/bluetooth_gatt_service.h" 24 #include "device/bluetooth/bluetooth_gatt_service.h"
24 25
25 using blink::WebBluetoothError; 26 using blink::WebBluetoothError;
26 using device::BluetoothAdapter; 27 using device::BluetoothAdapter;
27 using device::BluetoothAdapterFactory; 28 using device::BluetoothAdapterFactory;
28 using device::BluetoothGattCharacteristic; 29 using device::BluetoothGattCharacteristic;
29 using device::BluetoothGattService; 30 using device::BluetoothGattService;
30 using device::BluetoothUUID; 31 using device::BluetoothUUID;
31 32
32 namespace { 33 namespace {
33 34
35 const char kBaseStandardServiceUUID[] = "00001800-0000-1000-8000-00805f9b34fb";
36 // Current Max Standard Service UUID:
37 // https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx?SortFie ld=AssignedNumber&SortDir=Asc
38 const uint16_t kMaxStandardServiceUUID = 0x22;
Jeffrey Yasskin 2015/08/10 22:18:56 Let's not force ourselves to update this every tim
ortuno 2015/08/11 20:10:55 Changing to hash function instead.
39
34 // These types of errors aren't as common. We log them to understand 40 // These types of errors aren't as common. We log them to understand
35 // how common they are and if we need to investigate more. 41 // how common they are and if we need to investigate more.
36 enum class BluetoothGATTError { 42 enum class BluetoothGATTError {
37 UNKNOWN, 43 UNKNOWN,
38 FAILED, 44 FAILED,
39 IN_PROGRESS, 45 IN_PROGRESS,
40 NOT_PAIRED, 46 NOT_PAIRED,
41 // Add errors above this line and update corresponding histograms.xml enum. 47 // Add errors above this line and update corresponding histograms.xml enum.
42 MAX_ERROR, 48 MAX_ERROR,
43 }; 49 };
44 50
45 enum class UMARequestDeviceOutcome { 51 enum class UMARequestDeviceOutcome {
46 SUCCESS = 0, 52 SUCCESS = 0,
47 NO_BLUETOOTH_ADAPTER = 1, 53 NO_BLUETOOTH_ADAPTER = 1,
48 NO_RENDER_FRAME = 2, 54 NO_RENDER_FRAME = 2,
49 DISCOVERY_START_FAILED = 3, 55 DISCOVERY_START_FAILED = 3,
50 DISCOVERY_STOP_FAILED = 4, 56 DISCOVERY_STOP_FAILED = 4,
51 NO_MATCHING_DEVICES_FOUND = 5, 57 NO_MATCHING_DEVICES_FOUND = 5,
52 BLUETOOTH_ADAPTER_NOT_PRESENT = 6, 58 BLUETOOTH_ADAPTER_NOT_PRESENT = 6,
53 BLUETOOTH_ADAPTER_OFF = 7, 59 BLUETOOTH_ADAPTER_OFF = 7,
54 // NOTE: Add new requestDevice() outcomes immediately above this line. Make 60 // NOTE: Add new requestDevice() outcomes immediately above this line. Make
55 // sure to update the enum list in 61 // sure to update the enum list in
56 // tools/metrics/histogram/histograms.xml accordingly. 62 // tools/metrics/histogram/histograms.xml accordingly.
57 COUNT 63 COUNT
58 }; 64 };
59 65
60 void RecordRequestDeviceOutcome(UMARequestDeviceOutcome outcome) { 66 void RecordRequestDeviceOutcome(UMARequestDeviceOutcome outcome) {
61 UMA_HISTOGRAM_ENUMERATION("Bluetooth.RequestDevice.Outcome", 67 UMA_HISTOGRAM_ENUMERATION("Bluetooth.Web.RequestDevice.Outcome",
62 static_cast<int>(outcome), 68 static_cast<int>(outcome),
63 static_cast<int>(UMARequestDeviceOutcome::COUNT)); 69 static_cast<int>(UMARequestDeviceOutcome::COUNT));
64 } 70 }
65 71
72 int GetServiceEnum(const BluetoothUUID& service) {
73 if (!service.canonical_value().compare(0, 6,
Jeffrey Yasskin 2015/08/10 22:18:56 Please use ==0 for .compare(). It's a tri-valued f
ortuno 2015/08/11 20:10:55 Sorry. Should have looked at the documentation clo
74 kBaseStandardServiceUUID) // 000018
75 ||
76 !service.canonical_value().compare(
77 8, 28, kBaseStandardServiceUUID)) { // -0000-1000-8000-00805f9b34fb
Jeffrey Yasskin 2015/08/10 22:18:56 This comparison isn't quite right. kBaseStandardSe
ortuno 2015/08/11 20:10:55 Changing to hash based histogram.
78 return 0; // Unknown Service
79 }
80 uint16_t service_enum = 0;
81 for (int i = 0; i < 2; i++) {
82 service_enum <<= 4;
Alexei Svitkine (slow) 2015/08/10 22:03:35 Instead of doing this complicated logic, have you
Jeffrey Yasskin 2015/08/10 22:18:56 We didn't consider that, but 1) what's the maximum
Alexei Svitkine (slow) 2015/08/11 15:15:08 The UMA macro for a sparse histogram is UMA_HISTOG
ortuno 2015/08/11 20:10:55 Done.
83 service_enum += base::HexDigitToInt(service.canonical_value()[i + 6]);
Alexei Svitkine (slow) 2015/08/10 22:03:36 What guarantees that i+6 is in range?
Jeffrey Yasskin 2015/08/10 22:18:56 https://code.google.com/p/chromium/codesearch/#chr
ortuno 2015/08/11 20:10:55 No longer being used.
84 }
85 if (service_enum > kMaxStandardServiceUUID) {
86 return 0; // Unknown Service
87 }
88 // We shift everything by one because of the unknown service at 0.
89 return ++service_enum;
Alexei Svitkine (slow) 2015/08/10 22:03:35 This should be service_enum + 1, since incrementin
ortuno 2015/08/11 20:10:55 Removed.
90 }
91
92 void RecordRequestDeviceFilters(
93 const std::vector<content::BluetoothScanFilter>& filters) {
94 UMA_HISTOGRAM_COUNTS("Bluetooth.Web.RequestDevice.Filters.Count",
95 filters.size());
96 for (const content::BluetoothScanFilter& filter : filters) {
97 UMA_HISTOGRAM_COUNTS("Bluetooth.Web.RequestDevice.FilterSize",
98 filter.services.size());
99 for (const BluetoothUUID& service : filter.services) {
100 UMA_HISTOGRAM_ENUMERATION("Bluetooth.Web.RequestDevice.Filters.Services",
101 GetServiceEnum(service), 0x101);
102 }
103 }
104 }
105
106 void RecordRequestDeviceOptionalServices(
107 const std::vector<BluetoothUUID>& optional_services) {
108 UMA_HISTOGRAM_COUNTS("Bluetooth.Web.RequestDevice.OptionalServices.Count",
109 optional_services.size());
110 for (const BluetoothUUID& service : optional_services) {
111 UMA_HISTOGRAM_ENUMERATION(
112 "Bluetooth.Web.RequestDevice.OptionalServices.Services",
113 GetServiceEnum(service), 0x101);
114 }
115 }
116
117 void RecordUnionOfServices(
118 const std::vector<content::BluetoothScanFilter>& filters,
119 const std::vector<BluetoothUUID>& optional_services) {
120 const std::set<BluetoothUUID> union_of_services(optional_services.begin(),
121 optional_services.end());
122 for (const content::BluetoothScanFilter& filter : filters)
123 union_of_services.insert(filter.services.begin(), filter.services.end());
124
125 UMA_HISTOGRAM_COUNTS("Bluetooth.Web.RequestDevice.UnionOfServices.Count",
126 union_of_services.size());
127 }
128
66 enum class UMAWebBluetoothFunction { 129 enum class UMAWebBluetoothFunction {
67 REQUEST_DEVICE, 130 REQUEST_DEVICE,
68 CONNECT_GATT, 131 CONNECT_GATT,
69 GET_PRIMARY_SERVICE, 132 GET_PRIMARY_SERVICE,
70 GET_CHARACTERISTIC, 133 GET_CHARACTERISTIC,
71 CHARACTERISTIC_READ_VALUE, 134 CHARACTERISTIC_READ_VALUE,
72 CHARACTERISTIC_WRITE_VALUE, 135 CHARACTERISTIC_WRITE_VALUE,
73 // NOTE: Add new actions immediately above this line. Make sure to update the 136 // NOTE: Add new actions immediately above this line. Make sure to update the
74 // enum list in tools/metrics/histogram/histograms.xml accordingly. 137 // enum list in tools/metrics/histogram/histograms.xml accordingly.
75 COUNT 138 COUNT
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 } 327 }
265 328
266 void BluetoothDispatcherHost::OnRequestDevice( 329 void BluetoothDispatcherHost::OnRequestDevice(
267 int thread_id, 330 int thread_id,
268 int request_id, 331 int request_id,
269 int frame_routing_id, 332 int frame_routing_id,
270 const std::vector<BluetoothScanFilter>& filters, 333 const std::vector<BluetoothScanFilter>& filters,
271 const std::vector<BluetoothUUID>& optional_services) { 334 const std::vector<BluetoothUUID>& optional_services) {
272 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 335 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
273 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::REQUEST_DEVICE); 336 RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::REQUEST_DEVICE);
337 RecordRequestDeviceFilters(filters);
338 RecordRequestDeviceOptionalServices(optional_services);
339 RecordUnionOfServices(filters, optional_services);
340
341 VLOG(1) << "requestDevice called with the following filters: ";
342 for (const BluetoothScanFilter& filter : filters) {
343 VLOG(1) << "[";
344 for (const BluetoothUUID& service : filter.services)
345 VLOG(1) << "\t" << service.value();
346 VLOG(1) << "]";
347 }
348
349 VLOG(1) << "requestDevice called with the following optional services: ";
350 for (const BluetoothUUID& service : optional_services)
351 VLOG(1) << "\t" << service.value();
274 352
275 RenderFrameHostImpl* render_frame_host = 353 RenderFrameHostImpl* render_frame_host =
276 RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id); 354 RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id);
277 355
278 if (!render_frame_host) { 356 if (!render_frame_host) {
279 DLOG(WARNING) 357 VLOG(1) << "Got a requestDevice IPC without a matching RenderFrameHost: "
280 << "Got a requestDevice IPC without a matching RenderFrameHost: " 358 << render_process_id_ << ", " << frame_routing_id;
281 << render_process_id_ << ", " << frame_routing_id;
282 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::NO_RENDER_FRAME); 359 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::NO_RENDER_FRAME);
283 Send(new BluetoothMsg_RequestDeviceError( 360 Send(new BluetoothMsg_RequestDeviceError(
284 thread_id, request_id, WebBluetoothError::RequestDeviceWithoutFrame)); 361 thread_id, request_id, WebBluetoothError::RequestDeviceWithoutFrame));
285 } 362 }
286 363
287 // TODO(scheib): Device selection UI: crbug.com/436280 364 // TODO(scheib): Device selection UI: crbug.com/436280
288 // TODO(scheib): Utilize BluetoothAdapter::Observer::DeviceAdded/Removed. 365 // TODO(scheib): Utilize BluetoothAdapter::Observer::DeviceAdded/Removed.
289 if (adapter_.get()) { 366 if (adapter_.get()) {
290 if (!request_device_sessions_ 367 if (!request_device_sessions_
291 .insert(std::make_pair( 368 .insert(std::make_pair(
(...skipping 30 matching lines...) Expand all
322 request_device_sessions_.erase(std::make_pair(thread_id, request_id)); 399 request_device_sessions_.erase(std::make_pair(thread_id, request_id));
323 return; 400 return;
324 } 401 }
325 adapter_->StartDiscoverySessionWithFilter( 402 adapter_->StartDiscoverySessionWithFilter(
326 ComputeScanFilter(filters), 403 ComputeScanFilter(filters),
327 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStarted, 404 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStarted,
328 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id), 405 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id),
329 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStartedError, 406 base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStartedError,
330 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); 407 weak_ptr_factory_.GetWeakPtr(), thread_id, request_id));
331 } else { 408 } else {
332 DLOG(WARNING) << "No BluetoothAdapter. Can't serve requestDevice."; 409 VLOG(1) << "No BluetoothAdapter. Can't serve requestDevice.";
333 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::NO_BLUETOOTH_ADAPTER); 410 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::NO_BLUETOOTH_ADAPTER);
334 Send(new BluetoothMsg_RequestDeviceError( 411 Send(new BluetoothMsg_RequestDeviceError(
335 thread_id, request_id, WebBluetoothError::NoBluetoothAdapter)); 412 thread_id, request_id, WebBluetoothError::NoBluetoothAdapter));
336 } 413 }
337 return; 414 return;
338 } 415 }
339 416
340 void BluetoothDispatcherHost::OnConnectGATT( 417 void BluetoothDispatcherHost::OnConnectGATT(
341 int thread_id, 418 int thread_id,
342 int request_id, 419 int request_id,
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 } 683 }
607 684
608 void BluetoothDispatcherHost::OnDiscoverySessionStopped(int thread_id, 685 void BluetoothDispatcherHost::OnDiscoverySessionStopped(int thread_id,
609 int request_id) { 686 int request_id) {
610 DCHECK_CURRENTLY_ON(BrowserThread::UI); 687 DCHECK_CURRENTLY_ON(BrowserThread::UI);
611 auto session = 688 auto session =
612 request_device_sessions_.find(std::make_pair(thread_id, request_id)); 689 request_device_sessions_.find(std::make_pair(thread_id, request_id));
613 CHECK(session != request_device_sessions_.end()); 690 CHECK(session != request_device_sessions_.end());
614 BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); 691 BluetoothAdapter::DeviceList devices = adapter_->GetDevices();
615 for (device::BluetoothDevice* device : devices) { 692 for (device::BluetoothDevice* device : devices) {
693 VLOG(1) << "Device: " << device->GetName();
694 VLOG(1) << "UUIDs: ";
695 for (BluetoothUUID uuid : device->GetUUIDs())
696 VLOG(1) << "\t" << uuid.canonical_value();
616 if (MatchesFilters(*device, session->second.filters)) { 697 if (MatchesFilters(*device, session->second.filters)) {
617 content::BluetoothDevice device_ipc( 698 content::BluetoothDevice device_ipc(
618 device->GetAddress(), // instance_id 699 device->GetAddress(), // instance_id
619 device->GetName(), // name 700 device->GetName(), // name
620 device->GetBluetoothClass(), // device_class 701 device->GetBluetoothClass(), // device_class
621 device->GetVendorIDSource(), // vendor_id_source 702 device->GetVendorIDSource(), // vendor_id_source
622 device->GetVendorID(), // vendor_id 703 device->GetVendorID(), // vendor_id
623 device->GetProductID(), // product_id 704 device->GetProductID(), // product_id
624 device->GetDeviceID(), // product_version 705 device->GetDeviceID(), // product_version
625 device->IsPaired(), // paired 706 device->IsPaired(), // paired
626 content::BluetoothDevice::UUIDsFromBluetoothUUIDs( 707 content::BluetoothDevice::UUIDsFromBluetoothUUIDs(
627 device->GetUUIDs())); // uuids 708 device->GetUUIDs())); // uuids
628 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::SUCCESS); 709 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::SUCCESS);
629 Send(new BluetoothMsg_RequestDeviceSuccess(thread_id, request_id, 710 Send(new BluetoothMsg_RequestDeviceSuccess(thread_id, request_id,
630 device_ipc)); 711 device_ipc));
631 request_device_sessions_.erase(session); 712 request_device_sessions_.erase(session);
632 return; 713 return;
633 } 714 }
634 } 715 }
635 RecordRequestDeviceOutcome( 716 RecordRequestDeviceOutcome(
636 UMARequestDeviceOutcome::NO_MATCHING_DEVICES_FOUND); 717 UMARequestDeviceOutcome::NO_MATCHING_DEVICES_FOUND);
718 VLOG(1) << "No matching Bluetooth Devices found";
637 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, 719 Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id,
638 WebBluetoothError::NoDevicesFound)); 720 WebBluetoothError::NoDevicesFound));
639 request_device_sessions_.erase(session); 721 request_device_sessions_.erase(session);
640 } 722 }
641 723
642 void BluetoothDispatcherHost::OnDiscoverySessionStoppedError(int thread_id, 724 void BluetoothDispatcherHost::OnDiscoverySessionStoppedError(int thread_id,
643 int request_id) { 725 int request_id) {
644 DCHECK_CURRENTLY_ON(BrowserThread::UI); 726 DCHECK_CURRENTLY_ON(BrowserThread::UI);
645 DLOG(WARNING) << "BluetoothDispatcherHost::OnDiscoverySessionStoppedError"; 727 DLOG(WARNING) << "BluetoothDispatcherHost::OnDiscoverySessionStoppedError";
646 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::DISCOVERY_STOP_FAILED); 728 RecordRequestDeviceOutcome(UMARequestDeviceOutcome::DISCOVERY_STOP_FAILED);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 811
730 void BluetoothDispatcherHost::OnWriteValueFailed( 812 void BluetoothDispatcherHost::OnWriteValueFailed(
731 int thread_id, 813 int thread_id,
732 int request_id, 814 int request_id,
733 device::BluetoothGattService::GattErrorCode error_code) { 815 device::BluetoothGattService::GattErrorCode error_code) {
734 Send(new BluetoothMsg_WriteCharacteristicValueError( 816 Send(new BluetoothMsg_WriteCharacteristicValueError(
735 thread_id, request_id, TranslateGATTError(error_code))); 817 thread_id, request_id, TranslateGATTError(error_code)));
736 } 818 }
737 819
738 } // namespace content 820 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | tools/metrics/histograms/histograms.xml » ('J')

Powered by Google App Engine
This is Rietveld 408576698