media_stream_devices_controller.cc revision 58537e28ecd584eab876aee8be7156509866d23a
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)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDevicesController::MediaStreamDevicesController(
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::WebContents* web_contents,
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::MediaStreamRequest& request,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::MediaResponseCallback& callback)
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : web_contents_(web_contents),
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_(request),
643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback_(callback) {
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext());
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents);
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // For MEDIA_OPEN_DEVICE requests (Pepper) we always request both webcam
693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // and microphone to avoid popping two infobars.
703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // We start with setting the requested media type to allowed or blocked
713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // depending on the policy. If not blocked by policy it may be blocked later
723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // in the two remaining filtering steps (by user setting or by user when
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // clicking the infobar).
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // TODO(grunell): It's not the nicest solution to let the MEDIA_OPEN_DEVICE
753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // case take a ride on the MEDIA_DEVICE_*_CAPTURE permission. Should be fixed.
763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request.request_type == content::MEDIA_OPEN_DEVICE) {
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (GetDevicePolicy(prefs::kAudioCaptureAllowed,
793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        prefs::kAudioCaptureAllowedUrls) == ALWAYS_DENY) {
803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE] =
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          MEDIA_BLOCKED_BY_POLICY;
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE] = MEDIA_ALLOWED;
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE ||
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request.request_type == content::MEDIA_OPEN_DEVICE) {
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (GetDevicePolicy(prefs::kVideoCaptureAllowed,
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        prefs::kVideoCaptureAllowedUrls) == ALWAYS_DENY) {
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE] =
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          MEDIA_BLOCKED_BY_POLICY;
923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE] = MEDIA_ALLOWED;
943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)MediaStreamDevicesController::~MediaStreamDevicesController() {
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!callback_.is_null()) {
100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    callback_.Run(content::MediaStreamDevices(),
101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                  scoped_ptr<content::MediaStreamUI>());
102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MediaStreamDevicesController::RegisterProfilePrefs(
107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* prefs) {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed,
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             true,
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             true,
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls,
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls,
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() {
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Tab capture is allowed for extensions only and infobar is not shown for
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // extensions.
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (request_.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE ||
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      request_.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) {
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Deny the request if the security origin is empty, this happens with
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // file access without |--allow-file-access-from-files| flag.
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (request_.security_origin.is_empty()) {
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Deny the request if there is no device attached to the OS.
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!HasAnyAvailableDevice()) {
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check if any allow exception has been made for this request.
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsRequestAllowedByDefault()) {
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Accept(false);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Filter any parts of the request that have been blocked by default and deny
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // it if nothing is left to accept.
1517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (FilterBlockedByDefaultDevices() == 0) {
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check if the media default setting is set to block.
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsDefaultMediaAccessBlocked()) {
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Show the infobar.
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::HasAudio() const {
1673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return IsDeviceAudioCaptureRequestedAndAllowed();
1683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::HasVideo() const {
1713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return IsDeviceVideoCaptureRequestedAndAllowed();
1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const {
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return request_.security_origin.spec();
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::Accept(bool update_content_setting) {
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  NotifyUIRequestAccepted();
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get the default devices for the request.
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::MediaStreamDevices devices;
1833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool audio_allowed = IsDeviceAudioCaptureRequestedAndAllowed();
1843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool video_allowed = IsDeviceVideoCaptureRequestedAndAllowed();
1853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (audio_allowed || video_allowed) {
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (request_.request_type) {
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::MEDIA_OPEN_DEVICE: {
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        const content::MediaStreamDevice* device = NULL;
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // For open device request pick the desired device or fall back to the
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // first available of the given type.
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (audio_allowed &&
19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          device = MediaCaptureDevicesDispatcher::GetInstance()->
1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              GetRequestedAudioDevice(request_.requested_audio_device_id);
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          // TODO(wjia): Confirm this is the intended behavior.
1967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if (!device) {
1977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            device = MediaCaptureDevicesDispatcher::GetInstance()->
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                GetFirstAvailableAudioDevice();
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        } else if (video_allowed &&
20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
2027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          // Pepper API opens only one device at a time.
2037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          device = MediaCaptureDevicesDispatcher::GetInstance()->
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              GetRequestedVideoDevice(request_.requested_video_device_id);
2057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          // TODO(wjia): Confirm this is the intended behavior.
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if (!device) {
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            device = MediaCaptureDevicesDispatcher::GetInstance()->
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                GetFirstAvailableVideoDevice();
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (device)
2127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          devices.push_back(*device);
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
21558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case content::MEDIA_GENERATE_STREAM: {
21658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        bool get_default_audio_device = audio_allowed;
21758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        bool get_default_video_device = video_allowed;
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // Get the exact audio or video device if an id is specified.
22058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (audio_allowed && !request_.requested_audio_device_id.empty()) {
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          const content::MediaStreamDevice* audio_device =
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              MediaCaptureDevicesDispatcher::GetInstance()->
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  GetRequestedAudioDevice(request_.requested_audio_device_id);
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if (audio_device) {
2257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            devices.push_back(*audio_device);
22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            get_default_audio_device = false;
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
22958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (video_allowed && !request_.requested_video_device_id.empty()) {
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          const content::MediaStreamDevice* video_device =
2317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              MediaCaptureDevicesDispatcher::GetInstance()->
2327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  GetRequestedVideoDevice(request_.requested_video_device_id);
2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if (video_device) {
2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            devices.push_back(*video_device);
23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            get_default_video_device = false;
2367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
2377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // If either or both audio and video devices were requested but not
2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // specified by id, get the default devices.
24158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (get_default_audio_device || get_default_video_device) {
2427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          MediaCaptureDevicesDispatcher::GetInstance()->
2437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              GetDefaultDevicesForProfile(profile_,
24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                          get_default_audio_device,
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                          get_default_video_device,
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                          &devices);
2477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
2487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        break;
24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case content::MEDIA_DEVICE_ACCESS: {
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Get the default devices for the request.
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        MediaCaptureDevicesDispatcher::GetInstance()->
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetDefaultDevicesForProfile(profile_,
2543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        audio_allowed,
2553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        video_allowed,
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        &devices);
257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
25858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
25958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case content::MEDIA_ENUMERATE_DEVICES: {
2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // Do nothing.
2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        NOTREACHED();
2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        break;
26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }  // switch
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // TODO(raymes): We currently set the content permission for non-https
2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // websites for Pepper requests as well. This is temporary and should be
2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // removed.
2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (update_content_setting) {
2707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if ((IsSchemeSecure() && !devices.empty()) ||
2717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          request_.request_type == content::MEDIA_OPEN_DEVICE) {
2727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SetPermission(true);
2737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
2747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<content::MediaStreamUI> ui;
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!devices.empty()) {
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui = MediaCaptureDevicesDispatcher::GetInstance()->
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetMediaStreamCaptureIndicator()->RegisterMediaStream(
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            web_contents_, devices);
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
283868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::MediaResponseCallback cb = callback_;
284868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback_.Reset();
285868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  cb.Run(devices, ui.Pass());
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::Deny(bool update_content_setting) {
2897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  NotifyUIRequestDenied();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (update_content_setting)
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetPermission(false);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::MediaResponseCallback cb = callback_;
295868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback_.Reset();
296868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  cb.Run(content::MediaStreamDevices(), scoped_ptr<content::MediaStreamUI>());
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MediaStreamDevicesController::DevicePolicy
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaStreamDevicesController::GetDevicePolicy(
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* policy_name,
30290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* whitelist_policy_name) const {
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
30590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If the security origin policy matches a value in the whitelist, allow it.
30690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Otherwise, check the |policy_name| master switch for the default behavior.
30790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
31090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(tommi): Remove the kiosk mode check when the whitelist below
31190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // is visible in the media exceptions UI.
31290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // See discussion here: https://codereview.chromium.org/15738004/
31390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (IsInKioskMode()) {
31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::ListValue* list = prefs->GetList(whitelist_policy_name);
31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::string value;
31690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (size_t i = 0; i < list->GetSize(); ++i) {
31790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (list->GetString(i, &value)) {
31890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        ContentSettingsPattern pattern =
31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            ContentSettingsPattern::FromString(value);
32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (pattern == ContentSettingsPattern::Wildcard()) {
32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          DLOG(WARNING) << "Ignoring wildcard URL pattern: " << value;
32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          continue;
32390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        }
32490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        DLOG_IF(ERROR, !pattern.IsValid()) << "Invalid URL pattern: " << value;
32590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (pattern.IsValid() && pattern.Matches(request_.security_origin))
32690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          return ALWAYS_ALLOW;
32790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
32890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
32990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
33090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
33190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If a match was not found, check if audio capture is otherwise disallowed
33290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // or if the user should be prompted.  Setting the policy value to "true"
33390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // is equal to not setting it at all, so from hereon out, we will return
33490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // either POLICY_NOT_SET (prompt) or ALWAYS_DENY (no prompt, no access).
33590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!prefs->GetBoolean(policy_name))
33690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return ALWAYS_DENY;
33790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
33890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return POLICY_NOT_SET;
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsRequestAllowedByDefault() const {
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The request from internal objects like chrome://URLs is always allowed.
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (ShouldAlwaysAllowOrigin())
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  struct {
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool has_capability;
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* policy_name;
34990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* list_policy_name;
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ContentSettingsType settings_type;
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } device_checks[] = {
3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    { IsDeviceAudioCaptureRequestedAndAllowed(), prefs::kAudioCaptureAllowed,
35390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs::kAudioCaptureAllowedUrls, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC },
3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    { IsDeviceVideoCaptureRequestedAndAllowed(), prefs::kVideoCaptureAllowed,
35590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs::kVideoCaptureAllowedUrls,
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA },
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(device_checks); ++i) {
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!device_checks[i].has_capability)
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
36390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DevicePolicy policy = GetDevicePolicy(device_checks[i].policy_name,
36490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          device_checks[i].list_policy_name);
3657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (policy == ALWAYS_DENY)
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
3687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
3697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (policy == POLICY_NOT_SET) {
3707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Only load content settings from secure origins unless it is a
3717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // content::MEDIA_OPEN_DEVICE (Pepper) request.
3727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (!IsSchemeSecure() &&
3737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          request_.request_type != content::MEDIA_OPEN_DEVICE) {
3747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return false;
3757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
3767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (profile_->GetHostContentSettingsMap()->GetContentSetting(
3777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              request_.security_origin, request_.security_origin,
3787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              device_checks[i].settings_type, NO_RESOURCE_IDENTIFIER) !=
3797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              CONTENT_SETTING_ALLOW) {
3807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return false;
3817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If we get here, then either policy is set to ALWAYS_ALLOW or the content
384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // settings allow the request by default.
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint MediaStreamDevicesController::FilterBlockedByDefaultDevices() {
3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int requested_devices = 0;
3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceAudioCaptureRequestedAndAllowed()) {
3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (profile_->GetHostContentSettingsMap()->GetContentSetting(
3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
3963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
3973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
3983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) {
3993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE] =
4003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          MEDIA_BLOCKED_BY_USER_SETTING;
4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ++requested_devices;
4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceVideoCaptureRequestedAndAllowed()) {
4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (profile_->GetHostContentSettingsMap()->GetContentSetting(
4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) {
4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE] =
4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          MEDIA_BLOCKED_BY_USER_SETTING;
4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ++requested_devices;
4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return requested_devices;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsDefaultMediaAccessBlocked() const {
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSetting current_setting =
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL);
430c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return (current_setting == CONTENT_SETTING_BLOCK);
431c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsSchemeSecure() const {
434424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return request_.security_origin.SchemeIsSecure() ||
43558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      request_.security_origin.SchemeIs(extensions::kExtensionScheme) ||
43658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandLine::ForCurrentProcess()->HasSwitch(
43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          switches::kDisableUserMediaSecurity);
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
439c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
440c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() const {
441c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the
442c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and
443c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
444c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent(
445c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      request_.security_origin, request_.security_origin,
446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_MEDIASTREAM);
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::SetPermission(bool allowed) const {
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_ANDROID)
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We do not support sticky operations on Android yet.
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return;
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSettingsPattern primary_pattern =
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ContentSettingsPattern::FromURLNoWildcard(request_.security_origin);
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check the pattern is valid or not. When the request is from a file access,
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // no exception will be made.
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!primary_pattern.IsValid())
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSetting content_setting = allowed ?
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE) !=
4653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.end()) {
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->SetContentSetting(
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        primary_pattern,
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ContentSettingsPattern::Wildcard(),
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string(),
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        content_setting);
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
4733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE) !=
4743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.end()) {
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    profile_->GetHostContentSettingsMap()->SetContentSetting(
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        primary_pattern,
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ContentSettingsPattern::Wildcard(),
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
479c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string(),
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        content_setting);
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestAccepted() const {
4857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!content_settings_)
4867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
4877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content_settings_->OnMediaStreamPermissionSet(request_.security_origin,
4893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                request_permissions_);
4907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
4917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestDenied() {
4937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!content_settings_)
4947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
4957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceAudioCaptureRequestedAndAllowed()) {
4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE] =
4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        MEDIA_BLOCKED_BY_USER;
4997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceVideoCaptureRequestedAndAllowed()) {
5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE] =
5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        MEDIA_BLOCKED_BY_USER;
5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content_settings_->OnMediaStreamPermissionSet(request_.security_origin,
5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                request_permissions_);
5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceAudioCaptureRequestedAndAllowed()
5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const {
5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MediaStreamTypePermissionMap::const_iterator it =
5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE);
5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return it != request_permissions_.end() && it->second == MEDIA_ALLOWED;
5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceVideoCaptureRequestedAndAllowed()
5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const {
5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  MediaStreamTypePermissionMap::const_iterator it =
5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE);
5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return it != request_permissions_.end() && it->second == MEDIA_ALLOWED;
5217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
522