ScriptPromise BluetoothGATTCharacteristic::stopNotifications(ScriptState* scriptState) { WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); webbluetooth->stopNotifications(m_webCharacteristic->characteristicInstanceID, this, new CallbackPromiseAdapter<void, BluetoothError>(resolver)); return promise; }
void BluetoothRemoteGATTServer::disconnect(ScriptState* scriptState) { if (!m_connected) return; device()->cleanupDisconnectedDeviceAndFireEvent(); WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); webbluetooth->disconnect(device()->id()); }
void BluetoothGATTCharacteristic::notifyCharacteristicObjectRemoved() { if (!m_stopped) { m_stopped = true; WebBluetooth* webbluetooth = BluetoothSupplement::fromExecutionContext(ActiveDOMObject::executionContext()); webbluetooth->characteristicObjectRemoved(m_webCharacteristic->characteristicInstanceID, this); } }
ScriptPromise BluetoothRemoteGATTCharacteristic::readValue(ScriptState* scriptState) { WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); webbluetooth->readValue(m_webCharacteristic->characteristicInstanceID, new ReadValueCallback(this, resolver)); return promise; }
ScriptPromise BluetoothDevice::connectGATT(ScriptState* scriptState) { WebBluetooth* webbluetooth = Platform::current()->bluetooth(); if (!webbluetooth) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError)); RefPtrWillBeRawPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); webbluetooth->connectGATT(instanceID(), new CallbackPromiseAdapter<BluetoothGATTRemoteServer, BluetoothError>(resolver)); return promise; }
bool BluetoothGATTCharacteristic::addEventListenerInternal(const AtomicString& eventType, PassRefPtrWillBeRawPtr<EventListener> listener, const EventListenerOptions& options) { // We will also need to unregister a characteristic once all the event // listeners have been removed. See http://crbug.com/541390 if (eventType == EventTypeNames::characteristicvaluechanged) { WebBluetooth* webbluetooth = BluetoothSupplement::fromExecutionContext(executionContext()); webbluetooth->registerCharacteristicObject(m_webCharacteristic->characteristicInstanceID, this); } return EventTarget::addEventListenerInternal(eventType, listener, options); }
void BluetoothRemoteGATTCharacteristic::addedEventListener(const AtomicString& eventType, RegisteredEventListener& registeredListener) { EventTargetWithInlineData::addedEventListener(eventType, registeredListener); // We will also need to unregister a characteristic once all the event // listeners have been removed. See http://crbug.com/541390 if (eventType == EventTypeNames::characteristicvaluechanged) { WebBluetooth* webbluetooth = BluetoothSupplement::fromExecutionContext(getExecutionContext()); webbluetooth->registerCharacteristicObject(m_webCharacteristic->characteristicInstanceID, this); } }
ScriptPromise BluetoothGATTCharacteristic::readValue(ScriptState* scriptState) { WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); webbluetooth->readValue(m_webCharacteristic->characteristicInstanceID, new CallbackPromiseAdapter<ConvertWebVectorToArrayBuffer, BluetoothError>(resolver)); return promise; }
ScriptPromise BluetoothRemoteGATTServer::connect(ScriptState* scriptState) { WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); if (!webbluetooth) return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(NotSupportedError)); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); webbluetooth->connect(device()->id(), device(), new ConnectCallback(device(), resolver)); return promise; }
ScriptPromise BluetoothRemoteGATTServer::getPrimaryService(ScriptState* scriptState, const StringOrUnsignedLong& service, ExceptionState& exceptionState) { WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); String serviceUUID = BluetoothUUID::getService(service, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); webbluetooth->getPrimaryService(device()->id(), serviceUUID, new CallbackPromiseAdapter<BluetoothRemoteGATTService, BluetoothError>(resolver)); return promise; }
ScriptPromise BluetoothGATTService::getCharacteristic(ScriptState* scriptState, const StringOrUnsignedLong& characteristic, ExceptionState& exceptionState) { WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); String characteristicUUID = BluetoothUUID::getCharacteristic(characteristic, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); webbluetooth->getCharacteristic(m_webService->serviceInstanceID, characteristicUUID, new CallbackPromiseAdapter<BluetoothGATTCharacteristic, BluetoothError>(resolver)); return promise; }
ScriptPromise BluetoothRemoteGATTCharacteristic::stopNotifications(ScriptState* scriptState) { #if OS(MACOSX) || OS(ANDROID) // TODO(jlebel): Remove when stopNotifications is implemented. // TODO(scheib): Remove when stopNotifications is implemented. return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError, "stopNotifications is not implemented yet. See https://goo.gl/J6ASzs")); #endif // OS(MACOSX) || OS(ANDROID) WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); webbluetooth->stopNotifications(m_webCharacteristic->characteristicInstanceID, new CallbackPromiseAdapter<void, BluetoothError>(resolver)); return promise; }
// https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetooth-requestdevice ScriptPromise Bluetooth::requestDevice(ScriptState* scriptState, const RequestDeviceOptions& options, ExceptionState& exceptionState) { // TODO(https://crbug.com/584113) Enable Web Bluetooth Experiment. // Restore this logic when re-enabling the experiment: // // By adding the "OriginTrialEnabled" extended binding, we enable the // requestDevice function on all platforms for whitelisted domains. Since we // only support Chrome OS and Android for this experiment we reject any // promises from other platforms unless they have the enable-web-bluetooth // flag on. #if 0 // !OS(CHROMEOS) && !OS(ANDROID) if (!RuntimeEnabledFeatures::webBluetoothEnabled()) { return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError, "Web Bluetooth is not enabled on this platform. To find out how to enable it and the current implementation status visit https://goo.gl/HKa2If")); } #endif // 1. If the incumbent settings object is not a secure context, reject promise with a SecurityError and abort these steps. String errorMessage; if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) { return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(SecurityError, errorMessage)); } // 2. If the algorithm is not allowed to show a popup, reject promise with a SecurityError and abort these steps. if (!UserGestureIndicator::consumeUserGesture()) { return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(SecurityError, "Must be handling a user gesture to show a permission request.")); } WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); if (!webbluetooth) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError)); // 3. In order to convert the arguments from service names and aliases to just UUIDs, do the following substeps: WebRequestDeviceOptions webOptions; convertRequestDeviceOptions(options, webOptions, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); // Subsequent steps are handled in the browser process. ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); webbluetooth->requestDevice(webOptions, new CallbackPromiseAdapter<BluetoothDevice, BluetoothError>(resolver)); return promise; }
// https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetooth-requestdevice ScriptPromise Bluetooth::requestDevice(ScriptState* scriptState, const RequestDeviceOptions& options, ExceptionState& exceptionState) { ExecutionContext* context = scriptState->getExecutionContext(); // 1. If the incumbent settings object is not a secure context, reject promise // with a SecurityError and abort these steps. String errorMessage; if (!context->isSecureContext(errorMessage)) { return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(SecurityError, errorMessage)); } // 2. If the algorithm is not allowed to show a popup, reject promise with a // SecurityError and abort these steps. if (!UserGestureIndicator::consumeUserGesture()) { return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create( SecurityError, "Must be handling a user gesture to show a permission request.")); } WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); if (!webbluetooth) return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(NotSupportedError)); // 3. In order to convert the arguments from service names and aliases to just // UUIDs, do the following substeps: WebRequestDeviceOptions webOptions; convertRequestDeviceOptions(options, webOptions, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); // Subsequent steps are handled in the browser process. ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); webbluetooth->requestDevice(webOptions, new RequestDeviceCallback(this, resolver)); return promise; }
ScriptPromise BluetoothRemoteGATTServer::connect(ScriptState* scriptState) { // TODO(ortuno): Allow connections when the tab is in the background. // This is a short term solution instead of implementing a tab indicator // for bluetooth connections. // https://crbug.com/579746 if (!toDocument(scriptState->getExecutionContext())->page()->isPageVisible()) { return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(SecurityError, kPageHiddenError)); } WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); if (!webbluetooth) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(NotSupportedError)); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); webbluetooth->connect(device()->id(), new ConnectCallback(device(), resolver)); return promise; }
ScriptPromise BluetoothRemoteGATTServer::getPrimaryServicesImpl( ScriptState* scriptState, mojom::blink::WebBluetoothGATTQueryQuantity quantity, String servicesUUID) { if (!connected()) { return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(NetworkError, kGATTServerNotConnected)); } ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); webbluetooth->getPrimaryServices( device()->id(), static_cast<int32_t>(quantity), servicesUUID, new GetPrimaryServicesCallback(device(), quantity, resolver)); return promise; }
ScriptPromise BluetoothRemoteGATTService::getCharacteristicsImpl( ScriptState* scriptState, mojom::blink::WebBluetoothGATTQueryQuantity quantity, String characteristicsUUID) { if (!device()->gatt()->connected()) { return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(NetworkError, kGATTServerNotConnected)); } ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); webbluetooth->getCharacteristics( m_webService->serviceInstanceID, static_cast<int32_t>(quantity), characteristicsUUID, new GetCharacteristicsCallback(this, quantity, resolver)); return promise; }
ScriptPromise BluetoothGATTCharacteristic::writeValue(ScriptState* scriptState, const DOMArrayPiece& value) { WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); // Partial implementation of writeValue algorithm: // https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharacteristic-writevalue // If bytes is more than 512 bytes long (the maximum length of an attribute // value, per Long Attribute Values) return a promise rejected with an // InvalidModificationError and abort. if (value.byteLength() > 512) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidModificationError, "Value can't exceed 512 bytes.")); // Let valueVector be a copy of the bytes held by value. WebVector<uint8_t> valueVector(value.bytes(), value.byteLength()); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); webbluetooth->writeValue(m_webCharacteristic->characteristicInstanceID, valueVector, new CallbackPromiseAdapter<void, BluetoothError>(resolver)); return promise; }
void BluetoothRemoteGATTServer::disconnect(ScriptState* scriptState) { m_connected = false; WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState); webbluetooth->disconnect(device()->id()); }