| Index: Source/modules/permissions/Permissions.cpp
|
| diff --git a/Source/modules/permissions/Permissions.cpp b/Source/modules/permissions/Permissions.cpp
|
| index 92e662af2b8ece2bfbb04555d3e97944c211b169..ad99d5919370ac6a17ec30974e13c1c53bb627b7 100644
|
| --- a/Source/modules/permissions/Permissions.cpp
|
| +++ b/Source/modules/permissions/Permissions.cpp
|
| @@ -13,15 +13,58 @@
|
| #include "core/dom/DOMException.h"
|
| #include "core/dom/Document.h"
|
| #include "core/dom/ExceptionCode.h"
|
| +#include "modules/permissions/PermissionCallback.h"
|
| #include "modules/permissions/PermissionController.h"
|
| #include "modules/permissions/PermissionDescriptor.h"
|
| -#include "modules/permissions/PermissionQueryCallback.h"
|
| #include "modules/permissions/PermissionStatus.h"
|
| #include "public/platform/Platform.h"
|
| #include "public/platform/modules/permissions/WebPermissionClient.h"
|
|
|
| namespace blink {
|
|
|
| +namespace {
|
| +
|
| +// Here we handle some common permission patterns to prevent propogation up to the content layer
|
| +// Examples of behaviours which would go here are rejecting unsupported permissions, accepting
|
| +// permissions which are always granted or always denied according to the spec etc.
|
| +bool handleDefaultBehaviour(
|
| + ScriptState* scriptState, const ScriptValue& rawPermission, PassRefPtr<ScriptPromiseResolver> resolver, WebPermissionType type, TrackExceptionState& exceptionState)
|
| +{
|
| + if (type == WebPermissionTypePushNotifications) {
|
| + PushPermissionDescriptor pushPermission = NativeValueTraits<PushPermissionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState);
|
| + // Only "userVisibleOnly" push is supported for now.
|
| + if (!pushPermission.userVisibleOnly()) {
|
| + resolver->reject(DOMException::create(NotSupportedError, "Push Permission without userVisibleOnly:true isn't supported yet."));
|
| + return true;
|
| + }
|
| + } else if (type == WebPermissionTypeMidiSysEx) {
|
| + MidiPermissionDescriptor midiPermission = NativeValueTraits<MidiPermissionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState);
|
| + // Only sysex usage requires a permission, otherwise it is granted.
|
| + if (!midiPermission.sysex()) {
|
| + resolver->resolve(PermissionStatus::create(scriptState->executionContext(), WebPermissionStatusGranted, WebPermissionTypeMidi));
|
| + return true;
|
| + }
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +WebPermissionType convertPermissionStringToType(const String& name)
|
| +{
|
| + if (name == "geolocation")
|
| + return WebPermissionTypeGeolocation;
|
| + if (name == "notifications")
|
| + return WebPermissionTypeNotifications;
|
| + if (name == "push")
|
| + return WebPermissionTypePushNotifications;
|
| + if (name == "midi")
|
| + return WebPermissionTypeMidiSysEx;
|
| +
|
| + ASSERT_NOT_REACHED();
|
| + return WebPermissionTypeGeolocation;
|
| +}
|
| +
|
| +} // anonymous namespace
|
| +
|
| // static
|
| WebPermissionClient* Permissions::getClient(ExecutionContext* executionContext)
|
| {
|
| @@ -52,37 +95,41 @@ ScriptPromise Permissions::query(ScriptState* scriptState, const ScriptValue& ra
|
| ScriptPromise promise = resolver->promise();
|
|
|
| String name = permission.name();
|
| - WebPermissionType type;
|
| - if (name == "geolocation") {
|
| - type = WebPermissionTypeGeolocation;
|
| - } else if (name == "notifications") {
|
| - type = WebPermissionTypeNotifications;
|
| - } else if (name == "push") {
|
| - PushPermissionDescriptor pushPermission = NativeValueTraits<PushPermissionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState);
|
| - // Only "userVisibleOnly" push is supported for now.
|
| - if (!pushPermission.userVisibleOnly()) {
|
| - resolver->reject(DOMException::create(NotSupportedError, "Push Permission without userVisibleOnly:true isn't supported yet."));
|
| - return promise;
|
| - }
|
| - type = WebPermissionTypePushNotifications;
|
| - } else if (name == "midi") {
|
| - MidiPermissionDescriptor midiPermission = NativeValueTraits<MidiPermissionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState);
|
| - // Only sysex usage requires a permission, otherwise it is granted.
|
| - if (!midiPermission.sysex()) {
|
| - resolver->resolve(PermissionStatus::create(scriptState->executionContext(), WebPermissionStatusGranted, WebPermissionTypeMidi));
|
| - return promise;
|
| - }
|
| - type = WebPermissionTypeMidiSysEx;
|
| - } else {
|
| - ASSERT_NOT_REACHED();
|
| - type = WebPermissionTypeGeolocation;
|
| - }
|
| + WebPermissionType type = convertPermissionStringToType(name);
|
| +
|
| + if (handleDefaultBehaviour(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 PermissionQueryCallback(resolver, type));
|
| + client->queryPermission(type, KURL(KURL(), scriptState->executionContext()->securityOrigin()->toString()), new PermissionCallback(resolver, type));
|
| + return promise;
|
| +}
|
| +
|
| +ScriptPromise Permissions::revoke(ScriptState* scriptState, const ScriptValue& rawPermission)
|
| +{
|
| + WebPermissionClient* client = getClient(scriptState->executionContext());
|
| + if (!client)
|
| + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't revoke 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())));
|
| +
|
| + RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
|
| + ScriptPromise promise = resolver->promise();
|
| +
|
| + String name = permission.name();
|
| + WebPermissionType type = convertPermissionStringToType(name);
|
| +
|
| + if (handleDefaultBehaviour(scriptState, rawPermission, resolver, type, exceptionState))
|
| + return promise;
|
| +
|
| + client->revokePermission(type, KURL(KURL(), scriptState->executionContext()->securityOrigin()->toString()), new PermissionCallback(resolver, type));
|
| return promise;
|
| }
|
|
|
|
|