media_stream_devices_controller.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
1a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// Use of this source code is governed by a BSD-style license that can be 3a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard// found in the LICENSE file. 4a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 5a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/browser/media/media_stream_devices_controller.h" 6a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 7a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "base/command_line.h" 8a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "base/prefs/pref_service.h" 9a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "base/values.h" 10a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/browser/content_settings/content_settings_provider.h" 11a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/browser/content_settings/host_content_settings_map.h" 12a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/browser/content_settings/tab_specific_content_settings.h" 13a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/browser/media/media_capture_devices_dispatcher.h" 14a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/browser/media/media_stream_capture_indicator.h" 15a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/browser/prefs/scoped_user_pref_update.h" 16a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/browser/profiles/profile.h" 17a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/browser/ui/browser.h" 18a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/common/chrome_switches.h" 19a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/common/content_settings.h" 20a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/common/content_settings_pattern.h" 21a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/common/pref_names.h" 22a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "components/user_prefs/pref_registry_syncable.h" 23a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "content/public/browser/browser_thread.h" 24a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "content/public/common/media_stream_request.h" 25a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 26a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if defined(OS_CHROMEOS) 27a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#include "chrome/browser/chromeos/login/user_manager.h" 28a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif 29a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 30a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardusing content::BrowserThread; 31a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 32a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardnamespace { 33a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 34a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool HasAnyAvailableDevice() { 35a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const content::MediaStreamDevices& audio_devices = 36a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices(); 37a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const content::MediaStreamDevices& video_devices = 38a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard MediaCaptureDevicesDispatcher::GetInstance()->GetVideoCaptureDevices(); 39a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 40a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return !audio_devices.empty() || !video_devices.empty(); 41a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 42a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 43a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardbool IsInKioskMode() { 44a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) 45a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return true; 46a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 47a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#if defined(OS_CHROMEOS) 48a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const chromeos::UserManager* user_manager = chromeos::UserManager::Get(); 49a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return user_manager && user_manager->IsLoggedInAsKioskApp(); 50a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#else 51a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return false; 52a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard#endif 53a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 54a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 55a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} // namespace 56a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 57a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardMediaStreamDevicesController::MediaStreamDevicesController( 58a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard content::WebContents* web_contents, 59a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const content::MediaStreamRequest& request, 60a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const content::MediaResponseCallback& callback) 61a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard : web_contents_(web_contents), 62a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard request_(request), 63a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard callback_(callback), 64a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard microphone_requested_( 65a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE), 66a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard webcam_requested_( 67a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) { 68a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); 691b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents); 70a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 71a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard // Don't call GetDevicePolicy from the initializer list since the 729aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König // implementation depends on member variables. 739aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König if (microphone_requested_ && 74a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard GetDevicePolicy(prefs::kAudioCaptureAllowed, 75a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard prefs::kAudioCaptureAllowedUrls) == ALWAYS_DENY) { 7688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer microphone_requested_ = false; 7788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer } 7888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 7988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer if (webcam_requested_ && 8088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer GetDevicePolicy(prefs::kVideoCaptureAllowed, 8188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer prefs::kVideoCaptureAllowedUrls) == ALWAYS_DENY) { 8288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer webcam_requested_ = false; 8388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer } 8488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer} 8588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 8688a2e2388bfeee66cb6d873558431b0e0af7e316Michel DänzerMediaStreamDevicesController::~MediaStreamDevicesController() {} 8788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 8888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer// static 8988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzervoid MediaStreamDevicesController::RegisterUserPrefs( 9088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer user_prefs::PrefRegistrySyncable* prefs) { 9188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed, 9288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer true, 9388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 9488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed, 9588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer true, 9688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 9788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls, 9888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 9988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls, 10088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 10188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer} 10288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 10388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 10488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzerbool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() { 10588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // If this is a no UI check for policies only go straight to accept - policy 10688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // check will be done automatically on the way. 10788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer if (request_.request_type == content::MEDIA_OPEN_DEVICE) { 10888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer Accept(false); 10988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer return true; 11088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer } 11188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 11288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // Tab capture is allowed for extensions only and infobar is not shown for 11388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // extensions. 11488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer if (request_.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE || 11588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer request_.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) { 11688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer Deny(false); 11788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer return true; 11888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer } 11988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 12088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // Deny the request if the security origin is empty, this happens with 12188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // file access without |--allow-file-access-from-files| flag. 12288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer if (request_.security_origin.is_empty()) { 12388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer Deny(false); 12488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer return true; 12588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer } 12688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 12788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // Deny the request if there is no device attached to the OS. 12888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer if (!HasAnyAvailableDevice()) { 12988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer Deny(false); 13088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer return true; 13188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer } 13288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 13388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // Check if any allow exception has been made for this request. 13488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer if (IsRequestAllowedByDefault()) { 13588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer Accept(false); 13688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer return true; 13788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer } 13888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 13988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // Check if any block exception has been made for this request. 14088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer if (IsRequestBlockedByDefault()) { 14188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer Deny(false); 14288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer return true; 14388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer } 14488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 14588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // Check if the media default setting is set to block. 14688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer if (IsDefaultMediaAccessBlocked()) { 14788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer Deny(false); 14888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer return true; 14988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer } 15088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 15188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // Show the infobar. 15288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer return false; 15388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer} 15488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 15588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzerconst std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const { 15688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer return request_.security_origin.spec(); 15788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer} 15888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 15988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzervoid MediaStreamDevicesController::Accept(bool update_content_setting) { 16088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer if (content_settings_) 16188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer content_settings_->OnMediaStreamAllowed(); 16288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 16388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // Get the default devices for the request. 16488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer content::MediaStreamDevices devices; 16588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer if (microphone_requested_ || webcam_requested_) { 16688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer switch (request_.request_type) { 16788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer case content::MEDIA_OPEN_DEVICE: 16888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // For open device request pick the desired device or fall back to the 16988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // first available of the given type. 17088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer MediaCaptureDevicesDispatcher::GetInstance()->GetRequestedDevice( 17188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer request_.requested_device_id, 17288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer microphone_requested_, 17388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer webcam_requested_, 17488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer &devices); 17588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer break; 17688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer case content::MEDIA_DEVICE_ACCESS: 17788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer case content::MEDIA_GENERATE_STREAM: 178a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard case content::MEDIA_ENUMERATE_DEVICES: 179a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard // Get the default devices for the request. 180a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard MediaCaptureDevicesDispatcher::GetInstance()-> 181a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard GetDefaultDevicesForProfile(profile_, 182a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard microphone_requested_, 183a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard webcam_requested_, 184a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard &devices); 185a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard break; 186a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 187a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 188a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (update_content_setting && IsSchemeSecure() && !devices.empty()) 189a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard SetPermission(true); 190a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 191a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 192a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard scoped_ptr<content::MediaStreamUI> ui; 193a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!devices.empty()) { 19488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer ui = MediaCaptureDevicesDispatcher::GetInstance()-> 195a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard GetMediaStreamCaptureIndicator()->RegisterMediaStream( 196a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard web_contents_, devices); 197a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 198a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard callback_.Run(devices, ui.Pass()); 199a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 200a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 201a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellardvoid MediaStreamDevicesController::Deny(bool update_content_setting) { 202a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the 203a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and 204a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA. 205a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (content_settings_) { 206a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard content_settings_->OnContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM, 207a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard std::string()); 208a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 209a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 210a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (update_content_setting) 211a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard SetPermission(false); 212a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 213a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard callback_.Run(content::MediaStreamDevices(), 214a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard scoped_ptr<content::MediaStreamUI>()); 215a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard} 216a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 217a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardMediaStreamDevicesController::DevicePolicy 218a75c6163e605f35b14f26930dd9227e4f337ec9eTom StellardMediaStreamDevicesController::GetDevicePolicy( 219a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const char* policy_name, 220a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard const char* whitelist_policy_name) const { 221a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 222a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 223a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard // If the security origin policy matches a value in the whitelist, allow it. 224fe41287ffa8cb35421cadfb16d4cc27c5fcb8b76Christian König // Otherwise, check the |policy_name| master switch for the default behavior. 22588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer 226a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard PrefService* prefs = profile_->GetPrefs(); 227a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 22888a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // TODO(tommi): Remove the kiosk mode check when the whitelist below 2297446a0407d4e61a826385c11ed6c401837baf095Michel Dänzer // is visible in the media exceptions UI. 23088a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer // See discussion here: https://codereview.chromium.org/15738004/ 23188a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer if (IsInKioskMode()) { 23288a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer const base::ListValue* list = prefs->GetList(whitelist_policy_name); 23388a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer std::string value; 23488a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer for (size_t i = 0; i < list->GetSize(); ++i) { 23588a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer if (list->GetString(i, &value)) { 23688a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer ContentSettingsPattern pattern = 23788a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer ContentSettingsPattern::FromString(value); 2389aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König if (pattern == ContentSettingsPattern::Wildcard()) { 23988a2e2388bfeee66cb6d873558431b0e0af7e316Michel Dänzer DLOG(WARNING) << "Ignoring wildcard URL pattern: " << value; 240a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard continue; 2419aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König } 242a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard DLOG_IF(ERROR, !pattern.IsValid()) << "Invalid URL pattern: " << value; 243a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (pattern.IsValid() && pattern.Matches(request_.security_origin)) 244a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return ALWAYS_ALLOW; 245a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 246a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 247a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard } 248fe41287ffa8cb35421cadfb16d4cc27c5fcb8b76Christian König 249a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard // If a match was not found, check if audio capture is otherwise disallowed 250a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard // or if the user should be prompted. Setting the policy value to "true" 2519aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König // is equal to not setting it at all, so from hereon out, we will return 252a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard // either POLICY_NOT_SET (prompt) or ALWAYS_DENY (no prompt, no access). 253a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard if (!prefs->GetBoolean(policy_name)) 254a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return ALWAYS_DENY; 255a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard 256a75c6163e605f35b14f26930dd9227e4f337ec9eTom Stellard return POLICY_NOT_SET; 2571b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer} 2581b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 2591b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerbool MediaStreamDevicesController::IsRequestAllowedByDefault() const { 2601b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer // The request from internal objects like chrome://URLs is always allowed. 2611b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer if (ShouldAlwaysAllowOrigin()) 2621b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer return true; 2631b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 2641b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer struct { 2651b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer bool has_capability; 2661b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer const char* policy_name; 2671b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer const char* list_policy_name; 2681b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer ContentSettingsType settings_type; 2691b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer } device_checks[] = { 2701b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer { microphone_requested_, prefs::kAudioCaptureAllowed, 2711b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer prefs::kAudioCaptureAllowedUrls, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC }, 2721b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer { webcam_requested_, prefs::kVideoCaptureAllowed, 2731b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer prefs::kVideoCaptureAllowedUrls, 2741b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA }, 2751b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer }; 2761b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 2771b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer for (size_t i = 0; i < ARRAYSIZE_UNSAFE(device_checks); ++i) { 2781b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer if (!device_checks[i].has_capability) 2791b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer continue; 2801b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 2811b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer DevicePolicy policy = GetDevicePolicy(device_checks[i].policy_name, 2821b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer device_checks[i].list_policy_name); 2839aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König if (policy == ALWAYS_DENY || 2849aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König (policy == POLICY_NOT_SET && 2851b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer profile_->GetHostContentSettingsMap()->GetContentSetting( 2861b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer request_.security_origin, request_.security_origin, 2871b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer device_checks[i].settings_type, NO_RESOURCE_IDENTIFIER) != 2881b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer CONTENT_SETTING_ALLOW)) { 2891b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer return false; 2901b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer } 2911b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer // If we get here, then either policy is set to ALWAYS_ALLOW or the content 2921b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer // settings allow the request by default. 2931b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer } 2941b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 2951b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer return true; 2961b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer} 2971b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 2981b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerbool MediaStreamDevicesController::IsRequestBlockedByDefault() const { 2991b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer if (microphone_requested_ && 3001b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer profile_->GetHostContentSettingsMap()->GetContentSetting( 3011b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer request_.security_origin, 3021b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer request_.security_origin, 3031b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 3041b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer NO_RESOURCE_IDENTIFIER) != CONTENT_SETTING_BLOCK) { 3051b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer return false; 3061b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer } 3071b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 3081b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer if (webcam_requested_ && 3091b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer profile_->GetHostContentSettingsMap()->GetContentSetting( 3101b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer request_.security_origin, 3111b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer request_.security_origin, 3121b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 3131b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer NO_RESOURCE_IDENTIFIER) != CONTENT_SETTING_BLOCK) { 3141b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer return false; 3151b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer } 3161b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 3171b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer return true; 3181b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer} 3191b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 3201b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerbool MediaStreamDevicesController::IsDefaultMediaAccessBlocked() const { 3211b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3221b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the 3231b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and 3241b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA. 3251b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer ContentSetting current_setting = 3261b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer profile_->GetHostContentSettingsMap()->GetDefaultContentSetting( 3279aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL); 3281b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer return (current_setting == CONTENT_SETTING_BLOCK); 3291b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer} 3301b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 3311b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerbool MediaStreamDevicesController::IsSchemeSecure() const { 3321b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer return (request_.security_origin.SchemeIsSecure()); 3331b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer} 3341b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 3351b11395a36a44a902cfb3e1783758544662df73fMichel Dänzerbool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() const { 3361b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the 3371b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and 3381b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA. 3391b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent( 3401b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer request_.security_origin, request_.security_origin, 3411b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer CONTENT_SETTINGS_TYPE_MEDIASTREAM); 3421b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer} 3431b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 3441b11395a36a44a902cfb3e1783758544662df73fMichel Dänzervoid MediaStreamDevicesController::SetPermission(bool allowed) const { 3451b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3461b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer#if defined(OS_ANDROID) 3471b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer // We do not support sticky operations on Android yet. 3481b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer return; 3491b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer#endif 3501b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer ContentSettingsPattern primary_pattern = 3511b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer ContentSettingsPattern::FromURLNoWildcard(request_.security_origin); 3521b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer // Check the pattern is valid or not. When the request is from a file access, 3531b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer // no exception will be made. 3541b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer if (!primary_pattern.IsValid()) 3551b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer return; 3561b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer 3571b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer ContentSetting content_setting = allowed ? 3581b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 3591b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer if (microphone_requested_) { 3601b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer profile_->GetHostContentSettingsMap()->SetContentSetting( 3619aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König primary_pattern, 3629aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König ContentSettingsPattern::Wildcard(), 3631b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 3641b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer std::string(), 3651b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer content_setting); 3661b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer } 3671b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer if (webcam_requested_) { 3681b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer profile_->GetHostContentSettingsMap()->SetContentSetting( 3691b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer primary_pattern, 3709aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König ContentSettingsPattern::Wildcard(), 3719aacd5cc67ccbc3984bce6a0b40768a6cec2ec2dChristian König CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 3721b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer std::string(), 3731b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer content_setting); 3741b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer } 3751b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer} 3761b11395a36a44a902cfb3e1783758544662df73fMichel Dänzer