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