Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: chrome/browser/media/media_stream_devices_controller.cc

Issue 336653002: Revert: Per navigation sticky media permissions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/media/chrome_media_stream_infobar_browsertest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/media/media_stream_devices_controller.h" 5 #include "chrome/browser/media/media_stream_devices_controller.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/prefs/pref_service.h" 9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/scoped_user_pref_update.h" 10 #include "base/prefs/scoped_user_pref_update.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "chrome/browser/content_settings/content_settings_provider.h" 13 #include "chrome/browser/content_settings/content_settings_provider.h"
14 #include "chrome/browser/content_settings/host_content_settings_map.h" 14 #include "chrome/browser/content_settings/host_content_settings_map.h"
15 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 15 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
16 #include "chrome/browser/media/media_capture_devices_dispatcher.h" 16 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
17 #include "chrome/browser/media/media_stream_capture_indicator.h" 17 #include "chrome/browser/media/media_stream_capture_indicator.h"
18 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/browser.h" 19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/common/chrome_switches.h" 20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/content_settings.h" 21 #include "chrome/common/content_settings.h"
22 #include "chrome/common/content_settings_pattern.h" 22 #include "chrome/common/content_settings_pattern.h"
23 #include "chrome/common/pref_names.h" 23 #include "chrome/common/pref_names.h"
24 #include "components/pref_registry/pref_registry_syncable.h" 24 #include "components/pref_registry/pref_registry_syncable.h"
25 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/navigation_entry.h"
27 #include "content/public/common/media_stream_request.h" 26 #include "content/public/common/media_stream_request.h"
28 #include "extensions/common/constants.h" 27 #include "extensions/common/constants.h"
29 #include "grit/generated_resources.h" 28 #include "grit/generated_resources.h"
30 #include "grit/theme_resources.h" 29 #include "grit/theme_resources.h"
31 #include "ui/base/l10n/l10n_util.h" 30 #include "ui/base/l10n/l10n_util.h"
32 31
33 #if defined(OS_CHROMEOS) 32 #if defined(OS_CHROMEOS)
34 #include "chrome/browser/chromeos/login/users/user_manager.h" 33 #include "chrome/browser/chromeos/login/users/user_manager.h"
35 #endif 34 #endif
36 35
37 using content::BrowserThread; 36 using content::BrowserThread;
38 37
39 namespace { 38 namespace {
40 39
41 // This prefix is combined with request security origins to store media access
42 // permissions that the user has granted a specific page navigation instance.
43 // The string value stored with the navigation instance will contain one or more
44 // kMediaPermissionXxx constants that indicates the permission(s) that the user
45 // has granted the page.
46 const char kMediaPermissionKeyPrefix[] = "media_permissions#";
47 const base::char16 kMediaPermissionAudio = static_cast<base::char16>('a');
48 const base::char16 kMediaPermissionVideo = static_cast<base::char16>('v');
49
50 bool HasAvailableDevicesForRequest(const content::MediaStreamRequest& request) { 40 bool HasAvailableDevicesForRequest(const content::MediaStreamRequest& request) {
51 const content::MediaStreamDevices* audio_devices = 41 const content::MediaStreamDevices* audio_devices =
52 request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ? 42 request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ?
53 &MediaCaptureDevicesDispatcher::GetInstance() 43 &MediaCaptureDevicesDispatcher::GetInstance()
54 ->GetAudioCaptureDevices() : 44 ->GetAudioCaptureDevices() :
55 NULL; 45 NULL;
56 46
57 const content::MediaStreamDevices* video_devices = 47 const content::MediaStreamDevices* video_devices =
58 request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE ? 48 request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE ?
59 &MediaCaptureDevicesDispatcher::GetInstance() 49 &MediaCaptureDevicesDispatcher::GetInstance()
(...skipping 23 matching lines...) Expand all
83 } 73 }
84 74
85 if (!request.requested_video_device_id.empty() && 75 if (!request.requested_video_device_id.empty() &&
86 !video_devices->FindById(request.requested_video_device_id)) { 76 !video_devices->FindById(request.requested_video_device_id)) {
87 return false; 77 return false;
88 } 78 }
89 79
90 return true; 80 return true;
91 } 81 }
92 82
93 base::string16 GetMediaPermissionsFromNavigationEntry(
94 content::NavigationEntry* navigation_entry,
95 const content::MediaStreamRequest& request) {
96 const std::string key(kMediaPermissionKeyPrefix +
97 request.security_origin.spec());
98
99 base::string16 permissions;
100 if (!navigation_entry->GetExtraData(key, &permissions)) {
101 DCHECK(permissions.empty());
102 }
103
104 return permissions;
105 }
106
107 void SetMediaPermissionsForNavigationEntry(
108 content::NavigationEntry* navigation_entry,
109 const content::MediaStreamRequest& request,
110 const base::string16& permissions) {
111 const std::string key(kMediaPermissionKeyPrefix +
112 request.security_origin.spec());
113 permissions.empty() ?
114 navigation_entry->ClearExtraData(key) :
115 navigation_entry->SetExtraData(key, permissions);
116 }
117
118 void SetMediaPermissionsForNavigationEntry(
119 content::NavigationEntry* navigation_entry,
120 const content::MediaStreamRequest& request,
121 bool allow_audio,
122 bool allow_video) {
123 base::string16 permissions;
124 if (allow_audio)
125 permissions += kMediaPermissionAudio;
126 if (allow_video)
127 permissions += kMediaPermissionVideo;
128 SetMediaPermissionsForNavigationEntry(navigation_entry, request, permissions);
129 }
130
131 bool IsRequestAllowedByNavigationEntry(
132 content::NavigationEntry* navigation_entry,
133 const content::MediaStreamRequest& request) {
134 using content::MEDIA_NO_SERVICE;
135 using content::MEDIA_DEVICE_AUDIO_CAPTURE;
136 using content::MEDIA_DEVICE_VIDEO_CAPTURE;
137
138 // If we aren't being asked for at least one of these two, fail right away.
139 if (!navigation_entry ||
140 (request.audio_type != MEDIA_DEVICE_AUDIO_CAPTURE &&
141 request.video_type != MEDIA_DEVICE_VIDEO_CAPTURE)) {
142 return false;
143 }
144
145 base::string16 permissions =
146 GetMediaPermissionsFromNavigationEntry(navigation_entry, request);
147
148 bool audio_requested_and_granted =
149 request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE &&
150 permissions.find(kMediaPermissionAudio) != base::string16::npos;
151
152 bool video_requested_and_granted =
153 request.video_type == MEDIA_DEVICE_VIDEO_CAPTURE &&
154 permissions.find(kMediaPermissionVideo) != base::string16::npos;
155
156 return
157 (audio_requested_and_granted || request.audio_type == MEDIA_NO_SERVICE) &&
158 (video_requested_and_granted || request.video_type == MEDIA_NO_SERVICE);
159 }
160
161
162 bool IsInKioskMode() { 83 bool IsInKioskMode() {
163 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) 84 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
164 return true; 85 return true;
165 86
166 #if defined(OS_CHROMEOS) 87 #if defined(OS_CHROMEOS)
167 const chromeos::UserManager* user_manager = chromeos::UserManager::Get(); 88 const chromeos::UserManager* user_manager = chromeos::UserManager::Get();
168 return user_manager && user_manager->IsLoggedInAsKioskApp(); 89 return user_manager && user_manager->IsLoggedInAsKioskApp();
169 #else 90 #else
170 return false; 91 return false;
171 #endif 92 #endif
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED); 223 Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED);
303 return true; 224 return true;
304 } 225 }
305 226
306 // Check if the media default setting is set to block. 227 // Check if the media default setting is set to block.
307 if (IsDefaultMediaAccessBlocked()) { 228 if (IsDefaultMediaAccessBlocked()) {
308 Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED); 229 Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED);
309 return true; 230 return true;
310 } 231 }
311 232
312 // Check if the navigation entry has previously been granted access.
313 // We do this after the IsDefaultMediaAccessBlocked check to handle the use
314 // case where the user modifies the content settings to 'deny' after having
315 // previously granted the page access and the permissions in the
316 // NavigationEntry are out of date.
317 content::NavigationEntry* navigation_entry =
318 web_contents_->GetController().GetVisibleEntry();
319 if (IsRequestAllowedByNavigationEntry(navigation_entry, request_)) {
320 Accept(false);
321 return true;
322 }
323
324 // Show the infobar. 233 // Show the infobar.
325 return false; 234 return false;
326 } 235 }
327 236
328 bool MediaStreamDevicesController::HasAudio() const { 237 bool MediaStreamDevicesController::HasAudio() const {
329 return IsDeviceAudioCaptureRequestedAndAllowed(); 238 return IsDeviceAudioCaptureRequestedAndAllowed();
330 } 239 }
331 240
332 bool MediaStreamDevicesController::HasVideo() const { 241 bool MediaStreamDevicesController::HasVideo() const {
333 return IsDeviceVideoCaptureRequestedAndAllowed(); 242 return IsDeviceVideoCaptureRequestedAndAllowed();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 311
403 // If either or both audio and video devices were requested but not 312 // If either or both audio and video devices were requested but not
404 // specified by id, get the default devices. 313 // specified by id, get the default devices.
405 if (get_default_audio_device || get_default_video_device) { 314 if (get_default_audio_device || get_default_video_device) {
406 MediaCaptureDevicesDispatcher::GetInstance()-> 315 MediaCaptureDevicesDispatcher::GetInstance()->
407 GetDefaultDevicesForProfile(profile_, 316 GetDefaultDevicesForProfile(profile_,
408 get_default_audio_device, 317 get_default_audio_device,
409 get_default_video_device, 318 get_default_video_device,
410 &devices); 319 &devices);
411 } 320 }
412
413 // For pages accessed via http (not https), tag this navigation entry
414 // with the granted permissions. This avoids repeated prompts for
415 // device access.
416 if (!IsSchemeSecure()) {
417 content::NavigationEntry* navigation_entry =
418 web_contents_->GetController().GetVisibleEntry();
419 if (navigation_entry) {
420 SetMediaPermissionsForNavigationEntry(
421 navigation_entry, request_, audio_allowed, video_allowed);
422 }
423 }
424 break; 321 break;
425 } 322 }
426 case content::MEDIA_DEVICE_ACCESS: { 323 case content::MEDIA_DEVICE_ACCESS: {
427 // Get the default devices for the request. 324 // Get the default devices for the request.
428 MediaCaptureDevicesDispatcher::GetInstance()-> 325 MediaCaptureDevicesDispatcher::GetInstance()->
429 GetDefaultDevicesForProfile(profile_, 326 GetDefaultDevicesForProfile(profile_,
430 audio_allowed, 327 audio_allowed,
431 video_allowed, 328 video_allowed,
432 &devices); 329 &devices);
433 break; 330 break;
(...skipping 29 matching lines...) Expand all
463 content::MEDIA_DEVICE_NO_HARDWARE : content::MEDIA_DEVICE_OK, 360 content::MEDIA_DEVICE_NO_HARDWARE : content::MEDIA_DEVICE_OK,
464 ui.Pass()); 361 ui.Pass());
465 } 362 }
466 363
467 void MediaStreamDevicesController::Deny( 364 void MediaStreamDevicesController::Deny(
468 bool update_content_setting, 365 bool update_content_setting,
469 content::MediaStreamRequestResult result) { 366 content::MediaStreamRequestResult result) {
470 DLOG(WARNING) << "MediaStreamDevicesController::Deny: " << result; 367 DLOG(WARNING) << "MediaStreamDevicesController::Deny: " << result;
471 NotifyUIRequestDenied(); 368 NotifyUIRequestDenied();
472 369
473 // Clear previously allowed permissions from the navigation entry if any.
474 content::NavigationEntry* navigation_entry =
475 web_contents_->GetController().GetVisibleEntry();
476 if (navigation_entry) {
477 SetMediaPermissionsForNavigationEntry(
478 navigation_entry, request_, false, false);
479 }
480
481 if (update_content_setting) { 370 if (update_content_setting) {
482 CHECK_EQ(content::MEDIA_DEVICE_PERMISSION_DENIED, result); 371 CHECK_EQ(content::MEDIA_DEVICE_PERMISSION_DENIED, result);
483 SetPermission(false); 372 SetPermission(false);
484 } 373 }
485 374
486 content::MediaResponseCallback cb = callback_; 375 content::MediaResponseCallback cb = callback_;
487 callback_.Reset(); 376 callback_.Reset();
488 cb.Run(content::MediaStreamDevices(), 377 cb.Run(content::MediaStreamDevices(),
489 result, 378 result,
490 scoped_ptr<content::MediaStreamUI>()); 379 scoped_ptr<content::MediaStreamUI>());
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
764 it->second.permission == MEDIA_ALLOWED); 653 it->second.permission == MEDIA_ALLOWED);
765 } 654 }
766 655
767 bool MediaStreamDevicesController::IsDeviceVideoCaptureRequestedAndAllowed() 656 bool MediaStreamDevicesController::IsDeviceVideoCaptureRequestedAndAllowed()
768 const { 657 const {
769 MediaStreamTypeSettingsMap::const_iterator it = 658 MediaStreamTypeSettingsMap::const_iterator it =
770 request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE); 659 request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE);
771 return (it != request_permissions_.end() && 660 return (it != request_permissions_.end() &&
772 it->second.permission == MEDIA_ALLOWED); 661 it->second.permission == MEDIA_ALLOWED);
773 } 662 }
OLDNEW
« no previous file with comments | « chrome/browser/media/chrome_media_stream_infobar_browsertest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698