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

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

Issue 338753002: Revert of Revert: Per navigation sticky media permissions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 6 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/chrome_media_stream_infobar_browsertest.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/media/media_stream_devices_controller.cc
diff --git a/chrome/browser/media/media_stream_devices_controller.cc b/chrome/browser/media/media_stream_devices_controller.cc
index 3cb55cc23313826bef8491fc84a3064ca910a278..56e73b9efb1876cd0658f2984da93ba2b6f89022 100644
--- a/chrome/browser/media/media_stream_devices_controller.cc
+++ b/chrome/browser/media/media_stream_devices_controller.cc
@@ -23,6 +23,7 @@
#include "chrome/common/pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/navigation_entry.h"
#include "content/public/common/media_stream_request.h"
#include "extensions/common/constants.h"
#include "grit/generated_resources.h"
@@ -36,6 +37,15 @@
using content::BrowserThread;
namespace {
+
+// This prefix is combined with request security origins to store media access
+// permissions that the user has granted a specific page navigation instance.
+// The string value stored with the navigation instance will contain one or more
+// kMediaPermissionXxx constants that indicates the permission(s) that the user
+// has granted the page.
+const char kMediaPermissionKeyPrefix[] = "media_permissions#";
+const base::char16 kMediaPermissionAudio = static_cast<base::char16>('a');
+const base::char16 kMediaPermissionVideo = static_cast<base::char16>('v');
bool HasAvailableDevicesForRequest(const content::MediaStreamRequest& request) {
const content::MediaStreamDevices* audio_devices =
@@ -79,6 +89,75 @@
return true;
}
+
+base::string16 GetMediaPermissionsFromNavigationEntry(
+ content::NavigationEntry* navigation_entry,
+ const content::MediaStreamRequest& request) {
+ const std::string key(kMediaPermissionKeyPrefix +
+ request.security_origin.spec());
+
+ base::string16 permissions;
+ if (!navigation_entry->GetExtraData(key, &permissions)) {
+ DCHECK(permissions.empty());
+ }
+
+ return permissions;
+}
+
+void SetMediaPermissionsForNavigationEntry(
+ content::NavigationEntry* navigation_entry,
+ const content::MediaStreamRequest& request,
+ const base::string16& permissions) {
+ const std::string key(kMediaPermissionKeyPrefix +
+ request.security_origin.spec());
+ permissions.empty() ?
+ navigation_entry->ClearExtraData(key) :
+ navigation_entry->SetExtraData(key, permissions);
+}
+
+void SetMediaPermissionsForNavigationEntry(
+ content::NavigationEntry* navigation_entry,
+ const content::MediaStreamRequest& request,
+ bool allow_audio,
+ bool allow_video) {
+ base::string16 permissions;
+ if (allow_audio)
+ permissions += kMediaPermissionAudio;
+ if (allow_video)
+ permissions += kMediaPermissionVideo;
+ SetMediaPermissionsForNavigationEntry(navigation_entry, request, permissions);
+}
+
+bool IsRequestAllowedByNavigationEntry(
+ content::NavigationEntry* navigation_entry,
+ const content::MediaStreamRequest& request) {
+ using content::MEDIA_NO_SERVICE;
+ using content::MEDIA_DEVICE_AUDIO_CAPTURE;
+ using content::MEDIA_DEVICE_VIDEO_CAPTURE;
+
+ // If we aren't being asked for at least one of these two, fail right away.
+ if (!navigation_entry ||
+ (request.audio_type != MEDIA_DEVICE_AUDIO_CAPTURE &&
+ request.video_type != MEDIA_DEVICE_VIDEO_CAPTURE)) {
+ return false;
+ }
+
+ base::string16 permissions =
+ GetMediaPermissionsFromNavigationEntry(navigation_entry, request);
+
+ bool audio_requested_and_granted =
+ request.audio_type == MEDIA_DEVICE_AUDIO_CAPTURE &&
+ permissions.find(kMediaPermissionAudio) != base::string16::npos;
+
+ bool video_requested_and_granted =
+ request.video_type == MEDIA_DEVICE_VIDEO_CAPTURE &&
+ permissions.find(kMediaPermissionVideo) != base::string16::npos;
+
+ return
+ (audio_requested_and_granted || request.audio_type == MEDIA_NO_SERVICE) &&
+ (video_requested_and_granted || request.video_type == MEDIA_NO_SERVICE);
+}
+
bool IsInKioskMode() {
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode))
@@ -227,6 +306,18 @@
// Check if the media default setting is set to block.
if (IsDefaultMediaAccessBlocked()) {
Deny(false, content::MEDIA_DEVICE_PERMISSION_DENIED);
+ return true;
+ }
+
+ // Check if the navigation entry has previously been granted access.
+ // We do this after the IsDefaultMediaAccessBlocked check to handle the use
+ // case where the user modifies the content settings to 'deny' after having
+ // previously granted the page access and the permissions in the
+ // NavigationEntry are out of date.
+ content::NavigationEntry* navigation_entry =
+ web_contents_->GetController().GetVisibleEntry();
+ if (IsRequestAllowedByNavigationEntry(navigation_entry, request_)) {
+ Accept(false);
return true;
}
@@ -318,6 +409,18 @@
get_default_video_device,
&devices);
}
+
+ // For pages accessed via http (not https), tag this navigation entry
+ // with the granted permissions. This avoids repeated prompts for
+ // device access.
+ if (!IsSchemeSecure()) {
+ content::NavigationEntry* navigation_entry =
+ web_contents_->GetController().GetVisibleEntry();
+ if (navigation_entry) {
+ SetMediaPermissionsForNavigationEntry(
+ navigation_entry, request_, audio_allowed, video_allowed);
+ }
+ }
break;
}
case content::MEDIA_DEVICE_ACCESS: {
@@ -366,6 +469,14 @@
content::MediaStreamRequestResult result) {
DLOG(WARNING) << "MediaStreamDevicesController::Deny: " << result;
NotifyUIRequestDenied();
+
+ // Clear previously allowed permissions from the navigation entry if any.
+ content::NavigationEntry* navigation_entry =
+ web_contents_->GetController().GetVisibleEntry();
+ if (navigation_entry) {
+ SetMediaPermissionsForNavigationEntry(
+ navigation_entry, request_, false, false);
+ }
if (update_content_setting) {
CHECK_EQ(content::MEDIA_DEVICE_PERMISSION_DENIED, result);
« no previous file with comments | « chrome/browser/media/chrome_media_stream_infobar_browsertest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698