media_stream_devices_controller.cc revision 3551c9c881056c480085172ff9840cab31610854
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// found in the LICENSE file. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/media/media_stream_devices_controller.h" 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/command_line.h" 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/prefs/pref_service.h" 902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "base/values.h" 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/content_settings/content_settings_provider.h" 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/content_settings/host_content_settings_map.h" 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/content_settings/tab_specific_content_settings.h" 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/media/media_capture_devices_dispatcher.h" 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/media/media_stream_capture_indicator.h" 1502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch#include "chrome/browser/prefs/scoped_user_pref_update.h" 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/ui/browser.h" 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/common/chrome_switches.h" 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/common/content_settings.h" 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/common/content_settings_pattern.h" 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/common/pref_names.h" 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h" 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "content/public/common/media_stream_request.h" 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if defined(OS_CHROMEOS) 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h" 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)using content::BrowserThread; 31197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 325d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)namespace { 3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)bool HasAnyAvailableDevice() { 3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) const content::MediaStreamDevices& audio_devices = 3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices(); 37e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) const content::MediaStreamDevices& video_devices = 38e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()->GetVideoCaptureDevices(); 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 40c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return !audio_devices.empty() || !video_devices.empty(); 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool IsInKioskMode() { 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if defined(OS_CHROMEOS) 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const chromeos::UserManager* user_manager = chromeos::UserManager::Get(); 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return user_manager && user_manager->IsLoggedInAsKioskApp(); 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#else 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 535d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)} 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)MediaStreamDevicesController::MediaStreamDevicesController( 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) content::WebContents* web_contents, 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const content::MediaStreamRequest& request, 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const content::MediaResponseCallback& callback) 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : web_contents_(web_contents), 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_(request), 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback_(callback) { 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext()); 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents); 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // For MEDIA_OPEN_DEVICE requests (Pepper) we always request both webcam 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // and microphone to avoid popping two infobars. 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We start with setting the requested media type to allowed or blocked 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // depending on the policy. If not blocked by policy it may be blocked later 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // in the two remaining filtering steps (by user setting or by user when 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // clicking the infobar). 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // TODO(grunell): It's not the nicest solution to let the MEDIA_OPEN_DEVICE 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // case take a ride on the MEDIA_DEVICE_*_CAPTURE permission. Should be fixed. 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE || 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request.request_type == content::MEDIA_OPEN_DEVICE) { 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GetDevicePolicy(prefs::kAudioCaptureAllowed, 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prefs::kAudioCaptureAllowedUrls) == ALWAYS_DENY) { 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE] = 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MEDIA_BLOCKED_BY_POLICY; 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE] = MEDIA_ALLOWED; 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE || 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request.request_type == content::MEDIA_OPEN_DEVICE) { 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (GetDevicePolicy(prefs::kVideoCaptureAllowed, 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prefs::kVideoCaptureAllowedUrls) == ALWAYS_DENY) { 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE] = 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MEDIA_BLOCKED_BY_POLICY; 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE] = MEDIA_ALLOWED; 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)MediaStreamDevicesController::~MediaStreamDevicesController() { 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!callback_.is_null()) { 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback_.Run(content::MediaStreamDevices(), 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scoped_ptr<content::MediaStreamUI>()); 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// static 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void MediaStreamDevicesController::RegisterProfilePrefs( 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) user_prefs::PrefRegistrySyncable* prefs) { 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed, 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) true, 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed, 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) true, 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls, 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls, 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() { 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Tab capture is allowed for extensions only and infobar is not shown for 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // extensions. 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (request_.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE || 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) { 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Deny(false); 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Deny the request if the security origin is empty, this happens with 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // file access without |--allow-file-access-from-files| flag. 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (request_.security_origin.is_empty()) { 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Deny(false); 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Deny the request if there is no device attached to the OS. 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!HasAnyAvailableDevice()) { 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Deny(false); 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check if any allow exception has been made for this request. 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (IsRequestAllowedByDefault()) { 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Accept(false); 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Filter any parts of the request that have been blocked by default and deny 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // it if nothing is left to accept. 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (FilterBlockedByDefaultDevices() == 0) { 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Deny(false); 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check if the media default setting is set to block. 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (IsDefaultMediaAccessBlocked()) { 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) Deny(false); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Show the infobar. 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool MediaStreamDevicesController::HasAudio() const { 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IsDeviceAudioCaptureRequestedAndAllowed(); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool MediaStreamDevicesController::HasVideo() const { 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return IsDeviceVideoCaptureRequestedAndAllowed(); 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const { 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return request_.security_origin.spec(); 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void MediaStreamDevicesController::Accept(bool update_content_setting) { 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NotifyUIRequestAccepted(); 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Get the default devices for the request. 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) content::MediaStreamDevices devices; 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool audio_allowed = IsDeviceAudioCaptureRequestedAndAllowed(); 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool video_allowed = IsDeviceVideoCaptureRequestedAndAllowed(); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (audio_allowed || video_allowed) { 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (request_.request_type) { 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case content::MEDIA_OPEN_DEVICE: { 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const content::MediaStreamDevice* device = NULL; 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // For open device request pick the desired device or fall back to the 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // first available of the given type. 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) { 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) device = MediaCaptureDevicesDispatcher::GetInstance()-> 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GetRequestedAudioDevice(request_.requested_audio_device_id); 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // TODO(wjia): Confirm this is the intended behavior. 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!device) { 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) device = MediaCaptureDevicesDispatcher::GetInstance()-> 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GetFirstAvailableAudioDevice(); 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) { 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Pepper API opens only one device at a time. 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) device = MediaCaptureDevicesDispatcher::GetInstance()-> 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GetRequestedVideoDevice(request_.requested_video_device_id); 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // TODO(wjia): Confirm this is the intended behavior. 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!device) { 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) device = MediaCaptureDevicesDispatcher::GetInstance()-> 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GetFirstAvailableVideoDevice(); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (device) 2095d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) devices.push_back(*device); 2105d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) break; 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } case content::MEDIA_GENERATE_STREAM: { 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool needs_audio_device = audio_allowed; 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool needs_video_device = video_allowed; 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Get the exact audio or video device if an id is specified. 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!request_.requested_audio_device_id.empty()) { 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const content::MediaStreamDevice* audio_device = 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()-> 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GetRequestedAudioDevice(request_.requested_audio_device_id); 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (audio_device) { 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) devices.push_back(*audio_device); 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needs_audio_device = false; 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!request_.requested_video_device_id.empty()) { 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const content::MediaStreamDevice* video_device = 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()-> 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GetRequestedVideoDevice(request_.requested_video_device_id); 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (video_device) { 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) devices.push_back(*video_device); 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needs_video_device = false; 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2335d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) } 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If either or both audio and video devices were requested but not 2365d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // specified by id, get the default devices. 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (needs_audio_device || needs_video_device) { 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()-> 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GetDefaultDevicesForProfile(profile_, 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needs_audio_device, 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) needs_video_device, 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) &devices); 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } case content::MEDIA_DEVICE_ACCESS: 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Get the default devices for the request. 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MediaCaptureDevicesDispatcher::GetInstance()-> 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GetDefaultDevicesForProfile(profile_, 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) audio_allowed, 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) video_allowed, 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) &devices); 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case content::MEDIA_ENUMERATE_DEVICES: 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Do nothing. 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NOTREACHED(); 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) break; 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // TODO(raymes): We currently set the content permission for non-https 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // websites for Pepper requests as well. This is temporary and should be 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // removed. 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (update_content_setting) { 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if ((IsSchemeSecure() && !devices.empty()) || 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_.request_type == content::MEDIA_OPEN_DEVICE) { 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SetPermission(true); 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) scoped_ptr<content::MediaStreamUI> ui; 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!devices.empty()) { 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ui = MediaCaptureDevicesDispatcher::GetInstance()-> 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) GetMediaStreamCaptureIndicator()->RegisterMediaStream( 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) web_contents_, devices); 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) content::MediaResponseCallback cb = callback_; 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback_.Reset(); 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cb.Run(devices, ui.Pass()); 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void MediaStreamDevicesController::Deny(bool update_content_setting) { 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NotifyUIRequestDenied(); 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (update_content_setting) 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SetPermission(false); 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) content::MediaResponseCallback cb = callback_; 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) callback_.Reset(); 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) cb.Run(content::MediaStreamDevices(), scoped_ptr<content::MediaStreamUI>()); 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)MediaStreamDevicesController::DevicePolicy 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)MediaStreamDevicesController::GetDevicePolicy( 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const char* policy_name, 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const char* whitelist_policy_name) const { 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If the security origin policy matches a value in the whitelist, allow it. 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Otherwise, check the |policy_name| master switch for the default behavior. 3005d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) PrefService* prefs = profile_->GetPrefs(); 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // TODO(tommi): Remove the kiosk mode check when the whitelist below 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // is visible in the media exceptions UI. 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // See discussion here: https://codereview.chromium.org/15738004/ 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (IsInKioskMode()) { 3075d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) const base::ListValue* list = prefs->GetList(whitelist_policy_name); 3085d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) std::string value; 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < list->GetSize(); ++i) { 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (list->GetString(i, &value)) { 3115d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ContentSettingsPattern pattern = 3125d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) ContentSettingsPattern::FromString(value); 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (pattern == ContentSettingsPattern::Wildcard()) { 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DLOG(WARNING) << "Ignoring wildcard URL pattern: " << value; 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DLOG_IF(ERROR, !pattern.IsValid()) << "Invalid URL pattern: " << value; 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (pattern.IsValid() && pattern.Matches(request_.security_origin)) 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ALWAYS_ALLOW; 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If a match was not found, check if audio capture is otherwise disallowed 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // or if the user should be prompted. Setting the policy value to "true" 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // is equal to not setting it at all, so from hereon out, we will return 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // either POLICY_NOT_SET (prompt) or ALWAYS_DENY (no prompt, no access). 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!prefs->GetBoolean(policy_name)) 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return ALWAYS_DENY; 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return POLICY_NOT_SET; 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3345d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)bool MediaStreamDevicesController::IsRequestAllowedByDefault() const { 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The request from internal objects like chrome://URLs is always allowed. 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (ShouldAlwaysAllowOrigin()) 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) struct { 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool has_capability; 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const char* policy_name; 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const char* list_policy_name; 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ContentSettingsType settings_type; 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } device_checks[] = { 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { IsDeviceAudioCaptureRequestedAndAllowed(), prefs::kAudioCaptureAllowed, 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prefs::kAudioCaptureAllowedUrls, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC }, 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) { IsDeviceVideoCaptureRequestedAndAllowed(), prefs::kVideoCaptureAllowed, 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) prefs::kVideoCaptureAllowedUrls, 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA }, 35002772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch }; 3515d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(device_checks); ++i) { 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!device_checks[i].has_capability) 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) continue; 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DevicePolicy policy = GetDevicePolicy(device_checks[i].policy_name, 3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) device_checks[i].list_policy_name); 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3595d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (policy == ALWAYS_DENY) 3605d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) return false; 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (policy == POLICY_NOT_SET) { 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Only load content settings from secure origins unless it is a 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // content::MEDIA_OPEN_DEVICE (Pepper) request. 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!IsSchemeSecure() && 36602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch request_.request_type != content::MEDIA_OPEN_DEVICE) { 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (profile_->GetHostContentSettingsMap()->GetContentSetting( 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_.security_origin, request_.security_origin, 37102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch device_checks[i].settings_type, NO_RESOURCE_IDENTIFIER) != 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CONTENT_SETTING_ALLOW) { 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // If we get here, then either policy is set to ALWAYS_ALLOW or the content 3775d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) // settings allow the request by default. 37802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch } 3795d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)int MediaStreamDevicesController::FilterBlockedByDefaultDevices() { 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int requested_devices = 0; 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3865d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles) if (IsDeviceAudioCaptureRequestedAndAllowed()) { 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (profile_->GetHostContentSettingsMap()->GetContentSetting( 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_.security_origin, 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_.security_origin, 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) { 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE] = 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MEDIA_BLOCKED_BY_USER_SETTING; 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++requested_devices; 3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (IsDeviceVideoCaptureRequestedAndAllowed()) { 4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (profile_->GetHostContentSettingsMap()->GetContentSetting( 4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_.security_origin, 4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_.security_origin, 4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) { 4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE] = 4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MEDIA_BLOCKED_BY_USER_SETTING; 4075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++requested_devices; 4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return requested_devices; 4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 41502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdochbool MediaStreamDevicesController::IsDefaultMediaAccessBlocked() const { 416d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the 4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and 4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA. 4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ContentSetting current_setting = 4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) profile_->GetHostContentSettingsMap()->GetDefaultContentSetting( 4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL); 4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (current_setting == CONTENT_SETTING_BLOCK); 4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool MediaStreamDevicesController::IsSchemeSecure() const { 4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (request_.security_origin.SchemeIsSecure()); 4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() const { 4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the 4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and 4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA. 4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent( 4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_.security_origin, request_.security_origin, 4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM); 4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void MediaStreamDevicesController::SetPermission(bool allowed) const { 4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#if defined(OS_ANDROID) 4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // We do not support sticky operations on Android yet. 4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif 4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ContentSettingsPattern primary_pattern = 4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ContentSettingsPattern::FromURLNoWildcard(request_.security_origin); 4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Check the pattern is valid or not. When the request is from a file access, 4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // no exception will be made. 4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!primary_pattern.IsValid()) 4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 451a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) 4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ContentSetting content_setting = allowed ? 4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 45406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles) if (request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE) != 4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_permissions_.end()) { 4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) profile_->GetHostContentSettingsMap()->SetContentSetting( 4575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) primary_pattern, 4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ContentSettingsPattern::Wildcard(), 4595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, 460a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) std::string(), 461a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) content_setting); 462a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) } 463a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) if (request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE) != 46402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch request_permissions_.end()) { 4655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) profile_->GetHostContentSettingsMap()->SetContentSetting( 4665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) primary_pattern, 4675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ContentSettingsPattern::Wildcard(), 468d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, 4695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) std::string(), 4705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) content_setting); 4715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 47302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 4745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestAccepted() const { 4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!content_settings_) 4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 4775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) content_settings_->OnMediaStreamPermissionSet(request_.security_origin, 4795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_permissions_); 480d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 481d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 482d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestDenied() { 4835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!content_settings_) 484bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 485bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 4865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (IsDeviceAudioCaptureRequestedAndAllowed()) { 4875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE] = 4885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MEDIA_BLOCKED_BY_USER; 489bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 490bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (IsDeviceVideoCaptureRequestedAndAllowed()) { 4915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE] = 4925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MEDIA_BLOCKED_BY_USER; 4935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 495d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) content_settings_->OnMediaStreamPermissionSet(request_.security_origin, 4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_permissions_); 497d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)} 498d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 499d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceAudioCaptureRequestedAndAllowed() 5005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const { 5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) MediaStreamTypePermissionMap::const_iterator it = 502a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles) request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE); 5035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return it != request_permissions_.end() && it->second == MEDIA_ALLOWED; 504a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)} 505d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) 5065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool MediaStreamDevicesController::IsDeviceVideoCaptureRequestedAndAllowed() 507d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) const { 508d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles) MediaStreamTypePermissionMap::const_iterator it = 5095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE); 5105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return it != request_permissions_.end() && it->second == MEDIA_ALLOWED; 5115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 5125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)