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"
126d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "components/google/core/browser/google_util.h"
130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "components/infobars/core/infobar.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/web_contents.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "grit/generated_resources.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace {
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)enum DevicePermissionActions {
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  kAllowHttps = 0,
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  kAllowHttp,
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  kDeny,
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  kCancel,
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  kPermissionActionsMax  // Must always be last!
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}  // namespace
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochMediaStreamInfoBarDelegate::~MediaStreamInfoBarDelegate() {
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaStreamInfoBarDelegate::Create(
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    content::WebContents* web_contents,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::MediaStreamRequest& request,
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const content::MediaResponseCallback& callback) {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<MediaStreamDevicesController> controller(
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      new MediaStreamDevicesController(web_contents, request, callback));
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (controller->DismissInfoBarAndTakeActionOnSettings())
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InfoBarService* infobar_service =
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      InfoBarService::FromWebContents(web_contents);
47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  if (!infobar_service) {
48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // Deny the request if there is no place to show the infobar, e.g. when
49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    // the request comes from a background extension page.
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    controller->Deny(false, content::MEDIA_DEVICE_INVALID_STATE);
51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    return false;
52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  }
53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  scoped_ptr<infobars::InfoBar> infobar(
550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      ConfirmInfoBarDelegate::CreateInfoBar(scoped_ptr<ConfirmInfoBarDelegate>(
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          new MediaStreamInfoBarDelegate(controller.Pass()))));
57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  for (size_t i = 0; i < infobar_service->infobar_count(); ++i) {
580529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    infobars::InfoBar* old_infobar = infobar_service->infobar_at(i);
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (old_infobar->delegate()->AsMediaStreamInfoBarDelegate()) {
607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      infobar_service->ReplaceInfoBar(old_infobar, infobar.Pass());
617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      return true;
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  infobar_service->AddInfoBar(infobar.Pass());
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MediaStreamInfoBarDelegate::MediaStreamInfoBarDelegate(
697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    scoped_ptr<MediaStreamDevicesController> controller)
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : ConfirmInfoBarDelegate(),
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      controller_(controller.Pass()) {
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(controller_.get());
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(controller_->HasAudio() || controller_->HasVideo());
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
75ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MediaStreamInfoBarDelegate::InfoBarDismissed() {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Deny the request if the infobar was closed with the 'x' button, since
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we don't want WebRTC to be waiting for an answer that will never come.
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            kCancel, kPermissionActionsMax);
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  controller_->Deny(false, content::MEDIA_DEVICE_PERMISSION_DISMISSED);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int MediaStreamInfoBarDelegate::GetIconID() const {
853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return controller_->HasVideo() ?
8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      IDR_INFOBAR_MEDIA_STREAM_CAMERA : IDR_INFOBAR_MEDIA_STREAM_MIC;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochinfobars::InfoBarDelegate::Type MediaStreamInfoBarDelegate::GetInfoBarType()
900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    const {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PAGE_ACTION_TYPE;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaStreamInfoBarDelegate*
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MediaStreamInfoBarDelegate::AsMediaStreamInfoBarDelegate() {
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return this;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamInfoBarDelegate::GetMessageText() const {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int message_id = IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO;
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!controller_->HasAudio())
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY;
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  else if (!controller_->HasVideo())
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return l10n_util::GetStringFUTF16(
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      message_id, base::UTF8ToUTF16(controller_->GetSecurityOriginSpec()));
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamInfoBarDelegate::GetButtonLabel(
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    InfoBarButton button) const {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      IDS_MEDIA_CAPTURE_ALLOW : IDS_MEDIA_CAPTURE_DENY);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaStreamInfoBarDelegate::Accept() {
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GURL origin(controller_->GetSecurityOriginSpec());
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (origin.SchemeIsSecure()) {
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                              kAllowHttps, kPermissionActionsMax);
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  } else {
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                              kAllowHttp, kPermissionActionsMax);
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  controller_->Accept(true);
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaStreamInfoBarDelegate::Cancel() {
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION("Media.DevicePermissionActions",
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                            kDeny, kPermissionActionsMax);
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  controller_->Deny(true, content::MEDIA_DEVICE_PERMISSION_DENIED);
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return true;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::string16 MediaStreamInfoBarDelegate::GetLinkText() const {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool MediaStreamInfoBarDelegate::LinkClicked(
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WindowOpenDisposition disposition) {
141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  InfoBarService::WebContentsFromInfoBar(infobar())->OpenURL(
142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      content::OpenURLParams(
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          GURL(chrome::kMediaAccessLearnMoreUrl),
144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          content::Referrer(),
145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          content::PAGE_TRANSITION_LINK, false));
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;  // Do not dismiss the info bar.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
150