Chromium Code Reviews| 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()) || |
|
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 Loading... | |
| 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 |
| OLD | NEW |