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" |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "public/platform/InterfaceProvider.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 |
36 // Websites will be able to run code when `name()` is called, changing the | 37 // Parses the raw permission dictionary and returns the Mojo |
37 // current context. The caller should make sure that no assumption is made | 38 // PermissionDescriptor if parsing was successful. If an exception occurs, i
t |
38 // after this has been called. | 39 // will be stored in |exceptionState| and null will be returned. Therefore,
the |
39 PermissionName getPermissionName(ScriptState* scriptState, const Dictionary& raw
Permission, const PermissionDescriptor& permission, ExceptionState& exceptionSta
te) | 40 // |exceptionState| should be checked before attempting to use the returned |
40 { | 41 // permission as the non-null assert will be fired otherwise. |
41 const String& name = permission.name(); | 42 // |
42 if (name == "geolocation") | 43 // Websites will be able to run code when `name()` is called, changing the |
43 return PermissionName::GEOLOCATION; | 44 // current context. The caller should make sure that no assumption is made |
44 if (name == "notifications") | 45 // after this has been called. |
45 return PermissionName::NOTIFICATIONS; | 46 PermissionDescriptorPtr parsePermission(ScriptState* scriptState, const Dict
ionary rawPermission, ExceptionState& exceptionState) |
46 if (name == "push") | 47 { |
47 return PermissionName::PUSH_NOTIFICATIONS; | 48 PermissionDescriptor permission = NativeValueTraits<PermissionDescriptor
>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState); |
48 if (name == "midi") { | |
49 MidiPermissionDescriptor midiPermission = NativeValueTraits<MidiPermissi
onDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exce
ptionState); | |
50 return midiPermission.sysex() ? PermissionName::MIDI_SYSEX : PermissionN
ame::MIDI; | |
51 } | |
52 if (name == "background-sync") | |
53 return PermissionName::BACKGROUND_SYNC; | |
54 | 49 |
55 ASSERT_NOT_REACHED(); | |
56 return PermissionName::GEOLOCATION; | |
57 } | |
58 | |
59 // Parses the raw permission dictionary and returns the PermissionType if | |
60 // parsing was successful. If an exception occurs, it will be stored in | |
61 // |exceptionState| and null will be returned. Therefore, the |exceptionState| | |
62 // should be checked before attempting to use the returned permission as the | |
63 // non-null assert will be fired otherwise. | |
64 Nullable<PermissionName> parsePermission(ScriptState* scriptState, const Diction
ary rawPermission, ExceptionState& exceptionState) | |
65 { | |
66 PermissionDescriptor permission = NativeValueTraits<PermissionDescriptor>::n
ativeValue(scriptState->isolate(), rawPermission.v8Value(), exceptionState); | |
67 | |
68 if (exceptionState.hadException()) { | |
69 exceptionState.throwTypeError(exceptionState.message()); | |
70 return Nullable<PermissionName>(); | |
71 } | |
72 | |
73 PermissionName name = getPermissionName(scriptState, rawPermission, permissi
on, exceptionState); | |
74 if (exceptionState.hadException()) { | |
75 exceptionState.throwTypeError(exceptionState.message()); | |
76 return Nullable<PermissionName>(); | |
77 } | |
78 | |
79 // Here we reject any permissions which are not yet supported by Blink. | |
80 if (name == PermissionName::PUSH_NOTIFICATIONS) { | |
81 PushPermissionDescriptor pushPermission = NativeValueTraits<PushPermissi
onDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(), exce
ptionState); | |
82 if (exceptionState.hadException()) { | 50 if (exceptionState.hadException()) { |
83 exceptionState.throwTypeError(exceptionState.message()); | 51 exceptionState.throwTypeError(exceptionState.message()); |
84 return Nullable<PermissionName>(); | 52 return nullptr; |
85 } | 53 } |
86 | 54 |
87 // Only "userVisibleOnly" push is supported for now. | 55 auto permissionDescriptor = mojom::blink::PermissionDescriptor::New(); |
88 if (!pushPermission.userVisibleOnly()) { | 56 const String& name = permission.name(); |
89 exceptionState.throwDOMException(NotSupportedError, "Push Permission
without userVisibleOnly:true isn't supported yet."); | 57 if (name == "geolocation") { |
90 return Nullable<PermissionName>(); | 58 permissionDescriptor->name = PermissionName::GEOLOCATION; |
| 59 } else if (name == "notifications") { |
| 60 permissionDescriptor->name = PermissionName::NOTIFICATIONS; |
| 61 } else if (name == "push") { |
| 62 PushPermissionDescriptor pushPermission = NativeValueTraits<PushPerm
issionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(),
exceptionState); |
| 63 if (exceptionState.hadException()) { |
| 64 exceptionState.throwTypeError(exceptionState.message()); |
| 65 return nullptr; |
| 66 } |
| 67 |
| 68 // Only "userVisibleOnly" push is supported for now. |
| 69 if (!pushPermission.userVisibleOnly()) { |
| 70 exceptionState.throwDOMException(NotSupportedError, "Push Permis
sion without userVisibleOnly:true isn't supported yet."); |
| 71 return nullptr; |
| 72 } |
| 73 |
| 74 permissionDescriptor->name = PermissionName::PUSH_NOTIFICATIONS; |
| 75 } else if (name == "midi") { |
| 76 MidiPermissionDescriptor midiPermission = NativeValueTraits<MidiPerm
issionDescriptor>::nativeValue(scriptState->isolate(), rawPermission.v8Value(),
exceptionState); |
| 77 permissionDescriptor->name = PermissionName::MIDI; |
| 78 auto midiPermissionDescriptor = mojom::blink::MidiPermissionDescript
or::New(); |
| 79 midiPermissionDescriptor->sysex = midiPermission.sysex(); |
| 80 permissionDescriptor->extension = mojom::blink::PermissionDescriptor
Extension::New(); |
| 81 permissionDescriptor->extension->set_midi(std::move(midiPermissionDe
scriptor)); |
| 82 } else if (name == "background-sync") { |
| 83 permissionDescriptor->name = PermissionName::BACKGROUND_SYNC; |
| 84 } else { |
| 85 return nullptr; |
91 } | 86 } |
92 } | |
93 | 87 |
94 return Nullable<PermissionName>(name); | 88 return permissionDescriptor; |
95 } | 89 } |
96 | 90 |
97 } // anonymous namespace | 91 } // anonymous namespace |
98 | 92 |
99 // static | 93 // static |
100 bool Permissions::connectToService(ExecutionContext* executionContext, mojom::bl
ink::PermissionServiceRequest request) | 94 bool Permissions::connectToService(ExecutionContext* executionContext, mojom::bl
ink::PermissionServiceRequest request) |
101 { | 95 { |
102 InterfaceProvider* interfaceProvider = nullptr; | 96 InterfaceProvider* interfaceProvider = nullptr; |
103 if (executionContext->isDocument()) { | 97 if (executionContext->isDocument()) { |
104 Document* document = toDocument(executionContext); | 98 Document* document = toDocument(executionContext); |
105 if (document->frame()) | 99 if (document->frame()) |
106 interfaceProvider = document->frame()->interfaceProvider(); | 100 interfaceProvider = document->frame()->interfaceProvider(); |
107 } else { | 101 } else { |
108 interfaceProvider = Platform::current()->interfaceProvider(); | 102 interfaceProvider = Platform::current()->interfaceProvider(); |
109 } | 103 } |
110 | 104 |
111 if (interfaceProvider) | 105 if (interfaceProvider) |
112 interfaceProvider->getInterface(std::move(request)); | 106 interfaceProvider->getInterface(std::move(request)); |
113 return interfaceProvider; | 107 return interfaceProvider; |
114 } | 108 } |
115 | 109 |
116 ScriptPromise Permissions::query(ScriptState* scriptState, const Dictionary& raw
Permission) | 110 ScriptPromise Permissions::query(ScriptState* scriptState, const Dictionary& raw
Permission) |
117 { | 111 { |
118 ExceptionState exceptionState(ExceptionState::GetterContext, "query", "Perm
issions", scriptState->context()->Global(), scriptState->isolate()); | 112 ExceptionState exceptionState(ExceptionState::GetterContext, "query", "Perm
issions", scriptState->context()->Global(), scriptState->isolate()); |
119 Nullable<PermissionName> name = parsePermission(scriptState, rawPermission,
exceptionState); | 113 auto descriptor = parsePermission(scriptState, rawPermission, exceptionState
); |
120 if (exceptionState.hadException()) | 114 if (exceptionState.hadException()) |
121 return exceptionState.reject(scriptState); | 115 return exceptionState.reject(scriptState); |
122 | 116 |
123 // This must be called after `parsePermission` because the website might | 117 // This must be called after `parsePermission` because the website might |
124 // be able to run code. | 118 // be able to run code. |
125 PermissionService* service = getService(scriptState->getExecutionContext()); | 119 PermissionService* service = getService(scriptState->getExecutionContext()); |
126 if (!service) | 120 if (!service) |
127 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't query pe
rmissions.")); | 121 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't query pe
rmissions.")); |
128 | 122 |
129 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 123 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
130 ScriptPromise promise = resolver->promise(); | 124 ScriptPromise promise = resolver->promise(); |
131 | 125 |
132 // If the current origin is a file scheme, it will unlikely return a | 126 // If the current origin is a file scheme, it will unlikely return a |
133 // meaningful value because most APIs are broken on file scheme and no | 127 // meaningful value because most APIs are broken on file scheme and no |
134 // permission prompt will be shown even if the returned permission will most | 128 // permission prompt will be shown even if the returned permission will most |
135 // likely be "prompt". | 129 // likely be "prompt". |
136 service->HasPermission(name.get(), scriptState->getExecutionContext()->getSe
curityOrigin(), convertToBaseCallback(WTF::bind(&Permissions::taskComplete, wrap
Persistent(this), wrapPersistent(resolver), name.get()))); | 130 auto descriptorCopy = descriptor->Clone(); |
| 131 service->HasPermission(std::move(descriptor), scriptState->getExecutionConte
xt()->getSecurityOrigin(), convertToBaseCallback(WTF::bind(&Permissions::taskCom
plete, wrapPersistent(this), wrapPersistent(resolver), passed(std::move(descript
orCopy))))); |
137 return promise; | 132 return promise; |
138 } | 133 } |
139 | 134 |
140 ScriptPromise Permissions::request(ScriptState* scriptState, const Dictionary& r
awPermission) | 135 ScriptPromise Permissions::request(ScriptState* scriptState, const Dictionary& r
awPermission) |
141 { | 136 { |
142 ExceptionState exceptionState(ExceptionState::GetterContext, "request", "Pe
rmissions", scriptState->context()->Global(), scriptState->isolate()); | 137 ExceptionState exceptionState(ExceptionState::GetterContext, "request", "Pe
rmissions", scriptState->context()->Global(), scriptState->isolate()); |
143 Nullable<PermissionName> name = parsePermission(scriptState, rawPermission,
exceptionState); | 138 auto descriptor = parsePermission(scriptState, rawPermission, exceptionState
); |
144 if (exceptionState.hadException()) | 139 if (exceptionState.hadException()) |
145 return exceptionState.reject(scriptState); | 140 return exceptionState.reject(scriptState); |
146 | 141 |
147 // This must be called after `parsePermission` because the website might | 142 // This must be called after `parsePermission` because the website might |
148 // be able to run code. | 143 // be able to run code. |
149 PermissionService* service = getService(scriptState->getExecutionContext()); | 144 PermissionService* service = getService(scriptState->getExecutionContext()); |
150 if (!service) | 145 if (!service) |
151 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't request
permissions.")); | 146 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't request
permissions.")); |
152 | 147 |
153 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 148 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
154 ScriptPromise promise = resolver->promise(); | 149 ScriptPromise promise = resolver->promise(); |
155 | 150 |
156 service->RequestPermission(name.get(), scriptState->getExecutionContext()->g
etSecurityOrigin(), UserGestureIndicator::processingUserGesture(), convertToBase
Callback(WTF::bind(&Permissions::taskComplete, wrapPersistent(this), wrapPersist
ent(resolver), name.get()))); | 151 auto descriptorCopy = descriptor->Clone(); |
| 152 service->RequestPermission(std::move(descriptor), scriptState->getExecutionC
ontext()->getSecurityOrigin(), UserGestureIndicator::processingUserGesture(), co
nvertToBaseCallback(WTF::bind(&Permissions::taskComplete, wrapPersistent(this),
wrapPersistent(resolver), passed(std::move(descriptorCopy))))); |
157 return promise; | 153 return promise; |
158 } | 154 } |
159 | 155 |
160 ScriptPromise Permissions::revoke(ScriptState* scriptState, const Dictionary& ra
wPermission) | 156 ScriptPromise Permissions::revoke(ScriptState* scriptState, const Dictionary& ra
wPermission) |
161 { | 157 { |
162 ExceptionState exceptionState(ExceptionState::GetterContext, "revoke", "Per
missions", scriptState->context()->Global(), scriptState->isolate()); | 158 ExceptionState exceptionState(ExceptionState::GetterContext, "revoke", "Per
missions", scriptState->context()->Global(), scriptState->isolate()); |
163 Nullable<PermissionName> name = parsePermission(scriptState, rawPermission,
exceptionState); | 159 auto descriptor = parsePermission(scriptState, rawPermission, exceptionState
); |
164 if (exceptionState.hadException()) | 160 if (exceptionState.hadException()) |
165 return exceptionState.reject(scriptState); | 161 return exceptionState.reject(scriptState); |
166 | 162 |
167 // This must be called after `parsePermission` because the website might | 163 // This must be called after `parsePermission` because the website might |
168 // be able to run code. | 164 // be able to run code. |
169 PermissionService* service = getService(scriptState->getExecutionContext()); | 165 PermissionService* service = getService(scriptState->getExecutionContext()); |
170 if (!service) | 166 if (!service) |
171 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't revoke p
ermissions.")); | 167 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't revoke p
ermissions.")); |
172 | 168 |
173 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 169 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
174 ScriptPromise promise = resolver->promise(); | 170 ScriptPromise promise = resolver->promise(); |
175 | 171 |
176 service->RevokePermission(name.get(), scriptState->getExecutionContext()->ge
tSecurityOrigin(), convertToBaseCallback(WTF::bind(&Permissions::taskComplete, w
rapPersistent(this), wrapPersistent(resolver), name.get()))); | 172 auto descriptorCopy = descriptor->Clone(); |
| 173 service->RevokePermission(std::move(descriptor), scriptState->getExecutionCo
ntext()->getSecurityOrigin(), convertToBaseCallback(WTF::bind(&Permissions::task
Complete, wrapPersistent(this), wrapPersistent(resolver), passed(std::move(descr
iptorCopy))))); |
177 return promise; | 174 return promise; |
178 } | 175 } |
179 | 176 |
180 ScriptPromise Permissions::requestAll(ScriptState* scriptState, const Vector<Dic
tionary>& rawPermissions) | 177 ScriptPromise Permissions::requestAll(ScriptState* scriptState, const Vector<Dic
tionary>& rawPermissions) |
181 { | 178 { |
182 ExceptionState exceptionState(ExceptionState::GetterContext, "request", "Pe
rmissions", scriptState->context()->Global(), scriptState->isolate()); | 179 ExceptionState exceptionState(ExceptionState::GetterContext, "request", "Pe
rmissions", scriptState->context()->Global(), scriptState->isolate()); |
183 Vector<PermissionName> internalPermissions; | 180 Vector<PermissionDescriptorPtr> internalPermissions; |
184 Vector<int> callerIndexToInternalIndex; | 181 Vector<int> callerIndexToInternalIndex; |
185 callerIndexToInternalIndex.resize(rawPermissions.size()); | 182 callerIndexToInternalIndex.resize(rawPermissions.size()); |
186 for (size_t i = 0; i < rawPermissions.size(); ++i) { | 183 for (size_t i = 0; i < rawPermissions.size(); ++i) { |
187 const Dictionary& rawPermission = rawPermissions[i]; | 184 const Dictionary& rawPermission = rawPermissions[i]; |
188 | 185 |
189 Nullable<PermissionName> name = parsePermission(scriptState, rawPermissi
on, exceptionState); | 186 auto descriptor = parsePermission(scriptState, rawPermission, exceptionS
tate); |
190 if (exceptionState.hadException()) | 187 if (exceptionState.hadException()) |
191 return exceptionState.reject(scriptState); | 188 return exceptionState.reject(scriptState); |
192 | 189 |
193 // Only append permissions to the vector that is passed to the client if
it is not already | 190 // Only append permissions types that are not already present in the vec
tor. |
194 // in the vector (i.e. do not duplicate permisison types). | 191 int internalIndex = -1; |
195 int internalIndex; | 192 for (size_t j = 0; j < internalPermissions.size(); ++j) { |
196 auto it = internalPermissions.find(name.get()); | 193 if (internalPermissions[j]->name == descriptor->name) { |
197 if (it == kNotFound) { | 194 internalIndex = j; |
| 195 break; |
| 196 } |
| 197 } |
| 198 if (internalIndex == -1) { |
198 internalIndex = internalPermissions.size(); | 199 internalIndex = internalPermissions.size(); |
199 internalPermissions.append(name.get()); | 200 internalPermissions.append(std::move(descriptor)); |
200 } else { | |
201 internalIndex = it; | |
202 } | 201 } |
203 callerIndexToInternalIndex[i] = internalIndex; | 202 callerIndexToInternalIndex[i] = internalIndex; |
204 } | 203 } |
205 | 204 |
206 // This must be called after `parsePermission` because the website might | 205 // This must be called after `parsePermission` because the website might |
207 // be able to run code. | 206 // be able to run code. |
208 PermissionService* service = getService(scriptState->getExecutionContext()); | 207 PermissionService* service = getService(scriptState->getExecutionContext()); |
209 if (!service) | 208 if (!service) |
210 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't request
permissions.")); | 209 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::
create(InvalidStateError, "In its current state, the global scope can't request
permissions.")); |
211 | 210 |
212 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 211 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
213 ScriptPromise promise = resolver->promise(); | 212 ScriptPromise promise = resolver->promise(); |
214 | 213 |
215 service->RequestPermissions(internalPermissions, scriptState->getExecutionCo
ntext()->getSecurityOrigin(), UserGestureIndicator::processingUserGesture(), | 214 Vector<PermissionDescriptorPtr> internalPermissionsCopy; |
216 convertToBaseCallback(WTF::bind(&Permissions::batchTaskComplete, wrapPer
sistent(this), wrapPersistent(resolver), internalPermissions, callerIndexToInter
nalIndex))); | 215 internalPermissionsCopy.reserveCapacity(internalPermissions.size()); |
| 216 for (const auto& descriptor : internalPermissions) |
| 217 internalPermissionsCopy.append(descriptor->Clone()); |
| 218 |
| 219 service->RequestPermissions(std::move(internalPermissions), scriptState->get
ExecutionContext()->getSecurityOrigin(), UserGestureIndicator::processingUserGes
ture(), |
| 220 convertToBaseCallback(WTF::bind(&Permissions::batchTaskComplete, wrapPer
sistent(this), wrapPersistent(resolver), passed(std::move(internalPermissionsCop
y)), passed(std::move(callerIndexToInternalIndex))))); |
217 return promise; | 221 return promise; |
218 } | 222 } |
219 | 223 |
220 PermissionService* Permissions::getService(ExecutionContext* executionContext) | 224 PermissionService* Permissions::getService(ExecutionContext* executionContext) |
221 { | 225 { |
222 if (!m_service && connectToService(executionContext, mojo::GetProxy(&m_servi
ce))) | 226 if (!m_service && connectToService(executionContext, mojo::GetProxy(&m_servi
ce))) |
223 m_service.set_connection_error_handler(convertToBaseCallback(WTF::bind(&
Permissions::serviceConnectionError, wrapWeakPersistent(this)))); | 227 m_service.set_connection_error_handler(convertToBaseCallback(WTF::bind(&
Permissions::serviceConnectionError, wrapWeakPersistent(this)))); |
224 return m_service.get(); | 228 return m_service.get(); |
225 } | 229 } |
226 | 230 |
227 void Permissions::serviceConnectionError() | 231 void Permissions::serviceConnectionError() |
228 { | 232 { |
229 m_service.reset(); | 233 m_service.reset(); |
230 } | 234 } |
231 | 235 |
232 void Permissions::taskComplete(ScriptPromiseResolver* resolver, PermissionName n
ame, mojom::blink::PermissionStatus result) | 236 void Permissions::taskComplete(ScriptPromiseResolver* resolver, mojom::blink::Pe
rmissionDescriptorPtr descriptor, mojom::blink::PermissionStatus result) |
233 { | 237 { |
234 if (!resolver->getExecutionContext() || resolver->getExecutionContext()->act
iveDOMObjectsAreStopped()) | 238 if (!resolver->getExecutionContext() || resolver->getExecutionContext()->act
iveDOMObjectsAreStopped()) |
235 return; | 239 return; |
236 resolver->resolve(PermissionStatus::take(resolver, result, name)); | 240 resolver->resolve(PermissionStatus::take(resolver, result, std::move(descrip
tor))); |
237 } | 241 } |
238 | 242 |
239 void Permissions::batchTaskComplete(ScriptPromiseResolver* resolver, Vector<Perm
issionName> names, Vector<int> callerIndexToInternalIndex, const Vector<mojom::b
link::PermissionStatus>& results) | 243 void Permissions::batchTaskComplete(ScriptPromiseResolver* resolver, Vector<mojo
m::blink::PermissionDescriptorPtr> descriptors, Vector<int> callerIndexToInterna
lIndex, const Vector<mojom::blink::PermissionStatus>& results) |
240 { | 244 { |
241 if (!resolver->getExecutionContext() || resolver->getExecutionContext()->act
iveDOMObjectsAreStopped()) | 245 if (!resolver->getExecutionContext() || resolver->getExecutionContext()->act
iveDOMObjectsAreStopped()) |
242 return; | 246 return; |
243 | 247 |
244 // Create the response vector by finding the status for each index by | 248 // Create the response vector by finding the status for each index by |
245 // using the caller to internal index mapping and looking up the status | 249 // using the caller to internal index mapping and looking up the status |
246 // using the internal index obtained. | 250 // using the internal index obtained. |
247 HeapVector<Member<PermissionStatus>> result; | 251 HeapVector<Member<PermissionStatus>> result; |
248 result.reserveInitialCapacity(callerIndexToInternalIndex.size()); | 252 result.reserveInitialCapacity(callerIndexToInternalIndex.size()); |
249 for (int internalIndex : callerIndexToInternalIndex) | 253 for (int internalIndex : callerIndexToInternalIndex) |
250 result.append(PermissionStatus::createAndListen(resolver->getExecutionCo
ntext(), results[internalIndex], names[internalIndex])); | 254 result.append(PermissionStatus::createAndListen(resolver->getExecutionCo
ntext(), results[internalIndex], descriptors[internalIndex]->Clone())); |
251 resolver->resolve(result); | 255 resolver->resolve(result); |
252 } | 256 } |
253 | 257 |
254 } // namespace blink | 258 } // namespace blink |
OLD | NEW |