Index: content/browser/bluetooth/bluetooth_dispatcher_host.cc |
diff --git a/content/browser/bluetooth/bluetooth_dispatcher_host.cc b/content/browser/bluetooth/bluetooth_dispatcher_host.cc |
index eff5a668cd974e6058511b2e8bb560725439700c..e36e66fde1a85d7c611a59f01bcd4ca1e97a24f3 100644 |
--- a/content/browser/bluetooth/bluetooth_dispatcher_host.cc |
+++ b/content/browser/bluetooth/bluetooth_dispatcher_host.cc |
@@ -11,6 +11,7 @@ |
#include "content/browser/bluetooth/bluetooth_dispatcher_host.h" |
#include "base/metrics/histogram.h" |
+#include "base/strings/string_util.h" |
#include "base/strings/utf_string_conversions.h" |
#include "content/browser/bad_message.h" |
#include "content/browser/frame_host/render_frame_host_impl.h" |
@@ -31,6 +32,11 @@ using device::BluetoothUUID; |
namespace { |
+const char* kBaseStandardServiceUUID = "00001800-0000-1000-8000-00805f9b34fb"; |
Alexei Svitkine (slow)
2015/08/10 20:12:45
Nit: const char kBaseStandardServiceUUID[] =
ortuno
2015/08/10 21:47:38
Done.
|
+// Current Max Standard Service UUID: |
+// https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx?SortField=AssignedNumber&SortDir=Asc |
+const uint16_t kMaxStandardServiceUUID = 0x22; |
+ |
// These types of errors aren't as common. We log them to understand |
// how common they are and if we need to investigate more. |
enum class BluetoothGATTError { |
@@ -58,11 +64,68 @@ enum class UMARequestDeviceOutcome { |
}; |
void RecordRequestDeviceOutcome(UMARequestDeviceOutcome outcome) { |
- UMA_HISTOGRAM_ENUMERATION("Bluetooth.RequestDevice.Outcome", |
+ UMA_HISTOGRAM_ENUMERATION("Bluetooth.Web.RequestDevice.Outcome", |
static_cast<int>(outcome), |
static_cast<int>(UMARequestDeviceOutcome::COUNT)); |
} |
+int GetServiceEnum(const BluetoothUUID& service) { |
+ if (!service.canonical_value().compare(0, 6, |
+ kBaseStandardServiceUUID) // 000018 |
+ || |
+ !service.canonical_value().compare( |
+ 8, 28, kBaseStandardServiceUUID)) // -0000-1000-8000-00805f9b34fb |
Alexei Svitkine (slow)
2015/08/10 20:12:45
Nit: {}'s
ortuno
2015/08/10 21:47:38
Done.
|
+ return 0; // Unknown Service |
+ |
+ uint16_t serviceEnum = 0; |
+ for (int i = 0; i < 2; i++) { |
+ serviceEnum <<= 4; |
+ serviceEnum += base::HexDigitToInt(service.canonical_value()[i + 6]); |
+ } |
+ if (serviceEnum > kMaxStandardServiceUUID) { |
+ return 0; // Unknown Service |
+ } |
+ // We shift everything by one because of the unknown service at 0. |
+ return serviceEnum + 1; |
Alexei Svitkine (slow)
2015/08/10 20:12:45
nit: hacker_style
ortuno
2015/08/10 21:47:38
Done?
|
+} |
+ |
+void RecordRequestDeviceFilters( |
+ const std::vector<content::BluetoothScanFilter>& filters) { |
+ UMA_HISTOGRAM_COUNTS("Bluetooth.Web.RequestDevice.Filters.Count", |
+ filters.size()); |
+ for (const content::BluetoothScanFilter& filter : filters) { |
+ UMA_HISTOGRAM_COUNTS("Bluetooth.Web.RequestDevice.FilterSize", |
+ filter.services.size()); |
+ for (const BluetoothUUID& service : filter.services) { |
+ UMA_HISTOGRAM_ENUMERATION("Bluetooth.Web.RequestDevice.Filters.Services", |
+ GetServiceEnum(service), 0xFF); |
+ } |
+ } |
+} |
+ |
+void RecordRequestDeviceOptionalServices( |
+ const std::vector<BluetoothUUID>& optional_services) { |
+ UMA_HISTOGRAM_COUNTS("Bluetooth.Web.RequestDevice.OptionalServices.Count", |
+ optional_services.size()); |
+ for (const BluetoothUUID& service : optional_services) { |
+ UMA_HISTOGRAM_ENUMERATION( |
+ "Bluetooth.Web.RequestDevice.OptionalServices.Services", |
+ GetServiceEnum(service), 0xFF); |
Alexei Svitkine (slow)
2015/08/10 20:12:45
Why is the max value 0xFF?
ortuno
2015/08/10 21:47:38
Changed it to 0x101. Standard Service UUIDs are be
|
+ } |
+} |
+ |
+void RecordUnionOfServices( |
+ const std::vector<content::BluetoothScanFilter>& filters, |
+ const std::vector<BluetoothUUID>& optional_services) { |
+ const std::set<BluetoothUUID> unionOfServices(optional_services.begin(), |
Alexei Svitkine (slow)
2015/08/10 20:12:45
Nit: camel_case
ortuno
2015/08/10 21:47:38
Done.
|
+ optional_services.end()); |
+ for (const content::BluetoothScanFilter& filter : filters) |
+ unionOfServices.insert(filter.services.begin(), filter.services.end()); |
+ |
+ UMA_HISTOGRAM_COUNTS("Bluetooth.Web.RequestDevice.UnionOfServices.Count", |
+ unionOfServices.size()); |
+} |
+ |
enum class UMAWebBluetoothFunction { |
REQUEST_DEVICE, |
CONNECT_GATT, |
@@ -271,14 +334,28 @@ void BluetoothDispatcherHost::OnRequestDevice( |
const std::vector<BluetoothUUID>& optional_services) { |
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
RecordWebBluetoothFunctionCall(UMAWebBluetoothFunction::REQUEST_DEVICE); |
+ RecordRequestDeviceFilters(filters); |
+ RecordRequestDeviceOptionalServices(optional_services); |
+ RecordUnionOfServices(filters, optional_services); |
+ |
+ VLOG(1) << "requestDevice called with the following filters: "; |
Alexei Svitkine (slow)
2015/08/10 20:12:45
VLOGs are generally discouraged (search chromium-d
ortuno
2015/08/10 21:47:38
I read the email thread about VLOG. Since we are a
|
+ for (const BluetoothScanFilter& filter : filters) { |
+ VLOG(1) << "["; |
+ for (const BluetoothUUID& service : filter.services) |
+ VLOG(1) << "\t" << service.value(); |
+ VLOG(1) << "]"; |
+ } |
+ |
+ VLOG(1) << "requestDevice called with the following optional services: "; |
+ for (const BluetoothUUID& service : optional_services) |
+ VLOG(1) << "\t" << service.value(); |
RenderFrameHostImpl* render_frame_host = |
RenderFrameHostImpl::FromID(render_process_id_, frame_routing_id); |
if (!render_frame_host) { |
- DLOG(WARNING) |
- << "Got a requestDevice IPC without a matching RenderFrameHost: " |
- << render_process_id_ << ", " << frame_routing_id; |
+ VLOG(1) << "Got a requestDevice IPC without a matching RenderFrameHost: " |
+ << render_process_id_ << ", " << frame_routing_id; |
RecordRequestDeviceOutcome(UMARequestDeviceOutcome::NO_RENDER_FRAME); |
Send(new BluetoothMsg_RequestDeviceError( |
thread_id, request_id, WebBluetoothError::RequestDeviceWithoutFrame)); |
@@ -329,7 +406,7 @@ void BluetoothDispatcherHost::OnRequestDevice( |
base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStartedError, |
weak_ptr_factory_.GetWeakPtr(), thread_id, request_id)); |
} else { |
- DLOG(WARNING) << "No BluetoothAdapter. Can't serve requestDevice."; |
+ VLOG(1) << "No BluetoothAdapter. Can't serve requestDevice."; |
RecordRequestDeviceOutcome(UMARequestDeviceOutcome::NO_BLUETOOTH_ADAPTER); |
Send(new BluetoothMsg_RequestDeviceError( |
thread_id, request_id, WebBluetoothError::NoBluetoothAdapter)); |
@@ -613,6 +690,10 @@ void BluetoothDispatcherHost::OnDiscoverySessionStopped(int thread_id, |
CHECK(session != request_device_sessions_.end()); |
BluetoothAdapter::DeviceList devices = adapter_->GetDevices(); |
for (device::BluetoothDevice* device : devices) { |
+ VLOG(1) << "Device: " << device->GetName(); |
+ VLOG(1) << "UUIDs: "; |
+ for (BluetoothUUID uuid : device->GetUUIDs()) |
+ VLOG(1) << "\t" << uuid.canonical_value(); |
if (MatchesFilters(*device, session->second.filters)) { |
content::BluetoothDevice device_ipc( |
device->GetAddress(), // instance_id |
@@ -634,6 +715,7 @@ void BluetoothDispatcherHost::OnDiscoverySessionStopped(int thread_id, |
} |
RecordRequestDeviceOutcome( |
UMARequestDeviceOutcome::NO_MATCHING_DEVICES_FOUND); |
+ VLOG(1) << "No matching Bluetooth Devices found"; |
Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, |
WebBluetoothError::NoDevicesFound)); |
request_device_sessions_.erase(session); |