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 |
deleted file mode 100644 |
index 445d71265be185468eb12f2bfe620a4c01e4a64d..0000000000000000000000000000000000000000 |
--- a/chrome/browser/media/media_stream_devices_controller.cc |
+++ /dev/null |
@@ -1,649 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/media/media_stream_devices_controller.h" |
- |
-#include <map> |
-#include <utility> |
- |
-#include "base/auto_reset.h" |
-#include "base/callback_helpers.h" |
-#include "base/memory/ptr_util.h" |
-#include "base/metrics/histogram_macros.h" |
-#include "base/strings/utf_string_conversions.h" |
-#include "base/values.h" |
-#include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
-#include "chrome/browser/content_settings/tab_specific_content_settings.h" |
-#include "chrome/browser/media/media_capture_devices_dispatcher.h" |
-#include "chrome/browser/media/media_permission.h" |
-#include "chrome/browser/media/media_stream_capture_indicator.h" |
-#include "chrome/browser/media/media_stream_device_permissions.h" |
-#include "chrome/browser/permissions/permission_uma_util.h" |
-#include "chrome/browser/profiles/profile.h" |
-#include "chrome/browser/ui/browser.h" |
-#include "chrome/common/chrome_switches.h" |
-#include "chrome/common/features.h" |
-#include "chrome/common/pref_names.h" |
-#include "chrome/grit/generated_resources.h" |
-#include "chrome/grit/theme_resources.h" |
-#include "components/content_settings/core/browser/host_content_settings_map.h" |
-#include "components/content_settings/core/common/content_settings_pattern.h" |
-#include "components/pref_registry/pref_registry_syncable.h" |
-#include "components/prefs/scoped_user_pref_update.h" |
-#include "components/url_formatter/elide_url.h" |
-#include "content/public/browser/browser_thread.h" |
-#include "content/public/browser/permission_type.h" |
-#include "content/public/browser/render_frame_host.h" |
-#include "content/public/browser/render_process_host.h" |
-#include "content/public/browser/render_widget_host_view.h" |
-#include "content/public/common/media_stream_request.h" |
-#include "content/public/common/origin_util.h" |
-#include "extensions/common/constants.h" |
-#include "ui/base/l10n/l10n_util.h" |
- |
-#if BUILDFLAG(ANDROID_JAVA_UI) |
-#include <vector> |
- |
-#include "chrome/browser/android/preferences/pref_service_bridge.h" |
-#include "chrome/browser/permissions/permission_update_infobar_delegate_android.h" |
-#include "content/public/browser/android/content_view_core.h" |
-#include "ui/android/window_android.h" |
-#endif // BUILDFLAG(ANDROID_JAVA_UI) |
- |
-using content::BrowserThread; |
- |
-namespace { |
- |
-// Returns true if the given ContentSettingsType is being requested in |
-// |request|. |
-bool ContentTypeIsRequested(content::PermissionType type, |
- const content::MediaStreamRequest& request) { |
- if (request.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY) |
- return true; |
- |
- if (type == content::PermissionType::AUDIO_CAPTURE) |
- return request.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE; |
- |
- if (type == content::PermissionType::VIDEO_CAPTURE) |
- return request.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE; |
- |
- return false; |
-} |
- |
-using PermissionActionCallback = |
- base::Callback<void(content::PermissionType, |
- PermissionRequestGestureType, |
- const GURL&, |
- Profile*)>; |
- |
-void RecordSinglePermissionAction(const content::MediaStreamRequest& request, |
- content::PermissionType permission_type, |
- Profile* profile, |
- PermissionActionCallback callback) { |
- if (ContentTypeIsRequested(permission_type, request)) { |
- // TODO(stefanocs): Pass the actual |gesture_type| once this file has been |
- // refactored into PermissionContext. |
- callback.Run(permission_type, PermissionRequestGestureType::UNKNOWN, |
- request.security_origin, profile); |
- } |
-} |
- |
-// Calls |action_function| for each permission requested by |request|. |
-void RecordPermissionAction(const content::MediaStreamRequest& request, |
- Profile* profile, |
- PermissionActionCallback callback) { |
- RecordSinglePermissionAction(request, content::PermissionType::AUDIO_CAPTURE, |
- profile, callback); |
- RecordSinglePermissionAction(request, content::PermissionType::VIDEO_CAPTURE, |
- profile, callback); |
-} |
- |
-// This helper class helps to measure the number of media stream requests that |
-// occur. It ensures that only one request will be recorded per navigation, per |
-// frame. TODO(raymes): Remove this when https://crbug.com/526324 is fixed. |
-class MediaPermissionRequestLogger : content::WebContentsObserver { |
- // Map of <render process id, render frame id> -> |
- // MediaPermissionRequestLogger. |
- using RequestMap = std::map<std::pair<int, int>, |
- std::unique_ptr<MediaPermissionRequestLogger>>; |
- |
- public: |
- static void LogRequest(content::WebContents* contents, |
- int render_process_id, |
- int render_frame_id, |
- bool is_secure) { |
- RequestMap::key_type key = |
- std::make_pair(render_process_id, render_frame_id); |
- if (!base::ContainsKey(GetRequestMap(), key)) { |
- UMA_HISTOGRAM_BOOLEAN("Pepper.SecureOrigin.MediaStreamRequest", |
- is_secure); |
- GetRequestMap()[key] = |
- base::WrapUnique(new MediaPermissionRequestLogger(contents, key)); |
- } |
- } |
- |
- private: |
- MediaPermissionRequestLogger(content::WebContents* contents, |
- RequestMap::key_type key) |
- : WebContentsObserver(contents), key_(key) {} |
- |
- void PageChanged(content::RenderFrameHost* render_frame_host) { |
- if (std::make_pair(render_frame_host->GetProcess()->GetID(), |
- render_frame_host->GetRoutingID()) == key_) { |
- GetRequestMap().erase(key_); |
- } |
- } |
- |
- static RequestMap& GetRequestMap() { |
- CR_DEFINE_STATIC_LOCAL(RequestMap, request_map, ()); |
- return request_map; |
- } |
- |
- // content::WebContentsObserver overrides |
- void DidNavigateAnyFrame( |
- content::RenderFrameHost* render_frame_host, |
- const content::LoadCommittedDetails& details, |
- const content::FrameNavigateParams& params) override { |
- PageChanged(render_frame_host); |
- } |
- |
- void RenderFrameDeleted( |
- content::RenderFrameHost* render_frame_host) override { |
- PageChanged(render_frame_host); |
- } |
- |
- RequestMap::key_type key_; |
-}; |
- |
-} // namespace |
- |
-MediaStreamDevicesController::MediaStreamDevicesController( |
- content::WebContents* web_contents, |
- const content::MediaStreamRequest& request, |
- const content::MediaResponseCallback& callback) |
- : web_contents_(web_contents), |
- request_(request), |
- callback_(callback), |
- persist_permission_changes_(true) { |
- 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); |
- |
- // If either setting is ask, we show the infobar. |
- if (old_audio_setting_ == CONTENT_SETTING_ASK || |
- old_video_setting_ == CONTENT_SETTING_ASK) { |
- return; |
- } |
- |
-#if BUILDFLAG(ANDROID_JAVA_UI) |
- std::vector<ContentSettingsType> content_settings_types; |
- if (IsAllowedForAudio()) |
- content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); |
- |
- if (IsAllowedForVideo()) { |
- content_settings_types.push_back( |
- CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); |
- } |
- |
- // If the site had been previously granted the access to audio or video but |
- // Chrome is now missing the necessary permission, we need to show an infobar |
- // to resolve the difference. |
- if (!content_settings_types.empty() && |
- PermissionUpdateInfoBarDelegate::ShouldShowPermissionInfobar( |
- web_contents, content_settings_types)) { |
- return; |
- } |
-#endif |
- |
- // Otherwise we can run the callback immediately. |
- RunCallback(old_audio_setting_, old_video_setting_, denial_reason); |
-} |
- |
-MediaStreamDevicesController::~MediaStreamDevicesController() { |
- if (!callback_.is_null()) { |
- RecordPermissionAction(request_, profile_, |
- base::Bind(PermissionUmaUtil::PermissionIgnored)); |
- callback_.Run(content::MediaStreamDevices(), |
- content::MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN, |
- std::unique_ptr<content::MediaStreamUI>()); |
- } |
-} |
- |
-// static |
-void MediaStreamDevicesController::RegisterProfilePrefs( |
- user_prefs::PrefRegistrySyncable* prefs) { |
- prefs->RegisterBooleanPref(prefs::kVideoCaptureAllowed, true); |
- prefs->RegisterBooleanPref(prefs::kAudioCaptureAllowed, true); |
- prefs->RegisterListPref(prefs::kVideoCaptureAllowedUrls); |
- prefs->RegisterListPref(prefs::kAudioCaptureAllowedUrls); |
-} |
- |
-bool MediaStreamDevicesController::IsAllowedForAudio() const { |
- return old_audio_setting_ == CONTENT_SETTING_ALLOW; |
-} |
- |
-bool MediaStreamDevicesController::IsAllowedForVideo() const { |
- return old_video_setting_ == CONTENT_SETTING_ALLOW; |
-} |
- |
-bool MediaStreamDevicesController::IsAskingForAudio() const { |
- return old_audio_setting_ == CONTENT_SETTING_ASK; |
-} |
- |
-bool MediaStreamDevicesController::IsAskingForVideo() const { |
- return old_video_setting_ == CONTENT_SETTING_ASK; |
-} |
- |
-base::string16 MediaStreamDevicesController::GetMessageText() const { |
- int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO; |
- if (!IsAskingForAudio()) |
- message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY; |
- else if (!IsAskingForVideo()) |
- message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY; |
- return l10n_util::GetStringFUTF16( |
- message_id, |
- url_formatter::FormatUrlForSecurityDisplay( |
- GetOrigin(), url_formatter::SchemeDisplay::OMIT_CRYPTOGRAPHIC)); |
-} |
- |
-void MediaStreamDevicesController::ForcePermissionDeniedTemporarily() { |
- base::AutoReset<bool> persist_permissions( |
- &persist_permission_changes_, false); |
- // TODO(tsergeant): Determine whether it is appropriate to record permission |
- // action metrics here, as this is a different sort of user action. |
- RunCallback(CONTENT_SETTING_BLOCK, |
- CONTENT_SETTING_BLOCK, |
- content::MEDIA_DEVICE_PERMISSION_DENIED); |
-} |
- |
-int MediaStreamDevicesController::GetIconId() const { |
- if (IsAskingForVideo()) |
- return IDR_INFOBAR_MEDIA_STREAM_CAMERA; |
- |
- return IDR_INFOBAR_MEDIA_STREAM_MIC; |
-} |
- |
-base::string16 MediaStreamDevicesController::GetMessageTextFragment() const { |
- int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO_PERMISSION_FRAGMENT; |
- if (!IsAskingForAudio()) |
- message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_FRAGMENT; |
- else if (!IsAskingForVideo()) |
- message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY_PERMISSION_FRAGMENT; |
- return l10n_util::GetStringUTF16(message_id); |
-} |
- |
-GURL MediaStreamDevicesController::GetOrigin() const { |
- return request_.security_origin; |
-} |
- |
-void MediaStreamDevicesController::PermissionGranted() { |
- RecordPermissionAction(request_, profile_, |
- base::Bind(PermissionUmaUtil::PermissionGranted)); |
- RunCallback(GetNewSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, |
- old_audio_setting_, CONTENT_SETTING_ALLOW), |
- GetNewSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, |
- old_video_setting_, CONTENT_SETTING_ALLOW), |
- content::MEDIA_DEVICE_PERMISSION_DENIED); |
-} |
- |
-void MediaStreamDevicesController::PermissionDenied() { |
- RecordPermissionAction(request_, profile_, |
- base::Bind(PermissionUmaUtil::PermissionDenied)); |
- RunCallback(GetNewSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, |
- old_audio_setting_, CONTENT_SETTING_BLOCK), |
- GetNewSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, |
- old_video_setting_, CONTENT_SETTING_BLOCK), |
- content::MEDIA_DEVICE_PERMISSION_DENIED); |
-} |
- |
-void MediaStreamDevicesController::GroupedRequestFinished(bool audio_accepted, |
- bool video_accepted) { |
- RecordSinglePermissionAction( |
- request_, content::PermissionType::AUDIO_CAPTURE, profile_, |
- base::Bind(audio_accepted ? PermissionUmaUtil::PermissionGranted |
- : PermissionUmaUtil::PermissionDenied)); |
- RecordSinglePermissionAction( |
- request_, content::PermissionType::VIDEO_CAPTURE, profile_, |
- base::Bind(video_accepted ? PermissionUmaUtil::PermissionGranted |
- : PermissionUmaUtil::PermissionDenied)); |
- |
- ContentSetting audio_setting = |
- audio_accepted ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; |
- ContentSetting video_setting = |
- video_accepted ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; |
- RunCallback(GetNewSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, |
- old_audio_setting_, audio_setting), |
- GetNewSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, |
- old_video_setting_, video_setting), |
- content::MEDIA_DEVICE_PERMISSION_DENIED); |
-} |
- |
-void MediaStreamDevicesController::Cancelled() { |
- RecordPermissionAction(request_, profile_, |
- base::Bind(PermissionUmaUtil::PermissionDismissed)); |
- RunCallback(old_audio_setting_, old_video_setting_, |
- content::MEDIA_DEVICE_PERMISSION_DISMISSED); |
-} |
- |
-void MediaStreamDevicesController::RequestFinished() { |
- delete this; |
-} |
- |
-PermissionRequestType MediaStreamDevicesController::GetPermissionRequestType() |
- const { |
- return PermissionRequestType::MEDIA_STREAM; |
-} |
- |
-content::MediaStreamDevices MediaStreamDevicesController::GetDevices( |
- ContentSetting audio_setting, |
- ContentSetting video_setting) { |
- bool audio_allowed = audio_setting == CONTENT_SETTING_ALLOW; |
- bool video_allowed = video_setting == CONTENT_SETTING_ALLOW; |
- |
- if (!audio_allowed && !video_allowed) |
- return content::MediaStreamDevices(); |
- |
- content::MediaStreamDevices devices; |
- switch (request_.request_type) { |
- case content::MEDIA_OPEN_DEVICE_PEPPER_ONLY: { |
- const content::MediaStreamDevice* device = NULL; |
- // For open device request, when requested device_id is empty, pick |
- // the first available of the given type. If requested device_id is |
- // not empty, return the desired device if it's available. Otherwise, |
- // return no device. |
- if (audio_allowed && |
- request_.audio_type == content::MEDIA_DEVICE_AUDIO_CAPTURE) { |
- DCHECK_EQ(content::MEDIA_NO_SERVICE, request_.video_type); |
- if (!request_.requested_audio_device_id.empty()) { |
- device = |
- MediaCaptureDevicesDispatcher::GetInstance() |
- ->GetRequestedAudioDevice(request_.requested_audio_device_id); |
- } else { |
- device = MediaCaptureDevicesDispatcher::GetInstance() |
- ->GetFirstAvailableAudioDevice(); |
- } |
- } else if (video_allowed && |
- request_.video_type == content::MEDIA_DEVICE_VIDEO_CAPTURE) { |
- DCHECK_EQ(content::MEDIA_NO_SERVICE, request_.audio_type); |
- // Pepper API opens only one device at a time. |
- if (!request_.requested_video_device_id.empty()) { |
- device = |
- MediaCaptureDevicesDispatcher::GetInstance() |
- ->GetRequestedVideoDevice(request_.requested_video_device_id); |
- } else { |
- device = MediaCaptureDevicesDispatcher::GetInstance() |
- ->GetFirstAvailableVideoDevice(); |
- } |
- } |
- if (device) |
- devices.push_back(*device); |
- break; |
- } |
- case content::MEDIA_GENERATE_STREAM: { |
- bool get_default_audio_device = audio_allowed; |
- bool get_default_video_device = video_allowed; |
- |
- // Get the exact audio or video device if an id is specified. |
- if (audio_allowed && !request_.requested_audio_device_id.empty()) { |
- const content::MediaStreamDevice* audio_device = |
- MediaCaptureDevicesDispatcher::GetInstance() |
- ->GetRequestedAudioDevice(request_.requested_audio_device_id); |
- if (audio_device) { |
- devices.push_back(*audio_device); |
- get_default_audio_device = false; |
- } |
- } |
- if (video_allowed && !request_.requested_video_device_id.empty()) { |
- const content::MediaStreamDevice* video_device = |
- MediaCaptureDevicesDispatcher::GetInstance() |
- ->GetRequestedVideoDevice(request_.requested_video_device_id); |
- if (video_device) { |
- devices.push_back(*video_device); |
- get_default_video_device = false; |
- } |
- } |
- |
- // If either or both audio and video devices were requested but not |
- // specified by id, get the default devices. |
- if (get_default_audio_device || get_default_video_device) { |
- MediaCaptureDevicesDispatcher::GetInstance() |
- ->GetDefaultDevicesForProfile(profile_, get_default_audio_device, |
- get_default_video_device, &devices); |
- } |
- break; |
- } |
- case content::MEDIA_DEVICE_ACCESS: { |
- // Get the default devices for the request. |
- MediaCaptureDevicesDispatcher::GetInstance()->GetDefaultDevicesForProfile( |
- profile_, audio_allowed, video_allowed, &devices); |
- break; |
- } |
- case content::MEDIA_ENUMERATE_DEVICES: { |
- // Do nothing. |
- NOTREACHED(); |
- break; |
- } |
- } // switch |
- |
- if (audio_allowed) { |
- HostContentSettingsMapFactory::GetForProfile(profile_) |
- ->UpdateLastUsageByPattern( |
- ContentSettingsPattern::FromURLNoWildcard(request_.security_origin), |
- ContentSettingsPattern::Wildcard(), |
- CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); |
- } |
- if (video_allowed) { |
- HostContentSettingsMapFactory::GetForProfile(profile_) |
- ->UpdateLastUsageByPattern( |
- ContentSettingsPattern::FromURLNoWildcard(request_.security_origin), |
- ContentSettingsPattern::Wildcard(), |
- CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); |
- } |
- |
- return devices; |
-} |
- |
-void MediaStreamDevicesController::RunCallback( |
- ContentSetting audio_setting, |
- ContentSetting video_setting, |
- content::MediaStreamRequestResult denial_reason) { |
- CHECK(!callback_.is_null()); |
- |
- // If the kill switch is on we don't update the tab context or persist the |
- // setting. |
- if (persist_permission_changes_ && |
- denial_reason != content::MEDIA_DEVICE_KILL_SWITCH_ON) { |
- StorePermission(audio_setting, video_setting); |
- UpdateTabSpecificContentSettings(audio_setting, video_setting); |
- } |
- |
- content::MediaStreamDevices devices = |
- GetDevices(audio_setting, video_setting); |
- |
- // If either audio or video are allowed then the callback should report |
- // success, otherwise we report |denial_reason|. |
- content::MediaStreamRequestResult request_result = content::MEDIA_DEVICE_OK; |
- if (audio_setting != CONTENT_SETTING_ALLOW && |
- video_setting != CONTENT_SETTING_ALLOW) { |
- DCHECK_NE(content::MEDIA_DEVICE_OK, denial_reason); |
- request_result = denial_reason; |
- } else if (devices.empty()) { |
- // Even if one of the content settings was allowed, if there are no devices |
- // at this point we still report a failure. |
- request_result = content::MEDIA_DEVICE_NO_HARDWARE; |
- } |
- |
- std::unique_ptr<content::MediaStreamUI> ui; |
- if (!devices.empty()) { |
- ui = MediaCaptureDevicesDispatcher::GetInstance() |
- ->GetMediaStreamCaptureIndicator() |
- ->RegisterMediaStream(web_contents_, devices); |
- } |
- base::ResetAndReturn(&callback_).Run(devices, request_result, std::move(ui)); |
-} |
- |
-void MediaStreamDevicesController::StorePermission( |
- ContentSetting new_audio_setting, |
- ContentSetting new_video_setting) const { |
- DCHECK_CURRENTLY_ON(BrowserThread::UI); |
- DCHECK(content::IsOriginSecure(request_.security_origin) || |
- request_.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY); |
- |
- if (IsAskingForAudio() && new_audio_setting != CONTENT_SETTING_ASK) { |
- HostContentSettingsMapFactory::GetForProfile(profile_) |
- ->SetContentSettingDefaultScope(request_.security_origin, GURL(), |
- CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, |
- std::string(), new_audio_setting); |
- } |
- if (IsAskingForVideo() && new_video_setting != CONTENT_SETTING_ASK) { |
- HostContentSettingsMapFactory::GetForProfile(profile_) |
- ->SetContentSettingDefaultScope( |
- request_.security_origin, GURL(), |
- CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, std::string(), |
- new_video_setting); |
- } |
-} |
- |
-void MediaStreamDevicesController::UpdateTabSpecificContentSettings( |
- ContentSetting audio_setting, |
- ContentSetting video_setting) const { |
- if (!content_settings_) |
- return; |
- |
- TabSpecificContentSettings::MicrophoneCameraState microphone_camera_state = |
- TabSpecificContentSettings::MICROPHONE_CAMERA_NOT_ACCESSED; |
- std::string selected_audio_device; |
- std::string selected_video_device; |
- std::string requested_audio_device = request_.requested_audio_device_id; |
- std::string requested_video_device = request_.requested_video_device_id; |
- |
- // TODO(raymes): Why do we use the defaults here for the selected devices? |
- // Shouldn't we just use the devices that were actually selected? |
- PrefService* prefs = Profile::FromBrowserContext( |
- web_contents_->GetBrowserContext())->GetPrefs(); |
- if (audio_setting != CONTENT_SETTING_DEFAULT) { |
- selected_audio_device = |
- requested_audio_device.empty() |
- ? prefs->GetString(prefs::kDefaultAudioCaptureDevice) |
- : requested_audio_device; |
- microphone_camera_state |= |
- TabSpecificContentSettings::MICROPHONE_ACCESSED | |
- (audio_setting == CONTENT_SETTING_ALLOW |
- ? 0 |
- : TabSpecificContentSettings::MICROPHONE_BLOCKED); |
- } |
- |
- if (video_setting != CONTENT_SETTING_DEFAULT) { |
- selected_video_device = |
- requested_video_device.empty() |
- ? prefs->GetString(prefs::kDefaultVideoCaptureDevice) |
- : requested_video_device; |
- microphone_camera_state |= |
- TabSpecificContentSettings::CAMERA_ACCESSED | |
- (video_setting == CONTENT_SETTING_ALLOW |
- ? 0 |
- : TabSpecificContentSettings::CAMERA_BLOCKED); |
- } |
- |
- content_settings_->OnMediaStreamPermissionSet( |
- request_.security_origin, microphone_camera_state, selected_audio_device, |
- selected_video_device, requested_audio_device, requested_video_device); |
-} |
- |
-ContentSetting MediaStreamDevicesController::GetContentSetting( |
- ContentSettingsType content_type, |
- const content::MediaStreamRequest& request, |
- content::MediaStreamRequestResult* denial_reason) const { |
- DCHECK(content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC || |
- content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); |
- |
- 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 (!IsUserAcceptAllowed(content_type)) { |
- *denial_reason = content::MEDIA_DEVICE_PERMISSION_DENIED; |
- return CONTENT_SETTING_BLOCK; |
- } |
- |
- content::PermissionType permission_type; |
- if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC) { |
- permission_type = content::PermissionType::AUDIO_CAPTURE; |
- } else { |
- DCHECK(content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); |
- permission_type = content::PermissionType::VIDEO_CAPTURE; |
- } |
- |
- if (ContentTypeIsRequested(permission_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_); |
- return permission.GetPermissionStatusWithDeviceRequired(requested_device_id, |
- denial_reason); |
- } |
- // Return the default content setting if the device is not requested. |
- return CONTENT_SETTING_DEFAULT; |
-} |
- |
-ContentSetting MediaStreamDevicesController::GetNewSetting( |
- ContentSettingsType content_type, |
- ContentSetting old_setting, |
- ContentSetting user_decision) const { |
- DCHECK(user_decision == CONTENT_SETTING_ALLOW || |
- user_decision == CONTENT_SETTING_BLOCK); |
- ContentSetting result = old_setting; |
- if (old_setting == CONTENT_SETTING_ASK) { |
- if (user_decision == CONTENT_SETTING_ALLOW && |
- IsUserAcceptAllowed(content_type)) { |
- result = CONTENT_SETTING_ALLOW; |
- } else if (user_decision == CONTENT_SETTING_BLOCK) { |
- result = CONTENT_SETTING_BLOCK; |
- } |
- } |
- return result; |
-} |
- |
-bool MediaStreamDevicesController::IsUserAcceptAllowed( |
- ContentSettingsType content_type) const { |
-#if BUILDFLAG(ANDROID_JAVA_UI) |
- content::ContentViewCore* cvc = |
- content::ContentViewCore::FromWebContents(web_contents_); |
- if (!cvc) |
- return false; |
- |
- ui::WindowAndroid* window_android = cvc->GetWindowAndroid(); |
- if (!window_android) |
- return false; |
- |
- std::string android_permission = |
- PrefServiceBridge::GetAndroidPermissionForContentSetting(content_type); |
- bool android_permission_blocked = false; |
- if (!android_permission.empty()) { |
- android_permission_blocked = |
- !window_android->HasPermission(android_permission) && |
- !window_android->CanRequestPermission(android_permission); |
- } |
- if (android_permission_blocked) |
- return false; |
- |
- // Don't approve device requests if the tab was hidden. |
- // TODO(qinmin): Add a test for this. http://crbug.com/396869. |
- // TODO(raymes): Shouldn't this apply to all permissions not just audio/video? |
- return web_contents_->GetRenderWidgetHostView()->IsShowing(); |
-#endif |
- return true; |
-} |