Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(552)

Side by Side Diff: third_party/WebKit/Source/modules/permissions/Permissions.cpp

Issue 2255933002: Add PermissionDescriptor to the permissions Mojo interface. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@no_notification_dispatcher
Patch Set: Print the unexpected permission type. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698