Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(461)

Unified Diff: chrome/browser/media/webrtc/media_stream_devices_controller.cc

Issue 2728573002: Hoist device logic out of permissions check in MediaStreamDevicesController (Closed)
Patch Set: Hoist device logic out of permissions check in MediaStreamDevicesController Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/media/webrtc/media_stream_devices_controller.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/media/webrtc/media_stream_devices_controller.cc
diff --git a/chrome/browser/media/webrtc/media_stream_devices_controller.cc b/chrome/browser/media/webrtc/media_stream_devices_controller.cc
index e2ad13c5b49108a2c94bf2c0fde4c6f28db35df2..ea1c264f62b67e56e48482d26ceafad68e621440 100644
--- a/chrome/browser/media/webrtc/media_stream_devices_controller.cc
+++ b/chrome/browser/media/webrtc/media_stream_devices_controller.cc
@@ -173,8 +173,83 @@ class MediaPermissionRequestLogger : content::WebContentsObserver {
RequestMap::key_type key_;
};
+bool HasAvailableDevices(ContentSettingsType content_type,
+ const std::string& device_id) {
+ const content::MediaStreamDevices* devices = nullptr;
+ if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) {
+ devices =
+ &MediaCaptureDevicesDispatcher::GetInstance()->GetAudioCaptureDevices();
+ } else if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) {
+ devices =
+ &MediaCaptureDevicesDispatcher::GetInstance()->GetVideoCaptureDevices();
+ } else {
+ NOTREACHED();
+ }
+
+ // TODO(tommi): It's kind of strange to have this here since if we fail this
+ // test, there'll be a UI shown that indicates to the user that access to
+ // non-existing audio/video devices has been denied. The user won't have
+ // any way to change that but there will be a UI shown which indicates that
+ // access is blocked.
+ if (devices->empty())
+ return false;
+
+ // Note: we check device_id before dereferencing devices. If the requested
+ // device id is non-empty, then the corresponding device list must not be
+ // NULL.
+ if (!device_id.empty() && !devices->FindById(device_id))
+ return false;
+
+ return true;
+}
+
} // namespace
+// Stores whether a permission has been requested or blocked during the course
+// of a permission request, as well as the denial reason
+class MediaStreamDevicesController::MediaPermissionStatus {
+ public:
+ explicit MediaPermissionStatus(const content::MediaStreamRequest& request)
+ : audio_requested_(
+ ContentTypeIsRequested(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
+ request)),
+ video_requested_(
+ ContentTypeIsRequested(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
+ request)) {}
+
+ ~MediaPermissionStatus() {}
+
+ bool audio_requested() const { return audio_requested_; }
+ bool video_requested() const { return video_requested_; }
+
+ bool audio_blocked() const { return audio_blocked_; }
+ bool video_blocked() const { return video_blocked_; }
+
+ content::MediaStreamRequestResult denial_reason() const {
+ return denial_reason_;
+ }
+
+ void SetAudioBlocked(content::MediaStreamRequestResult denial_reason) {
+ DCHECK(audio_requested_);
+ audio_blocked_ = true;
+ denial_reason_ = denial_reason;
+ }
+
+ void SetVideoBlocked(content::MediaStreamRequestResult denial_reason) {
+ DCHECK(video_requested_);
+ video_blocked_ = true;
+ denial_reason_ = denial_reason;
+ }
+
+ private:
+ bool audio_requested_ = false;
+ bool video_requested_ = false;
+ bool audio_blocked_ = false;
+ bool video_blocked_ = false;
+
+ content::MediaStreamRequestResult denial_reason_ = content::MEDIA_DEVICE_OK;
+};
+
// Implementation of PermissionPromptDelegate which actually shows a permission
// prompt.
class MediaStreamDevicesController::PermissionPromptDelegateImpl
@@ -330,8 +405,28 @@ void MediaStreamDevicesController::RequestPermissionsWithDelegate(
const content::MediaStreamRequest& request,
const content::MediaResponseCallback& callback,
PermissionPromptDelegate* delegate) {
+ if (request.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY) {
+ MediaPermissionRequestLogger::LogRequest(
+ web_contents, request.render_process_id, request.render_frame_id,
+ content::IsOriginSecure(request.security_origin));
+ }
+
+ MediaPermissionStatus initial_permission(request);
+ if (initial_permission.audio_requested() &&
+ !HasAvailableDevices(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
+ request.requested_audio_device_id)) {
+ initial_permission.SetAudioBlocked(content::MEDIA_DEVICE_NO_HARDWARE);
+ }
+
+ if (initial_permission.video_requested() &&
+ !HasAvailableDevices(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
+ request.requested_video_device_id)) {
+ initial_permission.SetVideoBlocked(content::MEDIA_DEVICE_NO_HARDWARE);
+ }
+
std::unique_ptr<MediaStreamDevicesController> controller(
- new MediaStreamDevicesController(web_contents, request, callback));
+ new MediaStreamDevicesController(web_contents, request, callback,
+ initial_permission));
if (!controller->IsAskingForAudio() && !controller->IsAskingForVideo()) {
#if defined(OS_ANDROID)
// If either audio or video was previously allowed and Chrome no longer has
@@ -363,21 +458,22 @@ void MediaStreamDevicesController::RequestPermissionsWithDelegate(
MediaStreamDevicesController::MediaStreamDevicesController(
content::WebContents* web_contents,
const content::MediaStreamRequest& request,
- const content::MediaResponseCallback& callback)
+ const content::MediaResponseCallback& callback,
+ const MediaPermissionStatus& initial_permission)
: web_contents_(web_contents), request_(request), callback_(callback) {
- if (request_.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY) {
- MediaPermissionRequestLogger::LogRequest(
- web_contents, request.render_process_id, request.render_frame_id,
- content::IsOriginSecure(request_.security_origin));
- }
profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext());
content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents);
- content::MediaStreamRequestResult denial_reason = content::MEDIA_DEVICE_OK;
- old_audio_setting_ = GetContentSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
- request_, &denial_reason);
- old_video_setting_ = GetContentSetting(
- CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, request_, &denial_reason);
+ content::MediaStreamRequestResult denial_reason =
+ initial_permission.denial_reason();
+ old_audio_setting_ =
+ GetContentSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, request,
+ initial_permission.audio_requested(),
+ initial_permission.audio_blocked(), &denial_reason);
+ old_video_setting_ =
+ GetContentSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, request,
+ initial_permission.video_requested(),
+ initial_permission.video_blocked(), &denial_reason);
// If either setting is ask, we show the infobar.
if (old_audio_setting_ == CONTENT_SETTING_ASK ||
@@ -615,32 +711,32 @@ void MediaStreamDevicesController::UpdateTabSpecificContentSettings(
ContentSetting MediaStreamDevicesController::GetContentSetting(
ContentSettingsType content_type,
const content::MediaStreamRequest& request,
+ bool was_requested,
+ bool was_initially_blocked,
content::MediaStreamRequestResult* denial_reason) const {
DCHECK(content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC ||
content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
+ DCHECK(content::IsOriginSecure(request_.security_origin) ||
+ request_.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY);
+ if (!was_requested) {
+ // No denial reason set as it will have been previously set.
+ return CONTENT_SETTING_DEFAULT;
+ }
- std::string requested_device_id;
- if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)
- requested_device_id = request.requested_audio_device_id;
- else if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)
- requested_device_id = request.requested_video_device_id;
+ if (was_initially_blocked) {
+ // No denial reason set as it will have been previously set.
+ return CONTENT_SETTING_BLOCK;
+ }
if (!IsUserAcceptAllowed(content_type)) {
*denial_reason = content::MEDIA_DEVICE_PERMISSION_DENIED;
return CONTENT_SETTING_BLOCK;
}
- if (ContentTypeIsRequested(content_type, request)) {
- DCHECK(content::IsOriginSecure(request_.security_origin) ||
- request_.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY);
- MediaPermission permission(content_type, request.security_origin,
- web_contents_->GetLastCommittedURL().GetOrigin(),
- profile_, web_contents_);
- return permission.GetPermissionStatusWithDeviceRequired(requested_device_id,
- denial_reason);
- }
- // Return the default content setting if the device is not requested.
- return CONTENT_SETTING_DEFAULT;
+ MediaPermission permission(content_type, request.security_origin,
+ web_contents_->GetLastCommittedURL().GetOrigin(),
+ profile_, web_contents_);
+ return permission.GetPermissionStatus(denial_reason);
}
ContentSetting MediaStreamDevicesController::GetNewSetting(
« no previous file with comments | « chrome/browser/media/webrtc/media_stream_devices_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698