Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / media / media_permission.cc
blob91ec161b32e045b994bd7833af6a9badb99084ff
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/media/media_permission.h"
7 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
8 #include "chrome/browser/media/media_stream_device_permission_context.h"
9 #include "chrome/browser/media/media_stream_device_permissions.h"
10 #include "chrome/browser/permissions/permission_context.h"
11 #include "chrome/browser/permissions/permission_context_base.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/common/pref_names.h"
14 #include "content/public/browser/permission_manager.h"
15 #include "content/public/browser/permission_type.h"
16 #include "content/public/common/url_constants.h"
17 #include "extensions/common/constants.h"
19 namespace {
21 content::PermissionType ContentSettingsTypeToPermission(
22 ContentSettingsType content_setting) {
23 if (content_setting == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) {
24 return content::PermissionType::AUDIO_CAPTURE;
25 } else {
26 DCHECK_EQ(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, content_setting);
27 return content::PermissionType::VIDEO_CAPTURE;
31 } // namespace
33 MediaPermission::MediaPermission(ContentSettingsType content_type,
34 content::MediaStreamRequestType request_type,
35 const GURL& requesting_origin,
36 const GURL& embedding_origin,
37 Profile* profile)
38 : content_type_(content_type),
39 request_type_(request_type),
40 requesting_origin_(requesting_origin),
41 embedding_origin_(embedding_origin),
42 profile_(profile) {}
44 ContentSetting MediaPermission::GetPermissionStatus(
45 content::MediaStreamRequestResult* denial_reason) const {
46 // Deny the request if the security origin is empty, this happens with
47 // file access without |--allow-file-access-from-files| flag.
48 if (requesting_origin_.is_empty()) {
49 *denial_reason = content::MEDIA_DEVICE_INVALID_SECURITY_ORIGIN;
50 return CONTENT_SETTING_BLOCK;
53 // Check policy and content settings.
54 ContentSetting result = GetStoredContentSetting();
55 if (result == CONTENT_SETTING_BLOCK)
56 *denial_reason = content::MEDIA_DEVICE_PERMISSION_DENIED;
58 return result;
61 ContentSetting MediaPermission::GetPermissionStatusWithDeviceRequired(
62 const std::string& device_id,
63 content::MediaStreamRequestResult* denial_reason) const {
64 // Deny the request if there is no device attached to the OS of the requested
65 // type.
66 if (!HasAvailableDevices(device_id)) {
67 *denial_reason = content::MEDIA_DEVICE_NO_HARDWARE;
68 return CONTENT_SETTING_BLOCK;
71 return GetPermissionStatus(denial_reason);
74 ContentSetting MediaPermission::GetStoredContentSetting() const {
75 content::PermissionType permission_type =
76 ContentSettingsTypeToPermission(content_type_);
77 PermissionContextBase* permission_context =
78 PermissionContext::Get(profile_, permission_type);
80 if (!permission_context)
81 return CONTENT_SETTING_BLOCK;
83 MediaStreamDevicePermissionContext* media_device_permission_context =
84 static_cast<MediaStreamDevicePermissionContext*>(permission_context);
86 if (request_type_ == content::MEDIA_OPEN_DEVICE) {
87 return media_device_permission_context->GetPermissionStatusForPepper(
88 requesting_origin_, embedding_origin_);
89 } else {
90 return media_device_permission_context->GetPermissionStatus(
91 requesting_origin_, embedding_origin_);
95 bool MediaPermission::HasAvailableDevices(const std::string& device_id) const {
96 const content::MediaStreamDevices* devices = nullptr;
97 if (content_type_ == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) {
98 devices =
99 &MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices();
100 } else if (content_type_ == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) {
101 devices =
102 &MediaCaptureDevicesDispatcher::GetInstance()->GetVideoCaptureDevices();
103 } else {
104 NOTREACHED();
107 // TODO(tommi): It's kind of strange to have this here since if we fail this
108 // test, there'll be a UI shown that indicates to the user that access to
109 // non-existing audio/video devices has been denied. The user won't have
110 // any way to change that but there will be a UI shown which indicates that
111 // access is blocked.
112 if (devices->empty())
113 return false;
115 // Note: we check device_id before dereferencing devices. If the requested
116 // device id is non-empty, then the corresponding device list must not be
117 // NULL.
118 if (!device_id.empty() && !devices->FindById(device_id))
119 return false;
121 return true;