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
3 // found in the LICENSE file.
5 #include "content/child/permissions/permission_manager.h"
7 #include "content/child/worker_task_runner.h"
8 #include "content/public/common/service_registry.h"
9 #include "third_party/WebKit/public/platform/WebURL.h"
15 PermissionName
GetPermissionName(blink::WebPermissionType type
) {
17 case blink::WebPermissionTypeGeolocation
:
18 return PERMISSION_NAME_GEOLOCATION
;
19 case blink::WebPermissionTypeNotifications
:
20 return PERMISSION_NAME_NOTIFICATIONS
;
21 case blink::WebPermissionTypePushNotifications
:
22 return PERMISSION_NAME_PUSH_NOTIFICATIONS
;
23 case blink::WebPermissionTypeMidiSysEx
:
24 return PERMISSION_NAME_MIDI_SYSEX
;
26 // The default statement is only there to prevent compilation failures if
27 // WebPermissionType enum gets extended.
29 return PERMISSION_NAME_GEOLOCATION
;
33 blink::WebPermissionStatus
GetWebPermissionStatus(PermissionStatus status
) {
35 case PERMISSION_STATUS_GRANTED
:
36 return blink::WebPermissionStatusGranted
;
37 case PERMISSION_STATUS_DENIED
:
38 return blink::WebPermissionStatusDenied
;
39 case PERMISSION_STATUS_ASK
:
40 return blink::WebPermissionStatusPrompt
;
44 return blink::WebPermissionStatusDenied
;
47 const int kNoWorkerThread
= 0;
49 } // anonymous namespace
51 PermissionManager::CallbackInformation::CallbackInformation(
52 blink::WebPermissionQueryCallback
* callback
,
54 : callback_(callback
),
55 worker_thread_id_(worker_thread_id
) {
58 blink::WebPermissionQueryCallback
*
59 PermissionManager::CallbackInformation::callback() const {
60 return callback_
.get();
63 int PermissionManager::CallbackInformation::worker_thread_id() const {
64 return worker_thread_id_
;
67 blink::WebPermissionQueryCallback
*
68 PermissionManager::CallbackInformation::ReleaseCallback() {
69 return callback_
.release();
72 PermissionManager::CallbackInformation::~CallbackInformation() {
75 PermissionManager::PermissionManager(ServiceRegistry
* service_registry
)
76 : service_registry_(service_registry
) {
79 PermissionManager::~PermissionManager() {
82 void PermissionManager::queryPermission(
83 blink::WebPermissionType type
,
84 const blink::WebURL
& origin
,
85 blink::WebPermissionQueryCallback
* callback
) {
86 QueryPermissionInternal(
87 type
, origin
.string().utf8(), callback
, kNoWorkerThread
);
90 void PermissionManager::QueryPermissionForWorker(
91 blink::WebPermissionType type
,
92 const std::string
& origin
,
93 blink::WebPermissionQueryCallback
* callback
,
94 int worker_thread_id
) {
95 QueryPermissionInternal(type
, origin
, callback
, worker_thread_id
);
98 void PermissionManager::QueryPermissionInternal(
99 blink::WebPermissionType type
,
100 const std::string
& origin
,
101 blink::WebPermissionQueryCallback
* callback
,
102 int worker_thread_id
) {
103 // We need to save the |callback| in an IDMap so if |this| gets deleted, the
104 // callback will not leak. In the case of |this| gets deleted, the
105 // |permission_service_| pipe will be destroyed too so OnQueryPermission will
107 int request_id
= pending_callbacks_
.Add(
108 new CallbackInformation(callback
, worker_thread_id
));
109 if (!permission_service_
.get())
110 service_registry_
->ConnectToRemoteService(&permission_service_
);
111 permission_service_
->HasPermission(
112 GetPermissionName(type
),
114 base::Bind(&PermissionManager::OnQueryPermission
,
115 base::Unretained(this),
119 void PermissionManager::OnQueryPermission(int request_id
,
120 PermissionStatus result
) {
121 CallbackInformation
* callback_information
=
122 pending_callbacks_
.Lookup(request_id
);
123 DCHECK(callback_information
&& callback_information
->callback());
124 scoped_ptr
<blink::WebPermissionStatus
> status(
125 new blink::WebPermissionStatus(GetWebPermissionStatus(result
)));
127 if (callback_information
->worker_thread_id() != kNoWorkerThread
) {
128 blink::WebPermissionQueryCallback
* callback
=
129 callback_information
->ReleaseCallback();
130 int worker_thread_id
= callback_information
->worker_thread_id();
131 pending_callbacks_
.Remove(request_id
);
133 // If the worker is no longer running, ::PostTask() will return false and
134 // gracefully fail, destroying the callback too.
135 WorkerTaskRunner::Instance()->PostTask(
137 base::Bind(&PermissionManager::RunCallbackOnWorkerThread
,
138 base::Unretained(callback
),
139 base::Passed(&status
)));
143 callback_information
->callback()->onSuccess(status
.release());
144 pending_callbacks_
.Remove(request_id
);
148 void PermissionManager::RunCallbackOnWorkerThread(
149 blink::WebPermissionQueryCallback
* callback
,
150 scoped_ptr
<blink::WebPermissionStatus
> status
) {
151 callback
->onSuccess(status
.release());
155 } // namespace content