media_stream_devices_controller.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS)
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h"
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
2990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool HasAnyAvailableDevice() {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const content::MediaStreamDevices& audio_devices =
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices();
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const content::MediaStreamDevices& video_devices =
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaCaptureDevicesDispatcher::GetInstance()->GetVideoCaptureDevices();
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !audio_devices.empty() || !video_devices.empty();
4190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool IsInKioskMode() {
4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return true;
4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS)
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const chromeos::UserManager* user_manager = chromeos::UserManager::Get();
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return user_manager && user_manager->IsLoggedInAsKioskApp();
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return false;
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDevicesController::MediaStreamDevicesController(
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::WebContents* web_contents,
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::MediaStreamRequest& request,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::MediaResponseCallback& callback)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : web_contents_(web_contents),
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_(request),
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      callback_(callback),
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      microphone_requested_(
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE),
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      webcam_requested_(
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext());
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents);
70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Don't call GetDevicePolicy from the initializer list since the
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // implementation depends on member variables.
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (microphone_requested_ &&
7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GetDevicePolicy(prefs::kAudioCaptureAllowed,
7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      prefs::kAudioCaptureAllowedUrls) == ALWAYS_DENY) {
76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    microphone_requested_ = false;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (webcam_requested_ &&
8090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      GetDevicePolicy(prefs::kVideoCaptureAllowed,
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                      prefs::kVideoCaptureAllowedUrls) == ALWAYS_DENY) {
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    webcam_requested_ = false;
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)MediaStreamDevicesController::~MediaStreamDevicesController() {
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!callback_.is_null()) {
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    callback_.Run(content::MediaStreamDevices(),
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                  scoped_ptr<content::MediaStreamUI>());
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaStreamDevicesController::RegisterUserPrefs(
95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* prefs) {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed,
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             true,
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             true,
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
10290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls,
10390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
10490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls,
10590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() {
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If this is a no UI check for policies only go straight to accept - policy
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // check will be done automatically on the way.
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (request_.request_type == content::MEDIA_OPEN_DEVICE) {
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Accept(false);
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Tab capture is allowed for extensions only and infobar is not shown for
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // extensions.
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (request_.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE ||
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      request_.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) {
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Deny the request if the security origin is empty, this happens with
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // file access without |--allow-file-access-from-files| flag.
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (request_.security_origin.is_empty()) {
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Deny the request if there is no device attached to the OS.
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!HasAnyAvailableDevice()) {
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check if any allow exception has been made for this request.
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsRequestAllowedByDefault()) {
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Accept(false);
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check if any block exception has been made for this request.
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsRequestBlockedByDefault()) {
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check if the media default setting is set to block.
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsDefaultMediaAccessBlocked()) {
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Show the infobar.
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const {
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return request_.security_origin.spec();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::Accept(bool update_content_setting) {
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (content_settings_)
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content_settings_->OnMediaStreamAllowed();
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get the default devices for the request.
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::MediaStreamDevices devices;
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (microphone_requested_ || webcam_requested_) {
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (request_.request_type) {
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case content::MEDIA_OPEN_DEVICE:
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // For open device request pick the desired device or fall back to the
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // first available of the given type.
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        MediaCaptureDevicesDispatcher::GetInstance()->GetRequestedDevice(
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            request_.requested_device_id,
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            microphone_requested_,
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            webcam_requested_,
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            &devices);
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case content::MEDIA_DEVICE_ACCESS:
182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case content::MEDIA_GENERATE_STREAM:
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      case content::MEDIA_ENUMERATE_DEVICES:
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Get the default devices for the request.
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        MediaCaptureDevicesDispatcher::GetInstance()->
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetDefaultDevicesForProfile(profile_,
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        microphone_requested_,
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        webcam_requested_,
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        &devices);
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (update_content_setting && IsSchemeSecure() && !devices.empty())
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      SetPermission(true);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<content::MediaStreamUI> ui;
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!devices.empty()) {
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui = MediaCaptureDevicesDispatcher::GetInstance()->
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetMediaStreamCaptureIndicator()->RegisterMediaStream(
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            web_contents_, devices);
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
203868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::MediaResponseCallback cb = callback_;
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback_.Reset();
205868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  cb.Run(devices, ui.Pass());
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::Deny(bool update_content_setting) {
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (content_settings_) {
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content_settings_->OnContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM,
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        std::string());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (update_content_setting)
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetPermission(false);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
220868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::MediaResponseCallback cb = callback_;
221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback_.Reset();
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  cb.Run(content::MediaStreamDevices(), scoped_ptr<content::MediaStreamUI>());
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MediaStreamDevicesController::DevicePolicy
22690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaStreamDevicesController::GetDevicePolicy(
22790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* policy_name,
22890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* whitelist_policy_name) const {
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If the security origin policy matches a value in the whitelist, allow it.
23290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Otherwise, check the |policy_name| master switch for the default behavior.
23390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
23690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(tommi): Remove the kiosk mode check when the whitelist below
23790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // is visible in the media exceptions UI.
23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // See discussion here: https://codereview.chromium.org/15738004/
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (IsInKioskMode()) {
24090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::ListValue* list = prefs->GetList(whitelist_policy_name);
24190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::string value;
24290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (size_t i = 0; i < list->GetSize(); ++i) {
24390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (list->GetString(i, &value)) {
24490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        ContentSettingsPattern pattern =
24590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            ContentSettingsPattern::FromString(value);
24690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (pattern == ContentSettingsPattern::Wildcard()) {
24790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          DLOG(WARNING) << "Ignoring wildcard URL pattern: " << value;
24890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          continue;
24990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        }
25090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        DLOG_IF(ERROR, !pattern.IsValid()) << "Invalid URL pattern: " << value;
25190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (pattern.IsValid() && pattern.Matches(request_.security_origin))
25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          return ALWAYS_ALLOW;
25390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
25490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If a match was not found, check if audio capture is otherwise disallowed
25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // or if the user should be prompted.  Setting the policy value to "true"
25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // is equal to not setting it at all, so from hereon out, we will return
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // either POLICY_NOT_SET (prompt) or ALWAYS_DENY (no prompt, no access).
26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!prefs->GetBoolean(policy_name))
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return ALWAYS_DENY;
26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
26490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return POLICY_NOT_SET;
265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsRequestAllowedByDefault() const {
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The request from internal objects like chrome://URLs is always allowed.
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (ShouldAlwaysAllowOrigin())
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  struct {
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool has_capability;
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* policy_name;
27590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* list_policy_name;
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ContentSettingsType settings_type;
277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } device_checks[] = {
278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    { microphone_requested_, prefs::kAudioCaptureAllowed,
27990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs::kAudioCaptureAllowedUrls, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC },
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    { webcam_requested_, prefs::kVideoCaptureAllowed,
28190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs::kVideoCaptureAllowedUrls,
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA },
283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(device_checks); ++i) {
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!device_checks[i].has_capability)
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
28990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DevicePolicy policy = GetDevicePolicy(device_checks[i].policy_name,
29090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          device_checks[i].list_policy_name);
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (policy == ALWAYS_DENY ||
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        (policy == POLICY_NOT_SET &&
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         profile_->GetHostContentSettingsMap()->GetContentSetting(
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            request_.security_origin, request_.security_origin,
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            device_checks[i].settings_type, NO_RESOURCE_IDENTIFIER) !=
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         CONTENT_SETTING_ALLOW)) {
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If we get here, then either policy is set to ALWAYS_ALLOW or the content
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // settings allow the request by default.
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsRequestBlockedByDefault() const {
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (microphone_requested_ &&
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->GetContentSetting(
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          request_.security_origin,
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          request_.security_origin,
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          NO_RESOURCE_IDENTIFIER) != CONTENT_SETTING_BLOCK) {
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (webcam_requested_ &&
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->GetContentSetting(
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          request_.security_origin,
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          request_.security_origin,
320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          NO_RESOURCE_IDENTIFIER) != CONTENT_SETTING_BLOCK) {
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsDefaultMediaAccessBlocked() const {
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSetting current_setting =
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL);
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return (current_setting == CONTENT_SETTING_BLOCK);
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsSchemeSecure() const {
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return (request_.security_origin.SchemeIsSecure());
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() const {
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent(
348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      request_.security_origin, request_.security_origin,
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_MEDIASTREAM);
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
352c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::SetPermission(bool allowed) const {
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_ANDROID)
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // We do not support sticky operations on Android yet.
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return;
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSettingsPattern primary_pattern =
359c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ContentSettingsPattern::FromURLNoWildcard(request_.security_origin);
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check the pattern is valid or not. When the request is from a file access,
361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // no exception will be made.
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!primary_pattern.IsValid())
363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSetting content_setting = allowed ?
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (microphone_requested_) {
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->SetContentSetting(
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        primary_pattern,
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ContentSettingsPattern::Wildcard(),
371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
372c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string(),
373c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        content_setting);
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (webcam_requested_) {
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    profile_->GetHostContentSettingsMap()->SetContentSetting(
377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        primary_pattern,
378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ContentSettingsPattern::Wildcard(),
379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string(),
381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        content_setting);
382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
384