| 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 "content/browser/bluetooth/bluetooth_metrics.h" | 5 #include "content/browser/bluetooth/bluetooth_metrics.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <map> | 9 #include <map> |
| 10 #include <set> | 10 #include <set> |
| 11 #include <unordered_set> |
| 12 |
| 11 #include "base/hash.h" | 13 #include "base/hash.h" |
| 12 #include "base/metrics/histogram_macros.h" | 14 #include "base/metrics/histogram_macros.h" |
| 13 #include "base/metrics/sparse_histogram.h" | 15 #include "base/metrics/sparse_histogram.h" |
| 14 #include "device/bluetooth/bluetooth_uuid.h" | 16 #include "device/bluetooth/bluetooth_uuid.h" |
| 15 | 17 |
| 16 using device::BluetoothUUID; | 18 using device::BluetoothUUID; |
| 17 | 19 |
| 18 namespace { | 20 namespace { |
| 19 | 21 |
| 20 // Generates a hash from a canonical UUID string suitable for | 22 // Generates a hash from a canonical UUID string suitable for |
| 21 // UMA_HISTOGRAM_SPARSE_SLOWLY (positive int). | 23 // UMA_HISTOGRAM_SPARSE_SLOWLY (positive int). |
| 22 // | 24 // |
| 23 // Hash values can be produced manually using tool: bluetooth_metrics_hash. | 25 // Hash values can be produced manually using tool: bluetooth_metrics_hash. |
| 24 int HashUUID(const std::string& canonical_uuid) { | 26 int HashUUID(const base::Optional<BluetoothUUID>& uuid) { |
| 25 DCHECK(canonical_uuid == BluetoothUUID(canonical_uuid).canonical_value()); | 27 if (!uuid) { |
| 28 return 0; |
| 29 } |
| 26 | 30 |
| 27 // TODO(520284): Other than verifying that uuid is canonical, this logic | 31 // TODO(520284): Other than verifying that |uuid| contains a value, this logic |
| 28 // should be migrated to a dedicated histogram macro for hashed strings. | 32 // should be migrated to a dedicated histogram macro for hashed strings. |
| 33 const std::string& canonical_uuid = uuid->canonical_value(); |
| 29 uint32_t data = | 34 uint32_t data = |
| 30 base::SuperFastHash(canonical_uuid.data(), canonical_uuid.size()); | 35 base::SuperFastHash(canonical_uuid.data(), canonical_uuid.size()); |
| 31 | 36 |
| 32 // Strip off the sign bit because UMA doesn't support negative values, | 37 // Strip off the sign bit because UMA doesn't support negative values, |
| 33 // but takes a signed int as input. | 38 // but takes a signed int as input. |
| 34 return static_cast<int>(data & 0x7fffffff); | 39 return static_cast<int>(data & 0x7fffffff); |
| 35 } | 40 } |
| 36 } // namespace | 41 } // namespace |
| 37 | 42 |
| 38 namespace content { | 43 namespace content { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 53 static_cast<int>(UMARequestDeviceOutcome::COUNT)); | 58 static_cast<int>(UMARequestDeviceOutcome::COUNT)); |
| 54 } | 59 } |
| 55 | 60 |
| 56 static void RecordRequestDeviceFilters( | 61 static void RecordRequestDeviceFilters( |
| 57 const mojo::Array<blink::mojom::WebBluetoothScanFilterPtr>& filters) { | 62 const mojo::Array<blink::mojom::WebBluetoothScanFilterPtr>& filters) { |
| 58 UMA_HISTOGRAM_COUNTS_100("Bluetooth.Web.RequestDevice.Filters.Count", | 63 UMA_HISTOGRAM_COUNTS_100("Bluetooth.Web.RequestDevice.Filters.Count", |
| 59 filters.size()); | 64 filters.size()); |
| 60 for (const auto& filter : filters) { | 65 for (const auto& filter : filters) { |
| 61 UMA_HISTOGRAM_COUNTS_100("Bluetooth.Web.RequestDevice.FilterSize", | 66 UMA_HISTOGRAM_COUNTS_100("Bluetooth.Web.RequestDevice.FilterSize", |
| 62 filter->services.size()); | 67 filter->services.size()); |
| 63 for (const std::string& service : filter->services) { | 68 for (const base::Optional<BluetoothUUID>& service : filter->services) { |
| 64 // TODO(ortuno): Use a macro to histogram strings. | 69 // TODO(ortuno): Use a macro to histogram strings. |
| 65 // http://crbug.com/520284 | 70 // http://crbug.com/520284 |
| 66 UMA_HISTOGRAM_SPARSE_SLOWLY( | 71 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 67 "Bluetooth.Web.RequestDevice.Filters.Services", HashUUID(service)); | 72 "Bluetooth.Web.RequestDevice.Filters.Services", HashUUID(service)); |
| 68 } | 73 } |
| 69 } | 74 } |
| 70 } | 75 } |
| 71 | 76 |
| 72 static void RecordRequestDeviceOptionalServices( | 77 static void RecordRequestDeviceOptionalServices( |
| 73 const mojo::Array<mojo::String>& optional_services) { | 78 const mojo::Array<base::Optional<BluetoothUUID>>& optional_services) { |
| 74 UMA_HISTOGRAM_COUNTS_100("Bluetooth.Web.RequestDevice.OptionalServices.Count", | 79 UMA_HISTOGRAM_COUNTS_100("Bluetooth.Web.RequestDevice.OptionalServices.Count", |
| 75 optional_services.size()); | 80 optional_services.size()); |
| 76 for (const std::string& service : optional_services) { | 81 for (const base::Optional<BluetoothUUID>& service : optional_services) { |
| 77 // TODO(ortuno): Use a macro to histogram strings. | 82 // TODO(ortuno): Use a macro to histogram strings. |
| 78 // http://crbug.com/520284 | 83 // http://crbug.com/520284 |
| 79 UMA_HISTOGRAM_SPARSE_SLOWLY( | 84 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 80 "Bluetooth.Web.RequestDevice.OptionalServices.Services", | 85 "Bluetooth.Web.RequestDevice.OptionalServices.Services", |
| 81 HashUUID(service)); | 86 HashUUID(service)); |
| 82 } | 87 } |
| 83 } | 88 } |
| 84 | 89 |
| 85 static void RecordUnionOfServices( | 90 static void RecordUnionOfServices( |
| 86 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options) { | 91 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options) { |
| 87 std::set<mojo::String> union_of_services(options->optional_services.begin(), | 92 std::unordered_set<std::string> union_of_services; |
| 88 options->optional_services.end()); | 93 for (const base::Optional<BluetoothUUID>& service : |
| 94 options->optional_services) { |
| 95 union_of_services.insert(service->canonical_value()); |
| 96 } |
| 89 | 97 |
| 90 for (const auto& filter : options->filters) | 98 for (const auto& filter : options->filters) { |
| 91 union_of_services.insert(filter->services.begin(), filter->services.end()); | 99 for (const base::Optional<BluetoothUUID>& service : filter->services) { |
| 100 union_of_services.insert(service->canonical_value()); |
| 101 } |
| 102 } |
| 92 | 103 |
| 93 UMA_HISTOGRAM_COUNTS_100("Bluetooth.Web.RequestDevice.UnionOfServices.Count", | 104 UMA_HISTOGRAM_COUNTS_100("Bluetooth.Web.RequestDevice.UnionOfServices.Count", |
| 94 union_of_services.size()); | 105 union_of_services.size()); |
| 95 } | 106 } |
| 96 | 107 |
| 97 void RecordRequestDeviceOptions( | 108 void RecordRequestDeviceOptions( |
| 98 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options) { | 109 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options) { |
| 99 RecordRequestDeviceFilters(options->filters); | 110 RecordRequestDeviceFilters(options->filters); |
| 100 RecordRequestDeviceOptionalServices(options->optional_services); | 111 RecordRequestDeviceOptionalServices(options->optional_services); |
| 101 RecordUnionOfServices(options); | 112 RecordUnionOfServices(options); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 117 void RecordConnectGATTTimeSuccess(const base::TimeDelta& duration) { | 128 void RecordConnectGATTTimeSuccess(const base::TimeDelta& duration) { |
| 118 UMA_HISTOGRAM_MEDIUM_TIMES("Bluetooth.Web.ConnectGATT.TimeSuccess", duration); | 129 UMA_HISTOGRAM_MEDIUM_TIMES("Bluetooth.Web.ConnectGATT.TimeSuccess", duration); |
| 119 } | 130 } |
| 120 | 131 |
| 121 void RecordConnectGATTTimeFailed(const base::TimeDelta& duration) { | 132 void RecordConnectGATTTimeFailed(const base::TimeDelta& duration) { |
| 122 UMA_HISTOGRAM_MEDIUM_TIMES("Bluetooth.Web.ConnectGATT.TimeFailed", duration); | 133 UMA_HISTOGRAM_MEDIUM_TIMES("Bluetooth.Web.ConnectGATT.TimeFailed", duration); |
| 123 } | 134 } |
| 124 | 135 |
| 125 // getPrimaryService | 136 // getPrimaryService |
| 126 | 137 |
| 127 void RecordGetPrimaryServiceService(const BluetoothUUID& service) { | 138 void RecordGetPrimaryServiceService( |
| 139 const base::Optional<BluetoothUUID>& service) { |
| 128 // TODO(ortuno): Use a macro to histogram strings. | 140 // TODO(ortuno): Use a macro to histogram strings. |
| 129 // http://crbug.com/520284 | 141 // http://crbug.com/520284 |
| 130 UMA_HISTOGRAM_SPARSE_SLOWLY("Bluetooth.Web.GetPrimaryService.Services", | 142 UMA_HISTOGRAM_SPARSE_SLOWLY("Bluetooth.Web.GetPrimaryService.Services", |
| 131 HashUUID(service.canonical_value())); | 143 HashUUID(service)); |
| 132 } | 144 } |
| 133 | 145 |
| 134 void RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome outcome) { | 146 void RecordGetPrimaryServiceOutcome(UMAGetPrimaryServiceOutcome outcome) { |
| 135 UMA_HISTOGRAM_ENUMERATION( | 147 UMA_HISTOGRAM_ENUMERATION( |
| 136 "Bluetooth.Web.GetPrimaryService.Outcome", static_cast<int>(outcome), | 148 "Bluetooth.Web.GetPrimaryService.Outcome", static_cast<int>(outcome), |
| 137 static_cast<int>(UMAGetPrimaryServiceOutcome::COUNT)); | 149 static_cast<int>(UMAGetPrimaryServiceOutcome::COUNT)); |
| 138 } | 150 } |
| 139 | 151 |
| 140 void RecordGetPrimaryServiceOutcome(CacheQueryOutcome outcome) { | 152 void RecordGetPrimaryServiceOutcome(CacheQueryOutcome outcome) { |
| 141 DCHECK(outcome == CacheQueryOutcome::NO_DEVICE); | 153 DCHECK(outcome == CacheQueryOutcome::NO_DEVICE); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 UMAGetCharacteristicOutcome::NO_SERVICE); | 191 UMAGetCharacteristicOutcome::NO_SERVICE); |
| 180 return; | 192 return; |
| 181 case CacheQueryOutcome::NO_CHARACTERISTIC: | 193 case CacheQueryOutcome::NO_CHARACTERISTIC: |
| 182 NOTREACHED(); | 194 NOTREACHED(); |
| 183 return; | 195 return; |
| 184 } | 196 } |
| 185 } | 197 } |
| 186 | 198 |
| 187 void RecordGetCharacteristicsCharacteristic( | 199 void RecordGetCharacteristicsCharacteristic( |
| 188 blink::mojom::WebBluetoothGATTQueryQuantity quantity, | 200 blink::mojom::WebBluetoothGATTQueryQuantity quantity, |
| 189 const std::string& characteristic) { | 201 const base::Optional<BluetoothUUID>& characteristic) { |
| 190 switch (quantity) { | 202 switch (quantity) { |
| 191 case blink::mojom::WebBluetoothGATTQueryQuantity::SINGLE: | 203 case blink::mojom::WebBluetoothGATTQueryQuantity::SINGLE: |
| 192 UMA_HISTOGRAM_SPARSE_SLOWLY( | 204 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 193 "Bluetooth.Web.GetCharacteristic.Characteristic", | 205 "Bluetooth.Web.GetCharacteristic.Characteristic", |
| 194 HashUUID(characteristic)); | 206 HashUUID(characteristic)); |
| 195 return; | 207 return; |
| 196 case blink::mojom::WebBluetoothGATTQueryQuantity::MULTIPLE: | 208 case blink::mojom::WebBluetoothGATTQueryQuantity::MULTIPLE: |
| 197 UMA_HISTOGRAM_SPARSE_SLOWLY( | 209 UMA_HISTOGRAM_SPARSE_SLOWLY( |
| 198 "Bluetooth.Web.GetCharacteristics.Characteristic", | 210 "Bluetooth.Web.GetCharacteristics.Characteristic", |
| 199 HashUUID(characteristic)); | 211 HashUUID(characteristic)); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 static_cast<int>(outcome), | 287 static_cast<int>(outcome), |
| 276 static_cast<int>(UMAGATTOperationOutcome::COUNT)); | 288 static_cast<int>(UMAGATTOperationOutcome::COUNT)); |
| 277 } | 289 } |
| 278 | 290 |
| 279 void RecordStartNotificationsOutcome(CacheQueryOutcome outcome) { | 291 void RecordStartNotificationsOutcome(CacheQueryOutcome outcome) { |
| 280 RecordStartNotificationsOutcome( | 292 RecordStartNotificationsOutcome( |
| 281 TranslateCacheQueryOutcomeToGATTOperationOutcome(outcome)); | 293 TranslateCacheQueryOutcomeToGATTOperationOutcome(outcome)); |
| 282 } | 294 } |
| 283 | 295 |
| 284 } // namespace content | 296 } // namespace content |
| OLD | NEW |