1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
|
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/push_messaging/push_messaging_bridge.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_permission_state.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_push_subscription_options_init.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/permissions/permission_utils.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
namespace {
// Error message to explain that the userVisibleOnly flag must be set.
const char kUserVisibleOnlyRequired[] =
"Push subscriptions that don't enable userVisibleOnly are not supported.";
} // namespace
// static
PushMessagingBridge* PushMessagingBridge::From(
ServiceWorkerRegistration* service_worker_registration) {
DCHECK(service_worker_registration);
PushMessagingBridge* bridge =
Supplement<ServiceWorkerRegistration>::From<PushMessagingBridge>(
service_worker_registration);
if (!bridge) {
bridge =
MakeGarbageCollected<PushMessagingBridge>(*service_worker_registration);
Supplement<ServiceWorkerRegistration>::ProvideTo(
*service_worker_registration, bridge);
}
return bridge;
}
PushMessagingBridge::PushMessagingBridge(
ServiceWorkerRegistration& registration)
: Supplement<ServiceWorkerRegistration>(registration),
permission_service_(registration.GetExecutionContext()) {}
PushMessagingBridge::~PushMessagingBridge() = default;
const char PushMessagingBridge::kSupplementName[] = "PushMessagingBridge";
ScriptPromise<V8PermissionState> PushMessagingBridge::GetPermissionState(
ScriptState* script_state,
const PushSubscriptionOptionsInit* options) {
ExecutionContext* context = ExecutionContext::From(script_state);
if (!permission_service_.is_bound()) {
ConnectToPermissionService(
context, permission_service_.BindNewPipeAndPassReceiver(
context->GetTaskRunner(TaskType::kMiscPlatformAPI)));
}
auto* resolver =
MakeGarbageCollected<ScriptPromiseResolver<V8PermissionState>>(
script_state);
auto promise = resolver->Promise();
// The `userVisibleOnly` flag on |options| must be set, as it's intended to be
// a contract with the developer that they will show a notification upon
// receiving a push message. Permission is denied without this setting.
//
// TODO(peter): Would it be better to resolve DENIED rather than rejecting?
if (!options->hasUserVisibleOnly() || !options->userVisibleOnly()) {
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kNotSupportedError, kUserVisibleOnlyRequired));
return promise;
}
permission_service_->HasPermission(
CreatePermissionDescriptor(mojom::blink::PermissionName::NOTIFICATIONS),
WTF::BindOnce(&PushMessagingBridge::DidGetPermissionState,
WrapPersistent(this), WrapPersistent(resolver)));
return promise;
}
void PushMessagingBridge::Trace(Visitor* visitor) const {
visitor->Trace(permission_service_);
Supplement<ServiceWorkerRegistration>::Trace(visitor);
}
void PushMessagingBridge::DidGetPermissionState(
ScriptPromiseResolver<V8PermissionState>* resolver,
mojom::blink::PermissionStatus status) {
resolver->Resolve(ToV8PermissionState(status));
}
} // namespace blink
|