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