| 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 "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "content/child/worker_task_runner.h" | 8 #include "content/child/worker_task_runner.h" |
| 9 #include "content/public/common/service_registry.h" | 9 #include "content/public/common/service_registry.h" |
| 10 #include "third_party/WebKit/public/platform/WebURL.h" | 10 #include "third_party/WebKit/public/platform/WebURL.h" |
| 11 #include "third_party/WebKit/public/platform/modules/permissions/WebPermissionOb
server.h" | 11 #include "third_party/WebKit/public/platform/modules/permissions/WebPermissionOb
server.h" |
| 12 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" | 12 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" |
| 13 | 13 |
| 14 using blink::WebPermissionObserver; | 14 using blink::WebPermissionObserver; |
| 15 | 15 |
| 16 namespace content { | 16 namespace content { |
| 17 | 17 |
| 18 namespace { | 18 namespace { |
| 19 | 19 |
| 20 PermissionName GetPermissionName(blink::WebPermissionType type) { | 20 permission::Name GetPermissionName(blink::WebPermissionType type) { |
| 21 switch (type) { | 21 switch (type) { |
| 22 case blink::WebPermissionTypeGeolocation: | 22 case blink::WebPermissionTypeGeolocation: |
| 23 return PERMISSION_NAME_GEOLOCATION; | 23 return permission::NAME_GEOLOCATION; |
| 24 case blink::WebPermissionTypeNotifications: | 24 case blink::WebPermissionTypeNotifications: |
| 25 return PERMISSION_NAME_NOTIFICATIONS; | 25 return permission::NAME_NOTIFICATIONS; |
| 26 case blink::WebPermissionTypePushNotifications: | 26 case blink::WebPermissionTypePushNotifications: |
| 27 return PERMISSION_NAME_PUSH_NOTIFICATIONS; | 27 return permission::NAME_PUSH_NOTIFICATIONS; |
| 28 case blink::WebPermissionTypeMidiSysEx: | 28 case blink::WebPermissionTypeMidiSysEx: |
| 29 return PERMISSION_NAME_MIDI_SYSEX; | 29 return permission::NAME_MIDI_SYSEX; |
| 30 case blink::WebPermissionTypeDurableStorage: | 30 case blink::WebPermissionTypeDurableStorage: |
| 31 return PERMISSION_NAME_DURABLE_STORAGE; | 31 return permission::NAME_DURABLE_STORAGE; |
| 32 case blink::WebPermissionTypeMidi: | 32 case blink::WebPermissionTypeMidi: |
| 33 return PERMISSION_NAME_MIDI; | 33 return permission::NAME_MIDI; |
| 34 default: | 34 default: |
| 35 // The default statement is only there to prevent compilation failures if | 35 // The default statement is only there to prevent compilation failures if |
| 36 // WebPermissionType enum gets extended. | 36 // WebPermissionType enum gets extended. |
| 37 NOTREACHED(); | 37 NOTREACHED(); |
| 38 return PERMISSION_NAME_GEOLOCATION; | 38 return permission::NAME_GEOLOCATION; |
| 39 } | 39 } |
| 40 } | 40 } |
| 41 | 41 |
| 42 PermissionStatus GetPermissionStatus(blink::WebPermissionStatus status) { | 42 permission::Status GetPermissionStatus(blink::WebPermissionStatus status) { |
| 43 switch (status) { | 43 switch (status) { |
| 44 case blink::WebPermissionStatusGranted: | 44 case blink::WebPermissionStatusGranted: |
| 45 return PERMISSION_STATUS_GRANTED; | 45 return permission::STATUS_GRANTED; |
| 46 case blink::WebPermissionStatusDenied: | 46 case blink::WebPermissionStatusDenied: |
| 47 return PERMISSION_STATUS_DENIED; | 47 return permission::STATUS_DENIED; |
| 48 case blink::WebPermissionStatusPrompt: | 48 case blink::WebPermissionStatusPrompt: |
| 49 return PERMISSION_STATUS_ASK; | 49 return permission::STATUS_ASK; |
| 50 } | 50 } |
| 51 | 51 |
| 52 NOTREACHED(); | 52 NOTREACHED(); |
| 53 return PERMISSION_STATUS_DENIED; | 53 return permission::STATUS_DENIED; |
| 54 } | 54 } |
| 55 | 55 |
| 56 blink::WebPermissionStatus GetWebPermissionStatus(PermissionStatus status) { | 56 blink::WebPermissionStatus GetWebPermissionStatus(permission::Status status) { |
| 57 switch (status) { | 57 switch (status) { |
| 58 case PERMISSION_STATUS_GRANTED: | 58 case permission::STATUS_GRANTED: |
| 59 return blink::WebPermissionStatusGranted; | 59 return blink::WebPermissionStatusGranted; |
| 60 case PERMISSION_STATUS_DENIED: | 60 case permission::STATUS_DENIED: |
| 61 return blink::WebPermissionStatusDenied; | 61 return blink::WebPermissionStatusDenied; |
| 62 case PERMISSION_STATUS_ASK: | 62 case permission::STATUS_ASK: |
| 63 return blink::WebPermissionStatusPrompt; | 63 return blink::WebPermissionStatusPrompt; |
| 64 } | 64 } |
| 65 | 65 |
| 66 NOTREACHED(); | 66 NOTREACHED(); |
| 67 return blink::WebPermissionStatusDenied; | 67 return blink::WebPermissionStatusDenied; |
| 68 } | 68 } |
| 69 | 69 |
| 70 const int kNoWorkerThread = 0; | 70 const int kNoWorkerThread = 0; |
| 71 | 71 |
| 72 } // anonymous namespace | 72 } // anonymous namespace |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 | 120 |
| 121 void PermissionDispatcher::startListening( | 121 void PermissionDispatcher::startListening( |
| 122 blink::WebPermissionType type, | 122 blink::WebPermissionType type, |
| 123 const blink::WebURL& origin, | 123 const blink::WebURL& origin, |
| 124 WebPermissionObserver* observer) { | 124 WebPermissionObserver* observer) { |
| 125 if (!IsObservable(type)) | 125 if (!IsObservable(type)) |
| 126 return; | 126 return; |
| 127 | 127 |
| 128 RegisterObserver(observer); | 128 RegisterObserver(observer); |
| 129 | 129 |
| 130 GetNextPermissionChange(type, | 130 GetNextPermissionChange(type, origin.string().utf8(), observer, |
| 131 origin.string().utf8(), | |
| 132 observer, | |
| 133 // We initialize with an arbitrary value because the | 131 // We initialize with an arbitrary value because the |
| 134 // mojo service wants a value. Worst case, the | 132 // mojo service wants a value. Worst case, the |
| 135 // observer will get notified about a non-change which | 133 // observer will get notified about a non-change which |
| 136 // should be a no-op. After the first notification, | 134 // should be a no-op. After the first notification, |
| 137 // GetNextPermissionChange will be called with the | 135 // GetNextPermissionChange will be called with the |
| 138 // latest known value. | 136 // latest known value. |
| 139 PERMISSION_STATUS_ASK); | 137 permission::STATUS_ASK); |
| 140 } | 138 } |
| 141 | 139 |
| 142 void PermissionDispatcher::stopListening(WebPermissionObserver* observer) { | 140 void PermissionDispatcher::stopListening(WebPermissionObserver* observer) { |
| 143 UnregisterObserver(observer); | 141 UnregisterObserver(observer); |
| 144 } | 142 } |
| 145 | 143 |
| 146 void PermissionDispatcher::QueryPermissionForWorker( | 144 void PermissionDispatcher::QueryPermissionForWorker( |
| 147 blink::WebPermissionType type, | 145 blink::WebPermissionType type, |
| 148 const std::string& origin, | 146 const std::string& origin, |
| 149 blink::WebPermissionCallback* callback, | 147 blink::WebPermissionCallback* callback, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 174 int worker_thread_id) { | 172 int worker_thread_id) { |
| 175 RevokePermissionInternal(type, origin, callback, worker_thread_id); | 173 RevokePermissionInternal(type, origin, callback, worker_thread_id); |
| 176 } | 174 } |
| 177 | 175 |
| 178 void PermissionDispatcher::StartListeningForWorker( | 176 void PermissionDispatcher::StartListeningForWorker( |
| 179 blink::WebPermissionType type, | 177 blink::WebPermissionType type, |
| 180 const std::string& origin, | 178 const std::string& origin, |
| 181 int worker_thread_id, | 179 int worker_thread_id, |
| 182 const base::Callback<void(blink::WebPermissionStatus)>& callback) { | 180 const base::Callback<void(blink::WebPermissionStatus)>& callback) { |
| 183 GetPermissionServicePtr()->GetNextPermissionChange( | 181 GetPermissionServicePtr()->GetNextPermissionChange( |
| 184 GetPermissionName(type), | 182 GetPermissionName(type), origin, |
| 185 origin, | |
| 186 // We initialize with an arbitrary value because the mojo service wants a | 183 // We initialize with an arbitrary value because the mojo service wants a |
| 187 // value. Worst case, the observer will get notified about a non-change | 184 // value. Worst case, the observer will get notified about a non-change |
| 188 // which should be a no-op. After the first notification, | 185 // which should be a no-op. After the first notification, |
| 189 // GetNextPermissionChange will be called with the latest known value. | 186 // GetNextPermissionChange will be called with the latest known value. |
| 190 PERMISSION_STATUS_ASK, | 187 permission::STATUS_ASK, |
| 191 base::Bind(&PermissionDispatcher::OnPermissionChangedForWorker, | 188 base::Bind(&PermissionDispatcher::OnPermissionChangedForWorker, |
| 192 base::Unretained(this), | 189 base::Unretained(this), worker_thread_id, callback)); |
| 193 worker_thread_id, | |
| 194 callback)); | |
| 195 } | 190 } |
| 196 | 191 |
| 197 void PermissionDispatcher::GetNextPermissionChangeForWorker( | 192 void PermissionDispatcher::GetNextPermissionChangeForWorker( |
| 198 blink::WebPermissionType type, | 193 blink::WebPermissionType type, |
| 199 const std::string& origin, | 194 const std::string& origin, |
| 200 blink::WebPermissionStatus status, | 195 blink::WebPermissionStatus status, |
| 201 int worker_thread_id, | 196 int worker_thread_id, |
| 202 const base::Callback<void(blink::WebPermissionStatus)>& callback) { | 197 const base::Callback<void(blink::WebPermissionStatus)>& callback) { |
| 203 GetPermissionServicePtr()->GetNextPermissionChange( | 198 GetPermissionServicePtr()->GetNextPermissionChange( |
| 204 GetPermissionName(type), | 199 GetPermissionName(type), |
| (...skipping 11 matching lines...) Expand all Loading... |
| 216 blink::WebPermissionStatus status) { | 211 blink::WebPermissionStatus status) { |
| 217 callback->onSuccess(status); | 212 callback->onSuccess(status); |
| 218 } | 213 } |
| 219 | 214 |
| 220 void PermissionDispatcher::RunPermissionsCallbackOnWorkerThread( | 215 void PermissionDispatcher::RunPermissionsCallbackOnWorkerThread( |
| 221 scoped_ptr<blink::WebPermissionsCallback> callback, | 216 scoped_ptr<blink::WebPermissionsCallback> callback, |
| 222 scoped_ptr<blink::WebVector<blink::WebPermissionStatus>> statuses) { | 217 scoped_ptr<blink::WebVector<blink::WebPermissionStatus>> statuses) { |
| 223 callback->onSuccess(blink::adoptWebPtr(statuses.release())); | 218 callback->onSuccess(blink::adoptWebPtr(statuses.release())); |
| 224 } | 219 } |
| 225 | 220 |
| 226 PermissionServicePtr& PermissionDispatcher::GetPermissionServicePtr() { | 221 permission::PermissionServicePtr& |
| 222 PermissionDispatcher::GetPermissionServicePtr() { |
| 227 if (!permission_service_.get()) { | 223 if (!permission_service_.get()) { |
| 228 service_registry_->ConnectToRemoteService( | 224 service_registry_->ConnectToRemoteService( |
| 229 mojo::GetProxy(&permission_service_)); | 225 mojo::GetProxy(&permission_service_)); |
| 230 } | 226 } |
| 231 return permission_service_; | 227 return permission_service_; |
| 232 } | 228 } |
| 233 | 229 |
| 234 void PermissionDispatcher::QueryPermissionInternal( | 230 void PermissionDispatcher::QueryPermissionInternal( |
| 235 blink::WebPermissionType type, | 231 blink::WebPermissionType type, |
| 236 const std::string& origin, | 232 const std::string& origin, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 blink::WebPermissionsCallback* callback, | 278 blink::WebPermissionsCallback* callback, |
| 283 int worker_thread_id) { | 279 int worker_thread_id) { |
| 284 // We need to save the |callback| in an ScopedVector so if |this| gets | 280 // We need to save the |callback| in an ScopedVector so if |this| gets |
| 285 // deleted, the callback will not leak. In the case of |this| gets deleted, | 281 // deleted, the callback will not leak. In the case of |this| gets deleted, |
| 286 // the |permission_service_| pipe will be destroyed too so OnQueryPermission | 282 // the |permission_service_| pipe will be destroyed too so OnQueryPermission |
| 287 // will not be called. | 283 // will not be called. |
| 288 uintptr_t callback_key = reinterpret_cast<uintptr_t>(callback); | 284 uintptr_t callback_key = reinterpret_cast<uintptr_t>(callback); |
| 289 permissions_callbacks_.add(callback_key, | 285 permissions_callbacks_.add(callback_key, |
| 290 scoped_ptr<blink::WebPermissionsCallback>(callback)); | 286 scoped_ptr<blink::WebPermissionsCallback>(callback)); |
| 291 | 287 |
| 292 mojo::Array<PermissionName> names(types.size()); | 288 mojo::Array<permission::Name> names(types.size()); |
| 293 for (size_t i = 0; i < types.size(); ++i) | 289 for (size_t i = 0; i < types.size(); ++i) |
| 294 names[i] = GetPermissionName(types[i]); | 290 names[i] = GetPermissionName(types[i]); |
| 295 | 291 |
| 296 GetPermissionServicePtr()->RequestPermissions( | 292 GetPermissionServicePtr()->RequestPermissions( |
| 297 names.Pass(), | 293 names.Pass(), |
| 298 origin, | 294 origin, |
| 299 blink::WebUserGestureIndicator::isProcessingUserGesture(), | 295 blink::WebUserGestureIndicator::isProcessingUserGesture(), |
| 300 base::Bind(&PermissionDispatcher::OnRequestPermissionsResponse, | 296 base::Bind(&PermissionDispatcher::OnRequestPermissionsResponse, |
| 301 base::Unretained(this), | 297 base::Unretained(this), |
| 302 worker_thread_id, | 298 worker_thread_id, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 318 | 314 |
| 319 GetPermissionServicePtr()->RevokePermission( | 315 GetPermissionServicePtr()->RevokePermission( |
| 320 GetPermissionName(type), | 316 GetPermissionName(type), |
| 321 origin, | 317 origin, |
| 322 base::Bind(&PermissionDispatcher::OnPermissionResponse, | 318 base::Bind(&PermissionDispatcher::OnPermissionResponse, |
| 323 base::Unretained(this), | 319 base::Unretained(this), |
| 324 worker_thread_id, | 320 worker_thread_id, |
| 325 callback_key)); | 321 callback_key)); |
| 326 } | 322 } |
| 327 | 323 |
| 328 void PermissionDispatcher::OnPermissionResponse( | 324 void PermissionDispatcher::OnPermissionResponse(int worker_thread_id, |
| 329 int worker_thread_id, | 325 uintptr_t callback_key, |
| 330 uintptr_t callback_key, | 326 permission::Status result) { |
| 331 PermissionStatus result) { | |
| 332 scoped_ptr<blink::WebPermissionCallback> callback = | 327 scoped_ptr<blink::WebPermissionCallback> callback = |
| 333 permission_callbacks_.take_and_erase(callback_key); | 328 permission_callbacks_.take_and_erase(callback_key); |
| 334 blink::WebPermissionStatus status = GetWebPermissionStatus(result); | 329 blink::WebPermissionStatus status = GetWebPermissionStatus(result); |
| 335 | 330 |
| 336 if (worker_thread_id != kNoWorkerThread) { | 331 if (worker_thread_id != kNoWorkerThread) { |
| 337 // 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 |
| 338 // gracefully fail, destroying the callback too. | 333 // gracefully fail, destroying the callback too. |
| 339 WorkerTaskRunner::Instance()->PostTask( | 334 WorkerTaskRunner::Instance()->PostTask( |
| 340 worker_thread_id, | 335 worker_thread_id, |
| 341 base::Bind(&PermissionDispatcher::RunPermissionCallbackOnWorkerThread, | 336 base::Bind(&PermissionDispatcher::RunPermissionCallbackOnWorkerThread, |
| 342 base::Passed(&callback), status)); | 337 base::Passed(&callback), status)); |
| 343 return; | 338 return; |
| 344 } | 339 } |
| 345 | 340 |
| 346 callback->onSuccess(status); | 341 callback->onSuccess(status); |
| 347 } | 342 } |
| 348 | 343 |
| 349 void PermissionDispatcher::OnRequestPermissionsResponse( | 344 void PermissionDispatcher::OnRequestPermissionsResponse( |
| 350 int worker_thread_id, | 345 int worker_thread_id, |
| 351 uintptr_t callback_key, | 346 uintptr_t callback_key, |
| 352 const mojo::Array<PermissionStatus>& result) { | 347 const mojo::Array<permission::Status>& result) { |
| 353 scoped_ptr<blink::WebPermissionsCallback> callback = | 348 scoped_ptr<blink::WebPermissionsCallback> callback = |
| 354 permissions_callbacks_.take_and_erase(callback_key); | 349 permissions_callbacks_.take_and_erase(callback_key); |
| 355 scoped_ptr<blink::WebVector<blink::WebPermissionStatus>> statuses( | 350 scoped_ptr<blink::WebVector<blink::WebPermissionStatus>> statuses( |
| 356 new blink::WebVector<blink::WebPermissionStatus>(result.size())); | 351 new blink::WebVector<blink::WebPermissionStatus>(result.size())); |
| 357 | 352 |
| 358 for (size_t i = 0; i < result.size(); i++) | 353 for (size_t i = 0; i < result.size(); i++) |
| 359 statuses->operator[](i) = GetWebPermissionStatus(result[i]); | 354 statuses->operator[](i) = GetWebPermissionStatus(result[i]); |
| 360 | 355 |
| 361 if (worker_thread_id != kNoWorkerThread) { | 356 if (worker_thread_id != kNoWorkerThread) { |
| 362 // 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 |
| 363 // gracefully fail, destroying the callback too. | 358 // gracefully fail, destroying the callback too. |
| 364 WorkerTaskRunner::Instance()->PostTask( | 359 WorkerTaskRunner::Instance()->PostTask( |
| 365 worker_thread_id, | 360 worker_thread_id, |
| 366 base::Bind(&PermissionDispatcher::RunPermissionsCallbackOnWorkerThread, | 361 base::Bind(&PermissionDispatcher::RunPermissionsCallbackOnWorkerThread, |
| 367 base::Passed(&callback), | 362 base::Passed(&callback), |
| 368 base::Passed(&statuses))); | 363 base::Passed(&statuses))); |
| 369 return; | 364 return; |
| 370 } | 365 } |
| 371 | 366 |
| 372 callback->onSuccess(blink::adoptWebPtr(statuses.release())); | 367 callback->onSuccess(blink::adoptWebPtr(statuses.release())); |
| 373 } | 368 } |
| 374 | 369 |
| 375 void PermissionDispatcher::OnPermissionChanged( | 370 void PermissionDispatcher::OnPermissionChanged(blink::WebPermissionType type, |
| 376 blink::WebPermissionType type, | 371 const std::string& origin, |
| 377 const std::string& origin, | 372 WebPermissionObserver* observer, |
| 378 WebPermissionObserver* observer, | 373 permission::Status status) { |
| 379 PermissionStatus status) { | |
| 380 if (!IsObserverRegistered(observer)) | 374 if (!IsObserverRegistered(observer)) |
| 381 return; | 375 return; |
| 382 | 376 |
| 383 observer->permissionChanged(type, GetWebPermissionStatus(status)); | 377 observer->permissionChanged(type, GetWebPermissionStatus(status)); |
| 384 | 378 |
| 385 GetNextPermissionChange(type, origin, observer, status); | 379 GetNextPermissionChange(type, origin, observer, status); |
| 386 } | 380 } |
| 387 | 381 |
| 388 void PermissionDispatcher::OnPermissionChangedForWorker( | 382 void PermissionDispatcher::OnPermissionChangedForWorker( |
| 389 int worker_thread_id, | 383 int worker_thread_id, |
| 390 const base::Callback<void(blink::WebPermissionStatus)>& callback, | 384 const base::Callback<void(blink::WebPermissionStatus)>& callback, |
| 391 PermissionStatus status) { | 385 permission::Status status) { |
| 392 DCHECK(worker_thread_id != kNoWorkerThread); | 386 DCHECK(worker_thread_id != kNoWorkerThread); |
| 393 | 387 |
| 394 WorkerTaskRunner::Instance()->PostTask( | 388 WorkerTaskRunner::Instance()->PostTask( |
| 395 worker_thread_id, base::Bind(callback, GetWebPermissionStatus(status))); | 389 worker_thread_id, base::Bind(callback, GetWebPermissionStatus(status))); |
| 396 } | 390 } |
| 397 | 391 |
| 398 void PermissionDispatcher::GetNextPermissionChange( | 392 void PermissionDispatcher::GetNextPermissionChange( |
| 399 blink::WebPermissionType type, | 393 blink::WebPermissionType type, |
| 400 const std::string& origin, | 394 const std::string& origin, |
| 401 WebPermissionObserver* observer, | 395 WebPermissionObserver* observer, |
| 402 PermissionStatus current_status) { | 396 permission::Status current_status) { |
| 403 GetPermissionServicePtr()->GetNextPermissionChange( | 397 GetPermissionServicePtr()->GetNextPermissionChange( |
| 404 GetPermissionName(type), | 398 GetPermissionName(type), |
| 405 origin, | 399 origin, |
| 406 current_status, | 400 current_status, |
| 407 base::Bind(&PermissionDispatcher::OnPermissionChanged, | 401 base::Bind(&PermissionDispatcher::OnPermissionChanged, |
| 408 base::Unretained(this), | 402 base::Unretained(this), |
| 409 type, | 403 type, |
| 410 origin, | 404 origin, |
| 411 base::Unretained(observer))); | 405 base::Unretained(observer))); |
| 412 } | 406 } |
| 413 | 407 |
| 414 } // namespace content | 408 } // namespace content |
| OLD | NEW |