Fix various typos, error handling for GN auto-roller.
[chromium-blink-merge.git] / content / child / permissions / permission_dispatcher.cc
blob4a0957ecb7b8646e95b0a977e96abe921e0c83cd
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_dispatcher.h"
7 #include "base/callback.h"
8 #include "content/child/worker_task_runner.h"
9 #include "content/public/common/service_registry.h"
10 #include "third_party/WebKit/public/platform/WebURL.h"
11 #include "third_party/WebKit/public/platform/modules/permissions/WebPermissionObserver.h"
13 using blink::WebPermissionObserver;
15 namespace content {
17 namespace {
19 PermissionName GetPermissionName(blink::WebPermissionType type) {
20 switch (type) {
21 case blink::WebPermissionTypeGeolocation:
22 return PERMISSION_NAME_GEOLOCATION;
23 case blink::WebPermissionTypeNotifications:
24 return PERMISSION_NAME_NOTIFICATIONS;
25 case blink::WebPermissionTypePushNotifications:
26 return PERMISSION_NAME_PUSH_NOTIFICATIONS;
27 case blink::WebPermissionTypeMidiSysEx:
28 return PERMISSION_NAME_MIDI_SYSEX;
29 default:
30 // The default statement is only there to prevent compilation failures if
31 // WebPermissionType enum gets extended.
32 NOTREACHED();
33 return PERMISSION_NAME_GEOLOCATION;
37 PermissionStatus GetPermissionStatus(blink::WebPermissionStatus status) {
38 switch (status) {
39 case blink::WebPermissionStatusGranted:
40 return PERMISSION_STATUS_GRANTED;
41 case blink::WebPermissionStatusDenied:
42 return PERMISSION_STATUS_DENIED;
43 case blink::WebPermissionStatusPrompt:
44 return PERMISSION_STATUS_ASK;
47 NOTREACHED();
48 return PERMISSION_STATUS_DENIED;
51 blink::WebPermissionStatus GetWebPermissionStatus(PermissionStatus status) {
52 switch (status) {
53 case PERMISSION_STATUS_GRANTED:
54 return blink::WebPermissionStatusGranted;
55 case PERMISSION_STATUS_DENIED:
56 return blink::WebPermissionStatusDenied;
57 case PERMISSION_STATUS_ASK:
58 return blink::WebPermissionStatusPrompt;
61 NOTREACHED();
62 return blink::WebPermissionStatusDenied;
65 const int kNoWorkerThread = 0;
67 } // anonymous namespace
69 // static
70 bool PermissionDispatcher::IsObservable(blink::WebPermissionType type) {
71 return type == blink::WebPermissionTypeGeolocation ||
72 type == blink::WebPermissionTypeNotifications ||
73 type == blink::WebPermissionTypePushNotifications ||
74 type == blink::WebPermissionTypeMidiSysEx;
77 PermissionDispatcher::CallbackInformation::CallbackInformation(
78 blink::WebPermissionCallback* callback,
79 int worker_thread_id)
80 : callback_(callback),
81 worker_thread_id_(worker_thread_id) {
84 blink::WebPermissionCallback*
85 PermissionDispatcher::CallbackInformation::callback() const {
86 return callback_.get();
89 int PermissionDispatcher::CallbackInformation::worker_thread_id() const {
90 return worker_thread_id_;
93 blink::WebPermissionCallback*
94 PermissionDispatcher::CallbackInformation::ReleaseCallback() {
95 return callback_.release();
98 PermissionDispatcher::CallbackInformation::~CallbackInformation() {
101 PermissionDispatcher::PermissionDispatcher(ServiceRegistry* service_registry)
102 : service_registry_(service_registry) {
105 PermissionDispatcher::~PermissionDispatcher() {
108 void PermissionDispatcher::queryPermission(
109 blink::WebPermissionType type,
110 const blink::WebURL& origin,
111 blink::WebPermissionCallback* callback) {
112 QueryPermissionInternal(
113 type, origin.string().utf8(), callback, kNoWorkerThread);
116 void PermissionDispatcher::revokePermission(
117 blink::WebPermissionType type,
118 const blink::WebURL& origin,
119 blink::WebPermissionCallback* callback) {
120 RevokePermissionInternal(
121 type, origin.string().utf8(), callback, kNoWorkerThread);
124 void PermissionDispatcher::startListening(
125 blink::WebPermissionType type,
126 const blink::WebURL& origin,
127 WebPermissionObserver* observer) {
128 if (!IsObservable(type))
129 return;
131 RegisterObserver(observer);
133 GetNextPermissionChange(type,
134 origin.string().utf8(),
135 observer,
136 // We initialize with an arbitrary value because the
137 // mojo service wants a value. Worst case, the
138 // observer will get notified about a non-change which
139 // should be a no-op. After the first notification,
140 // GetNextPermissionChange will be called with the
141 // latest known value.
142 PERMISSION_STATUS_ASK);
145 void PermissionDispatcher::stopListening(WebPermissionObserver* observer) {
146 UnregisterObserver(observer);
149 void PermissionDispatcher::QueryPermissionForWorker(
150 blink::WebPermissionType type,
151 const std::string& origin,
152 blink::WebPermissionCallback* callback,
153 int worker_thread_id) {
154 QueryPermissionInternal(type, origin, callback, worker_thread_id);
157 void PermissionDispatcher::RevokePermissionForWorker(
158 blink::WebPermissionType type,
159 const std::string& origin,
160 blink::WebPermissionCallback* callback,
161 int worker_thread_id) {
162 RevokePermissionInternal(type, origin, callback, worker_thread_id);
165 void PermissionDispatcher::StartListeningForWorker(
166 blink::WebPermissionType type,
167 const std::string& origin,
168 int worker_thread_id,
169 const base::Callback<void(blink::WebPermissionStatus)>& callback) {
170 GetPermissionServicePtr()->GetNextPermissionChange(
171 GetPermissionName(type),
172 origin,
173 // We initialize with an arbitrary value because the mojo service wants a
174 // value. Worst case, the observer will get notified about a non-change
175 // which should be a no-op. After the first notification,
176 // GetNextPermissionChange will be called with the latest known value.
177 PERMISSION_STATUS_ASK,
178 base::Bind(&PermissionDispatcher::OnPermissionChangedForWorker,
179 base::Unretained(this),
180 worker_thread_id,
181 callback));
184 void PermissionDispatcher::GetNextPermissionChangeForWorker(
185 blink::WebPermissionType type,
186 const std::string& origin,
187 blink::WebPermissionStatus status,
188 int worker_thread_id,
189 const base::Callback<void(blink::WebPermissionStatus)>& callback) {
190 GetPermissionServicePtr()->GetNextPermissionChange(
191 GetPermissionName(type),
192 origin,
193 GetPermissionStatus(status),
194 base::Bind(&PermissionDispatcher::OnPermissionChangedForWorker,
195 base::Unretained(this),
196 worker_thread_id,
197 callback));
200 // static
201 void PermissionDispatcher::RunCallbackOnWorkerThread(
202 blink::WebPermissionCallback* callback,
203 scoped_ptr<blink::WebPermissionStatus> status) {
204 callback->onSuccess(status.release());
205 delete callback;
208 PermissionServicePtr& PermissionDispatcher::GetPermissionServicePtr() {
209 if (!permission_service_.get()) {
210 service_registry_->ConnectToRemoteService(
211 mojo::GetProxy(&permission_service_));
213 return permission_service_;
216 void PermissionDispatcher::QueryPermissionInternal(
217 blink::WebPermissionType type,
218 const std::string& origin,
219 blink::WebPermissionCallback* callback,
220 int worker_thread_id) {
221 // We need to save the |callback| in an IDMap so if |this| gets deleted, the
222 // callback will not leak. In the case of |this| gets deleted, the
223 // |permission_service_| pipe will be destroyed too so OnQueryPermission will
224 // not be called.
225 int request_id = pending_callbacks_.Add(
226 new CallbackInformation(callback, worker_thread_id));
227 GetPermissionServicePtr()->HasPermission(
228 GetPermissionName(type),
229 origin,
230 base::Bind(&PermissionDispatcher::OnPermissionResponse,
231 base::Unretained(this),
232 request_id));
235 void PermissionDispatcher::RevokePermissionInternal(
236 blink::WebPermissionType type,
237 const std::string& origin,
238 blink::WebPermissionCallback* callback,
239 int worker_thread_id) {
240 // We need to save the |callback| in an IDMap so if |this| gets deleted, the
241 // callback will not leak. In the case of |this| gets deleted, the
242 // |permission_service_| pipe will be destroyed too so OnQueryPermission will
243 // not be called.
244 int request_id = pending_callbacks_.Add(
245 new CallbackInformation(callback, worker_thread_id));
246 GetPermissionServicePtr()->RevokePermission(
247 GetPermissionName(type),
248 origin,
249 base::Bind(&PermissionDispatcher::OnPermissionResponse,
250 base::Unretained(this),
251 request_id));
254 void PermissionDispatcher::OnPermissionResponse(int request_id,
255 PermissionStatus result) {
256 CallbackInformation* callback_information =
257 pending_callbacks_.Lookup(request_id);
258 DCHECK(callback_information && callback_information->callback());
259 scoped_ptr<blink::WebPermissionStatus> status(
260 new blink::WebPermissionStatus(GetWebPermissionStatus(result)));
262 if (callback_information->worker_thread_id() != kNoWorkerThread) {
263 blink::WebPermissionCallback* callback =
264 callback_information->ReleaseCallback();
265 int worker_thread_id = callback_information->worker_thread_id();
266 pending_callbacks_.Remove(request_id);
268 // If the worker is no longer running, ::PostTask() will return false and
269 // gracefully fail, destroying the callback too.
270 WorkerTaskRunner::Instance()->PostTask(
271 worker_thread_id,
272 base::Bind(&PermissionDispatcher::RunCallbackOnWorkerThread,
273 base::Unretained(callback),
274 base::Passed(&status)));
275 return;
278 callback_information->callback()->onSuccess(status.release());
279 pending_callbacks_.Remove(request_id);
282 void PermissionDispatcher::OnPermissionChanged(
283 blink::WebPermissionType type,
284 const std::string& origin,
285 WebPermissionObserver* observer,
286 PermissionStatus status) {
287 if (!IsObserverRegistered(observer))
288 return;
290 observer->permissionChanged(type, GetWebPermissionStatus(status));
292 GetNextPermissionChange(type, origin, observer, status);
295 void PermissionDispatcher::OnPermissionChangedForWorker(
296 int worker_thread_id,
297 const base::Callback<void(blink::WebPermissionStatus)>& callback,
298 PermissionStatus status) {
299 DCHECK(worker_thread_id != kNoWorkerThread);
301 WorkerTaskRunner::Instance()->PostTask(
302 worker_thread_id, base::Bind(callback, GetWebPermissionStatus(status)));
305 void PermissionDispatcher::GetNextPermissionChange(
306 blink::WebPermissionType type,
307 const std::string& origin,
308 WebPermissionObserver* observer,
309 PermissionStatus current_status) {
310 GetPermissionServicePtr()->GetNextPermissionChange(
311 GetPermissionName(type),
312 origin,
313 current_status,
314 base::Bind(&PermissionDispatcher::OnPermissionChanged,
315 base::Unretained(this),
316 type,
317 origin,
318 base::Unretained(observer)));
321 } // namespace content