media_stream_devices_controller.cc revision e5d81f57cb97b3b6b7fccc9c5610d21eb81db09d
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)
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool HasAvailableDevicesForRequest(const content::MediaStreamRequest& request) {
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool has_audio_device =
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      request.audio_type == content::MEDIA_NO_SERVICE ||
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      !MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices()
44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          .empty();
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  bool has_video_device =
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      request.video_type == content::MEDIA_NO_SERVICE ||
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      !MediaCaptureDevicesDispatcher::GetInstance()->GetVideoCaptureDevices()
48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          .empty();
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return has_audio_device && has_video_device;
5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool IsInKioskMode() {
5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
5590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return true;
5690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS)
5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  const chromeos::UserManager* user_manager = chromeos::UserManager::Get();
5990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return user_manager && user_manager->IsLoggedInAsKioskApp();
6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else
6190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return false;
6290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
6390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum DevicePermissionActions {
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kAllowHttps = 0,
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kAllowHttp,
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kDeny,
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kCancel,
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kPermissionActionsMax  // Must always be last!
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings::MediaStreamTypeSettings(
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Permission permission, const std::string& requested_device_id):
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    permission(permission), requested_device_id(requested_device_id) {}
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings::
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    MediaStreamTypeSettings(): permission(MEDIA_NONE) {}
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings::
8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ~MediaStreamTypeSettings() {}
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDevicesController::MediaStreamDevicesController(
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::WebContents* web_contents,
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::MediaStreamRequest& request,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::MediaResponseCallback& callback)
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : web_contents_(web_contents),
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_(request),
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback_(callback) {
92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext());
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents);
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // For MEDIA_OPEN_DEVICE requests (Pepper) we always request both webcam
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // and microphone to avoid popping two infobars.
973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // We start with setting the requested media type to allowed or blocked
983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // depending on the policy. If not blocked by policy it may be blocked later
993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // in the two remaining filtering steps (by user setting or by user when
1003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // clicking the infobar).
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // TODO(grunell): It's not the nicest solution to let the MEDIA_OPEN_DEVICE
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // case take a ride on the MEDIA_DEVICE_*_CAPTURE permission. Should be fixed.
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request.request_type == content::MEDIA_OPEN_DEVICE) {
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (GetDevicePolicy(prefs::kAudioCaptureAllowed,
1063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        prefs::kAudioCaptureAllowedUrls) == ALWAYS_DENY) {
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_.insert(std::make_pair(
10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          content::MEDIA_DEVICE_AUDIO_CAPTURE,
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY,
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  request.requested_audio_device_id)));
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_.insert(std::make_pair(
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          content::MEDIA_DEVICE_AUDIO_CAPTURE,
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          MediaStreamTypeSettings(MEDIA_ALLOWED,
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  request.requested_audio_device_id)));
1163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE ||
1193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request.request_type == content::MEDIA_OPEN_DEVICE) {
1203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (GetDevicePolicy(prefs::kVideoCaptureAllowed,
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        prefs::kVideoCaptureAllowedUrls) == ALWAYS_DENY) {
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_.insert(std::make_pair(
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          content::MEDIA_DEVICE_VIDEO_CAPTURE,
12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY,
12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  request.requested_video_device_id)));
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_.insert(std::make_pair(
12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          content::MEDIA_DEVICE_VIDEO_CAPTURE,
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          MediaStreamTypeSettings(MEDIA_ALLOWED,
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  request.requested_video_device_id)));
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)MediaStreamDevicesController::~MediaStreamDevicesController() {
136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!callback_.is_null()) {
137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    callback_.Run(content::MediaStreamDevices(),
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                  content::MEDIA_DEVICE_INVALID_STATE,
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                  scoped_ptr<content::MediaStreamUI>());
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MediaStreamDevicesController::RegisterProfilePrefs(
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* prefs) {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed,
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             true,
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed,
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             true,
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
15290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls,
15390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
15490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls,
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(gbillock): rename? doesn't actually dismiss. More of a 'check profile
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// and system for compatibility' thing.
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() {
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Tab capture is allowed for extensions only and infobar is not shown for
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // extensions.
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (request_.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE ||
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      request_.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) {
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Deny(false, content::MEDIA_DEVICE_INVALID_STATE);
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Deny the request if the security origin is empty, this happens with
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // file access without |--allow-file-access-from-files| flag.
171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (request_.security_origin.is_empty()) {
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Deny(false, content::MEDIA_DEVICE_INVALID_SECURITY_ORIGIN);
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Deny the request if there is no device attached to the OS of the
177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // requested type. If both audio and video is requested, both types must be
178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // available.
179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!HasAvailableDevicesForRequest(request_)) {
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Deny(false, content::MEDIA_DEVICE_NO_HARDWARE);
181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check if any allow exception has been made for this request.
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsRequestAllowedByDefault()) {
186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Accept(false);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Filter any parts of the request that have been blocked by default and deny
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // it if nothing is left to accept.
1927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (FilterBlockedByDefaultDevices() == 0) {
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check if the media default setting is set to block.
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsDefaultMediaAccessBlocked()) {
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED);
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (request_.request_type == content::MEDIA_OPEN_DEVICE) {
20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    bool no_matched_audio_device =
20568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        (request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE &&
20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)         !request_.requested_audio_device_id.empty() &&
20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)         MediaCaptureDevicesDispatcher::GetInstance()->GetRequestedAudioDevice(
20868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)             request_.requested_audio_device_id) == NULL);
20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    bool no_matched_video_device =
21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        (request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE &&
21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)         !request_.requested_video_device_id.empty() &&
21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)         MediaCaptureDevicesDispatcher::GetInstance()->GetRequestedVideoDevice(
21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)             request_.requested_video_device_id) == NULL);
21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (no_matched_audio_device || no_matched_video_device) {
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED);
21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return true;
21768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Show the infobar.
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::HasAudio() const {
2253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return IsDeviceAudioCaptureRequestedAndAllowed();
2263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::HasVideo() const {
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return IsDeviceVideoCaptureRequestedAndAllowed();
2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const {
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return request_.security_origin.spec();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::Accept(bool update_content_setting) {
2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  NotifyUIRequestAccepted();
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get the default devices for the request.
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::MediaStreamDevices devices;
2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool audio_allowed = IsDeviceAudioCaptureRequestedAndAllowed();
2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool video_allowed = IsDeviceVideoCaptureRequestedAndAllowed();
2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (audio_allowed || video_allowed) {
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (request_.request_type) {
2457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::MEDIA_OPEN_DEVICE: {
2467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        const content::MediaStreamDevice* device = NULL;
24768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // For open device request, when requested device_id is empty, pick
24868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // the first available of the given type. If requested device_id is
24968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // not empty, return the desired device if it's available. Otherwise,
25068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // return no device.
25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (audio_allowed &&
25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
25368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          if (!request_.requested_audio_device_id.empty()) {
25468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            device = MediaCaptureDevicesDispatcher::GetInstance()->
25568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                GetRequestedAudioDevice(request_.requested_audio_device_id);
25668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          } else {
2577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            device = MediaCaptureDevicesDispatcher::GetInstance()->
2587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                GetFirstAvailableAudioDevice();
2597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
26058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        } else if (video_allowed &&
26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
2627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          // Pepper API opens only one device at a time.
26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          if (!request_.requested_video_device_id.empty()) {
26468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            device = MediaCaptureDevicesDispatcher::GetInstance()->
26568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                GetRequestedVideoDevice(request_.requested_video_device_id);
26668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          } else {
2677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            device = MediaCaptureDevicesDispatcher::GetInstance()->
2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                GetFirstAvailableVideoDevice();
2697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
2707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
2717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (device)
2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          devices.push_back(*device);
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
27458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case content::MEDIA_GENERATE_STREAM: {
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        bool get_default_audio_device = audio_allowed;
27758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        bool get_default_video_device = video_allowed;
2787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // Get the exact audio or video device if an id is specified.
28058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (audio_allowed && !request_.requested_audio_device_id.empty()) {
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          const content::MediaStreamDevice* audio_device =
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              MediaCaptureDevicesDispatcher::GetInstance()->
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  GetRequestedAudioDevice(request_.requested_audio_device_id);
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if (audio_device) {
2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            devices.push_back(*audio_device);
28658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            get_default_audio_device = false;
2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
2887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (video_allowed && !request_.requested_video_device_id.empty()) {
2907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          const content::MediaStreamDevice* video_device =
2917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              MediaCaptureDevicesDispatcher::GetInstance()->
2927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  GetRequestedVideoDevice(request_.requested_video_device_id);
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if (video_device) {
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            devices.push_back(*video_device);
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            get_default_video_device = false;
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // If either or both audio and video devices were requested but not
3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // specified by id, get the default devices.
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (get_default_audio_device || get_default_video_device) {
3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          MediaCaptureDevicesDispatcher::GetInstance()->
3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              GetDefaultDevicesForProfile(profile_,
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                          get_default_audio_device,
30558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                          get_default_video_device,
3067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                          &devices);
3077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
3087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        break;
30958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case content::MEDIA_DEVICE_ACCESS: {
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Get the default devices for the request.
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        MediaCaptureDevicesDispatcher::GetInstance()->
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetDefaultDevicesForProfile(profile_,
3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        audio_allowed,
3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        video_allowed,
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        &devices);
317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
31858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case content::MEDIA_ENUMERATE_DEVICES: {
3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // Do nothing.
3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        NOTREACHED();
3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        break;
32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }  // switch
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // TODO(raymes): We currently set the content permission for non-https
3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // websites for Pepper requests as well. This is temporary and should be
3287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // removed.
3297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (update_content_setting) {
3307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if ((IsSchemeSecure() && !devices.empty()) ||
3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          request_.request_type == content::MEDIA_OPEN_DEVICE) {
3327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SetPermission(true);
3337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
3347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<content::MediaStreamUI> ui;
338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!devices.empty()) {
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui = MediaCaptureDevicesDispatcher::GetInstance()->
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetMediaStreamCaptureIndicator()->RegisterMediaStream(
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            web_contents_, devices);
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::MediaResponseCallback cb = callback_;
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback_.Reset();
345e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  cb.Run(devices,
346e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch         devices.empty() ?
347e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch             content::MEDIA_DEVICE_NO_HARDWARE : content::MEDIA_DEVICE_OK,
348e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch         ui.Pass());
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MediaStreamDevicesController::Deny(
352a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool update_content_setting,
353a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    content::MediaStreamRequestResult result) {
354a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DLOG(WARNING) << "MediaStreamDevicesController::Deny: " << result;
3557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  NotifyUIRequestDenied();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (update_content_setting)
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetPermission(false);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
360868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::MediaResponseCallback cb = callback_;
361868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback_.Reset();
362a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  cb.Run(content::MediaStreamDevices(),
363a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         result,
364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         scoped_ptr<content::MediaStreamUI>());
365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
367a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int MediaStreamDevicesController::GetIconID() const {
368a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (HasVideo())
369a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return IDR_INFOBAR_MEDIA_STREAM_CAMERA;
370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return IDR_INFOBAR_MEDIA_STREAM_MIC;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamDevicesController::GetMessageText() const {
3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO;
3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!HasAudio())
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY;
3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else if (!HasVideo())
3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY;
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return l10n_util::GetStringFUTF16(
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      message_id, base::UTF8ToUTF16(GetSecurityOriginSpec()));
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamDevicesController::GetMessageTextFragment() const {
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO_PERMISSION_FRAGMENT;
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!HasAudio())
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_FRAGMENT;
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else if (!HasVideo())
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY_PERMISSION_FRAGMENT;
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return l10n_util::GetStringUTF16(message_id);
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool MediaStreamDevicesController::HasUserGesture() const {
394effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return request_.user_gesture;
3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)GURL MediaStreamDevicesController::GetRequestingHostname() const {
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return request_.security_origin;
3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::PermissionGranted() {
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL origin(GetSecurityOriginSpec());
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (origin.SchemeIsSecure()) {
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              kAllowHttps, kPermissionActionsMax);
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              kAllowHttp, kPermissionActionsMax);
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Accept(true);
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::PermissionDenied() {
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            kDeny, kPermissionActionsMax);
416a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Deny(true, content::MEDIA_DEVICE_PERMISSION_DENIED);
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::Cancelled() {
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            kCancel, kPermissionActionsMax);
422a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Deny(true, content::MEDIA_DEVICE_PERMISSION_DISMISSED);
4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::RequestFinished() {
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete this;
4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MediaStreamDevicesController::DevicePolicy
43090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaStreamDevicesController::GetDevicePolicy(
43190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* policy_name,
43290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* whitelist_policy_name) const {
433c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
43590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If the security origin policy matches a value in the whitelist, allow it.
43690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Otherwise, check the |policy_name| master switch for the default behavior.
43790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
44090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(tommi): Remove the kiosk mode check when the whitelist below
44190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // is visible in the media exceptions UI.
44290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // See discussion here: https://codereview.chromium.org/15738004/
44390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (IsInKioskMode()) {
44490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::ListValue* list = prefs->GetList(whitelist_policy_name);
44590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::string value;
44690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (size_t i = 0; i < list->GetSize(); ++i) {
44790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (list->GetString(i, &value)) {
44890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        ContentSettingsPattern pattern =
44990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            ContentSettingsPattern::FromString(value);
45090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (pattern == ContentSettingsPattern::Wildcard()) {
45190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          DLOG(WARNING) << "Ignoring wildcard URL pattern: " << value;
45290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          continue;
45390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        }
45490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        DLOG_IF(ERROR, !pattern.IsValid()) << "Invalid URL pattern: " << value;
45590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (pattern.IsValid() && pattern.Matches(request_.security_origin))
45690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          return ALWAYS_ALLOW;
45790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
45890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
45990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
46090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If a match was not found, check if audio capture is otherwise disallowed
46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // or if the user should be prompted.  Setting the policy value to "true"
46390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // is equal to not setting it at all, so from hereon out, we will return
46490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // either POLICY_NOT_SET (prompt) or ALWAYS_DENY (no prompt, no access).
46590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!prefs->GetBoolean(policy_name))
46690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return ALWAYS_DENY;
46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
46890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return POLICY_NOT_SET;
469c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
471c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsRequestAllowedByDefault() const {
472c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The request from internal objects like chrome://URLs is always allowed.
473c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (ShouldAlwaysAllowOrigin())
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
475c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
476c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  struct {
477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool has_capability;
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* policy_name;
47990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* list_policy_name;
480c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ContentSettingsType settings_type;
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } device_checks[] = {
4823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    { IsDeviceAudioCaptureRequestedAndAllowed(), prefs::kAudioCaptureAllowed,
48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs::kAudioCaptureAllowedUrls, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC },
4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    { IsDeviceVideoCaptureRequestedAndAllowed(), prefs::kVideoCaptureAllowed,
48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs::kVideoCaptureAllowedUrls,
486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA },
487c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(device_checks); ++i) {
490c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!device_checks[i].has_capability)
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DevicePolicy policy = GetDevicePolicy(device_checks[i].policy_name,
49490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          device_checks[i].list_policy_name);
4957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (policy == ALWAYS_DENY)
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
4987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
4997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (policy == POLICY_NOT_SET) {
5007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Only load content settings from secure origins unless it is a
5017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // content::MEDIA_OPEN_DEVICE (Pepper) request.
5027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (!IsSchemeSecure() &&
5037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          request_.request_type != content::MEDIA_OPEN_DEVICE) {
5047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return false;
5057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
5067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (profile_->GetHostContentSettingsMap()->GetContentSetting(
5077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              request_.security_origin, request_.security_origin,
5087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              device_checks[i].settings_type, NO_RESOURCE_IDENTIFIER) !=
5097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              CONTENT_SETTING_ALLOW) {
5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return false;
5117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
5122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
513c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If we get here, then either policy is set to ALWAYS_ALLOW or the content
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // settings allow the request by default.
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint MediaStreamDevicesController::FilterBlockedByDefaultDevices() {
5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int requested_devices = 0;
5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceAudioCaptureRequestedAndAllowed()) {
5243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (profile_->GetHostContentSettingsMap()->GetContentSetting(
5253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
5263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
5273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
5283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) {
52968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission =
5303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          MEDIA_BLOCKED_BY_USER_SETTING;
5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ++requested_devices;
5333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceVideoCaptureRequestedAndAllowed()) {
5373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (profile_->GetHostContentSettingsMap()->GetContentSetting(
5383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
5393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) {
54268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission =
5433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          MEDIA_BLOCKED_BY_USER_SETTING;
5443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ++requested_devices;
5463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return requested_devices;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
552c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsDefaultMediaAccessBlocked() const {
553c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
554c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and
556c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSetting current_setting =
558c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL);
560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return (current_setting == CONTENT_SETTING_BLOCK);
561c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsSchemeSecure() const {
564424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return request_.security_origin.SchemeIsSecure() ||
56558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      request_.security_origin.SchemeIs(extensions::kExtensionScheme) ||
56658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      CommandLine::ForCurrentProcess()->HasSwitch(
56758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)          switches::kDisableUserMediaSecurity);
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() const {
571c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the
572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and
573c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
574c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent(
575c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      request_.security_origin, request_.security_origin,
576c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_MEDIASTREAM);
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::SetPermission(bool allowed) const {
580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSettingsPattern primary_pattern =
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ContentSettingsPattern::FromURLNoWildcard(request_.security_origin);
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check the pattern is valid or not. When the request is from a file access,
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // no exception will be made.
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!primary_pattern.IsValid())
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSetting content_setting = allowed ?
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
5903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE) !=
5913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.end()) {
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->SetContentSetting(
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        primary_pattern,
594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ContentSettingsPattern::Wildcard(),
595c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string(),
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        content_setting);
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
5993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE) !=
6003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.end()) {
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    profile_->GetHostContentSettingsMap()->SetContentSetting(
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        primary_pattern,
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ContentSettingsPattern::Wildcard(),
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string(),
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        content_setting);
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestAccepted() const {
6117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!content_settings_)
6127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
6137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content_settings_->OnMediaStreamPermissionSet(request_.security_origin,
6153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                request_permissions_);
6167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
6177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestDenied() {
6197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!content_settings_)
6207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
6217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceAudioCaptureRequestedAndAllowed()) {
62368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission =
6243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        MEDIA_BLOCKED_BY_USER;
6257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceVideoCaptureRequestedAndAllowed()) {
62768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission =
6283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        MEDIA_BLOCKED_BY_USER;
6293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
6303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content_settings_->OnMediaStreamPermissionSet(request_.security_origin,
6323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                request_permissions_);
6333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceAudioCaptureRequestedAndAllowed()
6363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const {
63768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MediaStreamTypeSettingsMap::const_iterator it =
6383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE);
63968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return (it != request_permissions_.end() &&
64068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          it->second.permission == MEDIA_ALLOWED);
6413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceVideoCaptureRequestedAndAllowed()
6443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const {
64568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MediaStreamTypeSettingsMap::const_iterator it =
6463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE);
64768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return (it != request_permissions_.end() &&
64868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          it->second.permission == MEDIA_ALLOWED);
6497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
650