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 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; }
Notification* Notification::create(ExecutionContext* context, const String& title, const NotificationOptions& options, ExceptionState& exceptionState) { // The Notification constructor may be disabled through a runtime feature when // the platform does not support non-persistent notifications. if (!RuntimeEnabledFeatures::notificationConstructorEnabled()) { exceptionState.throwTypeError( "Illegal constructor. Use ServiceWorkerRegistration.showNotification() " "instead."); return nullptr; } // The Notification constructor may not be used in Service Worker contexts. if (context->isServiceWorkerGlobalScope()) { exceptionState.throwTypeError("Illegal constructor."); return nullptr; } if (!options.actions().isEmpty()) { exceptionState.throwTypeError( "Actions are only supported for persistent notifications shown using " "ServiceWorkerRegistration.showNotification()."); return nullptr; } String insecureOriginMessage; if (context->isSecureContext(insecureOriginMessage)) { UseCounter::count(context, UseCounter::NotificationSecureOrigin); if (context->isDocument()) UseCounter::countCrossOriginIframe( *toDocument(context), UseCounter::NotificationAPISecureOriginIframe); } else { UseCounter::count(context, UseCounter::NotificationInsecureOrigin); if (context->isDocument()) UseCounter::countCrossOriginIframe( *toDocument(context), UseCounter::NotificationAPIInsecureOriginIframe); } WebNotificationData data = createWebNotificationData(context, title, options, exceptionState); if (exceptionState.hadException()) return nullptr; Notification* notification = new Notification(context, Type::NonPersistent, data); notification->schedulePrepareShow(); notification->suspendIfNeeded(); return notification; }
Notification* Notification::create(ExecutionContext* context, const String& title, const NotificationOptions& options, ExceptionState& exceptionState) { // The Web Notification constructor may be disabled through a runtime feature. The // behavior of the constructor is changing, but not completely agreed upon yet. if (!RuntimeEnabledFeatures::notificationConstructorEnabled()) { exceptionState.throwTypeError("Illegal constructor. Use ServiceWorkerRegistration.showNotification() instead."); return nullptr; } // The Web Notification constructor may not be used in Service Worker contexts. if (context->isServiceWorkerGlobalScope()) { exceptionState.throwTypeError("Illegal constructor."); return nullptr; } if (!options.actions().isEmpty()) { exceptionState.throwTypeError("Actions are only supported for persistent notifications shown using ServiceWorkerRegistration.showNotification()."); return nullptr; } String insecureOriginMessage; UseCounter::Feature feature = context->isSecureContext(insecureOriginMessage) ? UseCounter::NotificationSecureOrigin : UseCounter::NotificationInsecureOrigin; UseCounter::count(context, feature); WebNotificationData data = createWebNotificationData(context, title, options, exceptionState); if (exceptionState.hadException()) return nullptr; Notification* notification = new Notification(context, data); notification->scheduleShow(); notification->suspendIfNeeded(); return notification; }