1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/media/media_stream_infobar_delegate.h" 6 7 #include "base/logging.h" 8 #include "base/metrics/histogram.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "chrome/browser/infobars/infobar_service.h" 11 #include "chrome/common/url_constants.h" 12 #include "chrome/grit/generated_resources.h" 13 #include "components/google/core/browser/google_util.h" 14 #include "components/infobars/core/infobar.h" 15 #include "content/public/browser/web_contents.h" 16 #include "grit/components_strings.h" 17 #include "grit/theme_resources.h" 18 #include "ui/base/l10n/l10n_util.h" 19 #include "url/gurl.h" 20 21 namespace { 22 23 enum DevicePermissionActions { 24 kAllowHttps = 0, 25 kAllowHttp, 26 kDeny, 27 kCancel, 28 kPermissionActionsMax // Must always be last! 29 }; 30 31 } // namespace 32 33 MediaStreamInfoBarDelegate::~MediaStreamInfoBarDelegate() { 34 } 35 36 // static 37 bool MediaStreamInfoBarDelegate::Create( 38 content::WebContents* web_contents, 39 const content::MediaStreamRequest& request, 40 const content::MediaResponseCallback& callback) { 41 scoped_ptr<MediaStreamDevicesController> controller( 42 new MediaStreamDevicesController(web_contents, request, callback)); 43 if (controller->DismissInfoBarAndTakeActionOnSettings()) 44 return false; 45 46 InfoBarService* infobar_service = 47 InfoBarService::FromWebContents(web_contents); 48 if (!infobar_service) { 49 // Deny the request if there is no place to show the infobar, e.g. when 50 // the request comes from a background extension page. 51 controller->Deny(false, content::MEDIA_DEVICE_INVALID_STATE); 52 return false; 53 } 54 55 scoped_ptr<infobars::InfoBar> infobar( 56 ConfirmInfoBarDelegate::CreateInfoBar(scoped_ptr<ConfirmInfoBarDelegate>( 57 new MediaStreamInfoBarDelegate(controller.Pass())))); 58 for (size_t i = 0; i < infobar_service->infobar_count(); ++i) { 59 infobars::InfoBar* old_infobar = infobar_service->infobar_at(i); 60 if (old_infobar->delegate()->AsMediaStreamInfoBarDelegate()) { 61 infobar_service->ReplaceInfoBar(old_infobar, infobar.Pass()); 62 return true; 63 } 64 } 65 infobar_service->AddInfoBar(infobar.Pass()); 66 return true; 67 } 68 69 MediaStreamInfoBarDelegate::MediaStreamInfoBarDelegate( 70 scoped_ptr<MediaStreamDevicesController> controller) 71 : ConfirmInfoBarDelegate(), 72 controller_(controller.Pass()) { 73 DCHECK(controller_.get()); 74 DCHECK(controller_->HasAudio() || controller_->HasVideo()); 75 } 76 77 void MediaStreamInfoBarDelegate::InfoBarDismissed() { 78 // Deny the request if the infobar was closed with the 'x' button, since 79 // we don't want WebRTC to be waiting for an answer that will never come. 80 UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions", 81 kCancel, kPermissionActionsMax); 82 controller_->Deny(false, content::MEDIA_DEVICE_PERMISSION_DISMISSED); 83 } 84 85 int MediaStreamInfoBarDelegate::GetIconID() const { 86 return controller_->HasVideo() ? 87 IDR_INFOBAR_MEDIA_STREAM_CAMERA : IDR_INFOBAR_MEDIA_STREAM_MIC; 88 } 89 90 infobars::InfoBarDelegate::Type MediaStreamInfoBarDelegate::GetInfoBarType() 91 const { 92 return PAGE_ACTION_TYPE; 93 } 94 95 MediaStreamInfoBarDelegate* 96 MediaStreamInfoBarDelegate::AsMediaStreamInfoBarDelegate() { 97 return this; 98 } 99 100 base::string16 MediaStreamInfoBarDelegate::GetMessageText() const { 101 int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO; 102 if (!controller_->HasAudio()) 103 message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY; 104 else if (!controller_->HasVideo()) 105 message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY; 106 return l10n_util::GetStringFUTF16( 107 message_id, base::UTF8ToUTF16(controller_->GetSecurityOriginSpec())); 108 } 109 110 base::string16 MediaStreamInfoBarDelegate::GetButtonLabel( 111 InfoBarButton button) const { 112 return l10n_util::GetStringUTF16((button == BUTTON_OK) ? 113 IDS_MEDIA_CAPTURE_ALLOW : IDS_MEDIA_CAPTURE_DENY); 114 } 115 116 bool MediaStreamInfoBarDelegate::Accept() { 117 GURL origin(controller_->GetSecurityOriginSpec()); 118 if (origin.SchemeIsSecure()) { 119 UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions", 120 kAllowHttps, kPermissionActionsMax); 121 } else { 122 UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions", 123 kAllowHttp, kPermissionActionsMax); 124 } 125 controller_->Accept(true); 126 return true; 127 } 128 129 bool MediaStreamInfoBarDelegate::Cancel() { 130 UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions", 131 kDeny, kPermissionActionsMax); 132 controller_->Deny(true, content::MEDIA_DEVICE_PERMISSION_DENIED); 133 return true; 134 } 135 136 base::string16 MediaStreamInfoBarDelegate::GetLinkText() const { 137 return l10n_util::GetStringUTF16(IDS_LEARN_MORE); 138 } 139 140 bool MediaStreamInfoBarDelegate::LinkClicked( 141 WindowOpenDisposition disposition) { 142 InfoBarService::WebContentsFromInfoBar(infobar())->OpenURL( 143 content::OpenURLParams( 144 GURL(chrome::kMediaAccessLearnMoreUrl), 145 content::Referrer(), 146 (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition, 147 ui::PAGE_TRANSITION_LINK, false)); 148 149 return false; // Do not dismiss the info bar. 150 } 151