OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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 "chrome/browser/permissions/permission_manager.h" | 5 #include "chrome/browser/permissions/permission_manager.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/memory/ptr_util.h" |
10 #include "build/build_config.h" | 11 #include "build/build_config.h" |
| 12 #include "chrome/browser/background_sync/background_sync_permission_context.h" |
11 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 13 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
12 #include "chrome/browser/permissions/permission_context.h" | 14 #include "chrome/browser/media/media_stream_device_permission_context.h" |
| 15 #include "chrome/browser/media/midi_permission_context.h" |
| 16 #include "chrome/browser/notifications/notification_permission_context.h" |
13 #include "chrome/browser/permissions/permission_context_base.h" | 17 #include "chrome/browser/permissions/permission_context_base.h" |
| 18 #include "chrome/browser/permissions/permission_manager_factory.h" |
14 #include "chrome/browser/permissions/permission_request_id.h" | 19 #include "chrome/browser/permissions/permission_request_id.h" |
15 #include "chrome/browser/profiles/profile.h" | 20 #include "chrome/browser/profiles/profile.h" |
| 21 #include "chrome/browser/push_messaging/push_messaging_permission_context.h" |
| 22 #include "chrome/browser/storage/durable_storage_permission_context.h" |
16 #include "chrome/browser/tab_contents/tab_util.h" | 23 #include "chrome/browser/tab_contents/tab_util.h" |
| 24 #include "chrome/common/features.h" |
17 #include "components/content_settings/core/browser/host_content_settings_map.h" | 25 #include "components/content_settings/core/browser/host_content_settings_map.h" |
18 #include "content/public/browser/permission_type.h" | 26 #include "content/public/browser/permission_type.h" |
19 #include "content/public/browser/render_frame_host.h" | 27 #include "content/public/browser/render_frame_host.h" |
20 #include "content/public/browser/render_process_host.h" | 28 #include "content/public/browser/render_process_host.h" |
21 #include "content/public/browser/web_contents.h" | 29 #include "content/public/browser/web_contents.h" |
22 | 30 |
| 31 #if defined(OS_ANDROID) || defined(OS_CHROMEOS) |
| 32 #include "chrome/browser/media/protected_media_identifier_permission_context.h" |
| 33 #endif |
| 34 |
23 #if !defined(OS_ANDROID) | 35 #if !defined(OS_ANDROID) |
24 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h" | 36 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h" |
25 #endif | 37 #endif |
26 | 38 |
| 39 #if BUILDFLAG(ANDROID_JAVA_UI) |
| 40 #include "chrome/browser/geolocation/geolocation_permission_context_android.h" |
| 41 #else |
| 42 #include "chrome/browser/geolocation/geolocation_permission_context.h" |
| 43 #endif |
| 44 |
27 using blink::mojom::PermissionStatus; | 45 using blink::mojom::PermissionStatus; |
28 using content::PermissionType; | 46 using content::PermissionType; |
29 | 47 |
30 namespace { | 48 namespace { |
31 | 49 |
32 // Helper method to convert ContentSetting to PermissionStatus. | 50 // Helper method to convert ContentSetting to PermissionStatus. |
33 PermissionStatus ContentSettingToPermissionStatus(ContentSetting setting) { | 51 PermissionStatus ContentSettingToPermissionStatus(ContentSetting setting) { |
34 switch (setting) { | 52 switch (setting) { |
35 case CONTENT_SETTING_ALLOW: | 53 case CONTENT_SETTING_ALLOW: |
36 case CONTENT_SETTING_SESSION_ONLY: | 54 case CONTENT_SETTING_SESSION_ONLY: |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 } | 110 } |
93 | 111 |
94 NOTREACHED() << "Unknown content setting for permission " | 112 NOTREACHED() << "Unknown content setting for permission " |
95 << static_cast<int>(permission); | 113 << static_cast<int>(permission); |
96 return CONTENT_SETTINGS_TYPE_DEFAULT; | 114 return CONTENT_SETTINGS_TYPE_DEFAULT; |
97 } | 115 } |
98 | 116 |
99 // Returns whether the permission has a constant PermissionStatus value (i.e. | 117 // Returns whether the permission has a constant PermissionStatus value (i.e. |
100 // always approved or always denied) | 118 // always approved or always denied) |
101 // The PermissionTypes for which true is returned should be exactly those which | 119 // The PermissionTypes for which true is returned should be exactly those which |
102 // return nullptr in PermissionContext::Get since they don't have a context. | 120 // return nullptr in PermissionManager::GetPermissionContext since they don't |
| 121 // have a context. |
103 bool IsConstantPermission(PermissionType type) { | 122 bool IsConstantPermission(PermissionType type) { |
104 switch (type) { | 123 switch (type) { |
105 case PermissionType::MIDI: | 124 case PermissionType::MIDI: |
106 return true; | 125 return true; |
107 default: | 126 default: |
108 return false; | 127 return false; |
109 } | 128 } |
110 } | 129 } |
111 | 130 |
112 void PermissionRequestResponseCallbackWrapper( | 131 void PermissionRequestResponseCallbackWrapper( |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 }; | 207 }; |
189 | 208 |
190 struct PermissionManager::Subscription { | 209 struct PermissionManager::Subscription { |
191 PermissionType permission; | 210 PermissionType permission; |
192 GURL requesting_origin; | 211 GURL requesting_origin; |
193 GURL embedding_origin; | 212 GURL embedding_origin; |
194 base::Callback<void(PermissionStatus)> callback; | 213 base::Callback<void(PermissionStatus)> callback; |
195 ContentSetting current_value; | 214 ContentSetting current_value; |
196 }; | 215 }; |
197 | 216 |
| 217 // static |
| 218 PermissionManager* PermissionManager::Get(Profile* profile) { |
| 219 return PermissionManagerFactory::GetForProfile(profile); |
| 220 } |
| 221 |
198 PermissionManager::PermissionManager(Profile* profile) | 222 PermissionManager::PermissionManager(Profile* profile) |
199 : profile_(profile), | 223 : profile_(profile), |
200 weak_ptr_factory_(this) { | 224 weak_ptr_factory_(this) { |
| 225 permission_contexts_[PermissionType::MIDI_SYSEX] = |
| 226 base::WrapUnique(new MidiPermissionContext(profile)); |
| 227 permission_contexts_[PermissionType::PUSH_MESSAGING] = |
| 228 base::WrapUnique(new PushMessagingPermissionContext(profile)); |
| 229 permission_contexts_[PermissionType::NOTIFICATIONS] = |
| 230 base::WrapUnique(new NotificationPermissionContext(profile)); |
| 231 #if !BUILDFLAG(ANDROID_JAVA_UI) |
| 232 permission_contexts_[PermissionType::GEOLOCATION] = |
| 233 base::WrapUnique(new GeolocationPermissionContext(profile)); |
| 234 #else |
| 235 permission_contexts_[PermissionType::GEOLOCATION] = |
| 236 base::WrapUnique(new GeolocationPermissionContextAndroid(profile)); |
| 237 #endif |
| 238 #if defined(OS_CHROMEOS) || defined(OS_ANDROID) |
| 239 permission_contexts_[PermissionType::PROTECTED_MEDIA_IDENTIFIER] = |
| 240 base::WrapUnique(new ProtectedMediaIdentifierPermissionContext(profile)); |
| 241 #endif |
| 242 permission_contexts_[PermissionType::DURABLE_STORAGE] = |
| 243 base::WrapUnique(new DurableStoragePermissionContext(profile)); |
| 244 permission_contexts_[PermissionType::AUDIO_CAPTURE] = |
| 245 base::WrapUnique(new MediaStreamDevicePermissionContext( |
| 246 profile, content::PermissionType::AUDIO_CAPTURE, |
| 247 CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)); |
| 248 permission_contexts_[PermissionType::VIDEO_CAPTURE] = |
| 249 base::WrapUnique(new MediaStreamDevicePermissionContext( |
| 250 profile, content::PermissionType::VIDEO_CAPTURE, |
| 251 CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)); |
| 252 permission_contexts_[PermissionType::BACKGROUND_SYNC] = |
| 253 base::WrapUnique(new BackgroundSyncPermissionContext(profile)); |
201 } | 254 } |
202 | 255 |
203 PermissionManager::~PermissionManager() { | 256 PermissionManager::~PermissionManager() { |
204 if (!subscriptions_.IsEmpty()) | 257 if (!subscriptions_.IsEmpty()) |
205 HostContentSettingsMapFactory::GetForProfile(profile_) | 258 HostContentSettingsMapFactory::GetForProfile(profile_) |
206 ->RemoveObserver(this); | 259 ->RemoveObserver(this); |
207 } | 260 } |
208 | 261 |
209 int PermissionManager::RequestPermission( | 262 int PermissionManager::RequestPermission( |
210 PermissionType permission, | 263 PermissionType permission, |
(...skipping 26 matching lines...) Expand all Loading... |
237 render_frame_host, permissions, callback); | 290 render_frame_host, permissions, callback); |
238 int request_id = pending_requests_.Add(pending_request); | 291 int request_id = pending_requests_.Add(pending_request); |
239 | 292 |
240 const PermissionRequestID request(render_frame_host, request_id); | 293 const PermissionRequestID request(render_frame_host, request_id); |
241 | 294 |
242 for (size_t i = 0; i < permissions.size(); ++i) { | 295 for (size_t i = 0; i < permissions.size(); ++i) { |
243 const PermissionType permission = permissions[i]; | 296 const PermissionType permission = permissions[i]; |
244 | 297 |
245 if (IsConstantPermission(permission) || | 298 if (IsConstantPermission(permission) || |
246 IsPermissionBubbleManagerMissing(web_contents) || | 299 IsPermissionBubbleManagerMissing(web_contents) || |
247 !PermissionContext::Get(profile_, permission)) { | 300 !GetPermissionContext(permission)) { |
248 OnPermissionsRequestResponseStatus(request_id, i, | 301 OnPermissionsRequestResponseStatus(request_id, i, |
249 GetPermissionStatus(permission, requesting_origin, embedding_origin)); | 302 GetPermissionStatus(permission, requesting_origin, embedding_origin)); |
250 continue; | 303 continue; |
251 } | 304 } |
252 | 305 |
253 PermissionContextBase* context = PermissionContext::Get( | 306 PermissionContextBase* context = GetPermissionContext(permission); |
254 profile_, permission); | |
255 context->RequestPermission( | 307 context->RequestPermission( |
256 web_contents, request, requesting_origin, | 308 web_contents, request, requesting_origin, |
257 base::Bind(&ContentSettingToPermissionStatusCallbackWrapper, | 309 base::Bind(&ContentSettingToPermissionStatusCallbackWrapper, |
258 base::Bind(&PermissionManager::OnPermissionsRequestResponseStatus, | 310 base::Bind(&PermissionManager::OnPermissionsRequestResponseStatus, |
259 weak_ptr_factory_.GetWeakPtr(), request_id, i))); | 311 weak_ptr_factory_.GetWeakPtr(), request_id, i))); |
260 } | 312 } |
261 | 313 |
262 // The request might have been resolved already. | 314 // The request might have been resolved already. |
263 if (!pending_requests_.Lookup(request_id)) | 315 if (!pending_requests_.Lookup(request_id)) |
264 return kNoPendingOperation; | 316 return kNoPendingOperation; |
265 | 317 |
266 return request_id; | 318 return request_id; |
267 } | 319 } |
268 | 320 |
| 321 PermissionContextBase* PermissionManager::GetPermissionContext( |
| 322 PermissionType type) { |
| 323 const auto& it = permission_contexts_.find(type); |
| 324 return it == permission_contexts_.end() ? nullptr : it->second.get(); |
| 325 } |
| 326 |
269 void PermissionManager::OnPermissionsRequestResponseStatus( | 327 void PermissionManager::OnPermissionsRequestResponseStatus( |
270 int request_id, | 328 int request_id, |
271 int permission_id, | 329 int permission_id, |
272 PermissionStatus status) { | 330 PermissionStatus status) { |
273 PendingRequest* pending_request = pending_requests_.Lookup(request_id); | 331 PendingRequest* pending_request = pending_requests_.Lookup(request_id); |
274 pending_request->SetPermissionStatus(permission_id, status); | 332 pending_request->SetPermissionStatus(permission_id, status); |
275 | 333 |
276 if (!pending_request->IsComplete()) | 334 if (!pending_request->IsComplete()) |
277 return; | 335 return; |
278 | 336 |
(...skipping 11 matching lines...) Expand all Loading... |
290 DCHECK(web_contents); | 348 DCHECK(web_contents); |
291 if (IsPermissionBubbleManagerMissing(web_contents)) { | 349 if (IsPermissionBubbleManagerMissing(web_contents)) { |
292 pending_requests_.Remove(request_id); | 350 pending_requests_.Remove(request_id); |
293 return; | 351 return; |
294 } | 352 } |
295 | 353 |
296 const PermissionRequestID request(pending_request->render_process_id(), | 354 const PermissionRequestID request(pending_request->render_process_id(), |
297 pending_request->render_frame_id(), | 355 pending_request->render_frame_id(), |
298 request_id); | 356 request_id); |
299 for (PermissionType permission : pending_request->permissions()) { | 357 for (PermissionType permission : pending_request->permissions()) { |
300 PermissionContextBase* context = PermissionContext::Get( | 358 PermissionContextBase* context = GetPermissionContext(permission); |
301 profile_, permission); | |
302 if (!context) | 359 if (!context) |
303 continue; | 360 continue; |
304 context->CancelPermissionRequest(web_contents, request); | 361 context->CancelPermissionRequest(web_contents, request); |
305 } | 362 } |
306 pending_requests_.Remove(request_id); | 363 pending_requests_.Remove(request_id); |
307 } | 364 } |
308 | 365 |
309 void PermissionManager::ResetPermission(PermissionType permission, | 366 void PermissionManager::ResetPermission(PermissionType permission, |
310 const GURL& requesting_origin, | 367 const GURL& requesting_origin, |
311 const GURL& embedding_origin) { | 368 const GURL& embedding_origin) { |
312 PermissionContextBase* context = PermissionContext::Get(profile_, permission); | 369 PermissionContextBase* context = GetPermissionContext(permission); |
313 if (!context) | 370 if (!context) |
314 return; | 371 return; |
315 | 372 |
316 context->ResetPermission(requesting_origin.GetOrigin(), | 373 context->ResetPermission(requesting_origin.GetOrigin(), |
317 embedding_origin.GetOrigin()); | 374 embedding_origin.GetOrigin()); |
318 } | 375 } |
319 | 376 |
320 PermissionStatus PermissionManager::GetPermissionStatus( | 377 PermissionStatus PermissionManager::GetPermissionStatus( |
321 PermissionType permission, | 378 PermissionType permission, |
322 const GURL& requesting_origin, | 379 const GURL& requesting_origin, |
323 const GURL& embedding_origin) { | 380 const GURL& embedding_origin) { |
324 if (IsConstantPermission(permission)) | 381 if (IsConstantPermission(permission)) |
325 return GetPermissionStatusForConstantPermission(permission); | 382 return GetPermissionStatusForConstantPermission(permission); |
326 | 383 |
327 PermissionContextBase* context = PermissionContext::Get(profile_, permission); | 384 PermissionContextBase* context = GetPermissionContext(permission); |
328 if (!context) | 385 if (!context) |
329 return PermissionStatus::DENIED; | 386 return PermissionStatus::DENIED; |
330 | 387 |
331 return ContentSettingToPermissionStatus(context->GetPermissionStatus( | 388 return ContentSettingToPermissionStatus(context->GetPermissionStatus( |
332 requesting_origin.GetOrigin(), embedding_origin.GetOrigin())); | 389 requesting_origin.GetOrigin(), embedding_origin.GetOrigin())); |
333 } | 390 } |
334 | 391 |
335 void PermissionManager::RegisterPermissionUsage(PermissionType permission, | 392 void PermissionManager::RegisterPermissionUsage(PermissionType permission, |
336 const GURL& requesting_origin, | 393 const GURL& requesting_origin, |
337 const GURL& embedding_origin) { | 394 const GURL& embedding_origin) { |
(...skipping 19 matching lines...) Expand all Loading... |
357 Subscription* subscription = new Subscription(); | 414 Subscription* subscription = new Subscription(); |
358 subscription->permission = permission; | 415 subscription->permission = permission; |
359 subscription->requesting_origin = requesting_origin; | 416 subscription->requesting_origin = requesting_origin; |
360 subscription->embedding_origin = embedding_origin; | 417 subscription->embedding_origin = embedding_origin; |
361 subscription->callback = callback; | 418 subscription->callback = callback; |
362 | 419 |
363 if (IsConstantPermission(permission)) { | 420 if (IsConstantPermission(permission)) { |
364 subscription->current_value = GetContentSettingForConstantPermission( | 421 subscription->current_value = GetContentSettingForConstantPermission( |
365 permission); | 422 permission); |
366 } else { | 423 } else { |
367 subscription->current_value = PermissionContext::Get(profile_, permission) | 424 subscription->current_value = |
368 ->GetPermissionStatus(subscription->requesting_origin, | 425 GetPermissionContext(permission) |
369 subscription->embedding_origin); | 426 ->GetPermissionStatus(subscription->requesting_origin, |
| 427 subscription->embedding_origin); |
370 } | 428 } |
371 | 429 |
372 return subscriptions_.Add(subscription); | 430 return subscriptions_.Add(subscription); |
373 } | 431 } |
374 | 432 |
375 void PermissionManager::UnsubscribePermissionStatusChange(int subscription_id) { | 433 void PermissionManager::UnsubscribePermissionStatusChange(int subscription_id) { |
376 // Whether |subscription_id| is known will be checked by the Remove() call. | 434 // Whether |subscription_id| is known will be checked by the Remove() call. |
377 subscriptions_.Remove(subscription_id); | 435 subscriptions_.Remove(subscription_id); |
378 | 436 |
379 if (subscriptions_.IsEmpty()) | 437 if (subscriptions_.IsEmpty()) |
(...skipping 24 matching lines...) Expand all Loading... |
404 } | 462 } |
405 | 463 |
406 if (primary_pattern.IsValid() && | 464 if (primary_pattern.IsValid() && |
407 !primary_pattern.Matches(subscription->requesting_origin)) | 465 !primary_pattern.Matches(subscription->requesting_origin)) |
408 continue; | 466 continue; |
409 if (secondary_pattern.IsValid() && | 467 if (secondary_pattern.IsValid() && |
410 !secondary_pattern.Matches(subscription->embedding_origin)) | 468 !secondary_pattern.Matches(subscription->embedding_origin)) |
411 continue; | 469 continue; |
412 | 470 |
413 ContentSetting new_value = | 471 ContentSetting new_value = |
414 PermissionContext::Get(profile_, subscription->permission) | 472 GetPermissionContext(subscription->permission) |
415 ->GetPermissionStatus(subscription->requesting_origin, | 473 ->GetPermissionStatus(subscription->requesting_origin, |
416 subscription->embedding_origin); | 474 subscription->embedding_origin); |
417 if (subscription->current_value == new_value) | 475 if (subscription->current_value == new_value) |
418 continue; | 476 continue; |
419 | 477 |
420 subscription->current_value = new_value; | 478 subscription->current_value = new_value; |
421 | 479 |
422 // Add the callback to |callbacks| which will be run after the loop to | 480 // Add the callback to |callbacks| which will be run after the loop to |
423 // prevent re-entrance issues. | 481 // prevent re-entrance issues. |
424 callbacks.push_back( | 482 callbacks.push_back( |
425 base::Bind(subscription->callback, | 483 base::Bind(subscription->callback, |
426 ContentSettingToPermissionStatus(new_value))); | 484 ContentSettingToPermissionStatus(new_value))); |
427 } | 485 } |
428 | 486 |
429 for (const auto& callback : callbacks) | 487 for (const auto& callback : callbacks) |
430 callback.Run(); | 488 callback.Run(); |
431 } | 489 } |
OLD | NEW |