media_stream_devices_controller.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
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"
2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/pref_registry/pref_registry_syncable.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "content/public/browser/render_widget_host_view.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/media_stream_request.h"
29424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "extensions/common/constants.h"
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/theme_resources.h"
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS)
346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "components/user_manager/user_manager.h"
3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool HasAvailableDevicesForRequest(const content::MediaStreamRequest& request) {
42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const content::MediaStreamDevices* audio_devices =
43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ?
44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          &MediaCaptureDevicesDispatcher::GetInstance()
45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)              ->GetAudioCaptureDevices() :
46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          NULL;
47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  const content::MediaStreamDevices* video_devices =
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE ?
50010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          &MediaCaptureDevicesDispatcher::GetInstance()
51010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)              ->GetVideoCaptureDevices() :
52010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          NULL;
53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Check if we're being asked for audio and/or video and that either of those
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // lists is empty.  If they are, we do not have devices available for the
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // request.
57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // TODO(tommi): It's kind of strange to have this here since if we fail this
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // test, there'll be a UI shown that indicates to the user that access to
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // non-existing audio/video devices has been denied.  The user won't have
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // any way to change that but there will be a UI shown which indicates that
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // access is blocked.
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if ((audio_devices != NULL && audio_devices->empty()) ||
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      (video_devices != NULL && video_devices->empty())) {
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Note: we check requested_[audio|video]_device_id before dereferencing
68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // [audio|video]_devices.  If the requested device id is non-empty, then
69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // the corresponding device list must not be NULL.
70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!request.requested_audio_device_id.empty() &&
72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      !audio_devices->FindById(request.requested_audio_device_id)) {
73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (!request.requested_video_device_id.empty() &&
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      !video_devices->FindById(request.requested_video_device_id)) {
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return false;
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return true;
82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)bool IsInKioskMode() {
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return true;
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
8890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#if defined(OS_CHROMEOS)
896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const user_manager::UserManager* user_manager =
906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      user_manager::UserManager::Get();
9190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return user_manager && user_manager->IsLoggedInAsKioskApp();
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return false;
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)enum DevicePermissionActions {
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kAllowHttps = 0,
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kAllowHttp,
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kDeny,
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kCancel,
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  kPermissionActionsMax  // Must always be last!
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings::MediaStreamTypeSettings(
10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    Permission permission, const std::string& requested_device_id):
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    permission(permission), requested_device_id(requested_device_id) {}
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings::
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    MediaStreamTypeSettings(): permission(MEDIA_NONE) {}
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)MediaStreamDevicesController::MediaStreamTypeSettings::
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    ~MediaStreamTypeSettings() {}
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDevicesController::MediaStreamDevicesController(
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    content::WebContents* web_contents,
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::MediaStreamRequest& request,
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::MediaResponseCallback& callback)
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : web_contents_(web_contents),
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_(request),
1233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      callback_(callback) {
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext());
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents);
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // For MEDIA_OPEN_DEVICE requests (Pepper) we always request both webcam
1283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // and microphone to avoid popping two infobars.
1293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // We start with setting the requested media type to allowed or blocked
1303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // depending on the policy. If not blocked by policy it may be blocked later
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // in the two remaining filtering steps (by user setting or by user when
1323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // clicking the infobar).
1333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // TODO(grunell): It's not the nicest solution to let the MEDIA_OPEN_DEVICE
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // case take a ride on the MEDIA_DEVICE_*_CAPTURE permission. Should be fixed.
1353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE ||
1363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request.request_type == content::MEDIA_OPEN_DEVICE) {
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (GetDevicePolicy(prefs::kAudioCaptureAllowed,
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        prefs::kAudioCaptureAllowedUrls) == ALWAYS_DENY) {
13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_.insert(std::make_pair(
14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          content::MEDIA_DEVICE_AUDIO_CAPTURE,
14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY,
14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  request.requested_audio_device_id)));
1433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_.insert(std::make_pair(
14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          content::MEDIA_DEVICE_AUDIO_CAPTURE,
14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          MediaStreamTypeSettings(MEDIA_ALLOWED,
14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  request.requested_audio_device_id)));
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE ||
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request.request_type == content::MEDIA_OPEN_DEVICE) {
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (GetDevicePolicy(prefs::kVideoCaptureAllowed,
1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                        prefs::kVideoCaptureAllowedUrls) == ALWAYS_DENY) {
15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_.insert(std::make_pair(
15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          content::MEDIA_DEVICE_VIDEO_CAPTURE,
15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          MediaStreamTypeSettings(MEDIA_BLOCKED_BY_POLICY,
15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  request.requested_video_device_id)));
1583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_.insert(std::make_pair(
16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          content::MEDIA_DEVICE_VIDEO_CAPTURE,
16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          MediaStreamTypeSettings(MEDIA_ALLOWED,
16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                  request.requested_video_device_id)));
1633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)MediaStreamDevicesController::~MediaStreamDevicesController() {
168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!callback_.is_null()) {
169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    callback_.Run(content::MediaStreamDevices(),
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                  content::MEDIA_DEVICE_INVALID_STATE,
171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                  scoped_ptr<content::MediaStreamUI>());
172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid MediaStreamDevicesController::RegisterProfilePrefs(
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    user_prefs::PrefRegistrySyncable* prefs) {
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed,
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             true,
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed,
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             true,
183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
18490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls,
18590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
18690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls,
18790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                          user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(gbillock): rename? doesn't actually dismiss. More of a 'check profile
1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// and system for compatibility' thing.
192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::DismissInfoBarAndTakeActionOnSettings() {
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Tab capture is allowed for extensions only and infobar is not shown for
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // extensions.
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (request_.audio_type == content::MEDIA_TAB_AUDIO_CAPTURE ||
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      request_.video_type == content::MEDIA_TAB_VIDEO_CAPTURE) {
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Deny(false, content::MEDIA_DEVICE_INVALID_STATE);
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Deny the request if the security origin is empty, this happens with
202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // file access without |--allow-file-access-from-files| flag.
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (request_.security_origin.is_empty()) {
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Deny(false, content::MEDIA_DEVICE_INVALID_SECURITY_ORIGIN);
205c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
208effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Deny the request if there is no device attached to the OS of the
209effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // requested type. If both audio and video is requested, both types must be
210effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // available.
211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  if (!HasAvailableDevicesForRequest(request_)) {
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Deny(false, content::MEDIA_DEVICE_NO_HARDWARE);
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check if any allow exception has been made for this request.
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsRequestAllowedByDefault()) {
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Accept(false);
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Filter any parts of the request that have been blocked by default and deny
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // it if nothing is left to accept.
2247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (FilterBlockedByDefaultDevices() == 0) {
225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED);
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check if the media default setting is set to block.
230c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (IsDefaultMediaAccessBlocked()) {
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED);
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Show the infobar.
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::HasAudio() const {
2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return IsDeviceAudioCaptureRequestedAndAllowed();
2413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::HasVideo() const {
2443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return IsDeviceVideoCaptureRequestedAndAllowed();
2453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::string& MediaStreamDevicesController::GetSecurityOriginSpec() const {
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return request_.security_origin.spec();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::Accept(bool update_content_setting) {
2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  NotifyUIRequestAccepted();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Get the default devices for the request.
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  content::MediaStreamDevices devices;
2563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool audio_allowed = IsDeviceAudioCaptureRequestedAndAllowed();
2573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool video_allowed = IsDeviceVideoCaptureRequestedAndAllowed();
2583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (audio_allowed || video_allowed) {
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    switch (request_.request_type) {
2607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      case content::MEDIA_OPEN_DEVICE: {
2617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        const content::MediaStreamDevice* device = NULL;
26268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // For open device request, when requested device_id is empty, pick
26368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // the first available of the given type. If requested device_id is
26468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // not empty, return the desired device if it's available. Otherwise,
26568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        // return no device.
26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (audio_allowed &&
26758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) {
26868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          if (!request_.requested_audio_device_id.empty()) {
26968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            device = MediaCaptureDevicesDispatcher::GetInstance()->
27068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                GetRequestedAudioDevice(request_.requested_audio_device_id);
27168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          } else {
2727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            device = MediaCaptureDevicesDispatcher::GetInstance()->
2737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                GetFirstAvailableAudioDevice();
2747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
27558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        } else if (video_allowed &&
27658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) {
2777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          // Pepper API opens only one device at a time.
27868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          if (!request_.requested_video_device_id.empty()) {
27968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)            device = MediaCaptureDevicesDispatcher::GetInstance()->
28068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                GetRequestedVideoDevice(request_.requested_video_device_id);
28168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          } else {
2827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            device = MediaCaptureDevicesDispatcher::GetInstance()->
2837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                GetFirstAvailableVideoDevice();
2847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
2857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
2867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        if (device)
2877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          devices.push_back(*device);
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
28958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case content::MEDIA_GENERATE_STREAM: {
29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        bool get_default_audio_device = audio_allowed;
29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        bool get_default_video_device = video_allowed;
2937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // Get the exact audio or video device if an id is specified.
29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (audio_allowed && !request_.requested_audio_device_id.empty()) {
2967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          const content::MediaStreamDevice* audio_device =
2977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              MediaCaptureDevicesDispatcher::GetInstance()->
2987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  GetRequestedAudioDevice(request_.requested_audio_device_id);
2997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if (audio_device) {
3007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            devices.push_back(*audio_device);
30158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            get_default_audio_device = false;
3027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
3037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
30458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (video_allowed && !request_.requested_video_device_id.empty()) {
3057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          const content::MediaStreamDevice* video_device =
3067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              MediaCaptureDevicesDispatcher::GetInstance()->
3077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                  GetRequestedVideoDevice(request_.requested_video_device_id);
3087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          if (video_device) {
3097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch            devices.push_back(*video_device);
31058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)            get_default_video_device = false;
3117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          }
3127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
3137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // If either or both audio and video devices were requested but not
3157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // specified by id, get the default devices.
31658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        if (get_default_audio_device || get_default_video_device) {
3177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          MediaCaptureDevicesDispatcher::GetInstance()->
3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              GetDefaultDevicesForProfile(profile_,
31958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                          get_default_audio_device,
32058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)                                          get_default_video_device,
3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                                          &devices);
3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        }
3237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        break;
32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
32558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case content::MEDIA_DEVICE_ACCESS: {
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // Get the default devices for the request.
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        MediaCaptureDevicesDispatcher::GetInstance()->
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            GetDefaultDevicesForProfile(profile_,
3293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        audio_allowed,
3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                        video_allowed,
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                        &devices);
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        break;
33358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
33458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      case content::MEDIA_ENUMERATE_DEVICES: {
3357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        // Do nothing.
3367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        NOTREACHED();
3377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        break;
33858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)      }
33958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    }  // switch
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // TODO(raymes): We currently set the content permission for non-https
3427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // websites for Pepper requests as well. This is temporary and should be
3437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // removed.
3447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (update_content_setting) {
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if ((IsSchemeSecure() && !devices.empty()) ||
3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          request_.request_type == content::MEDIA_OPEN_DEVICE) {
3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        SetPermission(true);
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
3497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
3505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (audio_allowed) {
3525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->UpdateLastUsageByPattern(
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          ContentSettingsPattern::FromURLNoWildcard(request_.security_origin),
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          ContentSettingsPattern::Wildcard(),
3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
3565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
3575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (video_allowed) {
3585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->UpdateLastUsageByPattern(
3595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          ContentSettingsPattern::FromURLNoWildcard(request_.security_origin),
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          ContentSettingsPattern::Wildcard(),
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)          CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    }
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<content::MediaStreamUI> ui;
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!devices.empty()) {
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui = MediaCaptureDevicesDispatcher::GetInstance()->
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        GetMediaStreamCaptureIndicator()->RegisterMediaStream(
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            web_contents_, devices);
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
371868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::MediaResponseCallback cb = callback_;
372868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback_.Reset();
373e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  cb.Run(devices,
374e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch         devices.empty() ?
375e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch             content::MEDIA_DEVICE_NO_HARDWARE : content::MEDIA_DEVICE_OK,
376e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch         ui.Pass());
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
379a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void MediaStreamDevicesController::Deny(
380a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    bool update_content_setting,
381a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    content::MediaStreamRequestResult result) {
382a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DLOG(WARNING) << "MediaStreamDevicesController::Deny: " << result;
3837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  NotifyUIRequestDenied();
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (update_content_setting) {
386010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    CHECK_EQ(content::MEDIA_DEVICE_PERMISSION_DENIED, result);
387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    SetPermission(false);
388010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
390868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  content::MediaResponseCallback cb = callback_;
391868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  callback_.Reset();
392a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  cb.Run(content::MediaStreamDevices(),
393a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         result,
394a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         scoped_ptr<content::MediaStreamUI>());
395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
396a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
397a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)int MediaStreamDevicesController::GetIconID() const {
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (HasVideo())
399a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return IDR_INFOBAR_MEDIA_STREAM_CAMERA;
400a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
401a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return IDR_INFOBAR_MEDIA_STREAM_MIC;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamDevicesController::GetMessageText() const {
4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO;
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!HasAudio())
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY;
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else if (!HasVideo())
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY;
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return l10n_util::GetStringFUTF16(
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      message_id, base::UTF8ToUTF16(GetSecurityOriginSpec()));
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamDevicesController::GetMessageTextFragment() const {
4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO_PERMISSION_FRAGMENT;
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!HasAudio())
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_FRAGMENT;
4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  else if (!HasVideo())
4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY_PERMISSION_FRAGMENT;
4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return l10n_util::GetStringUTF16(message_id);
4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
423a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool MediaStreamDevicesController::HasUserGesture() const {
424effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return request_.user_gesture;
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
427a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)GURL MediaStreamDevicesController::GetRequestingHostname() const {
428a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return request_.security_origin;
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::PermissionGranted() {
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GURL origin(GetSecurityOriginSpec());
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (origin.SchemeIsSecure()) {
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              kAllowHttps, kPermissionActionsMax);
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              kAllowHttp, kPermissionActionsMax);
4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Accept(true);
4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::PermissionDenied() {
4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            kDeny, kPermissionActionsMax);
446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Deny(true, content::MEDIA_DEVICE_PERMISSION_DENIED);
4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::Cancelled() {
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            kCancel, kPermissionActionsMax);
452010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  Deny(false, content::MEDIA_DEVICE_PERMISSION_DISMISSED);
4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void MediaStreamDevicesController::RequestFinished() {
4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete this;
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MediaStreamDevicesController::DevicePolicy
46090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)MediaStreamDevicesController::GetDevicePolicy(
46190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* policy_name,
46290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* whitelist_policy_name) const {
463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
46590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If the security origin policy matches a value in the whitelist, allow it.
46690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Otherwise, check the |policy_name| master switch for the default behavior.
46790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
468c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  PrefService* prefs = profile_->GetPrefs();
4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // TODO(tommi): Remove the kiosk mode check when the whitelist below
47190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // is visible in the media exceptions UI.
47290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // See discussion here: https://codereview.chromium.org/15738004/
47390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (IsInKioskMode()) {
47490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::ListValue* list = prefs->GetList(whitelist_policy_name);
47590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    std::string value;
47690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    for (size_t i = 0; i < list->GetSize(); ++i) {
47790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      if (list->GetString(i, &value)) {
47890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        ContentSettingsPattern pattern =
47990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            ContentSettingsPattern::FromString(value);
48090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (pattern == ContentSettingsPattern::Wildcard()) {
48190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          DLOG(WARNING) << "Ignoring wildcard URL pattern: " << value;
48290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          continue;
48390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        }
48490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        DLOG_IF(ERROR, !pattern.IsValid()) << "Invalid URL pattern: " << value;
48590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)        if (pattern.IsValid() && pattern.Matches(request_.security_origin))
48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          return ALWAYS_ALLOW;
48790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      }
48890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    }
48990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // If a match was not found, check if audio capture is otherwise disallowed
49290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // or if the user should be prompted.  Setting the policy value to "true"
49390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // is equal to not setting it at all, so from hereon out, we will return
49490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // either POLICY_NOT_SET (prompt) or ALWAYS_DENY (no prompt, no access).
49590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!prefs->GetBoolean(policy_name))
49690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return ALWAYS_DENY;
49790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
49890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return POLICY_NOT_SET;
499c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
500c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
501c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsRequestAllowedByDefault() const {
502c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // The request from internal objects like chrome://URLs is always allowed.
503c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (ShouldAlwaysAllowOrigin())
504c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
505c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  struct {
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    bool has_capability;
508c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const char* policy_name;
50990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const char* list_policy_name;
510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ContentSettingsType settings_type;
511c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } device_checks[] = {
5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    { IsDeviceAudioCaptureRequestedAndAllowed(), prefs::kAudioCaptureAllowed,
51390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs::kAudioCaptureAllowedUrls, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC },
5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    { IsDeviceVideoCaptureRequestedAndAllowed(), prefs::kVideoCaptureAllowed,
51590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      prefs::kVideoCaptureAllowedUrls,
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA },
517c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
518c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
519c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(device_checks); ++i) {
520c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!device_checks[i].has_capability)
521c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      continue;
522c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
52390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    DevicePolicy policy = GetDevicePolicy(device_checks[i].policy_name,
52490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                          device_checks[i].list_policy_name);
5257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (policy == ALWAYS_DENY)
527c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
5287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (policy == POLICY_NOT_SET) {
5307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // Only load content settings from secure origins unless it is a
5317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      // content::MEDIA_OPEN_DEVICE (Pepper) request.
5327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (!IsSchemeSecure() &&
5337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          request_.request_type != content::MEDIA_OPEN_DEVICE) {
5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return false;
5357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
5367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (profile_->GetHostContentSettingsMap()->GetContentSetting(
5377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              request_.security_origin, request_.security_origin,
5387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              device_checks[i].settings_type, NO_RESOURCE_IDENTIFIER) !=
5397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              CONTENT_SETTING_ALLOW) {
5407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        return false;
5417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      }
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
543c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // If we get here, then either policy is set to ALWAYS_ALLOW or the content
544c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // settings allow the request by default.
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return true;
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochint MediaStreamDevicesController::FilterBlockedByDefaultDevices() {
5513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  int requested_devices = 0;
5523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceAudioCaptureRequestedAndAllowed()) {
5543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (profile_->GetHostContentSettingsMap()->GetContentSetting(
5553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
5563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
5573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
5583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) {
55968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission =
5603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          MEDIA_BLOCKED_BY_USER_SETTING;
5613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
5623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ++requested_devices;
5633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceVideoCaptureRequestedAndAllowed()) {
5673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (profile_->GetHostContentSettingsMap()->GetContentSetting(
5683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
5693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        request_.security_origin,
5703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
5713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        NO_RESOURCE_IDENTIFIER) == CONTENT_SETTING_BLOCK) {
57268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission =
5733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          MEDIA_BLOCKED_BY_USER_SETTING;
5743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    } else {
5753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      ++requested_devices;
5763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return requested_devices;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsDefaultMediaAccessBlocked() const {
583c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the
585c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and
586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
587c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSetting current_setting =
588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          CONTENT_SETTINGS_TYPE_MEDIASTREAM, NULL);
590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return (current_setting == CONTENT_SETTING_BLOCK);
591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
593c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::IsSchemeSecure() const {
594424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  return request_.security_origin.SchemeIsSecure() ||
59546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      request_.security_origin.SchemeIs(extensions::kExtensionScheme);
596c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDevicesController::ShouldAlwaysAllowOrigin() const {
599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // TODO(markusheintz): Replace CONTENT_SETTINGS_TYPE_MEDIA_STREAM with the
600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // appropriate new CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC and
601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA.
602c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return profile_->GetHostContentSettingsMap()->ShouldAllowAllContent(
603c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      request_.security_origin, request_.security_origin,
604c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTINGS_TYPE_MEDIASTREAM);
605c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
606c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDevicesController::SetPermission(bool allowed) const {
608c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSettingsPattern primary_pattern =
610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ContentSettingsPattern::FromURLNoWildcard(request_.security_origin);
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Check the pattern is valid or not. When the request is from a file access,
612c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // no exception will be made.
613c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!primary_pattern.IsValid())
614c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
616c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ContentSetting content_setting = allowed ?
617c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
6183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE) !=
6193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.end()) {
620010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    profile_->GetHostContentSettingsMap()->SetContentSetting(
621c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        primary_pattern,
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ContentSettingsPattern::Wildcard(),
623c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string(),
625c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        content_setting);
626c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
6273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE) !=
6283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.end()) {
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    profile_->GetHostContentSettingsMap()->SetContentSetting(
630c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        primary_pattern,
631c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ContentSettingsPattern::Wildcard(),
632c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
633c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        std::string(),
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        content_setting);
635c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestAccepted() const {
6397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!content_settings_)
6407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
6417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content_settings_->OnMediaStreamPermissionSet(request_.security_origin,
6433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                request_permissions_);
6447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
6457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MediaStreamDevicesController::NotifyUIRequestDenied() {
6477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!content_settings_)
6487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
6497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceAudioCaptureRequestedAndAllowed()) {
65168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    request_permissions_[content::MEDIA_DEVICE_AUDIO_CAPTURE].permission =
6523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        MEDIA_BLOCKED_BY_USER;
6537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
6543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsDeviceVideoCaptureRequestedAndAllowed()) {
65568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    request_permissions_[content::MEDIA_DEVICE_VIDEO_CAPTURE].permission =
6563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        MEDIA_BLOCKED_BY_USER;
6573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
6583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  content_settings_->OnMediaStreamPermissionSet(request_.security_origin,
6603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                                request_permissions_);
6613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
6633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceAudioCaptureRequestedAndAllowed()
6643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const {
66568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MediaStreamTypeSettingsMap::const_iterator it =
6663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.find(content::MEDIA_DEVICE_AUDIO_CAPTURE);
6675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return (it != request_permissions_.end() && IsCaptureDeviceRequestAllowed() &&
66868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          it->second.permission == MEDIA_ALLOWED);
6693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
6707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
6713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool MediaStreamDevicesController::IsDeviceVideoCaptureRequestedAndAllowed()
6723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const {
67368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  MediaStreamTypeSettingsMap::const_iterator it =
6743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      request_permissions_.find(content::MEDIA_DEVICE_VIDEO_CAPTURE);
6755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return (it != request_permissions_.end() && IsCaptureDeviceRequestAllowed() &&
67668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          it->second.permission == MEDIA_ALLOWED);
6777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
6785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
6795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool MediaStreamDevicesController::IsCaptureDeviceRequestAllowed() const {
6805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_ANDROID)
6815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Don't approve device requests if the tab was hidden.
6825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // TODO(qinmin): Add a test for this. http://crbug.com/396869.
6835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return web_contents_->GetRenderWidgetHostView()->IsShowing();
6845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
6855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return true;
6865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
687