media_stream_devices_controller.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/media/media_stream_devices_controller.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/content_settings_provider.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/host_content_settings_map.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/content_settings/tab_specific_content_settings.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media/media_capture_devices_dispatcher.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media/media_stream_capture_indicator.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/scoped_user_pref_update.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/content_settings.h" 2090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/content_settings_pattern.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/media_stream_request.h" 25424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "extensions/common/constants.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS) 2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h" 2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool HasAnyAvailableDevice() { 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::MediaStreamDevices& audio_devices = 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices(); 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::MediaStreamDevices& video_devices = 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()->GetVideoCaptureDevices(); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return !audio_devices.empty() || !video_devices.empty(); 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool IsInKioskMode() { 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return true; 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS) 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const chromeos::UserManager* user_manager = chromeos::UserManager::Get(); 5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return user_manager && user_manager->IsLoggedInAsKioskApp(); 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return false; 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings::MediaStreamTypeSettings( 5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Permission permission, const std::string& requested_device_id): 6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) permission(permission), requested_device_id(requested_device_id) {} 6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings:: 6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettings(): permission(MEDIA_NONE) {} 6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings:: 6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ~MediaStreamTypeSettings() {} 6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDevicesController::MediaStreamDevicesController( 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::WebContents* web_contents, 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const content::MediaStreamRequest& request, 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::MediaResponseCallback& callback) 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : web_contents_(web_contents), 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_(request), 743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback_(callback) { 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // For MEDIA_OPEN_DEVICE requests (Pepper) we always request both webcam 793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // and microphone to avoid popping two infobars. 803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // We start with setting the requested media type to allowed or blocked 813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // depending on the policy. If not blocked by policy it may be blocked later 823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // in the two remaining filtering steps (by user setting or by user when 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // clicking the infobar). 843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // TODO(grunell): It's not the nicest solution to let the MEDIA_OPEN_DEVICE 853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // case take a ride on the MEDIA_DEVICE_*_CAPTURE permission. Should be fixed. 863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE || 873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request.request_type == content::MEDIA_OPEN_DEVICE) { 883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (GetDevicePolicy(prefs::kAudioCaptureAllowed, 893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kAudioCaptureAllowedUrls) == ALWAYS_DENY) { 9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_.insert(std::make_pair( 9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::MEDIA_DEVICE_AUDIO_CAPTURE, 9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY, 9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.requested_audio_device_id))); 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_.insert(std::make_pair( 9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::MEDIA_DEVICE_AUDIO_CAPTURE, 9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettings(MEDIA_ALLOWED, 9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.requested_audio_device_id))); 993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE || 1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request.request_type == content::MEDIA_OPEN_DEVICE) { 1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (GetDevicePolicy(prefs::kVideoCaptureAllowed, 1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) prefs::kVideoCaptureAllowedUrls) == ALWAYS_DENY) { 10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_.insert(std::make_pair( 10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::MEDIA_DEVICE_VIDEO_CAPTURE, 10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY, 10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.requested_video_device_id))); 1093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_.insert(std::make_pair( 11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::MEDIA_DEVICE_VIDEO_CAPTURE, 11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettings(MEDIA_ALLOWED, 11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request.requested_video_device_id))); 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)MediaStreamDevicesController::~MediaStreamDevicesController() { 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!callback_.is_null()) { 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback_.Run(content::MediaStreamDevices(), 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<content::MediaStreamUI>()); 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MediaStreamDevicesController::RegisterProfilePrefs( 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable* prefs) { 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed, 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true, 130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed, 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true, 133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls, 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls, 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() { 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Tab capture is allowed for extensions only and infobar is not shown for 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // extensions. 144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (request_.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE || 145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) { 146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Deny(false); 147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Deny the request if the security origin is empty, this happens with 151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // file access without |--allow-file-access-from-files| flag. 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (request_.security_origin.is_empty()) { 153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Deny(false); 154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Deny the request if there is no device attached to the OS. 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!HasAnyAvailableDevice()) { 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Deny(false); 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if any allow exception has been made for this request. 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsRequestAllowedByDefault()) { 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Accept(false); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Filter any parts of the request that have been blocked by default and deny 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // it if nothing is left to accept. 1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (FilterBlockedByDefaultDevices() == 0) { 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Deny(false); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if the media default setting is set to block. 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (IsDefaultMediaAccessBlocked()) { 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Deny(false); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (request_.request_type == content::MEDIA_OPEN_DEVICE) { 18368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool no_matched_audio_device = 18468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) (request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE && 18568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) !request_.requested_audio_device_id.empty() && 18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()->GetRequestedAudioDevice( 18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_.requested_audio_device_id) == NULL); 18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) bool no_matched_video_device = 18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) (request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE && 19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) !request_.requested_video_device_id.empty() && 19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()->GetRequestedVideoDevice( 19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_.requested_video_device_id) == NULL); 19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (no_matched_audio_device || no_matched_video_device) { 19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Deny(false); 19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return true; 19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Show the infobar. 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::HasAudio() const { 2043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return IsDeviceAudioCaptureRequestedAndAllowed(); 2053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::HasVideo() const { 2083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return IsDeviceVideoCaptureRequestedAndAllowed(); 2093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 2103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const { 212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return request_.security_origin.spec(); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::Accept(bool update_content_setting) { 2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NotifyUIRequestAccepted(); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the default devices for the request. 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::MediaStreamDevices devices; 2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool audio_allowed = IsDeviceAudioCaptureRequestedAndAllowed(); 2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool video_allowed = IsDeviceVideoCaptureRequestedAndAllowed(); 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (audio_allowed || video_allowed) { 223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (request_.request_type) { 2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case content::MEDIA_OPEN_DEVICE: { 2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const content::MediaStreamDevice* device = NULL; 22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // For open device request, when requested device_id is empty, pick 22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // the first available of the given type. If requested device_id is 22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // not empty, return the desired device if it's available. Otherwise, 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // return no device. 23058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (audio_allowed && 23158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) { 23268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!request_.requested_audio_device_id.empty()) { 23368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) device = MediaCaptureDevicesDispatcher::GetInstance()-> 23468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GetRequestedAudioDevice(request_.requested_audio_device_id); 23568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device = MediaCaptureDevicesDispatcher::GetInstance()-> 2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetFirstAvailableAudioDevice(); 2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 23958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (video_allowed && 24058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) { 2417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Pepper API opens only one device at a time. 24268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!request_.requested_video_device_id.empty()) { 24368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) device = MediaCaptureDevicesDispatcher::GetInstance()-> 24468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GetRequestedVideoDevice(request_.requested_video_device_id); 24568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch device = MediaCaptureDevicesDispatcher::GetInstance()-> 2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetFirstAvailableVideoDevice(); 2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (device) 2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch devices.push_back(*device); 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case content::MEDIA_GENERATE_STREAM: { 25558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool get_default_audio_device = audio_allowed; 25658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) bool get_default_video_device = video_allowed; 2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Get the exact audio or video device if an id is specified. 25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (audio_allowed && !request_.requested_audio_device_id.empty()) { 2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const content::MediaStreamDevice* audio_device = 2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch MediaCaptureDevicesDispatcher::GetInstance()-> 2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetRequestedAudioDevice(request_.requested_audio_device_id); 2637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (audio_device) { 2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch devices.push_back(*audio_device); 26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) get_default_audio_device = false; 2667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (video_allowed && !request_.requested_video_device_id.empty()) { 2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const content::MediaStreamDevice* video_device = 2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch MediaCaptureDevicesDispatcher::GetInstance()-> 2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetRequestedVideoDevice(request_.requested_video_device_id); 2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (video_device) { 2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch devices.push_back(*video_device); 27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) get_default_video_device = false; 2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // If either or both audio and video devices were requested but not 2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // specified by id, get the default devices. 28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (get_default_audio_device || get_default_video_device) { 2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch MediaCaptureDevicesDispatcher::GetInstance()-> 2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetDefaultDevicesForProfile(profile_, 28358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) get_default_audio_device, 28458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) get_default_video_device, 2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch &devices); 2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case content::MEDIA_DEVICE_ACCESS: { 290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Get the default devices for the request. 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()-> 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetDefaultDevicesForProfile(profile_, 2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) audio_allowed, 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) video_allowed, 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &devices); 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) case content::MEDIA_ENUMERATE_DEVICES: { 2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Do nothing. 3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NOTREACHED(); 3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } // switch 304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 3057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // TODO(raymes): We currently set the content permission for non-https 3067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // websites for Pepper requests as well. This is temporary and should be 3077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // removed. 3087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (update_content_setting) { 3097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if ((IsSchemeSecure() && !devices.empty()) || 3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) request_.request_type == content::MEDIA_OPEN_DEVICE) { 3117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) SetPermission(true); 3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<content::MediaStreamUI> ui; 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!devices.empty()) { 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui = MediaCaptureDevicesDispatcher::GetInstance()-> 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetMediaStreamCaptureIndicator()->RegisterMediaStream( 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) web_contents_, devices); 321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 322868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::MediaResponseCallback cb = callback_; 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback_.Reset(); 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cb.Run(devices, ui.Pass()); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::Deny(bool update_content_setting) { 3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) NotifyUIRequestDenied(); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (update_content_setting) 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetPermission(false); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 333868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::MediaResponseCallback cb = callback_; 334868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callback_.Reset(); 335868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) cb.Run(content::MediaStreamDevices(), scoped_ptr<content::MediaStreamUI>()); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MediaStreamDevicesController::DevicePolicy 33990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaStreamDevicesController::GetDevicePolicy( 34090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char* policy_name, 34190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char* whitelist_policy_name) const { 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If the security origin policy matches a value in the whitelist, allow it. 34590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Otherwise, check the |policy_name| master switch for the default behavior. 34690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PrefService* prefs = profile_->GetPrefs(); 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // TODO(tommi): Remove the kiosk mode check when the whitelist below 35090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // is visible in the media exceptions UI. 35190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // See discussion here: https://codereview.chromium.org/15738004/ 35290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (IsInKioskMode()) { 35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const base::ListValue* list = prefs->GetList(whitelist_policy_name); 35490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string value; 35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) for (size_t i = 0; i < list->GetSize(); ++i) { 35690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (list->GetString(i, &value)) { 35790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ContentSettingsPattern pattern = 35890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ContentSettingsPattern::FromString(value); 35990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (pattern == ContentSettingsPattern::Wildcard()) { 36090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DLOG(WARNING) << "Ignoring wildcard URL pattern: " << value; 36190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) continue; 36290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DLOG_IF(ERROR, !pattern.IsValid()) << "Invalid URL pattern: " << value; 36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (pattern.IsValid() && pattern.Matches(request_.security_origin)) 36590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ALWAYS_ALLOW; 36690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 36790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 36890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 36990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // If a match was not found, check if audio capture is otherwise disallowed 37190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // or if the user should be prompted. Setting the policy value to "true" 37290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // is equal to not setting it at all, so from hereon out, we will return 37390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // either POLICY_NOT_SET (prompt) or ALWAYS_DENY (no prompt, no access). 37490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!prefs->GetBoolean(policy_name)) 37590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ALWAYS_DENY; 37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 37790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return POLICY_NOT_SET; 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsRequestAllowedByDefault() const { 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The request from internal objects like chrome://URLs is always allowed. 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ShouldAlwaysAllowOrigin()) 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct { 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool has_capability; 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const char* policy_name; 38890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const char* list_policy_name; 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSettingsType settings_type; 390c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } device_checks[] = { 3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { IsDeviceAudioCaptureRequestedAndAllowed(), prefs::kAudioCaptureAllowed, 39290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) prefs::kAudioCaptureAllowedUrls, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC }, 3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) { IsDeviceVideoCaptureRequestedAndAllowed(), prefs::kVideoCaptureAllowed, 39490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) prefs::kVideoCaptureAllowedUrls, 395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA }, 396c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) }; 397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 398c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(device_checks); ++i) { 399c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!device_checks[i].has_capability) 400c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) continue; 401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 40290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DevicePolicy policy = GetDevicePolicy(device_checks[i].policy_name, 40390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) device_checks[i].list_policy_name); 4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (policy == ALWAYS_DENY) 406c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 4077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (policy == POLICY_NOT_SET) { 4097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Only load content settings from secure origins unless it is a 4107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // content::MEDIA_OPEN_DEVICE (Pepper) request. 4117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!IsSchemeSecure() && 4127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) request_.request_type != content::MEDIA_OPEN_DEVICE) { 4137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return false; 4147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (profile_->GetHostContentSettingsMap()->GetContentSetting( 4167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) request_.security_origin, request_.security_origin, 4177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) device_checks[i].settings_type, NO_RESOURCE_IDENTIFIER) != 4187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CONTENT_SETTING_ALLOW) { 4197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return false; 4207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If we get here, then either policy is set to ALWAYS_ALLOW or the content 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // settings allow the request by default. 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint MediaStreamDevicesController::FilterBlockedByDefaultDevices() { 4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int requested_devices = 0; 4313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 4323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsDeviceAudioCaptureRequestedAndAllowed()) { 4333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (profile_->GetHostContentSettingsMap()->GetContentSetting( 4343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_.security_origin, 4353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_.security_origin, 4363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) { 43868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission = 4393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MEDIA_BLOCKED_BY_USER_SETTING; 4403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 4413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ++requested_devices; 4423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsDeviceVideoCaptureRequestedAndAllowed()) { 4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (profile_->GetHostContentSettingsMap()->GetContentSetting( 4473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_.security_origin, 4483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_.security_origin, 4493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 4503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) { 45168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission = 4523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MEDIA_BLOCKED_BY_USER_SETTING; 4533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ++requested_devices; 4553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 4587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return requested_devices; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsDefaultMediaAccessBlocked() const { 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA. 466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSetting current_setting = 467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_->GetHostContentSettingsMap()->GetDefaultContentSetting( 468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL); 469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return (current_setting == CONTENT_SETTING_BLOCK); 470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsSchemeSecure() const { 473424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return request_.security_origin.SchemeIsSecure() || 47458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) request_.security_origin.SchemeIs(extensions::kExtensionScheme) || 47558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CommandLine::ForCurrentProcess()->HasSwitch( 47658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) switches::kDisableUserMediaSecurity); 477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() const { 480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the 481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and 482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA. 483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent( 484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request_.security_origin, request_.security_origin, 485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM); 486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::SetPermission(bool allowed) const { 489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_ANDROID) 491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We do not support sticky operations on Android yet. 492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSettingsPattern primary_pattern = 495c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSettingsPattern::FromURLNoWildcard(request_.security_origin); 496c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check the pattern is valid or not. When the request is from a file access, 497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // no exception will be made. 498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!primary_pattern.IsValid()) 499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSetting content_setting = allowed ? 502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE) != 5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_permissions_.end()) { 505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_->GetHostContentSettingsMap()->SetContentSetting( 506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_pattern, 507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSettingsPattern::Wildcard(), 508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), 510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content_setting); 511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE) != 5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_permissions_.end()) { 514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile_->GetHostContentSettingsMap()->SetContentSetting( 515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) primary_pattern, 516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ContentSettingsPattern::Wildcard(), 517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string(), 519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content_setting); 520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestAccepted() const { 5247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!content_settings_) 5257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 5267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content_settings_->OnMediaStreamPermissionSet(request_.security_origin, 5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_permissions_); 5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 5307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestDenied() { 5327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!content_settings_) 5337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return; 5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsDeviceAudioCaptureRequestedAndAllowed()) { 53668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission = 5373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MEDIA_BLOCKED_BY_USER; 5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (IsDeviceVideoCaptureRequestedAndAllowed()) { 54068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission = 5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) MEDIA_BLOCKED_BY_USER; 5423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) content_settings_->OnMediaStreamPermissionSet(request_.security_origin, 5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_permissions_); 5463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceAudioCaptureRequestedAndAllowed() 5493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const { 55068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettingsMap::const_iterator it = 5513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE); 55268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return (it != request_permissions_.end() && 55368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) it->second.permission == MEDIA_ALLOWED); 5543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 5563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceVideoCaptureRequestedAndAllowed() 5573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const { 55868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) MediaStreamTypeSettingsMap::const_iterator it = 5593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE); 56068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return (it != request_permissions_.end() && 56168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) it->second.permission == MEDIA_ALLOWED); 5627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 563