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