OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 "content/child/permissions/permission_dispatcher.h" | 5 #include "content/child/permissions/permission_dispatcher.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
11 #include "content/public/child/worker_thread.h" | 11 #include "content/public/child/worker_thread.h" |
12 #include "content/public/common/service_registry.h" | 12 #include "content/public/common/service_registry.h" |
13 #include "third_party/WebKit/public/platform/WebURL.h" | 13 #include "third_party/WebKit/public/platform/WebURL.h" |
14 #include "third_party/WebKit/public/platform/modules/permissions/WebPermissionOb
server.h" | 14 #include "third_party/WebKit/public/platform/modules/permissions/WebPermissionOb
server.h" |
15 | 15 |
16 using blink::WebPermissionObserver; | 16 using blink::WebPermissionObserver; |
| 17 using blink::mojom::PermissionName; |
| 18 using blink::mojom::PermissionStatus; |
17 | 19 |
18 namespace content { | 20 namespace content { |
19 | 21 |
20 namespace { | 22 namespace { |
21 | 23 |
22 mojom::PermissionName GetPermissionName(blink::WebPermissionType type) { | 24 PermissionName GetPermissionName(blink::WebPermissionType type) { |
23 switch (type) { | 25 switch (type) { |
24 case blink::WebPermissionTypeGeolocation: | 26 case blink::WebPermissionTypeGeolocation: |
25 return mojom::PermissionName::GEOLOCATION; | 27 return PermissionName::GEOLOCATION; |
26 case blink::WebPermissionTypeNotifications: | 28 case blink::WebPermissionTypeNotifications: |
27 return mojom::PermissionName::NOTIFICATIONS; | 29 return PermissionName::NOTIFICATIONS; |
28 case blink::WebPermissionTypePushNotifications: | 30 case blink::WebPermissionTypePushNotifications: |
29 return mojom::PermissionName::PUSH_NOTIFICATIONS; | 31 return PermissionName::PUSH_NOTIFICATIONS; |
30 case blink::WebPermissionTypeMidiSysEx: | 32 case blink::WebPermissionTypeMidiSysEx: |
31 return mojom::PermissionName::MIDI_SYSEX; | 33 return PermissionName::MIDI_SYSEX; |
32 case blink::WebPermissionTypeDurableStorage: | 34 case blink::WebPermissionTypeDurableStorage: |
33 return mojom::PermissionName::DURABLE_STORAGE; | 35 return PermissionName::DURABLE_STORAGE; |
34 case blink::WebPermissionTypeMidi: | 36 case blink::WebPermissionTypeMidi: |
35 return mojom::PermissionName::MIDI; | 37 return PermissionName::MIDI; |
36 default: | 38 default: |
37 // The default statement is only there to prevent compilation failures if | 39 // The default statement is only there to prevent compilation failures if |
38 // WebPermissionType enum gets extended. | 40 // WebPermissionType enum gets extended. |
39 NOTREACHED(); | 41 NOTREACHED(); |
40 return mojom::PermissionName::GEOLOCATION; | 42 return PermissionName::GEOLOCATION; |
41 } | 43 } |
42 } | 44 } |
43 | 45 |
44 mojom::PermissionStatus GetPermissionStatus(blink::WebPermissionStatus status) { | 46 PermissionStatus GetPermissionStatus(blink::WebPermissionStatus status) { |
45 switch (status) { | 47 switch (status) { |
46 case blink::WebPermissionStatusGranted: | 48 case blink::WebPermissionStatusGranted: |
47 return mojom::PermissionStatus::GRANTED; | 49 return PermissionStatus::GRANTED; |
48 case blink::WebPermissionStatusDenied: | 50 case blink::WebPermissionStatusDenied: |
49 return mojom::PermissionStatus::DENIED; | 51 return PermissionStatus::DENIED; |
50 case blink::WebPermissionStatusPrompt: | 52 case blink::WebPermissionStatusPrompt: |
51 return mojom::PermissionStatus::ASK; | 53 return PermissionStatus::ASK; |
52 } | 54 } |
53 | 55 |
54 NOTREACHED(); | 56 NOTREACHED(); |
55 return mojom::PermissionStatus::DENIED; | 57 return PermissionStatus::DENIED; |
56 } | 58 } |
57 | 59 |
58 blink::WebPermissionStatus GetWebPermissionStatus( | 60 blink::WebPermissionStatus GetWebPermissionStatus(PermissionStatus status) { |
59 mojom::PermissionStatus status) { | |
60 switch (status) { | 61 switch (status) { |
61 case mojom::PermissionStatus::GRANTED: | 62 case PermissionStatus::GRANTED: |
62 return blink::WebPermissionStatusGranted; | 63 return blink::WebPermissionStatusGranted; |
63 case mojom::PermissionStatus::DENIED: | 64 case PermissionStatus::DENIED: |
64 return blink::WebPermissionStatusDenied; | 65 return blink::WebPermissionStatusDenied; |
65 case mojom::PermissionStatus::ASK: | 66 case PermissionStatus::ASK: |
66 return blink::WebPermissionStatusPrompt; | 67 return blink::WebPermissionStatusPrompt; |
67 } | 68 } |
68 | 69 |
69 NOTREACHED(); | 70 NOTREACHED(); |
70 return blink::WebPermissionStatusDenied; | 71 return blink::WebPermissionStatusDenied; |
71 } | 72 } |
72 | 73 |
73 const int kNoWorkerThread = 0; | 74 const int kNoWorkerThread = 0; |
74 | 75 |
75 } // anonymous namespace | 76 } // anonymous namespace |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 | 132 |
132 RegisterObserver(observer); | 133 RegisterObserver(observer); |
133 | 134 |
134 GetNextPermissionChange(type, origin.string().utf8(), observer, | 135 GetNextPermissionChange(type, origin.string().utf8(), observer, |
135 // We initialize with an arbitrary value because the | 136 // We initialize with an arbitrary value because the |
136 // mojo service wants a value. Worst case, the | 137 // mojo service wants a value. Worst case, the |
137 // observer will get notified about a non-change which | 138 // observer will get notified about a non-change which |
138 // should be a no-op. After the first notification, | 139 // should be a no-op. After the first notification, |
139 // GetNextPermissionChange will be called with the | 140 // GetNextPermissionChange will be called with the |
140 // latest known value. | 141 // latest known value. |
141 mojom::PermissionStatus::ASK); | 142 PermissionStatus::ASK); |
142 } | 143 } |
143 | 144 |
144 void PermissionDispatcher::stopListening(WebPermissionObserver* observer) { | 145 void PermissionDispatcher::stopListening(WebPermissionObserver* observer) { |
145 UnregisterObserver(observer); | 146 UnregisterObserver(observer); |
146 } | 147 } |
147 | 148 |
148 void PermissionDispatcher::QueryPermissionForWorker( | 149 void PermissionDispatcher::QueryPermissionForWorker( |
149 blink::WebPermissionType type, | 150 blink::WebPermissionType type, |
150 const std::string& origin, | 151 const std::string& origin, |
151 blink::WebPermissionCallback* callback, | 152 blink::WebPermissionCallback* callback, |
(...skipping 29 matching lines...) Expand all Loading... |
181 blink::WebPermissionType type, | 182 blink::WebPermissionType type, |
182 const std::string& origin, | 183 const std::string& origin, |
183 int worker_thread_id, | 184 int worker_thread_id, |
184 const base::Callback<void(blink::WebPermissionStatus)>& callback) { | 185 const base::Callback<void(blink::WebPermissionStatus)>& callback) { |
185 GetPermissionServicePtr()->GetNextPermissionChange( | 186 GetPermissionServicePtr()->GetNextPermissionChange( |
186 GetPermissionName(type), origin, | 187 GetPermissionName(type), origin, |
187 // We initialize with an arbitrary value because the mojo service wants a | 188 // We initialize with an arbitrary value because the mojo service wants a |
188 // value. Worst case, the observer will get notified about a non-change | 189 // value. Worst case, the observer will get notified about a non-change |
189 // which should be a no-op. After the first notification, | 190 // which should be a no-op. After the first notification, |
190 // GetNextPermissionChange will be called with the latest known value. | 191 // GetNextPermissionChange will be called with the latest known value. |
191 mojom::PermissionStatus::ASK, | 192 PermissionStatus::ASK, |
192 base::Bind(&PermissionDispatcher::OnPermissionChangedForWorker, | 193 base::Bind(&PermissionDispatcher::OnPermissionChangedForWorker, |
193 base::Unretained(this), worker_thread_id, callback)); | 194 base::Unretained(this), worker_thread_id, callback)); |
194 } | 195 } |
195 | 196 |
196 void PermissionDispatcher::GetNextPermissionChangeForWorker( | 197 void PermissionDispatcher::GetNextPermissionChangeForWorker( |
197 blink::WebPermissionType type, | 198 blink::WebPermissionType type, |
198 const std::string& origin, | 199 const std::string& origin, |
199 blink::WebPermissionStatus status, | 200 blink::WebPermissionStatus status, |
200 int worker_thread_id, | 201 int worker_thread_id, |
201 const base::Callback<void(blink::WebPermissionStatus)>& callback) { | 202 const base::Callback<void(blink::WebPermissionStatus)>& callback) { |
(...skipping 13 matching lines...) Expand all Loading... |
215 blink::WebPermissionStatus status) { | 216 blink::WebPermissionStatus status) { |
216 callback->onSuccess(status); | 217 callback->onSuccess(status); |
217 } | 218 } |
218 | 219 |
219 void PermissionDispatcher::RunPermissionsCallbackOnWorkerThread( | 220 void PermissionDispatcher::RunPermissionsCallbackOnWorkerThread( |
220 scoped_ptr<blink::WebPermissionsCallback> callback, | 221 scoped_ptr<blink::WebPermissionsCallback> callback, |
221 scoped_ptr<blink::WebVector<blink::WebPermissionStatus>> statuses) { | 222 scoped_ptr<blink::WebVector<blink::WebPermissionStatus>> statuses) { |
222 callback->onSuccess(blink::adoptWebPtr(statuses.release())); | 223 callback->onSuccess(blink::adoptWebPtr(statuses.release())); |
223 } | 224 } |
224 | 225 |
225 mojom::PermissionServicePtr& PermissionDispatcher::GetPermissionServicePtr() { | 226 blink::mojom::PermissionService* |
| 227 PermissionDispatcher::GetPermissionServicePtr() { |
226 if (!permission_service_.get()) { | 228 if (!permission_service_.get()) { |
227 service_registry_->ConnectToRemoteService( | 229 service_registry_->ConnectToRemoteService( |
228 mojo::GetProxy(&permission_service_)); | 230 mojo::GetProxy(&permission_service_)); |
229 } | 231 } |
230 return permission_service_; | 232 return permission_service_.get(); |
231 } | 233 } |
232 | 234 |
233 void PermissionDispatcher::QueryPermissionInternal( | 235 void PermissionDispatcher::QueryPermissionInternal( |
234 blink::WebPermissionType type, | 236 blink::WebPermissionType type, |
235 const std::string& origin, | 237 const std::string& origin, |
236 blink::WebPermissionCallback* callback, | 238 blink::WebPermissionCallback* callback, |
237 int worker_thread_id) { | 239 int worker_thread_id) { |
238 // We need to save the |callback| in an ScopedPtrHashMap so if |this| gets | 240 // We need to save the |callback| in an ScopedPtrHashMap so if |this| gets |
239 // deleted, the callback will not leak. In the case of |this| gets deleted, | 241 // deleted, the callback will not leak. In the case of |this| gets deleted, |
240 // the |permission_service_| pipe will be destroyed too so OnQueryPermission | 242 // the |permission_service_| pipe will be destroyed too so OnQueryPermission |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 blink::WebPermissionsCallback* callback, | 282 blink::WebPermissionsCallback* callback, |
281 int worker_thread_id) { | 283 int worker_thread_id) { |
282 // We need to save the |callback| in an ScopedVector so if |this| gets | 284 // We need to save the |callback| in an ScopedVector so if |this| gets |
283 // deleted, the callback will not leak. In the case of |this| gets deleted, | 285 // deleted, the callback will not leak. In the case of |this| gets deleted, |
284 // the |permission_service_| pipe will be destroyed too so OnQueryPermission | 286 // the |permission_service_| pipe will be destroyed too so OnQueryPermission |
285 // will not be called. | 287 // will not be called. |
286 uintptr_t callback_key = reinterpret_cast<uintptr_t>(callback); | 288 uintptr_t callback_key = reinterpret_cast<uintptr_t>(callback); |
287 permissions_callbacks_.add(callback_key, | 289 permissions_callbacks_.add(callback_key, |
288 scoped_ptr<blink::WebPermissionsCallback>(callback)); | 290 scoped_ptr<blink::WebPermissionsCallback>(callback)); |
289 | 291 |
290 mojo::Array<mojom::PermissionName> names(types.size()); | 292 mojo::Array<PermissionName> names(types.size()); |
291 for (size_t i = 0; i < types.size(); ++i) | 293 for (size_t i = 0; i < types.size(); ++i) |
292 names[i] = GetPermissionName(types[i]); | 294 names[i] = GetPermissionName(types[i]); |
293 | 295 |
294 GetPermissionServicePtr()->RequestPermissions( | 296 GetPermissionServicePtr()->RequestPermissions( |
295 std::move(names), origin, | 297 std::move(names), origin, |
296 base::Bind(&PermissionDispatcher::OnRequestPermissionsResponse, | 298 base::Bind(&PermissionDispatcher::OnRequestPermissionsResponse, |
297 base::Unretained(this), worker_thread_id, callback_key)); | 299 base::Unretained(this), worker_thread_id, callback_key)); |
298 } | 300 } |
299 | 301 |
300 void PermissionDispatcher::RevokePermissionInternal( | 302 void PermissionDispatcher::RevokePermissionInternal( |
(...skipping 11 matching lines...) Expand all Loading... |
312 | 314 |
313 GetPermissionServicePtr()->RevokePermission( | 315 GetPermissionServicePtr()->RevokePermission( |
314 GetPermissionName(type), | 316 GetPermissionName(type), |
315 origin, | 317 origin, |
316 base::Bind(&PermissionDispatcher::OnPermissionResponse, | 318 base::Bind(&PermissionDispatcher::OnPermissionResponse, |
317 base::Unretained(this), | 319 base::Unretained(this), |
318 worker_thread_id, | 320 worker_thread_id, |
319 callback_key)); | 321 callback_key)); |
320 } | 322 } |
321 | 323 |
322 void PermissionDispatcher::OnPermissionResponse( | 324 void PermissionDispatcher::OnPermissionResponse(int worker_thread_id, |
323 int worker_thread_id, | 325 uintptr_t callback_key, |
324 uintptr_t callback_key, | 326 PermissionStatus result) { |
325 mojom::PermissionStatus result) { | |
326 scoped_ptr<blink::WebPermissionCallback> callback = | 327 scoped_ptr<blink::WebPermissionCallback> callback = |
327 permission_callbacks_.take_and_erase(callback_key); | 328 permission_callbacks_.take_and_erase(callback_key); |
328 blink::WebPermissionStatus status = GetWebPermissionStatus(result); | 329 blink::WebPermissionStatus status = GetWebPermissionStatus(result); |
329 | 330 |
330 if (worker_thread_id != kNoWorkerThread) { | 331 if (worker_thread_id != kNoWorkerThread) { |
331 // If the worker is no longer running, ::PostTask() will return false and | 332 // If the worker is no longer running, ::PostTask() will return false and |
332 // gracefully fail, destroying the callback too. | 333 // gracefully fail, destroying the callback too. |
333 WorkerThread::PostTask( | 334 WorkerThread::PostTask( |
334 worker_thread_id, | 335 worker_thread_id, |
335 base::Bind(&PermissionDispatcher::RunPermissionCallbackOnWorkerThread, | 336 base::Bind(&PermissionDispatcher::RunPermissionCallbackOnWorkerThread, |
336 base::Passed(&callback), status)); | 337 base::Passed(&callback), status)); |
337 return; | 338 return; |
338 } | 339 } |
339 | 340 |
340 callback->onSuccess(status); | 341 callback->onSuccess(status); |
341 } | 342 } |
342 | 343 |
343 void PermissionDispatcher::OnRequestPermissionsResponse( | 344 void PermissionDispatcher::OnRequestPermissionsResponse( |
344 int worker_thread_id, | 345 int worker_thread_id, |
345 uintptr_t callback_key, | 346 uintptr_t callback_key, |
346 const mojo::Array<mojom::PermissionStatus>& result) { | 347 const mojo::Array<PermissionStatus>& result) { |
347 scoped_ptr<blink::WebPermissionsCallback> callback = | 348 scoped_ptr<blink::WebPermissionsCallback> callback = |
348 permissions_callbacks_.take_and_erase(callback_key); | 349 permissions_callbacks_.take_and_erase(callback_key); |
349 scoped_ptr<blink::WebVector<blink::WebPermissionStatus>> statuses( | 350 scoped_ptr<blink::WebVector<blink::WebPermissionStatus>> statuses( |
350 new blink::WebVector<blink::WebPermissionStatus>(result.size())); | 351 new blink::WebVector<blink::WebPermissionStatus>(result.size())); |
351 | 352 |
352 for (size_t i = 0; i < result.size(); i++) | 353 for (size_t i = 0; i < result.size(); i++) |
353 statuses->operator[](i) = GetWebPermissionStatus(result[i]); | 354 statuses->operator[](i) = GetWebPermissionStatus(result[i]); |
354 | 355 |
355 if (worker_thread_id != kNoWorkerThread) { | 356 if (worker_thread_id != kNoWorkerThread) { |
356 // If the worker is no longer running, ::PostTask() will return false and | 357 // If the worker is no longer running, ::PostTask() will return false and |
357 // gracefully fail, destroying the callback too. | 358 // gracefully fail, destroying the callback too. |
358 WorkerThread::PostTask( | 359 WorkerThread::PostTask( |
359 worker_thread_id, | 360 worker_thread_id, |
360 base::Bind(&PermissionDispatcher::RunPermissionsCallbackOnWorkerThread, | 361 base::Bind(&PermissionDispatcher::RunPermissionsCallbackOnWorkerThread, |
361 base::Passed(&callback), base::Passed(&statuses))); | 362 base::Passed(&callback), base::Passed(&statuses))); |
362 return; | 363 return; |
363 } | 364 } |
364 | 365 |
365 callback->onSuccess(blink::adoptWebPtr(statuses.release())); | 366 callback->onSuccess(blink::adoptWebPtr(statuses.release())); |
366 } | 367 } |
367 | 368 |
368 void PermissionDispatcher::OnPermissionChanged(blink::WebPermissionType type, | 369 void PermissionDispatcher::OnPermissionChanged(blink::WebPermissionType type, |
369 const std::string& origin, | 370 const std::string& origin, |
370 WebPermissionObserver* observer, | 371 WebPermissionObserver* observer, |
371 mojom::PermissionStatus status) { | 372 PermissionStatus status) { |
372 if (!IsObserverRegistered(observer)) | 373 if (!IsObserverRegistered(observer)) |
373 return; | 374 return; |
374 | 375 |
375 observer->permissionChanged(type, GetWebPermissionStatus(status)); | 376 observer->permissionChanged(type, GetWebPermissionStatus(status)); |
376 | 377 |
377 GetNextPermissionChange(type, origin, observer, status); | 378 GetNextPermissionChange(type, origin, observer, status); |
378 } | 379 } |
379 | 380 |
380 void PermissionDispatcher::OnPermissionChangedForWorker( | 381 void PermissionDispatcher::OnPermissionChangedForWorker( |
381 int worker_thread_id, | 382 int worker_thread_id, |
382 const base::Callback<void(blink::WebPermissionStatus)>& callback, | 383 const base::Callback<void(blink::WebPermissionStatus)>& callback, |
383 mojom::PermissionStatus status) { | 384 PermissionStatus status) { |
384 DCHECK(worker_thread_id != kNoWorkerThread); | 385 DCHECK(worker_thread_id != kNoWorkerThread); |
385 | 386 |
386 WorkerThread::PostTask(worker_thread_id, | 387 WorkerThread::PostTask(worker_thread_id, |
387 base::Bind(callback, GetWebPermissionStatus(status))); | 388 base::Bind(callback, GetWebPermissionStatus(status))); |
388 } | 389 } |
389 | 390 |
390 void PermissionDispatcher::GetNextPermissionChange( | 391 void PermissionDispatcher::GetNextPermissionChange( |
391 blink::WebPermissionType type, | 392 blink::WebPermissionType type, |
392 const std::string& origin, | 393 const std::string& origin, |
393 WebPermissionObserver* observer, | 394 WebPermissionObserver* observer, |
394 mojom::PermissionStatus current_status) { | 395 PermissionStatus current_status) { |
395 GetPermissionServicePtr()->GetNextPermissionChange( | 396 GetPermissionServicePtr()->GetNextPermissionChange( |
396 GetPermissionName(type), | 397 GetPermissionName(type), |
397 origin, | 398 origin, |
398 current_status, | 399 current_status, |
399 base::Bind(&PermissionDispatcher::OnPermissionChanged, | 400 base::Bind(&PermissionDispatcher::OnPermissionChanged, |
400 base::Unretained(this), | 401 base::Unretained(this), |
401 type, | 402 type, |
402 origin, | 403 origin, |
403 base::Unretained(observer))); | 404 base::Unretained(observer))); |
404 } | 405 } |
405 | 406 |
406 } // namespace content | 407 } // namespace content |
OLD | NEW |