Home | History | Annotate | Download | only in media
      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