Chromium Code Reviews| Index: content/child/permissions/permission_manager.cc |
| diff --git a/content/child/permissions/permission_manager.cc b/content/child/permissions/permission_manager.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..e32f837f61b5b2b0db37614334f85f35091dd62e |
| --- /dev/null |
| +++ b/content/child/permissions/permission_manager.cc |
| @@ -0,0 +1,150 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "content/child/permissions/permission_manager.h" |
| + |
| +#include "content/child/worker_task_runner.h" |
| +#include "content/public/common/service_registry.h" |
| +#include "third_party/WebKit/public/platform/WebURL.h" |
| + |
| +namespace content { |
| + |
| +namespace { |
| + |
| +PermissionName GetPermissionName(blink::WebPermissionType type) { |
| + switch (type) { |
| + case blink::WebPermissionTypeGeolocation: |
| + return PERMISSION_NAME_GEOLOCATION; |
| + case blink::WebPermissionTypeNotifications: |
| + return PERMISSION_NAME_NOTIFICATIONS; |
| + case blink::WebPermissionTypePushNotifications: |
| + return PERMISSION_NAME_PUSH_NOTIFICATIONS; |
| + case blink::WebPermissionTypeMidiSysEx: |
| + return PERMISSION_NAME_MIDI_SYSEX; |
| + default: |
| + // The default statement is only there to prevent compilation failures if |
|
Bernhard Bauer
2015/03/23 10:20:43
Uh, if WebPermissionType does in fact get extended
|
| + // WebPermissionType enum gets extended. |
| + NOTREACHED(); |
| + return PERMISSION_NAME_GEOLOCATION; |
| + } |
| +} |
| + |
| +blink::WebPermissionStatus GetWebPermissionStatus(PermissionStatus status) { |
| + switch (status) { |
| + case PERMISSION_STATUS_GRANTED: |
| + return blink::WebPermissionStatusGranted; |
| + case PERMISSION_STATUS_DENIED: |
| + return blink::WebPermissionStatusDenied; |
| + case PERMISSION_STATUS_ASK: |
| + return blink::WebPermissionStatusPrompt; |
| + } |
| +} |
| + |
| +const int kNoWorkerThread = 0; |
| + |
| +} // anonymous namespace |
| + |
| +PermissionManager::CallbackInformation::CallbackInformation( |
| + blink::WebPermissionQueryCallback* callback, |
| + int worker_thread_id) |
| + : callback_(callback), |
| + worker_thread_id_(worker_thread_id) { |
| +} |
| + |
| +blink::WebPermissionQueryCallback* |
| +PermissionManager::CallbackInformation::callback() const { |
| + return callback_.get(); |
| +} |
| + |
| +int PermissionManager::CallbackInformation::worker_thread_id() const { |
| + return worker_thread_id_; |
| +} |
| + |
| +blink::WebPermissionQueryCallback* |
| +PermissionManager::CallbackInformation::ReleaseCallback() { |
| + return callback_.release(); |
| +} |
| + |
| +PermissionManager::CallbackInformation::~CallbackInformation() { |
| +} |
| + |
| +PermissionManager::PermissionManager(ServiceRegistry& service_registry) { |
| + service_registry.ConnectToRemoteService(&permission_service_); |
| +} |
| + |
| +PermissionManager::~PermissionManager() { |
| +} |
| + |
| +void PermissionManager::queryPermission( |
| + blink::WebPermissionType type, |
| + const blink::WebURL& origin, |
| + blink::WebPermissionQueryCallback* callback) { |
| + QueryPermissionInternal( |
| + type, origin.string().utf8(), callback, kNoWorkerThread); |
| +} |
| + |
| +void PermissionManager::QueryPermissionForWorker( |
| + blink::WebPermissionType type, |
| + const std::string& origin, |
| + blink::WebPermissionQueryCallback* callback, |
| + int worker_thread_id) { |
| + QueryPermissionInternal(type, origin, callback, worker_thread_id); |
| +} |
| + |
| +void PermissionManager::QueryPermissionInternal( |
| + blink::WebPermissionType type, |
| + const std::string& origin, |
| + blink::WebPermissionQueryCallback* callback, |
| + int worker_thread_id) { |
| + // We need to save the |callback| in an IDMap so if |this| gets deleted, the |
| + // callback will not leak. In the case of |this| gets deleted, the |
|
Bernhard Bauer
2015/03/23 10:20:43
s/In the case of/In case/ (or "In the case of |thi
|
| + // |permission_service_| pipe will be destroyed too so OnQueryPermission will |
| + // not be called. |
| + int request_id = pending_callbacks_.Add( |
| + new CallbackInformation(callback, worker_thread_id)); |
| + permission_service_->HasPermission( |
| + GetPermissionName(type), |
| + origin, |
| + base::Bind(&PermissionManager::OnQueryPermission, |
| + base::Unretained(this), |
| + request_id)); |
| +} |
| + |
| +void PermissionManager::OnQueryPermission(int request_id, |
| + PermissionStatus result) { |
| + CallbackInformation* callback_information = |
| + pending_callbacks_.Lookup(request_id); |
| + DCHECK(callback_information && callback_information->callback()); |
| + scoped_ptr<blink::WebPermissionStatus> status( |
| + new blink::WebPermissionStatus(GetWebPermissionStatus(result))); |
| + |
| + if (callback_information->worker_thread_id() != kNoWorkerThread) { |
| + blink::WebPermissionQueryCallback* callback = |
| + callback_information->ReleaseCallback(); |
| + int worker_thread_id = callback_information->worker_thread_id(); |
| + pending_callbacks_.Remove(request_id); |
| + |
| + // If the worker is no longer running, ::PostTask() will return false and |
| + // gracefully fail, destroying the callback too. |
|
Bernhard Bauer
2015/03/23 10:20:43
I don't understand this comment. The return value
|
| + WorkerTaskRunner::Instance()->PostTask( |
| + worker_thread_id, |
| + base::Bind(&PermissionManager::RunCallbackOnWorkerThread, |
| + base::Unretained(callback), |
|
Bernhard Bauer
2015/03/23 10:20:43
Could you pass this base::Owned or in a scoped_ptr
|
| + base::Passed(&status))); |
| + return; |
| + } |
| + |
| + callback_information->callback()->onSuccess(status.release()); |
| + pending_callbacks_.Remove(request_id); |
| +} |
| + |
| +// static |
| +void PermissionManager::RunCallbackOnWorkerThread( |
| + blink::WebPermissionQueryCallback* callback, |
| + scoped_ptr<blink::WebPermissionStatus> status) { |
| + callback->onSuccess(status.release()); |
| + delete callback; |
| +} |
| + |
| +} // namespace content |