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 |