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

Side by Side Diff: third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp

Issue 2510323002: bluetooth: Implement acceptAllDevices (Closed)
Patch Set: Clean up Created 4 years, 1 month 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 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 "modules/bluetooth/Bluetooth.h" 5 #include "modules/bluetooth/Bluetooth.h"
6 6
7 #include "bindings/core/v8/CallbackPromiseAdapter.h" 7 #include "bindings/core/v8/CallbackPromiseAdapter.h"
8 #include "bindings/core/v8/ScriptPromise.h" 8 #include "bindings/core/v8/ScriptPromise.h"
9 #include "bindings/core/v8/ScriptPromiseResolver.h" 9 #include "bindings/core/v8/ScriptPromiseResolver.h"
10 #include "core/dom/DOMException.h" 10 #include "core/dom/DOMException.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 "'namePrefix', if present, must me non-empty."); 93 "'namePrefix', if present, must me non-empty.");
94 return; 94 return;
95 } 95 }
96 canonicalizedFilter.namePrefix = filter.namePrefix(); 96 canonicalizedFilter.namePrefix = filter.namePrefix();
97 } 97 }
98 } 98 }
99 99
100 static void convertRequestDeviceOptions(const RequestDeviceOptions& options, 100 static void convertRequestDeviceOptions(const RequestDeviceOptions& options,
101 WebRequestDeviceOptions& result, 101 WebRequestDeviceOptions& result,
102 ExceptionState& exceptionState) { 102 ExceptionState& exceptionState) {
103 ASSERT(options.hasFilters()); 103 if ((options.hasFilters() && options.acceptAllDevices()) ||
scheib 2016/11/22 21:22:44 Do you find either of these easier to read? if
ortuno 2016/11/23 06:03:08 Went with the first one. Done.
104 104 (!options.hasFilters() && !options.acceptAllDevices())) {
105 if (options.filters().isEmpty()) {
106 exceptionState.throwTypeError( 105 exceptionState.throwTypeError(
107 "'filters' member must be non-empty to find any devices."); 106 "Either 'filters' should be present or 'acceptAllDevices' should be "
107 "true, but not both.");
108 return;
108 } 109 }
109 110
110 Vector<WebBluetoothScanFilter> filters; 111 result.acceptAllDevices = options.acceptAllDevices();
111 for (const BluetoothScanFilter& filter : options.filters()) {
112 WebBluetoothScanFilter canonicalizedFilter = WebBluetoothScanFilter();
113 112
114 canonicalizeFilter(filter, canonicalizedFilter, exceptionState); 113 if (options.hasFilters()) {
114 if (options.filters().isEmpty()) {
haraken 2016/11/22 03:58:42 Is it possible that isEmpty returns true while has
ortuno 2016/11/22 04:00:12 Yup: navigator.bluetooth.requestDevice({filters:
115 exceptionState.throwTypeError(
116 "'filters' member must be non-empty to find any devices.");
117 return;
118 }
115 119
116 if (exceptionState.hadException()) 120 Vector<WebBluetoothScanFilter> filters;
117 return; 121 for (const BluetoothScanFilter& filter : options.filters()) {
122 WebBluetoothScanFilter canonicalizedFilter = WebBluetoothScanFilter();
118 123
119 filters.append(canonicalizedFilter); 124 canonicalizeFilter(filter, canonicalizedFilter, exceptionState);
125
126 if (exceptionState.hadException())
127 return;
128
129 filters.append(canonicalizedFilter);
130 }
131
132 result.filters.assign(filters);
133 } else {
134 result.hasFilters = false;
120 } 135 }
121 136
122 result.filters.assign(filters);
123
124 if (options.hasOptionalServices()) { 137 if (options.hasOptionalServices()) {
125 Vector<WebString> optionalServices; 138 Vector<WebString> optionalServices;
126 for (const StringOrUnsignedLong& optionalService : 139 for (const StringOrUnsignedLong& optionalService :
127 options.optionalServices()) { 140 options.optionalServices()) {
128 const String& validatedOptionalService = 141 const String& validatedOptionalService =
129 BluetoothUUID::getService(optionalService, exceptionState); 142 BluetoothUUID::getService(optionalService, exceptionState);
130 if (exceptionState.hadException()) 143 if (exceptionState.hadException())
131 return; 144 return;
132 optionalServices.append(validatedOptionalService); 145 optionalServices.append(validatedOptionalService);
133 } 146 }
(...skipping 25 matching lines...) Expand all
159 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped()) 172 m_resolver->getExecutionContext()->activeDOMObjectsAreStopped())
160 return; 173 return;
161 m_resolver->reject(BluetoothError::take(m_resolver, error)); 174 m_resolver->reject(BluetoothError::take(m_resolver, error));
162 } 175 }
163 176
164 private: 177 private:
165 Persistent<Bluetooth> m_bluetooth; 178 Persistent<Bluetooth> m_bluetooth;
166 Persistent<ScriptPromiseResolver> m_resolver; 179 Persistent<ScriptPromiseResolver> m_resolver;
167 }; 180 };
168 181
169 // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetooth-requestdevi ce
170 ScriptPromise Bluetooth::requestDevice(ScriptState* scriptState, 182 ScriptPromise Bluetooth::requestDevice(ScriptState* scriptState,
171 const RequestDeviceOptions& options, 183 const RequestDeviceOptions& options,
172 ExceptionState& exceptionState) { 184 ExceptionState& exceptionState) {
173 ExecutionContext* context = scriptState->getExecutionContext(); 185 ExecutionContext* context = scriptState->getExecutionContext();
174 186
175 // 1. If the incumbent settings object is not a secure context, reject promise
176 // with a SecurityError and abort these steps.
177 String errorMessage; 187 String errorMessage;
178 if (!context->isSecureContext(errorMessage)) { 188 if (!context->isSecureContext(errorMessage)) {
179 return ScriptPromise::rejectWithDOMException( 189 return ScriptPromise::rejectWithDOMException(
180 scriptState, DOMException::create(SecurityError, errorMessage)); 190 scriptState, DOMException::create(SecurityError, errorMessage));
181 } 191 }
182 192
183 // 2. If the algorithm is not allowed to show a popup, reject promise with a
184 // SecurityError and abort these steps.
185 if (!UserGestureIndicator::consumeUserGesture()) { 193 if (!UserGestureIndicator::consumeUserGesture()) {
186 return ScriptPromise::rejectWithDOMException( 194 return ScriptPromise::rejectWithDOMException(
187 scriptState, 195 scriptState,
188 DOMException::create( 196 DOMException::create(
189 SecurityError, 197 SecurityError,
190 "Must be handling a user gesture to show a permission request.")); 198 "Must be handling a user gesture to show a permission request."));
191 } 199 }
192 200
193 WebBluetooth* webbluetooth = 201 WebBluetooth* webbluetooth =
194 BluetoothSupplement::fromScriptState(scriptState); 202 BluetoothSupplement::fromScriptState(scriptState);
195 if (!webbluetooth) 203 if (!webbluetooth)
196 return ScriptPromise::rejectWithDOMException( 204 return ScriptPromise::rejectWithDOMException(
197 scriptState, DOMException::create(NotSupportedError)); 205 scriptState, DOMException::create(NotSupportedError));
198 206
199 // 3. In order to convert the arguments from service names and aliases to just
200 // UUIDs, do the following substeps:
201 WebRequestDeviceOptions webOptions; 207 WebRequestDeviceOptions webOptions;
scheib 2016/11/22 21:22:44 Some of these comments helped explain why these st
ortuno 2016/11/23 06:03:08 hmm I think the code is pretty clear already but e
202 convertRequestDeviceOptions(options, webOptions, exceptionState); 208 convertRequestDeviceOptions(options, webOptions, exceptionState);
203 if (exceptionState.hadException()) 209 if (exceptionState.hadException())
204 return exceptionState.reject(scriptState); 210 return exceptionState.reject(scriptState);
205 211
206 // Subsequent steps are handled in the browser process.
207 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); 212 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
208 ScriptPromise promise = resolver->promise(); 213 ScriptPromise promise = resolver->promise();
209 webbluetooth->requestDevice(webOptions, 214 webbluetooth->requestDevice(webOptions,
210 new RequestDeviceCallback(this, resolver)); 215 new RequestDeviceCallback(this, resolver));
211 return promise; 216 return promise;
212 } 217 }
213 218
214 DEFINE_TRACE(Bluetooth) { 219 DEFINE_TRACE(Bluetooth) {
215 visitor->trace(m_deviceInstanceMap); 220 visitor->trace(m_deviceInstanceMap);
216 } 221 }
217 222
218 BluetoothDevice* Bluetooth::getBluetoothDeviceRepresentingDevice( 223 BluetoothDevice* Bluetooth::getBluetoothDeviceRepresentingDevice(
219 std::unique_ptr<WebBluetoothDeviceInit> deviceInit, 224 std::unique_ptr<WebBluetoothDeviceInit> deviceInit,
220 ScriptPromiseResolver* resolver) { 225 ScriptPromiseResolver* resolver) {
221 BluetoothDevice* device = m_deviceInstanceMap.get(deviceInit->id); 226 BluetoothDevice* device = m_deviceInstanceMap.get(deviceInit->id);
222 if (!device) { 227 if (!device) {
223 String deviceId = deviceInit->id; 228 String deviceId = deviceInit->id;
224 device = BluetoothDevice::take(resolver, std::move(deviceInit)); 229 device = BluetoothDevice::take(resolver, std::move(deviceInit));
225 230
226 auto result = m_deviceInstanceMap.add(deviceId, device); 231 auto result = m_deviceInstanceMap.add(deviceId, device);
227 DCHECK(result.isNewEntry); 232 DCHECK(result.isNewEntry);
228 } 233 }
229 return device; 234 return device;
230 } 235 }
231 236
232 } // namespace blink 237 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698