15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media/media_stream_infobar_delegate.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/metrics/histogram.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/infobars/infobar_service.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/url_constants.h"
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
136d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "components/google/core/browser/google_util.h"
140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/infobars/core/infobar.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "grit/components_strings.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace {
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)enum DevicePermissionActions {
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  kAllowHttps = 0,
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  kAllowHttp,
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  kDeny,
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  kCancel,
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  kPermissionActionsMax  // Must always be last!
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochMediaStreamInfoBarDelegate::~MediaStreamInfoBarDelegate() {
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaStreamInfoBarDelegate::Create(
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::WebContents* web_contents,
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::MediaStreamRequest& request,
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::MediaResponseCallback& callback) {
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<MediaStreamDevicesController> controller(
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new MediaStreamDevicesController(web_contents, request, callback));
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (controller->DismissInfoBarAndTakeActionOnSettings())
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InfoBarService* infobar_service =
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      InfoBarService::FromWebContents(web_contents);
48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!infobar_service) {
49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Deny the request if there is no place to show the infobar, e.g. when
50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // the request comes from a background extension page.
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    controller->Deny(false, content::MEDIA_DEVICE_INVALID_STATE);
52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return false;
53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<infobars::InfoBar> infobar(
560529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ConfirmInfoBarDelegate::CreateInfoBar(scoped_ptr<ConfirmInfoBarDelegate>(
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          new MediaStreamInfoBarDelegate(controller.Pass()))));
58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (size_t i = 0; i < infobar_service->infobar_count(); ++i) {
590529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    infobars::InfoBar* old_infobar = infobar_service->infobar_at(i);
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (old_infobar->delegate()->AsMediaStreamInfoBarDelegate()) {
617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      infobar_service->ReplaceInfoBar(old_infobar, infobar.Pass());
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return true;
637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  infobar_service->AddInfoBar(infobar.Pass());
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MediaStreamInfoBarDelegate::MediaStreamInfoBarDelegate(
707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<MediaStreamDevicesController> controller)
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : ConfirmInfoBarDelegate(),
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      controller_(controller.Pass()) {
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(controller_.get());
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(controller_->HasAudio() || controller_->HasVideo());
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
76ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaStreamInfoBarDelegate::InfoBarDismissed() {
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Deny the request if the infobar was closed with the 'x' button, since
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we don't want WebRTC to be waiting for an answer that will never come.
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            kCancel, kPermissionActionsMax);
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  controller_->Deny(false, content::MEDIA_DEVICE_PERMISSION_DISMISSED);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int MediaStreamInfoBarDelegate::GetIconID() const {
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return controller_->HasVideo() ?
8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      IDR_INFOBAR_MEDIA_STREAM_CAMERA : IDR_INFOBAR_MEDIA_STREAM_MIC;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochinfobars::InfoBarDelegate::Type MediaStreamInfoBarDelegate::GetInfoBarType()
910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const {
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PAGE_ACTION_TYPE;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaStreamInfoBarDelegate*
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaStreamInfoBarDelegate::AsMediaStreamInfoBarDelegate() {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return this;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamInfoBarDelegate::GetMessageText() const {
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO;
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!controller_->HasAudio())
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY;
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  else if (!controller_->HasVideo())
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY;
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return l10n_util::GetStringFUTF16(
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      message_id, base::UTF8ToUTF16(controller_->GetSecurityOriginSpec()));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamInfoBarDelegate::GetButtonLabel(
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InfoBarButton button) const {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IDS_MEDIA_CAPTURE_ALLOW : IDS_MEDIA_CAPTURE_DENY);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaStreamInfoBarDelegate::Accept() {
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GURL origin(controller_->GetSecurityOriginSpec());
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (origin.SchemeIsSecure()) {
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                              kAllowHttps, kPermissionActionsMax);
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else {
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                              kAllowHttp, kPermissionActionsMax);
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  controller_->Accept(true);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaStreamInfoBarDelegate::Cancel() {
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            kDeny, kPermissionActionsMax);
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  controller_->Deny(true, content::MEDIA_DEVICE_PERMISSION_DENIED);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamInfoBarDelegate::GetLinkText() const {
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaStreamInfoBarDelegate::LinkClicked(
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WindowOpenDisposition disposition) {
142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  InfoBarService::WebContentsFromInfoBar(infobar())->OpenURL(
143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      content::OpenURLParams(
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          GURL(chrome::kMediaAccessLearnMoreUrl),
145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          content::Referrer(),
146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          ui::PAGE_TRANSITION_LINK, false));
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;  // Do not dismiss the info bar.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
151