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 61d35955a2169cb768de875934ad772f2c66132c..3cdba38b7c19de094608f923920a73790b97a3bd 100644 |
--- a/content/browser/bluetooth/bluetooth_dispatcher_host.cc |
+++ b/content/browser/bluetooth/bluetooth_dispatcher_host.cc |
@@ -52,18 +52,161 @@ enum class UMARequestDeviceOutcome { |
DISCOVERY_START_FAILED = 3, |
DISCOVERY_STOP_FAILED = 4, |
NO_MATCHING_DEVICES_FOUND = 5, |
+ BLUETOOTH_ADAPTER_OFF = 6, |
// NOTE: Add new requestDevice() outcomes immediately above this line. Make |
// sure to update the enum list in |
// tools/metrics/histogram/histograms.xml accordingly. |
COUNT |
}; |
+enum class UMAGATTServices { |
+ UNKNOWN, |
+ ALERT_NOTIFICATION, |
+ AUTOMATION_IO, |
+ BATTERY_SERVICE, |
+ BLOOD_PRESSURE, |
+ BODY_COMPOSITION, |
+ BOND_MANAGEMENT, |
+ CONTINUOUS_GLUCOSE_MONITORING, |
+ CURRENT_TIME, |
+ CYCLING_POWER, |
+ CYCLING_SPEED_AND_CADENCE, |
+ DEVICE_INFORMATION, |
+ ENVIRONMENTAL_SENSING, |
+ GENERIC_ACCESS, |
+ GENERIC_ATTRIBUTE, |
+ GLUCOSE, |
+ HEALTH_THERMOMETER, |
+ HEART_RATE, |
+ HUMAN_INTERFACE_DEVICE, |
+ IMMEDIATE_ALERT, |
+ INDOOR_POSITIONING, |
+ INTERNET_PROTOCOL_SUPPORT, |
+ LINK_LOSS, |
+ LOCATION_AND_NAVIGATION, |
+ NEXT_DST_CHANGE, |
+ PHONE_ALERT_STATUS, |
+ PULSE_OXIMETER, |
+ REFERENCE_TIME_UPDATE, |
+ RUNNING_SPEED_AND_CADENCE, |
+ SCAN_PARAMETERS, |
+ TX_POWER, |
+ USER_DATA, |
+ WEIGHT_SCALE, |
+ // NOTE: Add new services immediately above this line. Make sure to update the |
+ // enum list in tools/metrics/histogram/histograms.xml accordingly. |
+ COUNT |
+}; |
+ |
+typedef std::map<BluetoothUUID, UMAGATTServices> BluetoothUUIDToServicesMap; |
+ |
+std::map<BluetoothUUID, UMAGATTServices>* getServiceToEnumMap() { |
+ CR_DEFINE_STATIC_LOCAL(BluetoothUUIDToServicesMap, services, ()); |
+ if (services.empty()) { |
+ services.insert(std::make_pair(BluetoothUUID("1811"), |
+ UMAGATTServices::ALERT_NOTIFICATION)); |
+ services.insert(std::make_pair(BluetoothUUID("180F"), |
+ UMAGATTServices::BATTERY_SERVICE)); |
+ services.insert( |
+ std::make_pair(BluetoothUUID("1810"), UMAGATTServices::BLOOD_PRESSURE)); |
+ services.insert(std::make_pair(BluetoothUUID("181B"), |
+ UMAGATTServices::BODY_COMPOSITION)); |
+ services.insert(std::make_pair(BluetoothUUID("181E"), |
+ UMAGATTServices::BOND_MANAGEMENT)); |
+ services.insert(std::make_pair( |
+ BluetoothUUID("181F"), UMAGATTServices::CONTINUOUS_GLUCOSE_MONITORING)); |
+ services.insert( |
+ std::make_pair(BluetoothUUID("1805"), UMAGATTServices::CURRENT_TIME)); |
+ services.insert( |
+ std::make_pair(BluetoothUUID("1818"), UMAGATTServices::CYCLING_POWER)); |
+ services.insert(std::make_pair(BluetoothUUID("1816"), |
+ UMAGATTServices::CYCLING_SPEED_AND_CADENCE)); |
+ services.insert(std::make_pair(BluetoothUUID("180A"), |
+ UMAGATTServices::DEVICE_INFORMATION)); |
+ services.insert(std::make_pair(BluetoothUUID("181A"), |
+ UMAGATTServices::ENVIRONMENTAL_SENSING)); |
+ services.insert( |
+ std::make_pair(BluetoothUUID("1800"), UMAGATTServices::GENERIC_ACCESS)); |
+ services.insert(std::make_pair(BluetoothUUID("1801"), |
+ UMAGATTServices::GENERIC_ATTRIBUTE)); |
+ services.insert( |
+ std::make_pair(BluetoothUUID("1808"), UMAGATTServices::GLUCOSE)); |
+ services.insert(std::make_pair(BluetoothUUID("1809"), |
+ UMAGATTServices::HEALTH_THERMOMETER)); |
+ services.insert( |
+ std::make_pair(BluetoothUUID("180D"), UMAGATTServices::HEART_RATE)); |
+ services.insert(std::make_pair(BluetoothUUID("1812"), |
+ UMAGATTServices::HUMAN_INTERFACE_DEVICE)); |
+ services.insert(std::make_pair(BluetoothUUID("1802"), |
+ UMAGATTServices::IMMEDIATE_ALERT)); |
+ services.insert(std::make_pair(BluetoothUUID("1821"), |
+ UMAGATTServices::INDOOR_POSITIONING)); |
+ services.insert(std::make_pair(BluetoothUUID("1820"), |
+ UMAGATTServices::INTERNET_PROTOCOL_SUPPORT)); |
+ services.insert( |
+ std::make_pair(BluetoothUUID("1803"), UMAGATTServices::LINK_LOSS)); |
+ services.insert(std::make_pair(BluetoothUUID("1819"), |
+ UMAGATTServices::LOCATION_AND_NAVIGATION)); |
+ services.insert(std::make_pair(BluetoothUUID("1807"), |
+ UMAGATTServices::NEXT_DST_CHANGE)); |
+ services.insert(std::make_pair(BluetoothUUID("180E"), |
+ UMAGATTServices::PHONE_ALERT_STATUS)); |
+ services.insert(std::make_pair(BluetoothUUID("1806"), |
+ UMAGATTServices::REFERENCE_TIME_UPDATE)); |
+ services.insert(std::make_pair(BluetoothUUID("1814"), |
+ UMAGATTServices::RUNNING_SPEED_AND_CADENCE)); |
+ services.insert(std::make_pair(BluetoothUUID("1813"), |
+ UMAGATTServices::SCAN_PARAMETERS)); |
+ services.insert( |
+ std::make_pair(BluetoothUUID("1804"), UMAGATTServices::TX_POWER)); |
+ services.insert( |
+ std::make_pair(BluetoothUUID("181C"), UMAGATTServices::USER_DATA)); |
+ services.insert( |
+ std::make_pair(BluetoothUUID("181D"), UMAGATTServices::WEIGHT_SCALE)); |
+ } |
+ return &services; |
+} |
+ |
+int GetServiceBucket(const BluetoothUUID& service) { |
+ std::map<BluetoothUUID, UMAGATTServices>* services = getServiceToEnumMap(); |
+ |
+ auto it = services->find(service); |
+ if (it == services->end()) |
+ return static_cast<int>(UMAGATTServices::UNKNOWN); |
+ return static_cast<int>(it->second); |
+} |
+ |
void RecordRequestDeviceOutcome(UMARequestDeviceOutcome outcome) { |
- UMA_HISTOGRAM_ENUMERATION("Bluetooth.RequestDevice.Outcome", |
+ UMA_HISTOGRAM_ENUMERATION("WebBluetooth.RequestDevice.Outcome", |
static_cast<int>(outcome), |
static_cast<int>(UMARequestDeviceOutcome::COUNT)); |
} |
+void RecordRequestDeviceFilters( |
+ const std::vector<content::BluetoothScanFilter>& filters) { |
+ UMA_HISTOGRAM_COUNTS("WebBluetooth.RequestDevice.Filters.Count", |
+ filters.size()); |
+ for (const content::BluetoothScanFilter& filter : filters) { |
+ for (const BluetoothUUID& service : filter.services) { |
+ UMA_HISTOGRAM_ENUMERATION("WebBluetooth.RequestDevice.Filters.Services", |
+ GetServiceBucket(service), |
+ static_cast<int>(UMAGATTServices::COUNT)); |
+ } |
+ } |
+} |
+ |
+void RecordRequestDeviceOptionalServices( |
+ const std::vector<BluetoothUUID>& optional_services) { |
+ UMA_HISTOGRAM_COUNTS("WebBluetooth.RequestDevice.OptionalServices.Count", |
+ optional_services.size()); |
+ for (const BluetoothUUID& service : optional_services) { |
+ UMA_HISTOGRAM_ENUMERATION( |
+ "WebBluetooth.RequestDevice.OptionalServices.Services", |
+ static_cast<int>(GetServiceBucket(service)), |
+ static_cast<int>(UMAGATTServices::COUNT)); |
+ } |
+} |
+ |
// TODO(ortuno): Once we have a chooser for scanning and the right |
// callback for discovered services we should delete these constants. |
// https://crbug.com/436280 and https://crbug.com/484504 |
@@ -254,14 +397,27 @@ void BluetoothDispatcherHost::OnRequestDevice( |
const std::vector<BluetoothUUID>& optional_services) { |
DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
RecordAction(UserMetricsAction("WebBluetooth_RequestDevice")); |
+ RecordRequestDeviceFilters(filters); |
+ RecordRequestDeviceOptionalServices(optional_services); |
+ |
+ VLOG(1) << "requestDevice called with the following filters: "; |
+ for (const BluetoothScanFilter& filter : filters) { |
+ VLOG(1) << "["; |
+ for (const BluetoothUUID& service : filter.services) |
+ VLOG(1) << service.value(); |
+ VLOG(1) << "]"; |
+ } |
+ |
+ VLOG(1) << "requestDevice called with the following optional services: "; |
+ for (const BluetoothUUID& service : optional_services) |
+ VLOG(1) << 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)); |
@@ -281,6 +437,22 @@ void BluetoothDispatcherHost::OnRequestDevice( |
bad_message::ReceivedBadMessage( |
this, bad_message::BDH_DUPLICATE_REQUEST_DEVICE_ID); |
} |
+ |
+ if (!adapter_->IsPresent()) { |
+ VLOG(1) << "BluetoothAdapter not present. Can't serve requestDevice."; |
+ RecordRequestDeviceOutcome(UMARequestDeviceOutcome::NO_BLUETOOTH_ADAPTER); |
+ Send(new BluetoothMsg_RequestDeviceError( |
+ thread_id, request_id, WebBluetoothError::NoBluetoothAdapter)); |
+ return; |
+ } |
+ if (!adapter_->IsPowered()) { |
+ VLOG(1) << "BluetoothAdapter is not powered. Can't serve requestDevice."; |
+ RecordRequestDeviceOutcome( |
+ UMARequestDeviceOutcome::BLUETOOTH_ADAPTER_OFF); |
+ Send(new BluetoothMsg_RequestDeviceError( |
+ thread_id, request_id, WebBluetoothError::BluetoothAdapterOff)); |
+ return; |
+ } |
adapter_->StartDiscoverySessionWithFilter( |
ComputeScanFilter(filters), |
base::Bind(&BluetoothDispatcherHost::OnDiscoverySessionStarted, |
@@ -288,7 +460,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)); |
@@ -589,6 +761,7 @@ void BluetoothDispatcherHost::OnDiscoverySessionStopped(int thread_id, |
return; |
} |
} |
+ VLOG(1) << "No matching Bluetooth Devices found"; |
RecordRequestDeviceOutcome( |
UMARequestDeviceOutcome::NO_MATCHING_DEVICES_FOUND); |
Send(new BluetoothMsg_RequestDeviceError(thread_id, request_id, |