ScriptPromise Permissions::query(ScriptState* scriptState, const Dictionary& rawPermission) { WebPermissionClient* client = getClient(scriptState->executionContext()); if (!client) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't query 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()))); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebPermissionType type = getPermissionType(scriptState, rawPermission, permission, exceptionState); if (handleNotSupportedPermission(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 PermissionCallback(resolver, type)); return promise; }
ScriptPromise Permissions::request(ScriptState* scriptState, const Vector<Dictionary>& rawPermissions) { WebPermissionClient* client = getClient(scriptState->executionContext()); if (!client) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't query permissions.")); TrackExceptionState exceptionState; OwnPtr<WebVector<WebPermissionType>> permissions = adoptPtr(new WebVector<WebPermissionType>(rawPermissions.size())); for (size_t i = 0; i < rawPermissions.size(); ++i) { const Dictionary& rawPermission = rawPermissions[i]; 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()))); permissions->operator[](i) = getPermissionType(scriptState, rawPermission, permission, exceptionState); } ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); // We need to do this is a separate loop because we can't create the Resolver and Promise untile we are clear of all parsing/type errors. for (size_t i = 0; i < rawPermissions.size(); ++i) { if (handleNotSupportedPermission(scriptState, rawPermissions[i], resolver, (*permissions)[i], exceptionState)) return promise; } client->requestPermissions(*permissions, KURL(KURL(), scriptState->executionContext()->securityOrigin()->toString()), new PermissionsCallback(resolver, permissions.release())); return promise; }
void PermissionStatus::startListening() { ASSERT(!m_listening); WebPermissionClient* client = permissionClient(executionContext()); if (!client) return; m_listening = true; client->startListening(m_type, KURL(KURL(), executionContext()->securityOrigin()->toString()), this); }
void PermissionStatus::stopListening() { if (!m_listening) return; ASSERT(executionContext()); m_listening = false; WebPermissionClient* client = permissionClient(executionContext()); if (!client) return; client->stopListening(this); }
ScriptPromise Permissions::query(ScriptState* scriptState, const ScriptValue& rawPermission) { WebPermissionClient* client = permissionClient(scriptState->executionContext()); if (!client) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't query 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; 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 "userVisible" push is supported for now. if (!pushPermission.userVisible()) { resolver->resolve(PermissionStatus::create(scriptState->executionContext(), WebPermissionStatusDenied, WebPermissionTypePush)); return promise; } type = WebPermissionTypePushNotifications; } else if (name == "midi") { MidiPermissionDescriptor midiPermission = NativeValueTraits<MidiPermissionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState); // Only sysex usage requires a permission for now. if (!midiPermission.sysex()) { resolver->resolve(PermissionStatus::create(scriptState->executionContext(), WebPermissionStatusGranted, WebPermissionTypeMidi)); return promise; } type = WebPermissionTypeMidiSysEx; } else { ASSERT_NOT_REACHED(); type = WebPermissionTypeGeolocation; } // 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)); return promise; }
ScriptPromise Permissions::revoke(ScriptState* scriptState, const Dictionary& rawPermission) { WebPermissionClient* client = getClient(scriptState->getExecutionContext()); if (!client) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't revoke permissions.")); ExceptionState exceptionState(ExceptionState::GetterContext, "revoke", "Permissions", scriptState->context()->Global(), scriptState->isolate()); Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermission, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); client->revokePermission(type.get(), KURL(KURL(), scriptState->getExecutionContext()->getSecurityOrigin()->toString()), new PermissionCallback(resolver, type.get())); return promise; }
ScriptPromise Permissions::query(ScriptState* scriptState, const Dictionary& rawPermission) { WebPermissionClient* client = getClient(scriptState->getExecutionContext()); if (!client) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't query permissions.")); ExceptionState exceptionState(ExceptionState::GetterContext, "query", "Permissions", scriptState->context()->Global(), scriptState->isolate()); Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermission, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->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.get(), KURL(KURL(), scriptState->getExecutionContext()->getSecurityOrigin()->toString()), new PermissionCallback(resolver, type.get())); return promise; }
ScriptPromise Permissions::revoke(ScriptState* scriptState, const Dictionary& rawPermission) { WebPermissionClient* client = getClient(scriptState->executionContext()); if (!client) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't query 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()))); ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebPermissionType type = getPermissionType(scriptState, rawPermission, permission, exceptionState); if (handleNotSupportedPermission(scriptState, rawPermission, resolver, type, exceptionState)) return promise; client->revokePermission(type, KURL(KURL(), scriptState->executionContext()->securityOrigin()->toString()), new PermissionCallback(resolver, type)); return promise; }
ScriptPromise Permissions::requestAll(ScriptState* scriptState, const Vector<Dictionary>& rawPermissions) { WebPermissionClient* client = getClient(scriptState->getExecutionContext()); if (!client) return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "In its current state, the global scope can't request permissions.")); ExceptionState exceptionState(ExceptionState::GetterContext, "request", "Permissions", scriptState->context()->Global(), scriptState->isolate()); OwnPtr<Vector<WebPermissionType>> internalPermissions = adoptPtr(new Vector<WebPermissionType>()); OwnPtr<Vector<int>> callerIndexToInternalIndex = adoptPtr(new Vector<int>(rawPermissions.size())); for (size_t i = 0; i < rawPermissions.size(); ++i) { const Dictionary& rawPermission = rawPermissions[i]; Nullable<WebPermissionType> type = parsePermission(scriptState, rawPermission, exceptionState); if (exceptionState.hadException()) return exceptionState.reject(scriptState); // Only append permissions to the vector that is passed to the client if it is not already // in the vector (i.e. do not duplicate permisison types). int internalIndex; auto it = internalPermissions->find(type.get()); if (it == kNotFound) { internalIndex = internalPermissions->size(); internalPermissions->append(type.get()); } else { internalIndex = it; } callerIndexToInternalIndex->operator[](i) = internalIndex; } ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); ScriptPromise promise = resolver->promise(); WebVector<WebPermissionType> internalWebPermissions = *internalPermissions; client->requestPermissions(internalWebPermissions, KURL(KURL(), scriptState->getExecutionContext()->getSecurityOrigin()->toString()), new PermissionsCallback(resolver, internalPermissions.release(), callerIndexToInternalIndex.release())); return promise; }