| 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 8c210a42b21548ff33bb6faf8272fa5897aa0c1c..a478c9b337fde4ee5a01e9d3b3bda8842aa694e3 100644
|
| --- a/chrome/browser/media/webrtc/media_stream_devices_controller.cc
|
| +++ b/chrome/browser/media/webrtc/media_stream_devices_controller.cc
|
| @@ -8,6 +8,7 @@
|
| #include <utility>
|
|
|
| #include "base/callback_helpers.h"
|
| +#include "base/command_line.h"
|
| #include "base/memory/ptr_util.h"
|
| #include "base/metrics/histogram_macros.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| @@ -82,42 +83,28 @@ using PermissionActionCallback =
|
| const GURL&,
|
| Profile*)>;
|
|
|
| -void RecordSinglePermissionAction(const content::MediaStreamRequest& request,
|
| - ContentSettingsType content_type,
|
| - Profile* profile,
|
| - PermissionActionCallback callback) {
|
| - if (ContentTypeIsRequested(content_type, request)) {
|
| - // TODO(stefanocs): Pass the actual |gesture_type| once this file has been
|
| - // refactored into PermissionContext.
|
| - callback.Run(content_type, PermissionRequestGestureType::UNKNOWN,
|
| - request.security_origin, profile);
|
| - }
|
| -}
|
|
|
| // Calls |action_function| for each permission requested by |request|.
|
| -void RecordPermissionAction(const content::MediaStreamRequest& request,
|
| +void RecordPermissionAction(bool is_asking_for_audio,
|
| + bool is_asking_for_video,
|
| + const GURL& security_origin,
|
| Profile* profile,
|
| PermissionActionCallback callback) {
|
| - RecordSinglePermissionAction(request, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
|
| - profile, callback);
|
| - RecordSinglePermissionAction(
|
| - request, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, profile, callback);
|
| -}
|
| + // TODO(stefanocs): Pass the actual |gesture_type| once this file has been
|
| + // refactored into PermissionContext.
|
| + if (is_asking_for_audio) {
|
| + callback.Run(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
|
| + PermissionRequestGestureType::UNKNOWN, security_origin,
|
| + profile);
|
| + }
|
|
|
| -#if defined(OS_ANDROID)
|
| -// Callback for the permission update infobar when the site and Chrome
|
| -// permissions are mismatched on Android.
|
| -void OnPermissionConflictResolved(
|
| - std::unique_ptr<MediaStreamDevicesController> controller,
|
| - bool allowed) {
|
| - if (allowed)
|
| - controller->PermissionGranted();
|
| - else
|
| - controller->ForcePermissionDeniedTemporarily();
|
| + if (is_asking_for_video) {
|
| + callback.Run(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
|
| + PermissionRequestGestureType::UNKNOWN, security_origin,
|
| + profile);
|
| + }
|
| }
|
|
|
| -#endif // defined(OS_ANDROID)
|
| -
|
| // 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.
|
| @@ -206,76 +193,129 @@ bool HasAvailableDevices(ContentSettingsType content_type,
|
|
|
| } // 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)) {}
|
| +namespace internal {
|
|
|
| - ~MediaPermissionStatus() {}
|
| +MediaStreamPermissionRequest::MediaStreamPermissionRequest(
|
| + Profile* profile,
|
| + bool is_asking_for_audio,
|
| + bool is_asking_for_video,
|
| + GURL security_origin,
|
| + base::Callback<void(ContentSetting, bool)> prompt_answered_callback)
|
| + : profile_(profile),
|
| + is_asking_for_audio_(is_asking_for_audio),
|
| + is_asking_for_video_(is_asking_for_video),
|
| + security_origin_(security_origin),
|
| + prompt_answered_callback_(prompt_answered_callback) {}
|
|
|
| - bool audio_requested() const { return audio_requested_; }
|
| - bool video_requested() const { return video_requested_; }
|
| +MediaStreamPermissionRequest::~MediaStreamPermissionRequest() {
|
| + RecordPermissionAction(is_asking_for_audio_, is_asking_for_video_,
|
| + security_origin_, profile_,
|
| + base::Bind(PermissionUmaUtil::PermissionIgnored));
|
| +}
|
|
|
| - bool audio_blocked() const { return audio_blocked_; }
|
| - bool video_blocked() const { return video_blocked_; }
|
| +bool MediaStreamPermissionRequest::IsAskingForAudio() const {
|
| + return is_asking_for_audio_;
|
| +}
|
|
|
| - content::MediaStreamRequestResult denial_reason() const {
|
| - return denial_reason_;
|
| - }
|
| +bool MediaStreamPermissionRequest::IsAskingForVideo() const {
|
| + return is_asking_for_video_;
|
| +}
|
|
|
| - void SetAudioBlocked(content::MediaStreamRequestResult denial_reason) {
|
| - DCHECK(audio_requested_);
|
| - audio_blocked_ = true;
|
| - denial_reason_ = denial_reason;
|
| - }
|
| +base::string16 MediaStreamPermissionRequest::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 SetVideoBlocked(content::MediaStreamRequestResult denial_reason) {
|
| - DCHECK(video_requested_);
|
| - video_blocked_ = true;
|
| - denial_reason_ = denial_reason;
|
| - }
|
| +PermissionRequest::IconId MediaStreamPermissionRequest::GetIconId() const {
|
| +#if defined(OS_ANDROID)
|
| + return IsAskingForVideo() ? IDR_INFOBAR_MEDIA_STREAM_CAMERA
|
| + : IDR_INFOBAR_MEDIA_STREAM_MIC;
|
| +#else
|
| + return IsAskingForVideo() ? ui::kVideocamIcon : ui::kMicrophoneIcon;
|
| +#endif
|
| +}
|
|
|
| - private:
|
| - bool audio_requested_ = false;
|
| - bool video_requested_ = false;
|
| - bool audio_blocked_ = false;
|
| - bool video_blocked_ = false;
|
| +base::string16 MediaStreamPermissionRequest::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);
|
| +}
|
|
|
| - content::MediaStreamRequestResult denial_reason_ = content::MEDIA_DEVICE_OK;
|
| -};
|
| +GURL MediaStreamPermissionRequest::GetOrigin() const {
|
| + return security_origin_;
|
| +}
|
| +
|
| +void MediaStreamPermissionRequest::PermissionGranted() {
|
| + RecordPermissionAction(is_asking_for_audio_, is_asking_for_video_,
|
| + security_origin_, profile_,
|
| + base::Bind(PermissionUmaUtil::PermissionGranted));
|
| + prompt_answered_callback_.Run(CONTENT_SETTING_ALLOW, persist());
|
| +}
|
| +
|
| +void MediaStreamPermissionRequest::PermissionDenied() {
|
| + RecordPermissionAction(is_asking_for_audio_, is_asking_for_video_,
|
| + security_origin_, profile_,
|
| + base::Bind(PermissionUmaUtil::PermissionDenied));
|
| + prompt_answered_callback_.Run(CONTENT_SETTING_BLOCK, persist());
|
| +}
|
| +
|
| +bool MediaStreamPermissionRequest::ShouldShowPersistenceToggle() const {
|
| + return PermissionUtil::ShouldShowPersistenceToggle();
|
| +}
|
| +
|
| +void MediaStreamPermissionRequest::Cancelled() {
|
| + RecordPermissionAction(is_asking_for_audio_, is_asking_for_video_,
|
| + security_origin_, profile_,
|
| + base::Bind(PermissionUmaUtil::PermissionDismissed));
|
| + prompt_answered_callback_.Run(CONTENT_SETTING_ASK, persist());
|
| +}
|
| +
|
| +void MediaStreamPermissionRequest::RequestFinished() {
|
| + delete this;
|
| +}
|
| +
|
| +PermissionRequestType MediaStreamPermissionRequest::GetPermissionRequestType()
|
| + const {
|
| + return PermissionRequestType::MEDIA_STREAM;
|
| +}
|
| +
|
| +} // namespace internal
|
|
|
| // Implementation of PermissionPromptDelegate which actually shows a permission
|
| // prompt.
|
| class MediaStreamDevicesController::PermissionPromptDelegateImpl
|
| : public internal::PermissionPromptDelegate {
|
| public:
|
| - void ShowPrompt(
|
| - bool user_gesture,
|
| - content::WebContents* web_contents,
|
| - std::unique_ptr<MediaStreamDevicesController> controller) override {
|
| + void ShowPrompt(bool user_gesture,
|
| + content::WebContents* web_contents,
|
| + std::unique_ptr<internal::MediaStreamPermissionRequest>
|
| + request) override {
|
| #if defined(OS_ANDROID)
|
| PermissionUmaUtil::RecordPermissionPromptShown(
|
| - controller->GetPermissionRequestType(),
|
| + request->GetPermissionRequestType(),
|
| PermissionUtil::GetGestureType(user_gesture));
|
| if (PermissionDialogDelegate::ShouldShowDialog(user_gesture)) {
|
| PermissionDialogDelegate::CreateMediaStreamDialog(
|
| - web_contents, user_gesture, std::move(controller));
|
| + web_contents, user_gesture, std::move(request));
|
| } else {
|
| MediaStreamInfoBarDelegateAndroid::Create(web_contents, user_gesture,
|
| - std::move(controller));
|
| + std::move(request));
|
| }
|
| #else
|
| PermissionRequestManager* permission_request_manager =
|
| PermissionRequestManager::FromWebContents(web_contents);
|
| if (permission_request_manager)
|
| - permission_request_manager->AddRequest(controller.release());
|
| + permission_request_manager->AddRequest(request.release());
|
| #endif
|
| }
|
| };
|
| @@ -299,8 +339,6 @@ void MediaStreamDevicesController::RegisterProfilePrefs(
|
|
|
| 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>());
|
| @@ -308,95 +346,70 @@ MediaStreamDevicesController::~MediaStreamDevicesController() {
|
| }
|
|
|
| bool MediaStreamDevicesController::IsAskingForAudio() const {
|
| - return old_audio_setting_ == CONTENT_SETTING_ASK;
|
| + return audio_setting_ == CONTENT_SETTING_ASK;
|
| }
|
|
|
| bool MediaStreamDevicesController::IsAskingForVideo() const {
|
| - return old_video_setting_ == CONTENT_SETTING_ASK;
|
| + return 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::PromptAnswered(ContentSetting setting,
|
| + bool persist) {
|
| + if (setting != CONTENT_SETTING_ALLOW)
|
| + denial_reason_ = content::MEDIA_DEVICE_PERMISSION_DENIED;
|
|
|
| -void MediaStreamDevicesController::ForcePermissionDeniedTemporarily() {
|
| - set_persist(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);
|
| - set_persist(true);
|
| -}
|
| + HostContentSettingsMap* host_content_settings_map =
|
| + HostContentSettingsMapFactory::GetForProfile(profile_);
|
| + if (audio_setting_ == CONTENT_SETTING_ASK) {
|
| + if (persist) {
|
| + host_content_settings_map->SetContentSettingDefaultScope(
|
| + request_.security_origin, GURL(),
|
| + CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, std::string(), setting);
|
| + }
|
| + audio_setting_ = setting;
|
| + }
|
|
|
| -PermissionRequest::IconId MediaStreamDevicesController::GetIconId() const {
|
| -#if defined(OS_ANDROID)
|
| - return IsAskingForVideo() ? IDR_INFOBAR_MEDIA_STREAM_CAMERA
|
| - : IDR_INFOBAR_MEDIA_STREAM_MIC;
|
| -#else
|
| - return IsAskingForVideo() ? ui::kVideocamIcon : ui::kMicrophoneIcon;
|
| -#endif
|
| -}
|
| + if (video_setting_ == CONTENT_SETTING_ASK) {
|
| + if (persist) {
|
| + host_content_settings_map->SetContentSettingDefaultScope(
|
| + request_.security_origin, GURL(),
|
| + CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, std::string(), setting);
|
| + }
|
| + video_setting_ = setting;
|
| + }
|
|
|
| -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);
|
| + RunCallback();
|
| }
|
|
|
| -GURL MediaStreamDevicesController::GetOrigin() const {
|
| - return request_.security_origin;
|
| -}
|
| +void MediaStreamDevicesController::PromptAnsweredGroupedRequest(
|
| + const std::vector<ContentSetting>& response) {
|
| + if (audio_setting_ == CONTENT_SETTING_ASK)
|
| + audio_setting_ = response.front();
|
|
|
| -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);
|
| -}
|
| + if (video_setting_ == CONTENT_SETTING_ASK)
|
| + video_setting_ = response.back();
|
|
|
| -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);
|
| -}
|
| + if (audio_setting_ != CONTENT_SETTING_ALLOW &&
|
| + video_setting_ != CONTENT_SETTING_ALLOW)
|
| + denial_reason_ = content::MEDIA_DEVICE_PERMISSION_DENIED;
|
|
|
| -bool MediaStreamDevicesController::ShouldShowPersistenceToggle() const {
|
| - return PermissionUtil::ShouldShowPersistenceToggle();
|
| + RunCallback();
|
| }
|
|
|
| -void MediaStreamDevicesController::Cancelled() {
|
| - RecordPermissionAction(request_, profile_,
|
| - base::Bind(PermissionUmaUtil::PermissionDismissed));
|
| - RunCallback(old_audio_setting_, old_video_setting_,
|
| - content::MEDIA_DEVICE_PERMISSION_DISMISSED);
|
| -}
|
| +void MediaStreamDevicesController::AndroidOSPromptAnswered(bool allowed) {
|
| + if (!allowed) {
|
| + denial_reason_ = content::MEDIA_DEVICE_PERMISSION_DENIED;
|
| + if (audio_setting_ == CONTENT_SETTING_ALLOW)
|
| + audio_setting_ = CONTENT_SETTING_BLOCK;
|
| + if (video_setting_ == CONTENT_SETTING_ALLOW)
|
| + video_setting_ = CONTENT_SETTING_BLOCK;
|
| + }
|
|
|
| -void MediaStreamDevicesController::RequestFinished() {
|
| - delete this;
|
| + RunCallback();
|
| }
|
|
|
| -PermissionRequestType MediaStreamDevicesController::GetPermissionRequestType()
|
| - const {
|
| - return PermissionRequestType::MEDIA_STREAM;
|
| +void MediaStreamDevicesController::RequestFinishedNoPrompt() {
|
| + RunCallback();
|
| }
|
|
|
| // static
|
| @@ -404,34 +417,21 @@ void MediaStreamDevicesController::RequestPermissionsWithDelegate(
|
| const content::MediaStreamRequest& request,
|
| const content::MediaResponseCallback& callback,
|
| internal::PermissionPromptDelegate* delegate) {
|
| + content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
|
| + request.render_process_id, request.render_frame_id);
|
| content::WebContents* web_contents =
|
| - content::WebContents::FromRenderFrameHost(
|
| - content::RenderFrameHost::FromID(request.render_process_id,
|
| - request.render_frame_id));
|
| + content::WebContents::FromRenderFrameHost(rfh);
|
| 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,
|
| - initial_permission));
|
| - if (!controller->IsAskingForAudio() && !controller->IsAskingForVideo()) {
|
| + new MediaStreamDevicesController(web_contents, request, callback));
|
| +
|
| #if defined(OS_ANDROID)
|
| + if (!controller->IsAskingForAudio() && !controller->IsAskingForVideo()) {
|
| // If either audio or video was previously allowed and Chrome no longer has
|
| // the necessary permissions, show a infobar to attempt to address this
|
| // mismatch.
|
| @@ -448,71 +448,69 @@ void MediaStreamDevicesController::RequestPermissionsWithDelegate(
|
| web_contents, content_settings_types)) {
|
| PermissionUpdateInfoBarDelegate::Create(
|
| web_contents, content_settings_types,
|
| - base::Bind(&OnPermissionConflictResolved, base::Passed(&controller)));
|
| + base::Bind(&AndroidOSPromptAnswered, base::Passed(&controller)));
|
| + return;
|
| }
|
| -#endif
|
| - return;
|
| }
|
| +#endif
|
|
|
| - delegate->ShowPrompt(request.user_gesture, web_contents,
|
| - std::move(controller));
|
| + Profile* profile =
|
| + Profile::FromBrowserContext(web_contents->GetBrowserContext());
|
| + if (!controller->IsAskingForAudio() && !controller->IsAskingForVideo()) {
|
| + controller->RequestFinishedNoPrompt();
|
| + } else {
|
| + if (base::CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kEnableGroupedMediaPermissionPrompts)) {
|
| + std::vector<ContentSettingsType> content_settings_types;
|
| +
|
| + if (controller->IsAskingForAudio())
|
| + content_settings_types.push_back(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC);
|
| + if (controller->IsAskingForVideo()) {
|
| + content_settings_types.push_back(
|
| + CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
|
| + }
|
| +
|
| + LOG(ERROR) << content_settings_types.size();
|
| +
|
| + PermissionManager::Get(profile)->RequestPermissions(
|
| + content_settings_types, rfh, request.security_origin,
|
| + request.user_gesture,
|
| + base::Bind(
|
| + &MediaStreamDevicesController::PromptAnsweredGroupedRequest,
|
| + base::Passed(&controller)));
|
| + } else {
|
| + delegate->ShowPrompt(
|
| + request.user_gesture, web_contents,
|
| + base::MakeUnique<internal::MediaStreamPermissionRequest>(
|
| + profile, controller->IsAskingForAudio(),
|
| + controller->IsAskingForVideo(), request.security_origin,
|
| + base::Bind(&MediaStreamDevicesController::PromptAnswered,
|
| + base::Passed(&controller))));
|
| + }
|
| + }
|
| }
|
|
|
| MediaStreamDevicesController::MediaStreamDevicesController(
|
| content::WebContents* web_contents,
|
| const content::MediaStreamRequest& request,
|
| - const content::MediaResponseCallback& callback,
|
| - const MediaPermissionStatus& initial_permission)
|
| + const content::MediaResponseCallback& callback)
|
| : web_contents_(web_contents), request_(request), callback_(callback) {
|
| profile_ = Profile::FromBrowserContext(web_contents->GetBrowserContext());
|
| content_settings_ = TabSpecificContentSettings::FromWebContents(web_contents);
|
|
|
| - 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 ||
|
| - old_video_setting_ == CONTENT_SETTING_ASK) {
|
| - return;
|
| - }
|
| -
|
| -#if defined(OS_ANDROID)
|
| - 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);
|
| + denial_reason_ = content::MEDIA_DEVICE_OK;
|
| + audio_setting_ = GetContentSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
|
| + request, &denial_reason_);
|
| + video_setting_ = GetContentSetting(CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
|
| + request, &denial_reason_);
|
| }
|
|
|
| bool MediaStreamDevicesController::IsAllowedForAudio() const {
|
| - return old_audio_setting_ == CONTENT_SETTING_ALLOW;
|
| + return audio_setting_ == CONTENT_SETTING_ALLOW;
|
| }
|
|
|
| bool MediaStreamDevicesController::IsAllowedForVideo() const {
|
| - return old_video_setting_ == CONTENT_SETTING_ALLOW;
|
| + return video_setting_ == CONTENT_SETTING_ALLOW;
|
| }
|
|
|
| content::MediaStreamDevices MediaStreamDevicesController::GetDevices(
|
| @@ -604,34 +602,25 @@ content::MediaStreamDevices MediaStreamDevicesController::GetDevices(
|
| return devices;
|
| }
|
|
|
| -void MediaStreamDevicesController::RunCallback(
|
| - ContentSetting audio_setting,
|
| - ContentSetting video_setting,
|
| - content::MediaStreamRequestResult denial_reason) {
|
| +void MediaStreamDevicesController::RunCallback() {
|
| CHECK(!callback_.is_null());
|
|
|
| - // If the kill switch is on we don't update the tab context or persist the
|
| - // setting.
|
| - if (denial_reason != content::MEDIA_DEVICE_KILL_SWITCH_ON) {
|
| - if (persist())
|
| - StorePermission(audio_setting, video_setting);
|
| - UpdateTabSpecificContentSettings(audio_setting, video_setting);
|
| - }
|
| + // If the kill switch is on we don't update the tab context.
|
| + if (denial_reason_ != content::MEDIA_DEVICE_KILL_SWITCH_ON)
|
| + UpdateTabSpecificContentSettings(audio_setting_, video_setting_);
|
|
|
| content::MediaStreamDevices devices =
|
| - GetDevices(audio_setting, video_setting);
|
| + 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;
|
| + // success, otherwise we report |denial_reason_|.
|
| + if (audio_setting_ != CONTENT_SETTING_ALLOW &&
|
| + video_setting_ != CONTENT_SETTING_ALLOW) {
|
| + DCHECK_NE(content::MEDIA_DEVICE_OK, 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;
|
| + denial_reason_ = content::MEDIA_DEVICE_NO_HARDWARE;
|
| }
|
|
|
| std::unique_ptr<content::MediaStreamUI> ui;
|
| @@ -640,29 +629,7 @@ void MediaStreamDevicesController::RunCallback(
|
| ->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);
|
| - }
|
| + base::ResetAndReturn(&callback_).Run(devices, denial_reason_, std::move(ui));
|
| }
|
|
|
| void MediaStreamDevicesController::UpdateTabSpecificContentSettings(
|
| @@ -714,21 +681,24 @@ 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(!request_.security_origin.is_empty());
|
| DCHECK(content::IsOriginSecure(request_.security_origin) ||
|
| request_.request_type == content::MEDIA_OPEN_DEVICE_PEPPER_ONLY);
|
| - if (!was_requested) {
|
| + if (!ContentTypeIsRequested(content_type, request)) {
|
| // No denial reason set as it will have been previously set.
|
| return CONTENT_SETTING_DEFAULT;
|
| }
|
|
|
| - if (was_initially_blocked) {
|
| - // No denial reason set as it will have been previously set.
|
| + std::string device_id;
|
| + if (content_type == CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC)
|
| + device_id = request.requested_audio_device_id;
|
| + else
|
| + device_id = request.requested_video_device_id;
|
| + if (!HasAvailableDevices(content_type, device_id)) {
|
| + *denial_reason = content::MEDIA_DEVICE_NO_HARDWARE;
|
| return CONTENT_SETTING_BLOCK;
|
| }
|
|
|
| @@ -750,18 +720,6 @@ ContentSetting MediaStreamDevicesController::GetContentSetting(
|
| return result.content_setting;
|
| }
|
|
|
| -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)
|
| - result = user_decision;
|
| - return result;
|
| -}
|
| -
|
| bool MediaStreamDevicesController::IsUserAcceptAllowed(
|
| ContentSettingsType content_type) const {
|
| #if defined(OS_ANDROID)
|
|
|