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; |
} |