media_stream_devices_controller.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/histogram.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/prefs/scoped_user_pref_update.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/content_settings_provider.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/content_settings/host_content_settings_map.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/content_settings/tab_specific_content_settings.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/media/media_capture_devices_dispatcher.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media/media_stream_capture_indicator.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/chrome_switches.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/content_settings.h"
2290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/content_settings_pattern.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/user_prefs/pref_registry_syncable.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/media_stream_request.h"
27424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "extensions/common/constants.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/generated_resources.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/theme_resources.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS)
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/chromeos/login/user_manager.h"
3490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool HasAnyAvailableDevice() {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const content::MediaStreamDevices& audio_devices =
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices();
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const content::MediaStreamDevices& video_devices =
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MediaCaptureDevicesDispatcher::GetInstance()->GetVideoCaptureDevices();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return !audio_devices.empty() || !video_devices.empty();
4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool IsInKioskMode() {
5090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return true;
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS)
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const chromeos::UserManager* user_manager = chromeos::UserManager::Get();
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return user_manager && user_manager->IsLoggedInAsKioskApp();
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return false;
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum DevicePermissionActions {
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kAllowHttps = 0,
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kAllowHttp,
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kDeny,
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kCancel,
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kPermissionActionsMax  // Must always be last!
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings::MediaStreamTypeSettings(
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Permission permission, const std::string& requested_device_id):
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    permission(permission), requested_device_id(requested_device_id) {}
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings::
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    MediaStreamTypeSettings(): permission(MEDIA_NONE) {}
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings::
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ~MediaStreamTypeSettings() {}
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDevicesController::MediaStreamDevicesController(
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::WebContents* web_contents,
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::MediaStreamRequest& request,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::MediaResponseCallback& callback)
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : web_contents_(web_contents),
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_(request),
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback_(callback) {
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext());
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents);
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // For MEDIA_OPEN_DEVICE requests (Pepper) we always request both webcam
923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // and microphone to avoid popping two infobars.
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // We start with setting the requested media type to allowed or blocked
943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // depending on the policy. If not blocked by policy it may be blocked later
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // in the two remaining filtering steps (by user setting or by user when
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // clicking the infobar).
973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // TODO(grunell): It's not the nicest solution to let the MEDIA_OPEN_DEVICE
983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // case take a ride on the MEDIA_DEVICE_*_CAPTURE permission. Should be fixed.
993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request.request_type == content::MEDIA_OPEN_DEVICE) {
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (GetDevicePolicy(prefs::kAudioCaptureAllowed,
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        prefs::kAudioCaptureAllowedUrls) == ALWAYS_DENY) {
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_.insert(std::make_pair(
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          content::MEDIA_DEVICE_AUDIO_CAPTURE,
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY,
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  request.requested_audio_device_id)));
1073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_.insert(std::make_pair(
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          content::MEDIA_DEVICE_AUDIO_CAPTURE,
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          MediaStreamTypeSettings(MEDIA_ALLOWED,
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  request.requested_audio_device_id)));
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE ||
1153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request.request_type == content::MEDIA_OPEN_DEVICE) {
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (GetDevicePolicy(prefs::kVideoCaptureAllowed,
1173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        prefs::kVideoCaptureAllowedUrls) == ALWAYS_DENY) {
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_.insert(std::make_pair(
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          content::MEDIA_DEVICE_VIDEO_CAPTURE,
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY,
12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  request.requested_video_device_id)));
1223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_.insert(std::make_pair(
12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          content::MEDIA_DEVICE_VIDEO_CAPTURE,
12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          MediaStreamTypeSettings(MEDIA_ALLOWED,
12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  request.requested_video_device_id)));
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)MediaStreamDevicesController::~MediaStreamDevicesController() {
132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!callback_.is_null()) {
133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    callback_.Run(content::MediaStreamDevices(),
134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                  scoped_ptr<content::MediaStreamUI>());
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MediaStreamDevicesController::RegisterProfilePrefs(
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* prefs) {
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed,
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             true,
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed,
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             true,
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
14790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls,
14890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
14990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls,
15090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(gbillock): rename? doesn't actually dismiss. More of a 'check profile
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// and system for compatibility' thing.
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() {
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Tab capture is allowed for extensions only and infobar is not shown for
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // extensions.
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (request_.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE ||
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      request_.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) {
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Deny the request if the security origin is empty, this happens with
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // file access without |--allow-file-access-from-files| flag.
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (request_.security_origin.is_empty()) {
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Deny the request if there is no device attached to the OS.
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!HasAnyAvailableDevice()) {
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check if any allow exception has been made for this request.
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsRequestAllowedByDefault()) {
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Accept(false);
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Filter any parts of the request that have been blocked by default and deny
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // it if nothing is left to accept.
1857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (FilterBlockedByDefaultDevices() == 0) {
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check if the media default setting is set to block.
191c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsDefaultMediaAccessBlocked()) {
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Deny(false);
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (request_.request_type == content::MEDIA_OPEN_DEVICE) {
19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    bool no_matched_audio_device =
19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        (request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE &&
19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)         !request_.requested_audio_device_id.empty() &&
20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)         MediaCaptureDevicesDispatcher::GetInstance()->GetRequestedAudioDevice(
20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)             request_.requested_audio_device_id) == NULL);
20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    bool no_matched_video_device =
20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        (request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE &&
20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)         !request_.requested_video_device_id.empty() &&
20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)         MediaCaptureDevicesDispatcher::GetInstance()->GetRequestedVideoDevice(
20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)             request_.requested_video_device_id) == NULL);
20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (no_matched_audio_device || no_matched_video_device) {
20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      Deny(false);
20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return true;
21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Show the infobar.
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::HasAudio() const {
2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return IsDeviceAudioCaptureRequestedAndAllowed();
2193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::HasVideo() const {
2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return IsDeviceVideoCaptureRequestedAndAllowed();
2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const {
226c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return request_.security_origin.spec();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::Accept(bool update_content_setting) {
2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  NotifyUIRequestAccepted();
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get the default devices for the request.
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::MediaStreamDevices devices;
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool audio_allowed = IsDeviceAudioCaptureRequestedAndAllowed();
2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool video_allowed = IsDeviceVideoCaptureRequestedAndAllowed();
2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (audio_allowed || video_allowed) {
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (request_.request_type) {
2387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::MEDIA_OPEN_DEVICE: {
2397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        const content::MediaStreamDevice* device = NULL;
24068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // For open device request, when requested device_id is empty, pick
24168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // the first available of the given type. If requested device_id is
24268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // not empty, return the desired device if it's available. Otherwise,
24368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // return no device.
24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (audio_allowed &&
24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
24668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          if (!request_.requested_audio_device_id.empty()) {
24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            device = MediaCaptureDevicesDispatcher::GetInstance()->
24868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                GetRequestedAudioDevice(request_.requested_audio_device_id);
24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          } else {
2507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            device = MediaCaptureDevicesDispatcher::GetInstance()->
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                GetFirstAvailableAudioDevice();
2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        } else if (video_allowed &&
25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
2557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          // Pepper API opens only one device at a time.
25668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          if (!request_.requested_video_device_id.empty()) {
25768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            device = MediaCaptureDevicesDispatcher::GetInstance()->
25868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                GetRequestedVideoDevice(request_.requested_video_device_id);
25968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          } else {
2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            device = MediaCaptureDevicesDispatcher::GetInstance()->
2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                GetFirstAvailableVideoDevice();
2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
2637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
2647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (device)
2657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          devices.push_back(*device);
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
26858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case content::MEDIA_GENERATE_STREAM: {
26958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        bool get_default_audio_device = audio_allowed;
27058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        bool get_default_video_device = video_allowed;
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // Get the exact audio or video device if an id is specified.
27358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (audio_allowed && !request_.requested_audio_device_id.empty()) {
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          const content::MediaStreamDevice* audio_device =
2757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              MediaCaptureDevicesDispatcher::GetInstance()->
2767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  GetRequestedAudioDevice(request_.requested_audio_device_id);
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if (audio_device) {
2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            devices.push_back(*audio_device);
27958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            get_default_audio_device = false;
2807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
28258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (video_allowed && !request_.requested_video_device_id.empty()) {
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          const content::MediaStreamDevice* video_device =
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              MediaCaptureDevicesDispatcher::GetInstance()->
2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  GetRequestedVideoDevice(request_.requested_video_device_id);
2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if (video_device) {
2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            devices.push_back(*video_device);
28858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            get_default_video_device = false;
2897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // If either or both audio and video devices were requested but not
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // specified by id, get the default devices.
29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (get_default_audio_device || get_default_video_device) {
2957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          MediaCaptureDevicesDispatcher::GetInstance()->
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              GetDefaultDevicesForProfile(profile_,
29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                          get_default_audio_device,
29858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                          get_default_video_device,
2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                          &devices);
3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
3017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        break;
30258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
30358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case content::MEDIA_DEVICE_ACCESS: {
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Get the default devices for the request.
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        MediaCaptureDevicesDispatcher::GetInstance()->
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetDefaultDevicesForProfile(profile_,
3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        audio_allowed,
3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        video_allowed,
309c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        &devices);
310c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
31158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
31258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case content::MEDIA_ENUMERATE_DEVICES: {
3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // Do nothing.
3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        NOTREACHED();
3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        break;
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
31758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }  // switch
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // TODO(raymes): We currently set the content permission for non-https
3207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // websites for Pepper requests as well. This is temporary and should be
3217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // removed.
3227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (update_content_setting) {
3237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if ((IsSchemeSecure() && !devices.empty()) ||
3247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          request_.request_type == content::MEDIA_OPEN_DEVICE) {
3257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SetPermission(true);
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<content::MediaStreamUI> ui;
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!devices.empty()) {
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui = MediaCaptureDevicesDispatcher::GetInstance()->
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetMediaStreamCaptureIndicator()->RegisterMediaStream(
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            web_contents_, devices);
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
336868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::MediaResponseCallback cb = callback_;
337868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback_.Reset();
338868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  cb.Run(devices, ui.Pass());
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::Deny(bool update_content_setting) {
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  NotifyUIRequestDenied();
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (update_content_setting)
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetPermission(false);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
347868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::MediaResponseCallback cb = callback_;
348868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback_.Reset();
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  cb.Run(content::MediaStreamDevices(), scoped_ptr<content::MediaStreamUI>());
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamDevicesController::GetMessageText() const {
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO;
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!HasAudio())
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY;
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else if (!HasVideo())
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY;
3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return l10n_util::GetStringFUTF16(
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      message_id, base::UTF8ToUTF16(GetSecurityOriginSpec()));
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamDevicesController::GetMessageTextFragment() const {
3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO_PERMISSION_FRAGMENT;
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!HasAudio())
3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_FRAGMENT;
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else if (!HasVideo())
3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY_PERMISSION_FRAGMENT;
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return l10n_util::GetStringUTF16(message_id);
3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MediaStreamDevicesController::GetAlternateAcceptButtonText() const {
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_MEDIA_CAPTURE_ALLOW);
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)MediaStreamDevicesController::GetAlternateDenyButtonText() const {
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_MEDIA_CAPTURE_DENY);
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::PermissionGranted() {
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL origin(GetSecurityOriginSpec());
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (origin.SchemeIsSecure()) {
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              kAllowHttps, kPermissionActionsMax);
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              kAllowHttp, kPermissionActionsMax);
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Accept(true);
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::PermissionDenied() {
3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            kDeny, kPermissionActionsMax);
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Deny(true);
3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::Cancelled() {
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            kCancel, kPermissionActionsMax);
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Deny(true);
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::RequestFinished() {
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete this;
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MediaStreamDevicesController::DevicePolicy
41090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaStreamDevicesController::GetDevicePolicy(
41190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* policy_name,
41290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* whitelist_policy_name) const {
413c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
41590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If the security origin policy matches a value in the whitelist, allow it.
41690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Otherwise, check the |policy_name| master switch for the default behavior.
41790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(tommi): Remove the kiosk mode check when the whitelist below
42190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // is visible in the media exceptions UI.
42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // See discussion here: https://codereview.chromium.org/15738004/
42390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (IsInKioskMode()) {
42490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::ListValue* list = prefs->GetList(whitelist_policy_name);
42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::string value;
42690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (size_t i = 0; i < list->GetSize(); ++i) {
42790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (list->GetString(i, &value)) {
42890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        ContentSettingsPattern pattern =
42990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            ContentSettingsPattern::FromString(value);
43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (pattern == ContentSettingsPattern::Wildcard()) {
43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          DLOG(WARNING) << "Ignoring wildcard URL pattern: " << value;
43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          continue;
43390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        }
43490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        DLOG_IF(ERROR, !pattern.IsValid()) << "Invalid URL pattern: " << value;
43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (pattern.IsValid() && pattern.Matches(request_.security_origin))
43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          return ALWAYS_ALLOW;
43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
43890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
43990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
44090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If a match was not found, check if audio capture is otherwise disallowed
44290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // or if the user should be prompted.  Setting the policy value to "true"
44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // is equal to not setting it at all, so from hereon out, we will return
44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // either POLICY_NOT_SET (prompt) or ALWAYS_DENY (no prompt, no access).
44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!prefs->GetBoolean(policy_name))
44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return ALWAYS_DENY;
44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return POLICY_NOT_SET;
449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
451c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsRequestAllowedByDefault() const {
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The request from internal objects like chrome://URLs is always allowed.
453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (ShouldAlwaysAllowOrigin())
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  struct {
457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool has_capability;
458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* policy_name;
45990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* list_policy_name;
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ContentSettingsType settings_type;
461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } device_checks[] = {
4623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    { IsDeviceAudioCaptureRequestedAndAllowed(), prefs::kAudioCaptureAllowed,
46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs::kAudioCaptureAllowedUrls, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC },
4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    { IsDeviceVideoCaptureRequestedAndAllowed(), prefs::kVideoCaptureAllowed,
46590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs::kVideoCaptureAllowedUrls,
466c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA },
467c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(device_checks); ++i) {
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!device_checks[i].has_capability)
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DevicePolicy policy = GetDevicePolicy(device_checks[i].policy_name,
47490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          device_checks[i].list_policy_name);
4757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (policy == ALWAYS_DENY)
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
4787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (policy == POLICY_NOT_SET) {
4807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Only load content settings from secure origins unless it is a
4817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // content::MEDIA_OPEN_DEVICE (Pepper) request.
4827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (!IsSchemeSecure() &&
4837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          request_.request_type != content::MEDIA_OPEN_DEVICE) {
4847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return false;
4857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
4867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (profile_->GetHostContentSettingsMap()->GetContentSetting(
4877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              request_.security_origin, request_.security_origin,
4887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              device_checks[i].settings_type, NO_RESOURCE_IDENTIFIER) !=
4897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              CONTENT_SETTING_ALLOW) {
4907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return false;
4917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If we get here, then either policy is set to ALWAYS_ALLOW or the content
494c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // settings allow the request by default.
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
498c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint MediaStreamDevicesController::FilterBlockedByDefaultDevices() {
5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int requested_devices = 0;
5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceAudioCaptureRequestedAndAllowed()) {
5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (profile_->GetHostContentSettingsMap()->GetContentSetting(
5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) {
50968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission =
5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          MEDIA_BLOCKED_BY_USER_SETTING;
5113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ++requested_devices;
5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceVideoCaptureRequestedAndAllowed()) {
5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (profile_->GetHostContentSettingsMap()->GetContentSetting(
5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) {
52268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission =
5233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          MEDIA_BLOCKED_BY_USER_SETTING;
5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
5253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ++requested_devices;
5263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return requested_devices;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsDefaultMediaAccessBlocked() const {
533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the
535c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and
536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
537c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSetting current_setting =
538c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
539c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL);
540c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return (current_setting == CONTENT_SETTING_BLOCK);
541c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
542c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsSchemeSecure() const {
544424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return request_.security_origin.SchemeIsSecure() ||
54558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      request_.security_origin.SchemeIs(extensions::kExtensionScheme) ||
54658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandLine::ForCurrentProcess()->HasSwitch(
54758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          switches::kDisableUserMediaSecurity);
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() const {
551c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent(
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      request_.security_origin, request_.security_origin,
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_MEDIASTREAM);
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::SetPermission(bool allowed) const {
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSettingsPattern primary_pattern =
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ContentSettingsPattern::FromURLNoWildcard(request_.security_origin);
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check the pattern is valid or not. When the request is from a file access,
564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // no exception will be made.
565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!primary_pattern.IsValid())
566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSetting content_setting = allowed ?
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
5703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE) !=
5713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.end()) {
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->SetContentSetting(
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        primary_pattern,
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ContentSettingsPattern::Wildcard(),
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string(),
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        content_setting);
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
5793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE) !=
5803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.end()) {
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    profile_->GetHostContentSettingsMap()->SetContentSetting(
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        primary_pattern,
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ContentSettingsPattern::Wildcard(),
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string(),
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        content_setting);
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestAccepted() const {
5917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!content_settings_)
5927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
5937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content_settings_->OnMediaStreamPermissionSet(request_.security_origin,
5953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                request_permissions_);
5967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
5977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestDenied() {
5997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!content_settings_)
6007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
6017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceAudioCaptureRequestedAndAllowed()) {
60368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission =
6043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        MEDIA_BLOCKED_BY_USER;
6057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceVideoCaptureRequestedAndAllowed()) {
60768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission =
6083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        MEDIA_BLOCKED_BY_USER;
6093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
6103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content_settings_->OnMediaStreamPermissionSet(request_.security_origin,
6123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                request_permissions_);
6133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceAudioCaptureRequestedAndAllowed()
6163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const {
61768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MediaStreamTypeSettingsMap::const_iterator it =
6183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE);
61968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return (it != request_permissions_.end() &&
62068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          it->second.permission == MEDIA_ALLOWED);
6213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceVideoCaptureRequestedAndAllowed()
6243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const {
62568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MediaStreamTypeSettingsMap::const_iterator it =
6263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE);
62768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return (it != request_permissions_.end() &&
62868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          it->second.permission == MEDIA_ALLOWED);
6297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
630