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 21namespace { 22 23enum DevicePermissionActions { 24 kAllowHttps = 0, 25 kAllowHttp, 26 kDeny, 27 kCancel, 28 kPermissionActionsMax // Must always be last! 29}; 30 31} // namespace 32 33MediaStreamInfoBarDelegate::~MediaStreamInfoBarDelegate() { 34} 35 36// static 37bool 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 69MediaStreamInfoBarDelegate::MediaStreamInfoBarDelegate( 70 scoped_ptr<MediaStreamDevicesController> controller) 71 : ConfirmInfoBarDelegate(), 72 controller_(controller.Pass()) { 73 DCHECK(controller_.get()); 74 DCHECK(controller_->HasAudio() || controller_->HasVideo()); 75} 76 77void 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 85int MediaStreamInfoBarDelegate::GetIconID() const { 86 return controller_->HasVideo() ? 87 IDR_INFOBAR_MEDIA_STREAM_CAMERA : IDR_INFOBAR_MEDIA_STREAM_MIC; 88} 89 90infobars::InfoBarDelegate::Type MediaStreamInfoBarDelegate::GetInfoBarType() 91 const { 92 return PAGE_ACTION_TYPE; 93} 94 95MediaStreamInfoBarDelegate* 96 MediaStreamInfoBarDelegate::AsMediaStreamInfoBarDelegate() { 97 return this; 98} 99 100base::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 110base::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 116bool 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 129bool 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 136base::string16 MediaStreamInfoBarDelegate::GetLinkText() const { 137 return l10n_util::GetStringUTF16(IDS_LEARN_MORE); 138} 139 140bool 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