| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "modules/permissions/Permissions.h" | 5 #include "modules/permissions/Permissions.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/Dictionary.h" | 7 #include "bindings/core/v8/Dictionary.h" |
| 8 #include "bindings/core/v8/Nullable.h" | 8 #include "bindings/core/v8/Nullable.h" |
| 9 #include "bindings/core/v8/ScriptPromise.h" | 9 #include "bindings/core/v8/ScriptPromise.h" |
| 10 #include "bindings/core/v8/ScriptPromiseResolver.h" | 10 #include "bindings/core/v8/ScriptPromiseResolver.h" |
| 11 #include "bindings/modules/v8/V8MidiPermissionDescriptor.h" | 11 #include "bindings/modules/v8/V8MidiPermissionDescriptor.h" |
| 12 #include "bindings/modules/v8/V8PermissionDescriptor.h" | 12 #include "bindings/modules/v8/V8PermissionDescriptor.h" |
| 13 #include "bindings/modules/v8/V8PushPermissionDescriptor.h" | 13 #include "bindings/modules/v8/V8PushPermissionDescriptor.h" |
| 14 #include "core/dom/DOMException.h" | 14 #include "core/dom/DOMException.h" |
| 15 #include "core/dom/Document.h" | 15 #include "core/dom/Document.h" |
| 16 #include "core/dom/ExceptionCode.h" | 16 #include "core/dom/ExceptionCode.h" |
| 17 #include "core/frame/LocalFrame.h" | 17 #include "core/frame/LocalFrame.h" |
| 18 #include "modules/permissions/PermissionDescriptor.h" | 18 #include "modules/permissions/PermissionDescriptor.h" |
| 19 #include "modules/permissions/PermissionStatus.h" | 19 #include "modules/permissions/PermissionStatus.h" |
| 20 #include "modules/permissions/PermissionUtils.h" |
| 20 #include "platform/UserGestureIndicator.h" | 21 #include "platform/UserGestureIndicator.h" |
| 21 #include "public/platform/InterfaceProvider.h" | |
| 22 #include "public/platform/Platform.h" | 22 #include "public/platform/Platform.h" |
| 23 #include "wtf/Functional.h" | 23 #include "wtf/Functional.h" |
| 24 #include "wtf/NotFound.h" | 24 #include "wtf/NotFound.h" |
| 25 #include "wtf/PtrUtil.h" | 25 #include "wtf/PtrUtil.h" |
| 26 #include "wtf/Vector.h" | 26 #include "wtf/Vector.h" |
| 27 #include <memory> | 27 #include <memory> |
| 28 | 28 |
| 29 namespace blink { | 29 namespace blink { |
| 30 | 30 |
| 31 using mojom::blink::PermissionDescriptorPtr; |
| 31 using mojom::blink::PermissionName; | 32 using mojom::blink::PermissionName; |
| 32 using mojom::blink::PermissionService; | 33 using mojom::blink::PermissionService; |
| 33 | 34 |
| 34 namespace { | 35 namespace { |
| 35 | 36 |
| 37 // Parses the raw permission dictionary and returns the Mojo |
| 38 // PermissionDescriptor if parsing was successful. If an exception occurs, it |
| 39 // will be stored in |exceptionState| and null will be returned. Therefore, the |
| 40 // |exceptionState| should be checked before attempting to use the returned |
| 41 // permission as the non-null assert will be fired otherwise. |
| 42 // |
| 36 // Websites will be able to run code when `name()` is called, changing the | 43 // Websites will be able to run code when `name()` is called, changing the |
| 37 // current context. The caller should make sure that no assumption is made | 44 // current context. The caller should make sure that no assumption is made |
| 38 // after this has been called. | 45 // after this has been called. |
| 39 PermissionName getPermissionName(ScriptState* scriptState, | 46 PermissionDescriptorPtr parsePermission(ScriptState* scriptState, |
| 40 const Dictionary& rawPermission, | 47 const Dictionary rawPermission, |
| 41 const PermissionDescriptor& permission, | 48 ExceptionState& exceptionState) { |
| 42 ExceptionState& exceptionState) { | |
| 43 const String& name = permission.name(); | |
| 44 if (name == "geolocation") | |
| 45 return PermissionName::GEOLOCATION; | |
| 46 if (name == "notifications") | |
| 47 return PermissionName::NOTIFICATIONS; | |
| 48 if (name == "push") | |
| 49 return PermissionName::PUSH_NOTIFICATIONS; | |
| 50 if (name == "midi") { | |
| 51 MidiPermissionDescriptor midiPermission = | |
| 52 NativeValueTraits<MidiPermissionDescriptor>::nativeValue( | |
| 53 scriptState->isolate(), rawPermission.v8Value(), exceptionState); | |
| 54 return midiPermission.sysex() ? PermissionName::MIDI_SYSEX | |
| 55 : PermissionName::MIDI; | |
| 56 } | |
| 57 if (name == "background-sync") | |
| 58 return PermissionName::BACKGROUND_SYNC; | |
| 59 | |
| 60 ASSERT_NOT_REACHED(); | |
| 61 return PermissionName::GEOLOCATION; | |
| 62 } | |
| 63 | |
| 64 // Parses the raw permission dictionary and returns the PermissionType if | |
| 65 // parsing was successful. If an exception occurs, it will be stored in | |
| 66 // |exceptionState| and null will be returned. Therefore, the |exceptionState| | |
| 67 // should be checked before attempting to use the returned permission as the | |
| 68 // non-null assert will be fired otherwise. | |
| 69 Nullable<PermissionName> parsePermission(ScriptState* scriptState, | |
| 70 const Dictionary rawPermission, | |
| 71 ExceptionState& exceptionState) { | |
| 72 PermissionDescriptor permission = | 49 PermissionDescriptor permission = |
| 73 NativeValueTraits<PermissionDescriptor>::nativeValue( | 50 NativeValueTraits<PermissionDescriptor>::nativeValue( |
| 74 scriptState->isolate(), rawPermission.v8Value(), exceptionState); | 51 scriptState->isolate(), rawPermission.v8Value(), exceptionState); |
| 75 | 52 |
| 76 if (exceptionState.hadException()) { | 53 if (exceptionState.hadException()) { |
| 77 exceptionState.throwTypeError(exceptionState.message()); | 54 exceptionState.throwTypeError(exceptionState.message()); |
| 78 return Nullable<PermissionName>(); | 55 return nullptr; |
| 79 } | 56 } |
| 80 | 57 |
| 81 PermissionName name = | 58 const String& name = permission.name(); |
| 82 getPermissionName(scriptState, rawPermission, permission, exceptionState); | 59 if (name == "geolocation") |
| 83 if (exceptionState.hadException()) { | 60 return createPermissionDescriptor(PermissionName::GEOLOCATION); |
| 84 exceptionState.throwTypeError(exceptionState.message()); | 61 if (name == "notifications") |
| 85 return Nullable<PermissionName>(); | 62 return createPermissionDescriptor(PermissionName::NOTIFICATIONS); |
| 86 } | 63 if (name == "push") { |
| 87 | |
| 88 // Here we reject any permissions which are not yet supported by Blink. | |
| 89 if (name == PermissionName::PUSH_NOTIFICATIONS) { | |
| 90 PushPermissionDescriptor pushPermission = | 64 PushPermissionDescriptor pushPermission = |
| 91 NativeValueTraits<PushPermissionDescriptor>::nativeValue( | 65 NativeValueTraits<PushPermissionDescriptor>::nativeValue( |
| 92 scriptState->isolate(), rawPermission.v8Value(), exceptionState); | 66 scriptState->isolate(), rawPermission.v8Value(), exceptionState); |
| 93 if (exceptionState.hadException()) { | 67 if (exceptionState.hadException()) { |
| 94 exceptionState.throwTypeError(exceptionState.message()); | 68 exceptionState.throwTypeError(exceptionState.message()); |
| 95 return Nullable<PermissionName>(); | 69 return nullptr; |
| 96 } | 70 } |
| 97 | 71 |
| 98 // Only "userVisibleOnly" push is supported for now. | 72 // Only "userVisibleOnly" push is supported for now. |
| 99 if (!pushPermission.userVisibleOnly()) { | 73 if (!pushPermission.userVisibleOnly()) { |
| 100 exceptionState.throwDOMException( | 74 exceptionState.throwDOMException( |
| 101 NotSupportedError, | 75 NotSupportedError, |
| 102 "Push Permission without userVisibleOnly:true isn't supported yet."); | 76 "Push Permission without userVisibleOnly:true isn't supported yet."); |
| 103 return Nullable<PermissionName>(); | 77 return nullptr; |
| 104 } | 78 } |
| 79 |
| 80 return createPermissionDescriptor(PermissionName::PUSH_NOTIFICATIONS); |
| 105 } | 81 } |
| 82 if (name == "midi") { |
| 83 MidiPermissionDescriptor midiPermission = |
| 84 NativeValueTraits<MidiPermissionDescriptor>::nativeValue( |
| 85 scriptState->isolate(), rawPermission.v8Value(), exceptionState); |
| 86 return createMidiPermissionDescriptor(midiPermission.sysex()); |
| 87 } |
| 88 if (name == "background-sync") |
| 89 return createPermissionDescriptor(PermissionName::BACKGROUND_SYNC); |
| 106 | 90 |
| 107 return Nullable<PermissionName>(name); | 91 return nullptr; |
| 108 } | 92 } |
| 109 | 93 |
| 110 } // anonymous namespace | 94 } // anonymous namespace |
| 111 | 95 |
| 112 // static | |
| 113 bool Permissions::connectToService( | |
| 114 ExecutionContext* executionContext, | |
| 115 mojom::blink::PermissionServiceRequest request) { | |
| 116 InterfaceProvider* interfaceProvider = nullptr; | |
| 117 if (executionContext->isDocument()) { | |
| 118 Document* document = toDocument(executionContext); | |
| 119 if (document->frame()) | |
| 120 interfaceProvider = document->frame()->interfaceProvider(); | |
| 121 } else { | |
| 122 interfaceProvider = Platform::current()->interfaceProvider(); | |
| 123 } | |
| 124 | |
| 125 if (interfaceProvider) | |
| 126 interfaceProvider->getInterface(std::move(request)); | |
| 127 return interfaceProvider; | |
| 128 } | |
| 129 | |
| 130 ScriptPromise Permissions::query(ScriptState* scriptState, | 96 ScriptPromise Permissions::query(ScriptState* scriptState, |
| 131 const Dictionary& rawPermission) { | 97 const Dictionary& rawPermission) { |
| 132 ExceptionState exceptionState(ExceptionState::GetterContext, "query", | 98 ExceptionState exceptionState(ExceptionState::GetterContext, "query", |
| 133 "Permissions", scriptState->context()->Global(), | 99 "Permissions", scriptState->context()->Global(), |
| 134 scriptState->isolate()); | 100 scriptState->isolate()); |
| 135 Nullable<PermissionName> name = | 101 PermissionDescriptorPtr descriptor = |
| 136 parsePermission(scriptState, rawPermission, exceptionState); | 102 parsePermission(scriptState, rawPermission, exceptionState); |
| 137 if (exceptionState.hadException()) | 103 if (exceptionState.hadException()) |
| 138 return exceptionState.reject(scriptState); | 104 return exceptionState.reject(scriptState); |
| 139 | 105 |
| 140 // This must be called after `parsePermission` because the website might | 106 // This must be called after `parsePermission` because the website might |
| 141 // be able to run code. | 107 // be able to run code. |
| 142 PermissionService* service = getService(scriptState->getExecutionContext()); | 108 PermissionService* service = getService(scriptState->getExecutionContext()); |
| 143 if (!service) | 109 if (!service) |
| 144 return ScriptPromise::rejectWithDOMException( | 110 return ScriptPromise::rejectWithDOMException( |
| 145 scriptState, | 111 scriptState, |
| 146 DOMException::create( | 112 DOMException::create( |
| 147 InvalidStateError, | 113 InvalidStateError, |
| 148 "In its current state, the global scope can't query permissions.")); | 114 "In its current state, the global scope can't query permissions.")); |
| 149 | 115 |
| 150 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 116 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| 151 ScriptPromise promise = resolver->promise(); | 117 ScriptPromise promise = resolver->promise(); |
| 152 | 118 |
| 153 // If the current origin is a file scheme, it will unlikely return a | 119 // If the current origin is a file scheme, it will unlikely return a |
| 154 // meaningful value because most APIs are broken on file scheme and no | 120 // meaningful value because most APIs are broken on file scheme and no |
| 155 // permission prompt will be shown even if the returned permission will most | 121 // permission prompt will be shown even if the returned permission will most |
| 156 // likely be "prompt". | 122 // likely be "prompt". |
| 123 PermissionDescriptorPtr descriptorCopy = descriptor->Clone(); |
| 157 service->HasPermission( | 124 service->HasPermission( |
| 158 name.get(), scriptState->getExecutionContext()->getSecurityOrigin(), | 125 std::move(descriptor), |
| 159 convertToBaseCallback(WTF::bind(&Permissions::taskComplete, | 126 scriptState->getExecutionContext()->getSecurityOrigin(), |
| 160 wrapPersistent(this), | 127 convertToBaseCallback(WTF::bind( |
| 161 wrapPersistent(resolver), name.get()))); | 128 &Permissions::taskComplete, wrapPersistent(this), |
| 129 wrapPersistent(resolver), passed(std::move(descriptorCopy))))); |
| 162 return promise; | 130 return promise; |
| 163 } | 131 } |
| 164 | 132 |
| 165 ScriptPromise Permissions::request(ScriptState* scriptState, | 133 ScriptPromise Permissions::request(ScriptState* scriptState, |
| 166 const Dictionary& rawPermission) { | 134 const Dictionary& rawPermission) { |
| 167 ExceptionState exceptionState(ExceptionState::GetterContext, "request", | 135 ExceptionState exceptionState(ExceptionState::GetterContext, "request", |
| 168 "Permissions", scriptState->context()->Global(), | 136 "Permissions", scriptState->context()->Global(), |
| 169 scriptState->isolate()); | 137 scriptState->isolate()); |
| 170 Nullable<PermissionName> name = | 138 PermissionDescriptorPtr descriptor = |
| 171 parsePermission(scriptState, rawPermission, exceptionState); | 139 parsePermission(scriptState, rawPermission, exceptionState); |
| 172 if (exceptionState.hadException()) | 140 if (exceptionState.hadException()) |
| 173 return exceptionState.reject(scriptState); | 141 return exceptionState.reject(scriptState); |
| 174 | 142 |
| 175 // This must be called after `parsePermission` because the website might | 143 // This must be called after `parsePermission` because the website might |
| 176 // be able to run code. | 144 // be able to run code. |
| 177 PermissionService* service = getService(scriptState->getExecutionContext()); | 145 PermissionService* service = getService(scriptState->getExecutionContext()); |
| 178 if (!service) | 146 if (!service) |
| 179 return ScriptPromise::rejectWithDOMException( | 147 return ScriptPromise::rejectWithDOMException( |
| 180 scriptState, DOMException::create(InvalidStateError, | 148 scriptState, DOMException::create(InvalidStateError, |
| 181 "In its current state, the global " | 149 "In its current state, the global " |
| 182 "scope can't request permissions.")); | 150 "scope can't request permissions.")); |
| 183 | 151 |
| 184 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 152 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| 185 ScriptPromise promise = resolver->promise(); | 153 ScriptPromise promise = resolver->promise(); |
| 186 | 154 |
| 155 PermissionDescriptorPtr descriptorCopy = descriptor->Clone(); |
| 187 service->RequestPermission( | 156 service->RequestPermission( |
| 188 name.get(), scriptState->getExecutionContext()->getSecurityOrigin(), | 157 std::move(descriptor), |
| 158 scriptState->getExecutionContext()->getSecurityOrigin(), |
| 189 UserGestureIndicator::processingUserGesture(), | 159 UserGestureIndicator::processingUserGesture(), |
| 190 convertToBaseCallback(WTF::bind(&Permissions::taskComplete, | 160 convertToBaseCallback(WTF::bind( |
| 191 wrapPersistent(this), | 161 &Permissions::taskComplete, wrapPersistent(this), |
| 192 wrapPersistent(resolver), name.get()))); | 162 wrapPersistent(resolver), passed(std::move(descriptorCopy))))); |
| 193 return promise; | 163 return promise; |
| 194 } | 164 } |
| 195 | 165 |
| 196 ScriptPromise Permissions::revoke(ScriptState* scriptState, | 166 ScriptPromise Permissions::revoke(ScriptState* scriptState, |
| 197 const Dictionary& rawPermission) { | 167 const Dictionary& rawPermission) { |
| 198 ExceptionState exceptionState(ExceptionState::GetterContext, "revoke", | 168 ExceptionState exceptionState(ExceptionState::GetterContext, "revoke", |
| 199 "Permissions", scriptState->context()->Global(), | 169 "Permissions", scriptState->context()->Global(), |
| 200 scriptState->isolate()); | 170 scriptState->isolate()); |
| 201 Nullable<PermissionName> name = | 171 PermissionDescriptorPtr descriptor = |
| 202 parsePermission(scriptState, rawPermission, exceptionState); | 172 parsePermission(scriptState, rawPermission, exceptionState); |
| 203 if (exceptionState.hadException()) | 173 if (exceptionState.hadException()) |
| 204 return exceptionState.reject(scriptState); | 174 return exceptionState.reject(scriptState); |
| 205 | 175 |
| 206 // This must be called after `parsePermission` because the website might | 176 // This must be called after `parsePermission` because the website might |
| 207 // be able to run code. | 177 // be able to run code. |
| 208 PermissionService* service = getService(scriptState->getExecutionContext()); | 178 PermissionService* service = getService(scriptState->getExecutionContext()); |
| 209 if (!service) | 179 if (!service) |
| 210 return ScriptPromise::rejectWithDOMException( | 180 return ScriptPromise::rejectWithDOMException( |
| 211 scriptState, DOMException::create(InvalidStateError, | 181 scriptState, DOMException::create(InvalidStateError, |
| 212 "In its current state, the global " | 182 "In its current state, the global " |
| 213 "scope can't revoke permissions.")); | 183 "scope can't revoke permissions.")); |
| 214 | 184 |
| 215 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 185 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| 216 ScriptPromise promise = resolver->promise(); | 186 ScriptPromise promise = resolver->promise(); |
| 217 | 187 |
| 188 PermissionDescriptorPtr descriptorCopy = descriptor->Clone(); |
| 218 service->RevokePermission( | 189 service->RevokePermission( |
| 219 name.get(), scriptState->getExecutionContext()->getSecurityOrigin(), | 190 std::move(descriptor), |
| 220 convertToBaseCallback(WTF::bind(&Permissions::taskComplete, | 191 scriptState->getExecutionContext()->getSecurityOrigin(), |
| 221 wrapPersistent(this), | 192 convertToBaseCallback(WTF::bind( |
| 222 wrapPersistent(resolver), name.get()))); | 193 &Permissions::taskComplete, wrapPersistent(this), |
| 194 wrapPersistent(resolver), passed(std::move(descriptorCopy))))); |
| 223 return promise; | 195 return promise; |
| 224 } | 196 } |
| 225 | 197 |
| 226 ScriptPromise Permissions::requestAll( | 198 ScriptPromise Permissions::requestAll( |
| 227 ScriptState* scriptState, | 199 ScriptState* scriptState, |
| 228 const Vector<Dictionary>& rawPermissions) { | 200 const Vector<Dictionary>& rawPermissions) { |
| 229 ExceptionState exceptionState(ExceptionState::GetterContext, "request", | 201 ExceptionState exceptionState(ExceptionState::GetterContext, "request", |
| 230 "Permissions", scriptState->context()->Global(), | 202 "Permissions", scriptState->context()->Global(), |
| 231 scriptState->isolate()); | 203 scriptState->isolate()); |
| 232 Vector<PermissionName> internalPermissions; | 204 Vector<PermissionDescriptorPtr> internalPermissions; |
| 233 Vector<int> callerIndexToInternalIndex; | 205 Vector<int> callerIndexToInternalIndex; |
| 234 callerIndexToInternalIndex.resize(rawPermissions.size()); | 206 callerIndexToInternalIndex.resize(rawPermissions.size()); |
| 235 for (size_t i = 0; i < rawPermissions.size(); ++i) { | 207 for (size_t i = 0; i < rawPermissions.size(); ++i) { |
| 236 const Dictionary& rawPermission = rawPermissions[i]; | 208 const Dictionary& rawPermission = rawPermissions[i]; |
| 237 | 209 |
| 238 Nullable<PermissionName> name = | 210 auto descriptor = |
| 239 parsePermission(scriptState, rawPermission, exceptionState); | 211 parsePermission(scriptState, rawPermission, exceptionState); |
| 240 if (exceptionState.hadException()) | 212 if (exceptionState.hadException()) |
| 241 return exceptionState.reject(scriptState); | 213 return exceptionState.reject(scriptState); |
| 242 | 214 |
| 243 // Only append permissions to the vector that is passed to the client if it
is not already | 215 // Only append permissions types that are not already present in the vector. |
| 244 // in the vector (i.e. do not duplicate permisison types). | 216 size_t internalIndex = kNotFound; |
| 245 int internalIndex; | 217 for (size_t j = 0; j < internalPermissions.size(); ++j) { |
| 246 auto it = internalPermissions.find(name.get()); | 218 if (internalPermissions[j]->name == descriptor->name) { |
| 247 if (it == kNotFound) { | 219 internalIndex = j; |
| 220 break; |
| 221 } |
| 222 } |
| 223 if (internalIndex == kNotFound) { |
| 248 internalIndex = internalPermissions.size(); | 224 internalIndex = internalPermissions.size(); |
| 249 internalPermissions.append(name.get()); | 225 internalPermissions.append(std::move(descriptor)); |
| 250 } else { | |
| 251 internalIndex = it; | |
| 252 } | 226 } |
| 253 callerIndexToInternalIndex[i] = internalIndex; | 227 callerIndexToInternalIndex[i] = internalIndex; |
| 254 } | 228 } |
| 255 | 229 |
| 256 // This must be called after `parsePermission` because the website might | 230 // This must be called after `parsePermission` because the website might |
| 257 // be able to run code. | 231 // be able to run code. |
| 258 PermissionService* service = getService(scriptState->getExecutionContext()); | 232 PermissionService* service = getService(scriptState->getExecutionContext()); |
| 259 if (!service) | 233 if (!service) |
| 260 return ScriptPromise::rejectWithDOMException( | 234 return ScriptPromise::rejectWithDOMException( |
| 261 scriptState, DOMException::create(InvalidStateError, | 235 scriptState, DOMException::create(InvalidStateError, |
| 262 "In its current state, the global " | 236 "In its current state, the global " |
| 263 "scope can't request permissions.")); | 237 "scope can't request permissions.")); |
| 264 | 238 |
| 265 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); | 239 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState); |
| 266 ScriptPromise promise = resolver->promise(); | 240 ScriptPromise promise = resolver->promise(); |
| 267 | 241 |
| 242 Vector<PermissionDescriptorPtr> internalPermissionsCopy; |
| 243 internalPermissionsCopy.reserveCapacity(internalPermissions.size()); |
| 244 for (const auto& descriptor : internalPermissions) |
| 245 internalPermissionsCopy.append(descriptor->Clone()); |
| 246 |
| 268 service->RequestPermissions( | 247 service->RequestPermissions( |
| 269 internalPermissions, | 248 std::move(internalPermissions), |
| 270 scriptState->getExecutionContext()->getSecurityOrigin(), | 249 scriptState->getExecutionContext()->getSecurityOrigin(), |
| 271 UserGestureIndicator::processingUserGesture(), | 250 UserGestureIndicator::processingUserGesture(), |
| 272 convertToBaseCallback( | 251 convertToBaseCallback(WTF::bind( |
| 273 WTF::bind(&Permissions::batchTaskComplete, wrapPersistent(this), | 252 &Permissions::batchTaskComplete, wrapPersistent(this), |
| 274 wrapPersistent(resolver), internalPermissions, | 253 wrapPersistent(resolver), passed(std::move(internalPermissionsCopy)), |
| 275 callerIndexToInternalIndex))); | 254 passed(std::move(callerIndexToInternalIndex))))); |
| 276 return promise; | 255 return promise; |
| 277 } | 256 } |
| 278 | 257 |
| 279 PermissionService* Permissions::getService(ExecutionContext* executionContext) { | 258 PermissionService* Permissions::getService(ExecutionContext* executionContext) { |
| 280 if (!m_service && | 259 if (!m_service && |
| 281 connectToService(executionContext, mojo::GetProxy(&m_service))) | 260 connectToPermissionService(executionContext, mojo::GetProxy(&m_service))) |
| 282 m_service.set_connection_error_handler(convertToBaseCallback(WTF::bind( | 261 m_service.set_connection_error_handler(convertToBaseCallback(WTF::bind( |
| 283 &Permissions::serviceConnectionError, wrapWeakPersistent(this)))); | 262 &Permissions::serviceConnectionError, wrapWeakPersistent(this)))); |
| 284 return m_service.get(); | 263 return m_service.get(); |
| 285 } | 264 } |
| 286 | 265 |
| 287 void Permissions::serviceConnectionError() { | 266 void Permissions::serviceConnectionError() { |
| 288 m_service.reset(); | 267 m_service.reset(); |
| 289 } | 268 } |
| 290 | 269 |
| 291 void Permissions::taskComplete(ScriptPromiseResolver* resolver, | 270 void Permissions::taskComplete(ScriptPromiseResolver* resolver, |
| 292 PermissionName name, | 271 mojom::blink::PermissionDescriptorPtr descriptor, |
| 293 mojom::blink::PermissionStatus result) { | 272 mojom::blink::PermissionStatus result) { |
| 294 if (!resolver->getExecutionContext() || | 273 if (!resolver->getExecutionContext() || |
| 295 resolver->getExecutionContext()->activeDOMObjectsAreStopped()) | 274 resolver->getExecutionContext()->activeDOMObjectsAreStopped()) |
| 296 return; | 275 return; |
| 297 resolver->resolve(PermissionStatus::take(resolver, result, name)); | 276 resolver->resolve( |
| 277 PermissionStatus::take(resolver, result, std::move(descriptor))); |
| 298 } | 278 } |
| 299 | 279 |
| 300 void Permissions::batchTaskComplete( | 280 void Permissions::batchTaskComplete( |
| 301 ScriptPromiseResolver* resolver, | 281 ScriptPromiseResolver* resolver, |
| 302 Vector<PermissionName> names, | 282 Vector<mojom::blink::PermissionDescriptorPtr> descriptors, |
| 303 Vector<int> callerIndexToInternalIndex, | 283 Vector<int> callerIndexToInternalIndex, |
| 304 const Vector<mojom::blink::PermissionStatus>& results) { | 284 const Vector<mojom::blink::PermissionStatus>& results) { |
| 305 if (!resolver->getExecutionContext() || | 285 if (!resolver->getExecutionContext() || |
| 306 resolver->getExecutionContext()->activeDOMObjectsAreStopped()) | 286 resolver->getExecutionContext()->activeDOMObjectsAreStopped()) |
| 307 return; | 287 return; |
| 308 | 288 |
| 309 // Create the response vector by finding the status for each index by | 289 // Create the response vector by finding the status for each index by |
| 310 // using the caller to internal index mapping and looking up the status | 290 // using the caller to internal index mapping and looking up the status |
| 311 // using the internal index obtained. | 291 // using the internal index obtained. |
| 312 HeapVector<Member<PermissionStatus>> result; | 292 HeapVector<Member<PermissionStatus>> result; |
| 313 result.reserveInitialCapacity(callerIndexToInternalIndex.size()); | 293 result.reserveInitialCapacity(callerIndexToInternalIndex.size()); |
| 314 for (int internalIndex : callerIndexToInternalIndex) | 294 for (int internalIndex : callerIndexToInternalIndex) { |
| 315 result.append(PermissionStatus::createAndListen( | 295 result.append(PermissionStatus::createAndListen( |
| 316 resolver->getExecutionContext(), results[internalIndex], | 296 resolver->getExecutionContext(), results[internalIndex], |
| 317 names[internalIndex])); | 297 descriptors[internalIndex]->Clone())); |
| 298 } |
| 318 resolver->resolve(result); | 299 resolver->resolve(result); |
| 319 } | 300 } |
| 320 | 301 |
| 321 } // namespace blink | 302 } // namespace blink |
| OLD | NEW |