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

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

Issue 2015463004: bluetooth: Use BluetoothUUID instead of string when sending uuids (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@bluetooth-mojo-request-device
Patch Set: Add header Created 4 years, 7 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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_device_chooser_controller.h" 5 #include "content/browser/bluetooth/bluetooth_device_chooser_controller.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <unordered_set> 9 #include <unordered_set>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/bind_helpers.h" 12 #include "base/bind_helpers.h"
13 #include "base/strings/string_util.h" 13 #include "base/strings/string_util.h"
14 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "content/browser/bluetooth/bluetooth_blacklist.h" 15 #include "content/browser/bluetooth/bluetooth_blacklist.h"
16 #include "content/browser/bluetooth/bluetooth_metrics.h" 16 #include "content/browser/bluetooth/bluetooth_metrics.h"
17 #include "content/browser/bluetooth/first_device_bluetooth_chooser.h" 17 #include "content/browser/bluetooth/first_device_bluetooth_chooser.h"
18 #include "content/browser/bluetooth/web_bluetooth_service_impl.h" 18 #include "content/browser/bluetooth/web_bluetooth_service_impl.h"
19 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/content_browser_client.h" 20 #include "content/public/browser/content_browser_client.h"
21 #include "content/public/browser/render_frame_host.h" 21 #include "content/public/browser/render_frame_host.h"
22 #include "content/public/browser/web_contents.h" 22 #include "content/public/browser/web_contents.h"
23 #include "content/public/browser/web_contents_delegate.h" 23 #include "content/public/browser/web_contents_delegate.h"
24 #include "device/bluetooth/bluetooth_adapter.h" 24 #include "device/bluetooth/bluetooth_adapter.h"
25 #include "device/bluetooth/bluetooth_discovery_session.h" 25 #include "device/bluetooth/bluetooth_discovery_session.h"
26 26
27 using device::BluetoothUUID;
28
27 namespace content { 29 namespace content {
28 30
29 namespace { 31 namespace {
30 constexpr size_t kMaxLengthForDeviceName = 32 constexpr size_t kMaxLengthForDeviceName =
31 29; // max length of device name in filter. 33 29; // max length of device name in filter.
32 34
33 void LogRequestDeviceOptions( 35 void LogRequestDeviceOptions(
34 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options) { 36 const blink::mojom::WebBluetoothRequestDeviceOptionsPtr& options) {
35 VLOG(1) << "requestDevice called with the following filters: "; 37 VLOG(1) << "requestDevice called with the following filters: ";
36 int i = 0; 38 int i = 0;
37 for (const auto& filter : options->filters) { 39 for (const auto& filter : options->filters) {
38 VLOG(1) << "Filter #" << ++i; 40 VLOG(1) << "Filter #" << ++i;
39 if (!filter->name.is_null()) 41 if (!filter->name.is_null())
40 VLOG(1) << "Name: " << filter->name; 42 VLOG(1) << "Name: " << filter->name;
41 43
42 if (!filter->name_prefix.is_null()) 44 if (!filter->name_prefix.is_null())
43 VLOG(1) << "Name Prefix: " << filter->name_prefix; 45 VLOG(1) << "Name Prefix: " << filter->name_prefix;
44 46
45 if (!filter->services.is_null()) { 47 if (!filter->services.is_null()) {
46 VLOG(1) << "Services: "; 48 VLOG(1) << "Services: ";
47 VLOG(1) << "\t["; 49 VLOG(1) << "\t[";
48 for (const auto& service : filter->services) 50 for (const auto& service : filter->services)
49 VLOG(1) << "\t\t" << service; 51 VLOG(1) << "\t\t" << service->canonical_value();
50 VLOG(1) << "\t]"; 52 VLOG(1) << "\t]";
51 } 53 }
52 } 54 }
53 } 55 }
54 56
55 bool IsValidUUID(const mojo::String& uuid) {
56 device::BluetoothUUID parsed_uuid(uuid);
57 return parsed_uuid.IsValid() &&
58 parsed_uuid.format() == device::BluetoothUUID::kFormat128Bit;
59 }
60
61 bool HasInvalidOptionalServices(
62 const mojo::Array<mojo::String>& optional_services) {
63 return optional_services.end() != std::find_if_not(optional_services.begin(),
64 optional_services.end(),
65 IsValidUUID);
66 }
67
68 bool IsEmptyOrInvalidFilter( 57 bool IsEmptyOrInvalidFilter(
69 const blink::mojom::WebBluetoothScanFilterPtr& filter) { 58 const blink::mojom::WebBluetoothScanFilterPtr& filter) {
70 // At least one member needs to be present. 59 // At least one member needs to be present.
71 if (filter->name.is_null() && filter->name_prefix.is_null() && 60 if (filter->name.is_null() && filter->name_prefix.is_null() &&
72 filter->services.is_null()) 61 filter->services.is_null())
73 return true; 62 return true;
74 63
75 // The renderer will never send a name or a name_prefix longer than 64 // The renderer will never send a name or a name_prefix longer than
76 // kMaxLengthForDeviceName. 65 // kMaxLengthForDeviceName.
77 if (!filter->name.is_null() && filter->name.size() > kMaxLengthForDeviceName) 66 if (!filter->name.is_null() && filter->name.size() > kMaxLengthForDeviceName)
78 return true; 67 return true;
79 if (!filter->name_prefix.is_null() && 68 if (!filter->name_prefix.is_null() &&
80 filter->name_prefix.size() > kMaxLengthForDeviceName) 69 filter->name_prefix.size() > kMaxLengthForDeviceName)
81 return true; 70 return true;
82 71
83 if (!filter->services.is_null()) {
84 const auto& services = filter->services;
85 return services.end() !=
86 std::find_if_not(services.begin(), services.end(), IsValidUUID);
87 }
88
89 return false; 72 return false;
90 } 73 }
91 74
92 bool HasEmptyOrInvalidFilter( 75 bool HasEmptyOrInvalidFilter(
93 const mojo::Array<blink::mojom::WebBluetoothScanFilterPtr>& filters) { 76 const mojo::Array<blink::mojom::WebBluetoothScanFilterPtr>& filters) {
94 return filters.empty() 77 return filters.empty()
95 ? true 78 ? true
96 : filters.end() != std::find_if(filters.begin(), filters.end(), 79 : filters.end() != std::find_if(filters.begin(), filters.end(),
97 IsEmptyOrInvalidFilter); 80 IsEmptyOrInvalidFilter);
98 } 81 }
99 82
100 bool MatchesFilter(const device::BluetoothDevice& device, 83 bool MatchesFilter(const device::BluetoothDevice& device,
101 const blink::mojom::WebBluetoothScanFilterPtr& filter) { 84 const blink::mojom::WebBluetoothScanFilterPtr& filter) {
102 DCHECK(!IsEmptyOrInvalidFilter(filter)); 85 DCHECK(!IsEmptyOrInvalidFilter(filter));
103 86
104 const std::string device_name = base::UTF16ToUTF8(device.GetName()); 87 const std::string device_name = base::UTF16ToUTF8(device.GetName());
105 88
106 if (!filter->name.is_null() && (device_name != filter->name)) { 89 if (!filter->name.is_null() && (device_name != filter->name)) {
107 return false; 90 return false;
108 } 91 }
109 92
110 if (!filter->name_prefix.is_null() && 93 if (!filter->name_prefix.is_null() &&
111 (!base::StartsWith(device_name, filter->name_prefix.get(), 94 (!base::StartsWith(device_name, filter->name_prefix.get(),
112 base::CompareCase::SENSITIVE))) { 95 base::CompareCase::SENSITIVE))) {
113 return false; 96 return false;
114 } 97 }
115 98
116 if (!filter->services.is_null()) { 99 if (!filter->services.is_null()) {
117 const auto& device_uuid_list = device.GetUUIDs(); 100 const auto& device_uuid_list = device.GetUUIDs();
118 const std::set<device::BluetoothUUID> device_uuids(device_uuid_list.begin(), 101 const std::set<BluetoothUUID> device_uuids(device_uuid_list.begin(),
119 device_uuid_list.end()); 102 device_uuid_list.end());
120 for (const auto& service : filter->services) { 103 for (const std::unique_ptr<BluetoothUUID>& service : filter->services) {
121 if (!ContainsKey(device_uuids, device::BluetoothUUID(service))) { 104 if (!ContainsKey(device_uuids, *service)) {
122 return false; 105 return false;
123 } 106 }
124 } 107 }
125 } 108 }
126 109
127 return true; 110 return true;
128 } 111 }
129 112
130 bool MatchesFilters( 113 bool MatchesFilters(
131 const device::BluetoothDevice& device, 114 const device::BluetoothDevice& device,
132 const mojo::Array<blink::mojom::WebBluetoothScanFilterPtr>& filters) { 115 const mojo::Array<blink::mojom::WebBluetoothScanFilterPtr>& filters) {
133 DCHECK(!HasEmptyOrInvalidFilter(filters)); 116 DCHECK(!HasEmptyOrInvalidFilter(filters));
134 for (const auto& filter : filters) { 117 for (const auto& filter : filters) {
135 if (MatchesFilter(device, filter)) { 118 if (MatchesFilter(device, filter)) {
136 return true; 119 return true;
137 } 120 }
138 } 121 }
139 return false; 122 return false;
140 } 123 }
141 124
142 std::unique_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter( 125 std::unique_ptr<device::BluetoothDiscoveryFilter> ComputeScanFilter(
143 const mojo::Array<blink::mojom::WebBluetoothScanFilterPtr>& filters) { 126 const mojo::Array<blink::mojom::WebBluetoothScanFilterPtr>& filters) {
144 std::unordered_set<std::string> services; 127 std::set<BluetoothUUID> services;
145 for (const auto& filter : filters) { 128 for (const auto& filter : filters) {
146 for (const std::string& service : filter->services) { 129 for (const std::unique_ptr<BluetoothUUID>& service : filter->services) {
147 services.insert(service); 130 services.insert(*service);
148 } 131 }
149 } 132 }
150 auto discovery_filter = base::MakeUnique<device::BluetoothDiscoveryFilter>( 133 auto discovery_filter = base::MakeUnique<device::BluetoothDiscoveryFilter>(
151 device::BluetoothDiscoveryFilter::TRANSPORT_DUAL); 134 device::BluetoothDiscoveryFilter::TRANSPORT_DUAL);
152 for (const std::string& service : services) { 135 for (const BluetoothUUID& service : services) {
153 discovery_filter->AddUUID(device::BluetoothUUID(service)); 136 discovery_filter->AddUUID(service);
154 } 137 }
155 return discovery_filter; 138 return discovery_filter;
156 } 139 }
157 140
158 void StopDiscoverySession( 141 void StopDiscoverySession(
159 std::unique_ptr<device::BluetoothDiscoverySession> discovery_session) { 142 std::unique_ptr<device::BluetoothDiscoverySession> discovery_session) {
160 // Nothing goes wrong if the discovery session fails to stop, and we don't 143 // Nothing goes wrong if the discovery session fails to stop, and we don't
161 // need to wait for it before letting the user's script proceed, so we ignore 144 // need to wait for it before letting the user's script proceed, so we ignore
162 // the results here. 145 // the results here.
163 discovery_session->Stop(base::Bind(&base::DoNothing), 146 discovery_session->Stop(base::Bind(&base::DoNothing),
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 DCHECK_CURRENTLY_ON(BrowserThread::UI); 209 DCHECK_CURRENTLY_ON(BrowserThread::UI);
227 210
228 // GetDevice should only be called once. 211 // GetDevice should only be called once.
229 DCHECK(success_callback_.is_null()); 212 DCHECK(success_callback_.is_null());
230 DCHECK(error_callback_.is_null()); 213 DCHECK(error_callback_.is_null());
231 214
232 success_callback_ = success_callback; 215 success_callback_ = success_callback;
233 error_callback_ = error_callback; 216 error_callback_ = error_callback;
234 217
235 // The renderer should never send empty filters. 218 // The renderer should never send empty filters.
236 if (HasEmptyOrInvalidFilter(options->filters) || 219 if (HasEmptyOrInvalidFilter(options->filters)) {
237 HasInvalidOptionalServices(options->optional_services)) {
238 web_bluetooth_service_->CrashRendererAndClosePipe( 220 web_bluetooth_service_->CrashRendererAndClosePipe(
239 bad_message::BDH_EMPTY_OR_INVALID_FILTERS); 221 bad_message::BDH_EMPTY_OR_INVALID_FILTERS);
240 return; 222 return;
241 } 223 }
242 options_ = std::move(options); 224 options_ = std::move(options);
243 LogRequestDeviceOptions(options_); 225 LogRequestDeviceOptions(options_);
244 226
245 // Check blacklist to reject invalid filters and adjust optional_services. 227 // Check blacklist to reject invalid filters and adjust optional_services.
246 if (BluetoothBlacklist::Get().IsExcluded(options_->filters)) { 228 if (BluetoothBlacklist::Get().IsExcluded(options_->filters)) {
247 RecordRequestDeviceOutcome( 229 RecordRequestDeviceOutcome(
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 456
475 void BluetoothDeviceChooserController::PostErrorCallback( 457 void BluetoothDeviceChooserController::PostErrorCallback(
476 blink::mojom::WebBluetoothError error) { 458 blink::mojom::WebBluetoothError error) {
477 if (!base::ThreadTaskRunnerHandle::Get()->PostTask( 459 if (!base::ThreadTaskRunnerHandle::Get()->PostTask(
478 FROM_HERE, base::Bind(error_callback_, error))) { 460 FROM_HERE, base::Bind(error_callback_, error))) {
479 LOG(WARNING) << "No TaskRunner."; 461 LOG(WARNING) << "No TaskRunner.";
480 } 462 }
481 } 463 }
482 464
483 } // namespace content 465 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698