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