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