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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}