Index: chrome/browser/content_settings/tab_specific_content_settings.cc |
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc |
index cca7a210a7b9bd774c3790967c6ee6ea54d43c80..bfe3e2987d27a736083c44f279bf491cf5046bb6 100644 |
--- a/chrome/browser/content_settings/tab_specific_content_settings.cc |
+++ b/chrome/browser/content_settings/tab_specific_content_settings.cc |
@@ -8,6 +8,7 @@ |
#include "base/command_line.h" |
#include "base/lazy_instance.h" |
+#include "base/prefs/pref_service.h" |
#include "base/strings/utf_string_conversions.h" |
#include "chrome/browser/browsing_data/browsing_data_appcache_helper.h" |
#include "chrome/browser/browsing_data/browsing_data_cookie_helper.h" |
@@ -20,9 +21,11 @@ |
#include "chrome/browser/content_settings/content_settings_details.h" |
#include "chrome/browser/content_settings/content_settings_utils.h" |
#include "chrome/browser/content_settings/host_content_settings_map.h" |
+#include "chrome/browser/media/media_stream_capture_indicator.h" |
#include "chrome/browser/prerender/prerender_manager.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/common/chrome_switches.h" |
+#include "chrome/common/pref_names.h" |
#include "chrome/common/render_messages.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/navigation_controller.h" |
@@ -44,6 +47,21 @@ using content::RenderViewHost; |
using content::WebContents; |
DEFINE_WEB_CONTENTS_USER_DATA_KEY(TabSpecificContentSettings); |
+STATIC_CONST_MEMBER_DEFINITION const |
+ TabSpecificContentSettings::MicrophoneCameraState |
+ TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED; |
+STATIC_CONST_MEMBER_DEFINITION const |
+ TabSpecificContentSettings::MicrophoneCameraState |
+ TabSpecificContentSettings::MICROPHONE_ACCESSED; |
+STATIC_CONST_MEMBER_DEFINITION const |
+ TabSpecificContentSettings::MicrophoneCameraState |
+ TabSpecificContentSettings::MICROPHONE_BLOCKED; |
+STATIC_CONST_MEMBER_DEFINITION const |
+ TabSpecificContentSettings::MicrophoneCameraState |
+ TabSpecificContentSettings::CAMERA_ACCESSED; |
+STATIC_CONST_MEMBER_DEFINITION const |
+ TabSpecificContentSettings::MicrophoneCameraState |
+ TabSpecificContentSettings::CAMERA_BLOCKED; |
TabSpecificContentSettings::SiteDataObserver::SiteDataObserver( |
TabSpecificContentSettings* tab_specific_content_settings) |
@@ -71,6 +89,7 @@ TabSpecificContentSettings::TabSpecificContentSettings(WebContents* tab) |
previous_protocol_handler_(ProtocolHandler::EmptyProtocolHandler()), |
pending_protocol_handler_setting_(CONTENT_SETTING_DEFAULT), |
load_plugins_link_enabled_(true), |
+ microphone_camera_state_(MICROPHONE_CAMERA_NOT_ACCESSED), |
observer_(this) { |
ClearBlockedContentSettingsExceptForCookies(); |
ClearCookieSpecificContentSettings(); |
@@ -272,24 +291,20 @@ bool TabSpecificContentSettings::IsContentAllowed( |
void TabSpecificContentSettings::OnContentBlocked(ContentSettingsType type) { |
DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION) |
<< "Geolocation settings handled by OnGeolocationPermissionSet"; |
+ DCHECK(type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC && |
+ type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) |
+ << "Media stream settings handled by OnMediaStreamPermissionSet"; |
if (type < 0 || type >= CONTENT_SETTINGS_NUM_TYPES) |
return; |
- // Media is different from other content setting types since it allows new |
- // setting to kick in without reloading the page, and the UI for media is |
- // always reflecting the newest permission setting. |
- switch (type) { |
- case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC: |
- case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA: |
-#if defined(OS_ANDROID) |
- case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER: |
-#endif |
- content_allowed_[type] = false; |
- break; |
- default: |
- content_allowed_[type] = true; |
- break; |
- } |
+ // TODO(robwu): Should this be restricted to cookies only? |
+ // In the past, content_allowed_ was set to false, but this logic was inverted |
+ // in https://codereview.chromium.org/13375004 to fix an issue with the cookie |
+ // permission UI. This unconditional assignment seems incorrect, because the |
+ // flag will now always be true after calling either OnContentBlocked or |
+ // OnContentAllowed. Consequently IsContentAllowed will always return true |
+ // for every supported setting that is not handled elsewhere. |
+ content_allowed_[type] = true; |
#if defined(OS_ANDROID) |
if (type == CONTENT_SETTINGS_TYPE_POPUPS) { |
@@ -315,20 +330,22 @@ void TabSpecificContentSettings::OnContentBlocked(ContentSettingsType type) { |
void TabSpecificContentSettings::OnContentAllowed(ContentSettingsType type) { |
DCHECK(type != CONTENT_SETTINGS_TYPE_GEOLOCATION) |
<< "Geolocation settings handled by OnGeolocationPermissionSet"; |
+ DCHECK(type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC && |
+ type != CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) |
+ << "Media stream settings handled by OnMediaStreamPermissionSet"; |
bool access_changed = false; |
switch (type) { |
- case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC: |
- case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA: |
#if defined(OS_ANDROID) |
case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER: |
-#endif |
- // The setting for media is overwritten here because media does not need |
- // to reload the page to have the new setting kick in. See issue/175993. |
+ // content_allowed_[type] is always set to true in OnContentBlocked, so we |
+ // have to use content_blocked_ to detect whether the protected media |
+ // setting has changed. |
if (content_blocked_[type]) { |
content_blocked_[type] = false; |
access_changed = true; |
} |
break; |
+#endif |
default: |
break; |
} |
@@ -478,25 +495,40 @@ void TabSpecificContentSettings::OnProtectedMediaIdentifierPermissionSet( |
TabSpecificContentSettings::MicrophoneCameraState |
TabSpecificContentSettings::GetMicrophoneCameraState() const { |
- if (IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) && |
- IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) { |
- return MICROPHONE_CAMERA_ACCESSED; |
- } else if (IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)) { |
- return MICROPHONE_ACCESSED; |
- } else if (IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) { |
- return CAMERA_ACCESSED; |
- } |
+ return microphone_camera_state_; |
+} |
+ |
+bool TabSpecificContentSettings::IsMicrophoneCameraStateChanged() const { |
+ if ((microphone_camera_state_ & (MICROPHONE_ACCESSED | MICROPHONE_BLOCKED)) ? |
+ !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) : |
+ !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)) |
+ return true; |
+ |
+ if ((microphone_camera_state_ & (CAMERA_ACCESSED | CAMERA_BLOCKED)) ? |
+ !IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) : |
+ !IsContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) |
+ return true; |
+ |
+ PrefService* prefs = |
+ Profile::FromBrowserContext(web_contents()->GetBrowserContext())-> |
+ GetPrefs(); |
+ scoped_refptr<MediaStreamCaptureIndicator> media_indicator = |
+ MediaCaptureDevicesDispatcher::GetInstance()-> |
+ GetMediaStreamCaptureIndicator(); |
+ |
+ if ((microphone_camera_state_ & MICROPHONE_ACCESSED) && |
+ prefs->GetString(prefs::kDefaultAudioCaptureDevice) != |
+ media_stream_selected_audio_device() && |
+ media_indicator->IsCapturingAudio(web_contents())) |
+ return true; |
+ |
+ if ((microphone_camera_state_ & CAMERA_ACCESSED) && |
+ prefs->GetString(prefs::kDefaultVideoCaptureDevice) != |
+ media_stream_selected_video_device() && |
+ media_indicator->IsCapturingVideo(web_contents())) |
+ return true; |
- if (IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) && |
- IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) { |
- return MICROPHONE_CAMERA_BLOCKED; |
- } else if (IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)) { |
- return MICROPHONE_BLOCKED; |
- } else if (IsContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA)) { |
- return CAMERA_BLOCKED; |
- } |
- |
- return MICROPHONE_CAMERA_NOT_ACCESSED; |
+ return false; |
} |
void TabSpecificContentSettings::OnMediaStreamPermissionSet( |
@@ -504,44 +536,50 @@ void TabSpecificContentSettings::OnMediaStreamPermissionSet( |
const MediaStreamDevicesController::MediaStreamTypeSettingsMap& |
request_permissions) { |
media_stream_access_origin_ = request_origin; |
+ unsigned prev_microphone_camera_state = microphone_camera_state_; |
Bernhard Bauer
2014/09/25 16:18:27
Unsigned what? I thought you had the typedef Micro
robwu
2014/09/25 19:15:53
Done.
|
+ microphone_camera_state_ = MICROPHONE_CAMERA_NOT_ACCESSED; |
+ PrefService* prefs = |
+ Profile::FromBrowserContext(web_contents()->GetBrowserContext())-> |
+ GetPrefs(); |
MediaStreamDevicesController::MediaStreamTypeSettingsMap::const_iterator it = |
request_permissions.find(content::MEDIA_DEVICE_AUDIO_CAPTURE); |
if (it != request_permissions.end()) { |
media_stream_requested_audio_device_ = it->second.requested_device_id; |
- switch (it->second.permission) { |
- case MediaStreamDevicesController::MEDIA_NONE: |
- NOTREACHED(); |
- break; |
- case MediaStreamDevicesController::MEDIA_ALLOWED: |
- OnContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); |
- break; |
- // TODO(grunell): UI should show for what reason access has been blocked. |
- case MediaStreamDevicesController::MEDIA_BLOCKED_BY_POLICY: |
- case MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER_SETTING: |
- case MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER: |
- OnContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); |
- break; |
- } |
+ media_stream_selected_audio_device_ = |
+ media_stream_requested_audio_device_.empty() ? |
+ prefs->GetString(prefs::kDefaultAudioCaptureDevice) : |
+ media_stream_requested_audio_device_; |
+ DCHECK_NE(MediaStreamDevicesController::MEDIA_NONE, it->second.permission); |
+ const bool mic_allowed = |
Bernhard Bauer
2014/09/25 16:18:27
Nit: We usually don't bother with making purely lo
robwu
2014/09/25 19:15:53
Done.
|
+ it->second.permission == MediaStreamDevicesController::MEDIA_ALLOWED; |
+ content_allowed_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC] = mic_allowed; |
+ content_blocked_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC] = !mic_allowed; |
+ microphone_camera_state_ |= |
+ MICROPHONE_ACCESSED | (mic_allowed ? 0 : MICROPHONE_BLOCKED); |
} |
it = request_permissions.find(content::MEDIA_DEVICE_VIDEO_CAPTURE); |
if (it != request_permissions.end()) { |
media_stream_requested_video_device_ = it->second.requested_device_id; |
- switch (it->second.permission) { |
- case MediaStreamDevicesController::MEDIA_NONE: |
- NOTREACHED(); |
- break; |
- case MediaStreamDevicesController::MEDIA_ALLOWED: |
- OnContentAllowed(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); |
- break; |
- // TODO(grunell): UI should show for what reason access has been blocked. |
- case MediaStreamDevicesController::MEDIA_BLOCKED_BY_POLICY: |
- case MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER_SETTING: |
- case MediaStreamDevicesController::MEDIA_BLOCKED_BY_USER: |
- OnContentBlocked(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); |
- break; |
- } |
+ media_stream_selected_video_device_ = |
+ media_stream_requested_video_device_.empty() ? |
+ prefs->GetString(prefs::kDefaultVideoCaptureDevice) : |
+ media_stream_requested_video_device_; |
+ DCHECK_NE(MediaStreamDevicesController::MEDIA_NONE, it->second.permission); |
+ const bool cam_allowed = |
+ it->second.permission == MediaStreamDevicesController::MEDIA_ALLOWED; |
+ content_allowed_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA] = cam_allowed; |
+ content_blocked_[CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA] = !cam_allowed; |
+ microphone_camera_state_ |= |
+ CAMERA_ACCESSED | (cam_allowed ? 0 : CAMERA_BLOCKED); |
+ } |
+ |
+ if (microphone_camera_state_ != prev_microphone_camera_state) { |
+ content::NotificationService::current()->Notify( |
+ chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, |
+ content::Source<WebContents>(web_contents()), |
+ content::NotificationService::NoDetails()); |
} |
} |
@@ -565,6 +603,7 @@ void TabSpecificContentSettings::ClearBlockedContentSettingsExceptForCookies() { |
content_allowed_[i] = false; |
content_blockage_indicated_to_user_[i] = false; |
} |
+ microphone_camera_state_ = MICROPHONE_CAMERA_NOT_ACCESSED; |
load_plugins_link_enabled_ = true; |
content::NotificationService::current()->Notify( |
chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, |
@@ -707,9 +746,20 @@ void TabSpecificContentSettings::OnContentSettingChanged( |
details.primary_pattern().Matches(entry_url)) { |
Profile* profile = |
Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
+ const HostContentSettingsMap* map = profile->GetHostContentSettingsMap(); |
+ |
+ if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC || |
+ content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA) { |
+ const GURL media_origin = media_stream_access_origin(); |
+ ContentSetting setting = map->GetContentSetting(media_origin, |
+ media_origin, |
+ content_type, |
+ std::string()); |
+ content_allowed_[content_type] = setting == CONTENT_SETTING_ALLOW; |
+ content_blocked_[content_type] = setting == CONTENT_SETTING_BLOCK; |
+ } |
RendererContentSettingRules rules; |
- GetRendererContentSettingRules(profile->GetHostContentSettingsMap(), |
- &rules); |
+ GetRendererContentSettingRules(map, &rules); |
Send(new ChromeViewMsg_SetContentSettingRules(rules)); |
} |
} |