OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/browser/permissions/permission_service_impl.h" | 5 #include "content/browser/permissions/permission_service_impl.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "content/public/browser/browser_context.h" | 11 #include "content/public/browser/browser_context.h" |
12 #include "content/public/browser/permission_manager.h" | 12 #include "content/public/browser/permission_manager.h" |
13 #include "content/public/browser/permission_type.h" | 13 #include "content/public/browser/permission_type.h" |
14 | 14 |
| 15 using blink::mojom::PermissionDescriptorPtr; |
15 using blink::mojom::PermissionName; | 16 using blink::mojom::PermissionName; |
16 using blink::mojom::PermissionStatus; | 17 using blink::mojom::PermissionStatus; |
17 | 18 |
18 namespace content { | 19 namespace content { |
19 | 20 |
20 namespace { | 21 namespace { |
21 | 22 |
22 PermissionType PermissionNameToPermissionType(PermissionName name) { | 23 PermissionType PermissionDescriptorToPermissionType( |
23 switch(name) { | 24 const PermissionDescriptorPtr& descriptor) { |
| 25 switch (descriptor->name) { |
24 case PermissionName::GEOLOCATION: | 26 case PermissionName::GEOLOCATION: |
25 return PermissionType::GEOLOCATION; | 27 return PermissionType::GEOLOCATION; |
26 case PermissionName::NOTIFICATIONS: | 28 case PermissionName::NOTIFICATIONS: |
27 return PermissionType::NOTIFICATIONS; | 29 return PermissionType::NOTIFICATIONS; |
28 case PermissionName::PUSH_NOTIFICATIONS: | 30 case PermissionName::PUSH_NOTIFICATIONS: |
29 return PermissionType::PUSH_MESSAGING; | 31 return PermissionType::PUSH_MESSAGING; |
30 case PermissionName::MIDI: | 32 case PermissionName::MIDI: { |
| 33 if (descriptor->extension && descriptor->extension->is_midi() && |
| 34 descriptor->extension->get_midi()->sysex) { |
| 35 return PermissionType::MIDI_SYSEX; |
| 36 } |
31 return PermissionType::MIDI; | 37 return PermissionType::MIDI; |
32 case PermissionName::MIDI_SYSEX: | 38 } |
33 return PermissionType::MIDI_SYSEX; | |
34 case PermissionName::PROTECTED_MEDIA_IDENTIFIER: | 39 case PermissionName::PROTECTED_MEDIA_IDENTIFIER: |
35 return PermissionType::PROTECTED_MEDIA_IDENTIFIER; | 40 return PermissionType::PROTECTED_MEDIA_IDENTIFIER; |
36 case PermissionName::DURABLE_STORAGE: | 41 case PermissionName::DURABLE_STORAGE: |
37 return PermissionType::DURABLE_STORAGE; | 42 return PermissionType::DURABLE_STORAGE; |
38 case PermissionName::AUDIO_CAPTURE: | 43 case PermissionName::AUDIO_CAPTURE: |
39 return PermissionType::AUDIO_CAPTURE; | 44 return PermissionType::AUDIO_CAPTURE; |
40 case PermissionName::VIDEO_CAPTURE: | 45 case PermissionName::VIDEO_CAPTURE: |
41 return PermissionType::VIDEO_CAPTURE; | 46 return PermissionType::VIDEO_CAPTURE; |
42 case PermissionName::BACKGROUND_SYNC: | 47 case PermissionName::BACKGROUND_SYNC: |
43 return PermissionType::BACKGROUND_SYNC; | 48 return PermissionType::BACKGROUND_SYNC; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 DCHECK(pending_requests_.IsEmpty()); | 104 DCHECK(pending_requests_.IsEmpty()); |
100 } | 105 } |
101 | 106 |
102 void PermissionServiceImpl::OnConnectionError() { | 107 void PermissionServiceImpl::OnConnectionError() { |
103 CancelPendingOperations(); | 108 CancelPendingOperations(); |
104 context_->ServiceHadConnectionError(this); | 109 context_->ServiceHadConnectionError(this); |
105 // After that call, |this| will be deleted. | 110 // After that call, |this| will be deleted. |
106 } | 111 } |
107 | 112 |
108 void PermissionServiceImpl::RequestPermission( | 113 void PermissionServiceImpl::RequestPermission( |
109 PermissionName permission, | 114 PermissionDescriptorPtr permission, |
110 const url::Origin& origin, | 115 const url::Origin& origin, |
111 bool user_gesture, | 116 bool user_gesture, |
112 const PermissionStatusCallback& callback) { | 117 const PermissionStatusCallback& callback) { |
113 // This condition is valid if the call is coming from a ChildThread instead of | 118 // This condition is valid if the call is coming from a ChildThread instead of |
114 // a RenderFrame. Some consumers of the service run in Workers and some in | 119 // a RenderFrame. Some consumers of the service run in Workers and some in |
115 // Frames. In the context of a Worker, it is not possible to show a | 120 // Frames. In the context of a Worker, it is not possible to show a |
116 // permission prompt because there is no tab. In the context of a Frame, we | 121 // permission prompt because there is no tab. In the context of a Frame, we |
117 // can. Even if the call comes from a context where it is not possible to show | 122 // can. Even if the call comes from a context where it is not possible to show |
118 // any UI, we want to still return something relevant so the current | 123 // any UI, we want to still return something relevant so the current |
119 // permission status is returned. | 124 // permission status is returned. |
120 BrowserContext* browser_context = context_->GetBrowserContext(); | 125 BrowserContext* browser_context = context_->GetBrowserContext(); |
121 DCHECK(browser_context); | 126 DCHECK(browser_context); |
122 if (!context_->render_frame_host() || | 127 if (!context_->render_frame_host() || |
123 !browser_context->GetPermissionManager()) { | 128 !browser_context->GetPermissionManager()) { |
124 callback.Run(GetPermissionStatusFromName(permission, origin)); | 129 callback.Run(GetPermissionStatus(permission, origin)); |
125 return; | 130 return; |
126 } | 131 } |
127 | 132 |
128 int pending_request_id = pending_requests_.Add(new PendingRequest( | 133 int pending_request_id = pending_requests_.Add(new PendingRequest( |
129 base::Bind(&PermissionRequestResponseCallbackWrapper, callback), 1)); | 134 base::Bind(&PermissionRequestResponseCallbackWrapper, callback), 1)); |
130 int id = browser_context->GetPermissionManager()->RequestPermission( | 135 int id = browser_context->GetPermissionManager()->RequestPermission( |
131 PermissionNameToPermissionType(permission), context_->render_frame_host(), | 136 PermissionDescriptorToPermissionType(permission), |
132 GURL(origin.Serialize()), user_gesture, | 137 context_->render_frame_host(), GURL(origin.Serialize()), user_gesture, |
133 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, | 138 base::Bind(&PermissionServiceImpl::OnRequestPermissionResponse, |
134 weak_factory_.GetWeakPtr(), pending_request_id)); | 139 weak_factory_.GetWeakPtr(), pending_request_id)); |
135 | 140 |
136 // Check if the request still exists. It might have been removed by the | 141 // Check if the request still exists. It might have been removed by the |
137 // callback if it was run synchronously. | 142 // callback if it was run synchronously. |
138 PendingRequest* pending_request = pending_requests_.Lookup( | 143 PendingRequest* pending_request = pending_requests_.Lookup( |
139 pending_request_id); | 144 pending_request_id); |
140 if (!pending_request) | 145 if (!pending_request) |
141 return; | 146 return; |
142 pending_request->id = id; | 147 pending_request->id = id; |
143 } | 148 } |
144 | 149 |
145 void PermissionServiceImpl::OnRequestPermissionResponse( | 150 void PermissionServiceImpl::OnRequestPermissionResponse( |
146 int pending_request_id, | 151 int pending_request_id, |
147 PermissionStatus status) { | 152 PermissionStatus status) { |
148 OnRequestPermissionsResponse(pending_request_id, | 153 OnRequestPermissionsResponse(pending_request_id, |
149 std::vector<PermissionStatus>(1, status)); | 154 std::vector<PermissionStatus>(1, status)); |
150 } | 155 } |
151 | 156 |
152 void PermissionServiceImpl::RequestPermissions( | 157 void PermissionServiceImpl::RequestPermissions( |
153 const std::vector<PermissionName>& permissions, | 158 std::vector<PermissionDescriptorPtr> permissions, |
154 const url::Origin& origin, | 159 const url::Origin& origin, |
155 bool user_gesture, | 160 bool user_gesture, |
156 const RequestPermissionsCallback& callback) { | 161 const RequestPermissionsCallback& callback) { |
157 // This condition is valid if the call is coming from a ChildThread instead of | 162 // This condition is valid if the call is coming from a ChildThread instead of |
158 // a RenderFrame. Some consumers of the service run in Workers and some in | 163 // a RenderFrame. Some consumers of the service run in Workers and some in |
159 // Frames. In the context of a Worker, it is not possible to show a | 164 // Frames. In the context of a Worker, it is not possible to show a |
160 // permission prompt because there is no tab. In the context of a Frame, we | 165 // permission prompt because there is no tab. In the context of a Frame, we |
161 // can. Even if the call comes from a context where it is not possible to show | 166 // can. Even if the call comes from a context where it is not possible to show |
162 // any UI, we want to still return something relevant so the current | 167 // any UI, we want to still return something relevant so the current |
163 // permission status is returned for each permission. | 168 // permission status is returned for each permission. |
164 BrowserContext* browser_context = context_->GetBrowserContext(); | 169 BrowserContext* browser_context = context_->GetBrowserContext(); |
165 DCHECK(browser_context); | 170 DCHECK(browser_context); |
166 if (!context_->render_frame_host() || | 171 if (!context_->render_frame_host() || |
167 !browser_context->GetPermissionManager()) { | 172 !browser_context->GetPermissionManager()) { |
168 std::vector<PermissionStatus> result(permissions.size()); | 173 std::vector<PermissionStatus> result(permissions.size()); |
169 for (size_t i = 0; i < permissions.size(); ++i) { | 174 for (size_t i = 0; i < permissions.size(); ++i) |
170 result[i] = GetPermissionStatusFromName(permissions[i], origin); | 175 result[i] = GetPermissionStatus(permissions[i], origin); |
171 } | |
172 callback.Run(result); | 176 callback.Run(result); |
173 return; | 177 return; |
174 } | 178 } |
175 | 179 |
176 std::vector<PermissionType> types(permissions.size()); | 180 std::vector<PermissionType> types(permissions.size()); |
177 for (size_t i = 0; i < types.size(); ++i) | 181 for (size_t i = 0; i < types.size(); ++i) |
178 types[i] = PermissionNameToPermissionType(permissions[i]); | 182 types[i] = PermissionDescriptorToPermissionType(permissions[i]); |
179 | 183 |
180 int pending_request_id = pending_requests_.Add( | 184 int pending_request_id = pending_requests_.Add( |
181 new PendingRequest(callback, permissions.size())); | 185 new PendingRequest(callback, permissions.size())); |
182 int id = browser_context->GetPermissionManager()->RequestPermissions( | 186 int id = browser_context->GetPermissionManager()->RequestPermissions( |
183 types, context_->render_frame_host(), GURL(origin.Serialize()), | 187 types, context_->render_frame_host(), GURL(origin.Serialize()), |
184 user_gesture, | 188 user_gesture, |
185 base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse, | 189 base::Bind(&PermissionServiceImpl::OnRequestPermissionsResponse, |
186 weak_factory_.GetWeakPtr(), pending_request_id)); | 190 weak_factory_.GetWeakPtr(), pending_request_id)); |
187 | 191 |
188 // Check if the request still exists. It may have been removed by the | 192 // Check if the request still exists. It may have been removed by the |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType( | 230 it.GetCurrentValue()->callback.Run(GetPermissionStatusFromType( |
227 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); | 231 it.GetCurrentValue()->permission, it.GetCurrentValue()->origin)); |
228 it.GetCurrentValue()->callback.Reset(); | 232 it.GetCurrentValue()->callback.Reset(); |
229 permission_manager->UnsubscribePermissionStatusChange( | 233 permission_manager->UnsubscribePermissionStatusChange( |
230 it.GetCurrentValue()->id); | 234 it.GetCurrentValue()->id); |
231 } | 235 } |
232 pending_subscriptions_.Clear(); | 236 pending_subscriptions_.Clear(); |
233 } | 237 } |
234 | 238 |
235 void PermissionServiceImpl::HasPermission( | 239 void PermissionServiceImpl::HasPermission( |
236 PermissionName permission, | 240 PermissionDescriptorPtr permission, |
237 const url::Origin& origin, | 241 const url::Origin& origin, |
238 const PermissionStatusCallback& callback) { | 242 const PermissionStatusCallback& callback) { |
239 callback.Run(GetPermissionStatusFromName(permission, origin)); | 243 callback.Run(GetPermissionStatus(permission, origin)); |
240 } | 244 } |
241 | 245 |
242 void PermissionServiceImpl::RevokePermission( | 246 void PermissionServiceImpl::RevokePermission( |
243 PermissionName permission, | 247 PermissionDescriptorPtr permission, |
244 const url::Origin& origin, | 248 const url::Origin& origin, |
245 const PermissionStatusCallback& callback) { | 249 const PermissionStatusCallback& callback) { |
246 PermissionType permission_type = PermissionNameToPermissionType(permission); | 250 PermissionType permission_type = |
| 251 PermissionDescriptorToPermissionType(permission); |
247 PermissionStatus status = | 252 PermissionStatus status = |
248 GetPermissionStatusFromType(permission_type, origin); | 253 GetPermissionStatusFromType(permission_type, origin); |
249 | 254 |
250 // Resetting the permission should only be possible if the permission is | 255 // Resetting the permission should only be possible if the permission is |
251 // already granted. | 256 // already granted. |
252 if (status != PermissionStatus::GRANTED) { | 257 if (status != PermissionStatus::GRANTED) { |
253 callback.Run(status); | 258 callback.Run(status); |
254 return; | 259 return; |
255 } | 260 } |
256 | 261 |
257 ResetPermissionStatus(permission_type, origin); | 262 ResetPermissionStatus(permission_type, origin); |
258 | 263 |
259 callback.Run(GetPermissionStatusFromType(permission_type, origin)); | 264 callback.Run(GetPermissionStatusFromType(permission_type, origin)); |
260 } | 265 } |
261 | 266 |
262 void PermissionServiceImpl::GetNextPermissionChange( | 267 void PermissionServiceImpl::GetNextPermissionChange( |
263 PermissionName permission, | 268 PermissionDescriptorPtr permission, |
264 const url::Origin& origin, | 269 const url::Origin& origin, |
265 PermissionStatus last_known_status, | 270 PermissionStatus last_known_status, |
266 const PermissionStatusCallback& callback) { | 271 const PermissionStatusCallback& callback) { |
267 PermissionStatus current_status = | 272 PermissionStatus current_status = GetPermissionStatus(permission, origin); |
268 GetPermissionStatusFromName(permission, origin); | |
269 if (current_status != last_known_status) { | 273 if (current_status != last_known_status) { |
270 callback.Run(current_status); | 274 callback.Run(current_status); |
271 return; | 275 return; |
272 } | 276 } |
273 | 277 |
274 BrowserContext* browser_context = context_->GetBrowserContext(); | 278 BrowserContext* browser_context = context_->GetBrowserContext(); |
275 DCHECK(browser_context); | 279 DCHECK(browser_context); |
276 if (!browser_context->GetPermissionManager()) { | 280 if (!browser_context->GetPermissionManager()) { |
277 callback.Run(current_status); | 281 callback.Run(current_status); |
278 return; | 282 return; |
279 } | 283 } |
280 | 284 |
281 PermissionType permission_type = PermissionNameToPermissionType(permission); | 285 PermissionType permission_type = |
| 286 PermissionDescriptorToPermissionType(permission); |
282 | 287 |
283 // We need to pass the id of PendingSubscription in pending_subscriptions_ | 288 // We need to pass the id of PendingSubscription in pending_subscriptions_ |
284 // to the callback but SubscribePermissionStatusChange() will also return an | 289 // to the callback but SubscribePermissionStatusChange() will also return an |
285 // id which is different. | 290 // id which is different. |
286 PendingSubscription* subscription = | 291 PendingSubscription* subscription = |
287 new PendingSubscription(permission_type, origin, callback); | 292 new PendingSubscription(permission_type, origin, callback); |
288 int pending_subscription_id = pending_subscriptions_.Add(subscription); | 293 int pending_subscription_id = pending_subscriptions_.Add(subscription); |
289 | 294 |
290 GURL requesting_origin(origin.Serialize()); | 295 GURL requesting_origin(origin.Serialize()); |
291 GURL embedding_origin = context_->GetEmbeddingOrigin(); | 296 GURL embedding_origin = context_->GetEmbeddingOrigin(); |
292 subscription->id = | 297 subscription->id = |
293 browser_context->GetPermissionManager()->SubscribePermissionStatusChange( | 298 browser_context->GetPermissionManager()->SubscribePermissionStatusChange( |
294 permission_type, requesting_origin, | 299 permission_type, requesting_origin, |
295 // If the embedding_origin is empty, we,ll use the |origin| instead. | 300 // If the embedding_origin is empty, we,ll use the |origin| instead. |
296 embedding_origin.is_empty() ? requesting_origin : embedding_origin, | 301 embedding_origin.is_empty() ? requesting_origin : embedding_origin, |
297 base::Bind(&PermissionServiceImpl::OnPermissionStatusChanged, | 302 base::Bind(&PermissionServiceImpl::OnPermissionStatusChanged, |
298 weak_factory_.GetWeakPtr(), pending_subscription_id)); | 303 weak_factory_.GetWeakPtr(), pending_subscription_id)); |
299 } | 304 } |
300 | 305 |
301 PermissionStatus PermissionServiceImpl::GetPermissionStatusFromName( | 306 PermissionStatus PermissionServiceImpl::GetPermissionStatus( |
302 PermissionName permission, | 307 const PermissionDescriptorPtr& permission, |
303 const url::Origin& origin) { | 308 const url::Origin& origin) { |
304 return GetPermissionStatusFromType(PermissionNameToPermissionType(permission), | 309 return GetPermissionStatusFromType( |
305 origin); | 310 PermissionDescriptorToPermissionType(permission), origin); |
306 } | 311 } |
307 | 312 |
308 PermissionStatus PermissionServiceImpl::GetPermissionStatusFromType( | 313 PermissionStatus PermissionServiceImpl::GetPermissionStatusFromType( |
309 PermissionType type, | 314 PermissionType type, |
310 const url::Origin& origin) { | 315 const url::Origin& origin) { |
311 BrowserContext* browser_context = context_->GetBrowserContext(); | 316 BrowserContext* browser_context = context_->GetBrowserContext(); |
312 DCHECK(browser_context); | 317 DCHECK(browser_context); |
313 if (!browser_context->GetPermissionManager()) | 318 if (!browser_context->GetPermissionManager()) |
314 return PermissionStatus::DENIED; | 319 return PermissionStatus::DENIED; |
315 | 320 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 | 356 |
352 PermissionStatusCallback callback = subscription->callback; | 357 PermissionStatusCallback callback = subscription->callback; |
353 | 358 |
354 subscription->callback.Reset(); | 359 subscription->callback.Reset(); |
355 pending_subscriptions_.Remove(pending_subscription_id); | 360 pending_subscriptions_.Remove(pending_subscription_id); |
356 | 361 |
357 callback.Run(status); | 362 callback.Run(status); |
358 } | 363 } |
359 | 364 |
360 } // namespace content | 365 } // namespace content |
OLD | NEW |