ScriptPromise Worklet::import(ScriptState* scriptState, const String& url) { KURL scriptURL = executionContext()->completeURL(url); if (!scriptURL.isValid()) { return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(SyntaxError, "'" + url + "' is not a valid URL.")); } // TODO(ikilpatrick): Perform upfront CSP checks once we decide on a // CSP-policy for worklets. ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); m_resolvers.append(resolver); ScriptPromise promise = resolver->promise(); // TODO(ikilpatrick): WorkerScriptLoader will need to be extended to allow // module loading support. For now just fetch a 'classic' script. // NOTE: WorkerScriptLoader may synchronously invoke its callbacks // (resolving the promise) before we return it. m_scriptLoaders.append(WorkerScriptLoader::create()); m_scriptLoaders.last()->loadAsynchronously(*executionContext(), scriptURL, DenyCrossOriginRequests, bind(&Worklet::onResponse, this), bind(&Worklet::onFinished, this, m_scriptLoaders.last().get(), resolver)); return promise; }
ScriptPromise Permissions::query(ScriptState* scriptState, const Dictionary& rawPermission) { WebPermissionClient* client = getClient(scriptState->executionContext()); if (!client) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't query permissions.")); TrackExceptionState exceptionState; PermissionDescriptor permission = NativeValueTraits<PermissionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState); if (exceptionState.hadException()) return ScriptPromise::reject(scriptState, v8::Exception::TypeError(v8String(scriptState->isolate(), exceptionState.message()))); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebPermissionType type = getPermissionType(scriptState, rawPermission, permission, exceptionState); if (handleNotSupportedPermission(scriptState, rawPermission, resolver, type, exceptionState)) return promise; // If the current origin is a file scheme, it will unlikely return a // meaningful value because most APIs are broken on file scheme and no // permission prompt will be shown even if the returned permission will most // likely be "prompt". client->queryPermission(type, KURL(KURL(), scriptState->executionContext()->securityOrigin()->toString()), new PermissionCallback(resolver, type)); return promise; }
ScriptPromise Permissions::requestAll( ScriptState* scriptState, const Vector<Dictionary>& rawPermissions) { ExceptionState exceptionState(scriptState->isolate(), ExceptionState::GetterContext, "Permissions", "requestAll"); Vector<PermissionDescriptorPtr> internalPermissions; Vector<int> callerIndexToInternalIndex; callerIndexToInternalIndex.resize(rawPermissions.size()); for (size_t i = 0; i < rawPermissions.size(); ++i) { const Dictionary& rawPermission = rawPermissions[i]; auto descriptor = parsePermission(scriptState, rawPermission, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); // Only append permissions types that are not already present in the vector. size_t internalIndex = kNotFound; for (size_t j = 0; j < internalPermissions.size(); ++j) { if (internalPermissions[j]->name == descriptor->name) { internalIndex = j; break; } } if (internalIndex == kNotFound) { internalIndex = internalPermissions.size(); internalPermissions.append(std::move(descriptor)); } callerIndexToInternalIndex[i] = internalIndex; } // This must be called after `parsePermission` because the website might // be able to run code. PermissionService* service = getService(scriptState->getExecutionContext()); if (!service) return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(InvalidStateError, "In its current state, the global " "scope can't request permissions.")); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); Vector<PermissionDescriptorPtr> internalPermissionsCopy; internalPermissionsCopy.reserveCapacity(internalPermissions.size()); for (const auto& descriptor : internalPermissions) internalPermissionsCopy.append(descriptor->Clone()); service->RequestPermissions( std::move(internalPermissions), scriptState->getExecutionContext()->getSecurityOrigin(), UserGestureIndicator::processingUserGesture(), convertToBaseCallback( WTF::bind(&Permissions::batchTaskComplete, wrapPersistent(this), wrapPersistent(resolver), WTF::passed(std::move(internalPermissionsCopy)), WTF::passed(std::move(callerIndexToInternalIndex))))); return promise; }
ScriptPromise Permissions::request(ScriptState* scriptState, const Vector<Dictionary>& rawPermissions) { WebPermissionClient* client = getClient(scriptState->executionContext()); if (!client) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't query permissions.")); TrackExceptionState exceptionState; OwnPtr<WebVector<WebPermissionType>> permissions = adoptPtr(new WebVector<WebPermissionType>(rawPermissions.size())); for (size_t i = 0; i < rawPermissions.size(); ++i) { const Dictionary& rawPermission = rawPermissions[i]; PermissionDescriptor permission = NativeValueTraits<PermissionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState); if (exceptionState.hadException()) return ScriptPromise::reject(scriptState, v8::Exception::TypeError(v8String(scriptState->isolate(), exceptionState.message()))); permissions->operator[](i) = getPermissionType(scriptState, rawPermission, permission, exceptionState); } ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); // We need to do this is a separate loop because we can't create the Resolver and Promise untile we are clear of all parsing/type errors. for (size_t i = 0; i < rawPermissions.size(); ++i) { if (handleNotSupportedPermission(scriptState, rawPermissions[i], resolver, (*permissions)[i], exceptionState)) return promise; } client->requestPermissions(*permissions, KURL(KURL(), scriptState->executionContext()->securityOrigin()->toString()), new PermissionsCallback(resolver, permissions.release())); return promise; }
ScriptPromise BudgetService::reserve(ScriptState* scriptState, const AtomicString& operation) { DCHECK(m_service); mojom::blink::BudgetOperationType type = stringToOperationType(operation); if (type == mojom::blink::BudgetOperationType::INVALID_OPERATION) return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(NotSupportedError, "Invalid operation type specified")); String errorMessage; if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(SecurityError, errorMessage)); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); // Call to the BudgetService to place the reservation. RefPtr<SecurityOrigin> origin( scriptState->getExecutionContext()->getSecurityOrigin()); m_service->Reserve(origin, type, convertToBaseCallback(WTF::bind( &BudgetService::gotReservation, wrapPersistent(this), wrapPersistent(resolver)))); return promise; }
ScriptPromise ServiceWorkerRegistrationNotifications::showNotification(ScriptState* scriptState, ServiceWorkerRegistration& serviceWorkerRegistration, const String& title, const NotificationOptions& options, ExceptionState& exceptionState) { ExecutionContext* executionContext = scriptState->executionContext(); // If context object's active worker is null, reject promise with a TypeError exception. if (!serviceWorkerRegistration.active()) return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "No active registration available on the ServiceWorkerRegistration.")); // If permission for notification's origin is not "granted", reject promise with a TypeError exception, and terminate these substeps. if (Notification::checkPermission(executionContext) != WebNotificationPermissionAllowed) return ScriptPromise::reject(scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "No notification permission has been granted for this origin.")); // Validate the developer-provided values to get a WebNotificationData object. WebNotificationData data = createWebNotificationData(executionContext, title, options, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); // Log number of actions developer provided in linear histogram: 0 -> underflow bucket, 1-16 -> distinct buckets, 17+ -> overflow bucket. Platform::current()->histogramEnumeration("Notifications.PersistentNotificationActionCount", options.actions().size(), 17); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebNotificationShowCallbacks* callbacks = new CallbackPromiseAdapter<void, void>(resolver); SecurityOrigin* origin = executionContext->securityOrigin(); WebNotificationManager* notificationManager = Platform::current()->notificationManager(); ASSERT(notificationManager); notificationManager->showPersistent(WebSecurityOrigin(origin), data, serviceWorkerRegistration.webRegistration(), callbacks); return promise; }
ScriptPromise AudioContext::resumeContext(ScriptState* scriptState) { ASSERT(isMainThread()); if (isContextClosed()) { return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create( InvalidAccessError, "cannot resume a closed AudioContext")); } ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); // Restart the destination node to pull on the audio graph. if (destination()) startRendering(); // Save the resolver which will get resolved when the destination node starts pulling on the // graph again. { AutoLocker locker(this); m_resumeResolvers.append(resolver); } return promise; }
ScriptPromise ServiceWorkerClients::openWindow(ScriptState* scriptState, const String& url) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); ExecutionContext* context = scriptState->getExecutionContext(); KURL parsedUrl = KURL(toWorkerGlobalScope(context)->location()->url(), url); if (!parsedUrl.isValid()) { resolver->reject(V8ThrowException::createTypeError( scriptState->isolate(), "'" + url + "' is not a valid URL.")); return promise; } if (!context->getSecurityOrigin()->canDisplay(parsedUrl)) { resolver->reject(V8ThrowException::createTypeError( scriptState->isolate(), "'" + parsedUrl.elidedString() + "' cannot be opened.")); return promise; } if (!context->isWindowInteractionAllowed()) { resolver->reject(DOMException::create(InvalidAccessError, "Not allowed to open a window.")); return promise; } context->consumeWindowInteraction(); ServiceWorkerGlobalScopeClient::from(context)->openWindow( parsedUrl, WTF::makeUnique<NavigateClientCallback>(resolver)); return promise; }
ScriptPromise SyncManager::registerFunction(ScriptState* scriptState, const String& tag) { // TODO(jkarlin): Wait for the registration to become active instead of // rejecting. See crbug.com/542437. if (!m_registration->active()) return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(AbortError, "Registration failed - no active Service Worker")); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); mojom::blink::SyncRegistrationPtr syncRegistration = mojom::blink::SyncRegistration::New(); syncRegistration->id = SyncManager::kUnregisteredSyncID; syncRegistration->tag = tag; syncRegistration->network_state = blink::mojom::BackgroundSyncNetworkState::ONLINE; getBackgroundSyncServicePtr()->Register( std::move(syncRegistration), m_registration->webRegistration()->registrationId(), convertToBaseCallback( WTF::bind(SyncManager::registerCallback, wrapPersistent(resolver)))); return promise; }
ScriptPromise SyncManager::registerFunction(ScriptState* scriptState, ExecutionContext* context, const String& tag) { // TODO(jkarlin): Wait for the registration to become active instead of rejecting. See crbug.com/542437. if (!m_registration->active()) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(AbortError, "Registration failed - no active Service Worker")); if (scriptState->executionContext()->isDocument()) { Document* document = toDocument(scriptState->executionContext()); if (!document->domWindow() || !document->frame()) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "Document is detached from window.")); if (!document->frame()->isMainFrame()) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(AbortError, "Registration failed - not called from a main frame.")); } ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebSyncRegistration* webSyncRegistration = new WebSyncRegistration( WebSyncRegistration::UNREGISTERED_SYNC_ID /* id */, WebSyncRegistration::PeriodicityOneShot, tag, 0 /* minPeriod */, WebSyncRegistration::NetworkStateOnline /* networkState */, WebSyncRegistration::PowerStateAuto /* powerState */ ); backgroundSyncProvider()->registerBackgroundSync(webSyncRegistration, m_registration->webRegistration(), context->isServiceWorkerGlobalScope(), new SyncRegistrationCallbacks(resolver, m_registration)); return promise; }
ScriptPromise ImageCapture::grabFrame(ScriptState* scriptState, ExceptionState& exceptionState) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); if (trackIsInactive(*m_streamTrack)) { resolver->reject(DOMException::create(InvalidStateError, "The associated Track is in an invalid state.")); return promise; } // Create |m_frameGrabber| the first time. if (!m_frameGrabber) m_frameGrabber = adoptPtr(Platform::current()->createImageCaptureFrameGrabber()); if (!m_frameGrabber) { resolver->reject(DOMException::create(UnknownError, "Couldn't create platform resources")); return promise; } // The platform does not know about MediaStreamTrack, so we wrap it up. WebMediaStreamTrack track(m_streamTrack->component()); m_frameGrabber->grabFrame(&track, new CallbackPromiseAdapter<ImageBitmap, void>(resolver)); return promise; }
ScriptPromise Permissions::revoke(ScriptState* scriptState, const Dictionary& rawPermission) { ExceptionState exceptionState(ExceptionState::GetterContext, "revoke", "Permissions", scriptState->context()->Global(), scriptState->isolate()); PermissionDescriptorPtr descriptor = parsePermission(scriptState, rawPermission, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); // This must be called after `parsePermission` because the website might // be able to run code. PermissionService* service = getService(scriptState->getExecutionContext()); if (!service) return ScriptPromise::rejectWithDOMException( scriptState, DOMException::create(InvalidStateError, "In its current state, the global " "scope can't revoke permissions.")); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); PermissionDescriptorPtr descriptorCopy = descriptor->Clone(); service->RevokePermission( std::move(descriptor), scriptState->getExecutionContext()->getSecurityOrigin(), convertToBaseCallback(WTF::bind( &Permissions::taskComplete, wrapPersistent(this), wrapPersistent(resolver), passed(std::move(descriptorCopy))))); return promise; }
ScriptPromise FontFaceSet::load(ScriptState* scriptState, const String& fontString, const String& text) { if (!inActiveDocumentContext()) return ScriptPromise(); Font font; if (!resolveFontStyle(fontString, font)) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); resolver->reject(DOMException::create(SyntaxError, "Could not resolve '" + fontString + "' as a font.")); return promise; } FontFaceCache* fontFaceCache = document()->styleEngine().fontSelector()->fontFaceCache(); FontFaceArray faces; for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next()) { CSSSegmentedFontFace* segmentedFontFace = fontFaceCache->get(font.fontDescription(), f->family()); if (segmentedFontFace) segmentedFontFace->match(text, faces); } RefPtrWillBeRawPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(faces, scriptState); ScriptPromise promise = resolver->promise(); resolver->loadFonts(executionContext()); // After this, resolver->promise() may return null. return promise; }
ScriptPromise MediaSession::deactivate(ScriptState* scriptState) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); m_webMediaSession->deactivate(new CallbackPromiseAdapter<void, void>(resolver)); return promise; }
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; }
ScriptPromise PushManager::getSubscription(ScriptState* scriptState) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); pushProvider()->getSubscription( m_registration->webRegistration(), WTF::makeUnique<PushSubscriptionCallbacks>(resolver, m_registration)); return promise; }
ScriptPromise SyncManager::getTags(ScriptState* scriptState) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); backgroundSyncProvider()->getRegistrations(WebSyncRegistration::PeriodicityOneShot, m_registration->webRegistration(), new SyncGetRegistrationsCallbacks(resolver, m_registration)); return promise; }
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 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 SyncManager::getTags(ScriptState* scriptState) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); getBackgroundSyncServicePtr()->GetRegistrations( m_registration->webRegistration()->registrationId(), convertToBaseCallback(WTF::bind(&SyncManager::getRegistrationsCallback, wrapPersistent(resolver)))); return promise; }
ScriptPromise ReadableStreamReader::cancel(ScriptState* scriptState, ScriptValue reason) { if (isActive()) return m_stream->cancelInternal(scriptState, reason); // A method should return a different promise on each call. ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); resolver->resolve(closed(scriptState).v8Value()); return promise; }
ScriptPromise PushSubscription::unsubscribe(ScriptState* scriptState) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebPushProvider* webPushProvider = Platform::current()->pushProvider(); ASSERT(webPushProvider); webPushProvider->unsubscribe(m_serviceWorkerRegistration->webRegistration(), new CallbackPromiseAdapter<bool, PushError>(resolver)); return promise; }
ScriptPromise ServiceWorkerRegistrationNotifications::showNotification( ScriptState* scriptState, ServiceWorkerRegistration& registration, const String& title, const NotificationOptions& options, ExceptionState& exceptionState) { ExecutionContext* executionContext = scriptState->getExecutionContext(); // If context object's active worker is null, reject the promise with a // TypeError exception. if (!registration.active()) return ScriptPromise::reject( scriptState, V8ThrowException::createTypeError(scriptState->isolate(), "No active registration available on " "the ServiceWorkerRegistration.")); // If permission for notification's origin is not "granted", reject the // promise with a TypeError exception, and terminate these substeps. if (NotificationManager::from(executionContext) ->permissionStatus(executionContext) != mojom::blink::PermissionStatus::GRANTED) return ScriptPromise::reject( scriptState, V8ThrowException::createTypeError( scriptState->isolate(), "No notification permission has been granted for this origin.")); // Validate the developer-provided options to get the WebNotificationData. WebNotificationData data = createWebNotificationData(executionContext, title, options, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); // Log number of actions developer provided in linear histogram: // 0 -> underflow bucket, // 1-16 -> distinct buckets, // 17+ -> overflow bucket. DEFINE_THREAD_SAFE_STATIC_LOCAL( EnumerationHistogram, notificationCountHistogram, new EnumerationHistogram( "Notifications.PersistentNotificationActionCount", 17)); notificationCountHistogram.count(options.actions().size()); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); std::unique_ptr<WebNotificationShowCallbacks> callbacks = WTF::wrapUnique(new CallbackPromiseAdapter<void, void>(resolver)); ServiceWorkerRegistrationNotifications::from(executionContext, registration) .prepareShow(data, std::move(callbacks)); return promise; }
ScriptPromise ImageBitmapSource::fulfillImageBitmap(ScriptState* scriptState, ImageBitmap* imageBitmap) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); if (imageBitmap && imageBitmap->bitmapImage()) { resolver->resolve(imageBitmap); } else { resolver->reject( ScriptValue(scriptState, v8::Null(scriptState->isolate()))); } return promise; }
ScriptPromise SyncManager::permissionState(ScriptState* scriptState) { if (!m_registration->active()) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(AbortError, "Operation failed - no active Service Worker")); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); backgroundSyncProvider()->getPermissionStatus(WebSyncRegistration::PeriodicityOneShot, m_registration->webRegistration(), new SyncGetPermissionStatusCallbacks(resolver, m_registration)); return promise; }
ScriptPromise ServiceWorkerRegistrationNotifications::getNotifications(ScriptState* scriptState, ServiceWorkerRegistration& serviceWorkerRegistration, const GetNotificationOptions& options) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebNotificationGetCallbacks* callbacks = new CallbackPromiseAdapter<NotificationArray, void>(resolver); WebNotificationManager* notificationManager = Platform::current()->notificationManager(); ASSERT(notificationManager); notificationManager->getNotifications(options.tag(), serviceWorkerRegistration.webRegistration(), callbacks); return promise; }
ScriptPromise PresentationRequest::getAvailability(ScriptState* scriptState) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebPresentationClient* client = presentationClient(getExecutionContext()); if (!client) { resolver->reject(DOMException::create(InvalidStateError, "The object is no longer associated to a frame.")); return promise; } client->getAvailability(m_url.getString(), new PresentationAvailabilityCallbacks(resolver, m_url)); return promise; }
ScriptPromise ServiceWorkerGlobalScope::skipWaiting(ScriptState* scriptState) { ExecutionContext* executionContext = scriptState->executionContext(); // FIXME: short-term fix, see details at: https://codereview.chromium.org/535193002/. if (!executionContext) return ScriptPromise(); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); ServiceWorkerGlobalScopeClient::from(executionContext)->skipWaiting(new SkipWaitingCallback(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 PresentationRequest::reconnect(ScriptState* scriptState, const String& id) { ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebPresentationClient* client = presentationClient(getExecutionContext()); if (!client) { resolver->reject(DOMException::create(InvalidStateError, "The PresentationRequest is no longer associated to a frame.")); return promise; } client->joinSession(m_url.getString(), id, new PresentationConnectionCallbacks(resolver, this)); return promise; }