| Index: content/child/permissions/permission_dispatcher.cc
|
| diff --git a/content/child/permissions/permission_dispatcher.cc b/content/child/permissions/permission_dispatcher.cc
|
| index f9dae5203709c07e322749799163a6a73c36bc06..2b0278fb954e5e37ad72b308f696da7b1f313c68 100644
|
| --- a/content/child/permissions/permission_dispatcher.cc
|
| +++ b/content/child/permissions/permission_dispatcher.cc
|
| @@ -4,9 +4,13 @@
|
|
|
| #include "content/child/permissions/permission_dispatcher.h"
|
|
|
| +#include "base/callback.h"
|
| #include "content/child/worker_task_runner.h"
|
| #include "content/public/common/service_registry.h"
|
| #include "third_party/WebKit/public/platform/WebURL.h"
|
| +#include "third_party/WebKit/public/platform/modules/permissions/WebPermissionObserver.h"
|
| +
|
| +using blink::WebPermissionObserver;
|
|
|
| namespace content {
|
|
|
| @@ -30,6 +34,20 @@ PermissionName GetPermissionName(blink::WebPermissionType type) {
|
| }
|
| }
|
|
|
| +PermissionStatus GetPermissionStatus(blink::WebPermissionStatus status) {
|
| + switch (status) {
|
| + case blink::WebPermissionStatusGranted:
|
| + return PERMISSION_STATUS_GRANTED;
|
| + case blink::WebPermissionStatusDenied:
|
| + return PERMISSION_STATUS_DENIED;
|
| + case blink::WebPermissionStatusPrompt:
|
| + return PERMISSION_STATUS_ASK;
|
| + }
|
| +
|
| + NOTREACHED();
|
| + return PERMISSION_STATUS_DENIED;
|
| +}
|
| +
|
| blink::WebPermissionStatus GetWebPermissionStatus(PermissionStatus status) {
|
| switch (status) {
|
| case PERMISSION_STATUS_GRANTED:
|
| @@ -48,6 +66,14 @@ const int kNoWorkerThread = 0;
|
|
|
| } // anonymous namespace
|
|
|
| +// static
|
| +bool PermissionDispatcher::IsObservable(blink::WebPermissionType type) {
|
| + return type == blink::WebPermissionTypeGeolocation ||
|
| + type == blink::WebPermissionTypeNotifications ||
|
| + type == blink::WebPermissionTypePushNotifications ||
|
| + type == blink::WebPermissionTypeMidiSysEx;
|
| +}
|
| +
|
| PermissionDispatcher::CallbackInformation::CallbackInformation(
|
| blink::WebPermissionQueryCallback* callback,
|
| int worker_thread_id)
|
| @@ -87,6 +113,31 @@ void PermissionDispatcher::queryPermission(
|
| type, origin.string().utf8(), callback, kNoWorkerThread);
|
| }
|
|
|
| +void PermissionDispatcher::startListening(
|
| + blink::WebPermissionType type,
|
| + const blink::WebURL& origin,
|
| + WebPermissionObserver* observer) {
|
| + if (!IsObservable(type))
|
| + return;
|
| +
|
| + RegisterObserver(observer);
|
| +
|
| + GetNextPermissionChange(type,
|
| + origin.string().utf8(),
|
| + observer,
|
| + // We initialize with an arbitrary value because the
|
| + // mojo service wants a value. Worst case, the
|
| + // observer will get notified about a non-change which
|
| + // should be a no-op. After the first notification,
|
| + // GetNextPermissionChange will be called with the
|
| + // latest known value.
|
| + PERMISSION_STATUS_ASK);
|
| +}
|
| +
|
| +void PermissionDispatcher::stopListening(WebPermissionObserver* observer) {
|
| + UnregisterObserver(observer);
|
| +}
|
| +
|
| void PermissionDispatcher::QueryPermissionForWorker(
|
| blink::WebPermissionType type,
|
| const std::string& origin,
|
| @@ -95,6 +146,55 @@ void PermissionDispatcher::QueryPermissionForWorker(
|
| QueryPermissionInternal(type, origin, callback, worker_thread_id);
|
| }
|
|
|
| +void PermissionDispatcher::StartListeningForWorker(
|
| + blink::WebPermissionType type,
|
| + const std::string& origin,
|
| + int worker_thread_id,
|
| + const base::Callback<void(blink::WebPermissionStatus)>& callback) {
|
| + GetPermissionServicePtr()->GetNextPermissionChange(
|
| + GetPermissionName(type),
|
| + origin,
|
| + // We initialize with an arbitrary value because the mojo service wants a
|
| + // value. Worst case, the observer will get notified about a non-change
|
| + // which should be a no-op. After the first notification,
|
| + // GetNextPermissionChange will be called with the latest known value.
|
| + PERMISSION_STATUS_ASK,
|
| + base::Bind(&PermissionDispatcher::OnPermissionChangedForWorker,
|
| + base::Unretained(this),
|
| + worker_thread_id,
|
| + callback));
|
| +}
|
| +
|
| +void PermissionDispatcher::GetNextPermissionChangeForWorker(
|
| + blink::WebPermissionType type,
|
| + const std::string& origin,
|
| + blink::WebPermissionStatus status,
|
| + int worker_thread_id,
|
| + const base::Callback<void(blink::WebPermissionStatus)>& callback) {
|
| + GetPermissionServicePtr()->GetNextPermissionChange(
|
| + GetPermissionName(type),
|
| + origin,
|
| + GetPermissionStatus(status),
|
| + base::Bind(&PermissionDispatcher::OnPermissionChangedForWorker,
|
| + base::Unretained(this),
|
| + worker_thread_id,
|
| + callback));
|
| +}
|
| +
|
| +// static
|
| +void PermissionDispatcher::RunCallbackOnWorkerThread(
|
| + blink::WebPermissionQueryCallback* callback,
|
| + scoped_ptr<blink::WebPermissionStatus> status) {
|
| + callback->onSuccess(status.release());
|
| + delete callback;
|
| +}
|
| +
|
| +PermissionServicePtr& PermissionDispatcher::GetPermissionServicePtr() {
|
| + if (!permission_service_.get())
|
| + service_registry_->ConnectToRemoteService(&permission_service_);
|
| + return permission_service_;
|
| +}
|
| +
|
| void PermissionDispatcher::QueryPermissionInternal(
|
| blink::WebPermissionType type,
|
| const std::string& origin,
|
| @@ -106,9 +206,7 @@ void PermissionDispatcher::QueryPermissionInternal(
|
| // not be called.
|
| int request_id = pending_callbacks_.Add(
|
| new CallbackInformation(callback, worker_thread_id));
|
| - if (!permission_service_.get())
|
| - service_registry_->ConnectToRemoteService(&permission_service_);
|
| - permission_service_->HasPermission(
|
| + GetPermissionServicePtr()->HasPermission(
|
| GetPermissionName(type),
|
| origin,
|
| base::Bind(&PermissionDispatcher::OnQueryPermission,
|
| @@ -117,7 +215,7 @@ void PermissionDispatcher::QueryPermissionInternal(
|
| }
|
|
|
| void PermissionDispatcher::OnQueryPermission(int request_id,
|
| - PermissionStatus result) {
|
| + PermissionStatus result) {
|
| CallbackInformation* callback_information =
|
| pending_callbacks_.Lookup(request_id);
|
| DCHECK(callback_information && callback_information->callback());
|
| @@ -144,12 +242,43 @@ void PermissionDispatcher::OnQueryPermission(int request_id,
|
| pending_callbacks_.Remove(request_id);
|
| }
|
|
|
| -// static
|
| -void PermissionDispatcher::RunCallbackOnWorkerThread(
|
| - blink::WebPermissionQueryCallback* callback,
|
| - scoped_ptr<blink::WebPermissionStatus> status) {
|
| - callback->onSuccess(status.release());
|
| - delete callback;
|
| +void PermissionDispatcher::OnPermissionChanged(
|
| + blink::WebPermissionType type,
|
| + const std::string& origin,
|
| + WebPermissionObserver* observer,
|
| + PermissionStatus status) {
|
| + if (!IsObserverRegistered(observer))
|
| + return;
|
| +
|
| + observer->permissionChanged(type, GetWebPermissionStatus(status));
|
| +
|
| + GetNextPermissionChange(type, origin, observer, status);
|
| +}
|
| +
|
| +void PermissionDispatcher::OnPermissionChangedForWorker(
|
| + int worker_thread_id,
|
| + const base::Callback<void(blink::WebPermissionStatus)>& callback,
|
| + PermissionStatus status) {
|
| + DCHECK(worker_thread_id != kNoWorkerThread);
|
| +
|
| + WorkerTaskRunner::Instance()->PostTask(
|
| + worker_thread_id, base::Bind(callback, GetWebPermissionStatus(status)));
|
| +}
|
| +
|
| +void PermissionDispatcher::GetNextPermissionChange(
|
| + blink::WebPermissionType type,
|
| + const std::string& origin,
|
| + WebPermissionObserver* observer,
|
| + PermissionStatus current_status) {
|
| + GetPermissionServicePtr()->GetNextPermissionChange(
|
| + GetPermissionName(type),
|
| + origin,
|
| + current_status,
|
| + base::Bind(&PermissionDispatcher::OnPermissionChanged,
|
| + base::Unretained(this),
|
| + type,
|
| + origin,
|
| + base::Unretained(observer)));
|
| }
|
|
|
| } // namespace content
|
|
|