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