| 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 "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 Loading... |
| 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())) { |
| 104 | |
| 105 if (options.filters().isEmpty()) { | |
| 106 exceptionState.throwTypeError( | 104 exceptionState.throwTypeError( |
| 107 "'filters' member must be non-empty to find any devices."); | 105 "Either 'filters' should be present or 'acceptAllDevices' should be " |
| 106 "true, but not both."); |
| 107 return; |
| 108 } | 108 } |
| 109 | 109 |
| 110 Vector<WebBluetoothScanFilter> filters; | 110 result.acceptAllDevices = options.acceptAllDevices(); |
| 111 for (const BluetoothScanFilterInit& filter : options.filters()) { | |
| 112 WebBluetoothScanFilter canonicalizedFilter = WebBluetoothScanFilter(); | |
| 113 | 111 |
| 114 canonicalizeFilter(filter, canonicalizedFilter, exceptionState); | 112 result.hasFilters = options.hasFilters(); |
| 113 if (result.hasFilters) { |
| 114 if (options.filters().isEmpty()) { |
| 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 BluetoothScanFilterInit& 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); |
| 120 } | 133 } |
| 121 | 134 |
| 122 result.filters.assign(filters); | |
| 123 | |
| 124 if (options.hasOptionalServices()) { | 135 if (options.hasOptionalServices()) { |
| 125 Vector<WebString> optionalServices; | 136 Vector<WebString> optionalServices; |
| 126 for (const StringOrUnsignedLong& optionalService : | 137 for (const StringOrUnsignedLong& optionalService : |
| 127 options.optionalServices()) { | 138 options.optionalServices()) { |
| 128 const String& validatedOptionalService = | 139 const String& validatedOptionalService = |
| 129 BluetoothUUID::getService(optionalService, exceptionState); | 140 BluetoothUUID::getService(optionalService, exceptionState); |
| 130 if (exceptionState.hadException()) | 141 if (exceptionState.hadException()) |
| 131 return; | 142 return; |
| 132 optionalServices.append(validatedOptionalService); | 143 optionalServices.append(validatedOptionalService); |
| 133 } | 144 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 Persistent<Bluetooth> m_bluetooth; | 176 Persistent<Bluetooth> m_bluetooth; |
| 166 Persistent<ScriptPromiseResolver> m_resolver; | 177 Persistent<ScriptPromiseResolver> m_resolver; |
| 167 }; | 178 }; |
| 168 | 179 |
| 169 // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice | 180 // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice |
| 170 ScriptPromise Bluetooth::requestDevice(ScriptState* scriptState, | 181 ScriptPromise Bluetooth::requestDevice(ScriptState* scriptState, |
| 171 const RequestDeviceOptions& options, | 182 const RequestDeviceOptions& options, |
| 172 ExceptionState& exceptionState) { | 183 ExceptionState& exceptionState) { |
| 173 ExecutionContext* context = scriptState->getExecutionContext(); | 184 ExecutionContext* context = scriptState->getExecutionContext(); |
| 174 | 185 |
| 175 // 1. If the incumbent settings object is not a secure context, reject promise | 186 // If the incumbent settings object is not a secure context, reject promise |
| 176 // with a SecurityError and abort these steps. | 187 // with a SecurityError and abort these steps. |
| 177 String errorMessage; | 188 String errorMessage; |
| 178 if (!context->isSecureContext(errorMessage)) { | 189 if (!context->isSecureContext(errorMessage)) { |
| 179 return ScriptPromise::rejectWithDOMException( | 190 return ScriptPromise::rejectWithDOMException( |
| 180 scriptState, DOMException::create(SecurityError, errorMessage)); | 191 scriptState, DOMException::create(SecurityError, errorMessage)); |
| 181 } | 192 } |
| 182 | 193 |
| 183 // 2. If the algorithm is not allowed to show a popup, reject promise with a | 194 // If the algorithm is not allowed to show a popup, reject promise with a |
| 184 // SecurityError and abort these steps. | 195 // SecurityError and abort these steps. |
| 185 if (!UserGestureIndicator::consumeUserGesture()) { | 196 if (!UserGestureIndicator::consumeUserGesture()) { |
| 186 return ScriptPromise::rejectWithDOMException( | 197 return ScriptPromise::rejectWithDOMException( |
| 187 scriptState, | 198 scriptState, |
| 188 DOMException::create( | 199 DOMException::create( |
| 189 SecurityError, | 200 SecurityError, |
| 190 "Must be handling a user gesture to show a permission request.")); | 201 "Must be handling a user gesture to show a permission request.")); |
| 191 } | 202 } |
| 192 | 203 |
| 193 WebBluetooth* webbluetooth = | 204 WebBluetooth* webbluetooth = |
| 194 BluetoothSupplement::fromScriptState(scriptState); | 205 BluetoothSupplement::fromScriptState(scriptState); |
| 195 if (!webbluetooth) | 206 if (!webbluetooth) |
| 196 return ScriptPromise::rejectWithDOMException( | 207 return ScriptPromise::rejectWithDOMException( |
| 197 scriptState, DOMException::create(NotSupportedError)); | 208 scriptState, DOMException::create(NotSupportedError)); |
| 198 | 209 |
| 199 // 3. In order to convert the arguments from service names and aliases to just | 210 // In order to convert the arguments from service names and aliases to just |
| 200 // UUIDs, do the following substeps: | 211 // UUIDs, do the following substeps: |
| 201 WebRequestDeviceOptions webOptions; | 212 WebRequestDeviceOptions webOptions; |
| 202 convertRequestDeviceOptions(options, webOptions, exceptionState); | 213 convertRequestDeviceOptions(options, webOptions, exceptionState); |
| 203 if (exceptionState.hadException()) | 214 if (exceptionState.hadException()) |
| 204 return exceptionState.reject(scriptState); | 215 return exceptionState.reject(scriptState); |
| 205 | 216 |
| 206 // Subsequent steps are handled in the browser process. | 217 // Subsequent steps are handled in the browser process. |
| 207 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 218 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| 208 ScriptPromise promise = resolver->promise(); | 219 ScriptPromise promise = resolver->promise(); |
| 209 webbluetooth->requestDevice(webOptions, | 220 webbluetooth->requestDevice(webOptions, |
| 210 new RequestDeviceCallback(this, resolver)); | 221 new RequestDeviceCallback(this, resolver)); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 223 String deviceId = deviceInit->id; | 234 String deviceId = deviceInit->id; |
| 224 device = BluetoothDevice::take(resolver, std::move(deviceInit)); | 235 device = BluetoothDevice::take(resolver, std::move(deviceInit)); |
| 225 | 236 |
| 226 auto result = m_deviceInstanceMap.add(deviceId, device); | 237 auto result = m_deviceInstanceMap.add(deviceId, device); |
| 227 DCHECK(result.isNewEntry); | 238 DCHECK(result.isNewEntry); |
| 228 } | 239 } |
| 229 return device; | 240 return device; |
| 230 } | 241 } |
| 231 | 242 |
| 232 } // namespace blink | 243 } // namespace blink |
| OLD | NEW |