1// Copyright 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/geolocation/geolocation_infobar_delegate.h" 6 7#include "base/metrics/histogram.h" 8#include "chrome/browser/content_settings/permission_queue_controller.h" 9#include "chrome/browser/infobars/infobar_service.h" 10#include "chrome/grit/generated_resources.h" 11#include "chrome/grit/locale_settings.h" 12#include "components/google/core/browser/google_util.h" 13#include "components/infobars/core/infobar.h" 14#include "content/public/browser/navigation_details.h" 15#include "content/public/browser/navigation_entry.h" 16#include "content/public/browser/web_contents.h" 17#include "grit/theme_resources.h" 18#include "net/base/net_util.h" 19#include "ui/base/l10n/l10n_util.h" 20 21 22namespace { 23 24enum GeolocationInfoBarDelegateEvent { 25 // NOTE: Do not renumber these as that would confuse interpretation of 26 // previously logged data. When making changes, also update the enum list 27 // in tools/metrics/histograms/histograms.xml to keep it in sync. 28 29 // The bar was created. 30 GEOLOCATION_INFO_BAR_DELEGATE_EVENT_CREATE = 0, 31 32 // User allowed use of geolocation. 33 GEOLOCATION_INFO_BAR_DELEGATE_EVENT_ALLOW = 1, 34 35 // User denied use of geolocation. 36 GEOLOCATION_INFO_BAR_DELEGATE_EVENT_DENY = 2, 37 38 // User dismissed the bar. 39 GEOLOCATION_INFO_BAR_DELEGATE_EVENT_DISMISS = 3, 40 41 // User clicked on link. 42 DEPRECATED_GEOLOCATION_INFO_BAR_DELEGATE_EVENT_LINK_CLICK = 4, 43 44 // User ignored the bar. 45 GEOLOCATION_INFO_BAR_DELEGATE_EVENT_IGNORED = 5, 46 47 // NOTE: Add entries only immediately above this line. 48 GEOLOCATION_INFO_BAR_DELEGATE_EVENT_COUNT = 6 49}; 50 51void RecordUmaEvent(GeolocationInfoBarDelegateEvent event) { 52 UMA_HISTOGRAM_ENUMERATION("Geolocation.InfoBarDelegate.Event", 53 event, GEOLOCATION_INFO_BAR_DELEGATE_EVENT_COUNT); 54} 55 56} // namespace 57 58// static 59infobars::InfoBar* GeolocationInfoBarDelegate::Create( 60 InfoBarService* infobar_service, 61 PermissionQueueController* controller, 62 const PermissionRequestID& id, 63 const GURL& requesting_frame, 64 const std::string& display_languages) { 65 RecordUmaEvent(GEOLOCATION_INFO_BAR_DELEGATE_EVENT_CREATE); 66 const content::NavigationEntry* committed_entry = 67 infobar_service->web_contents()->GetController().GetLastCommittedEntry(); 68 GeolocationInfoBarDelegate* const delegate = new GeolocationInfoBarDelegate( 69 controller, id, requesting_frame, 70 committed_entry ? committed_entry->GetUniqueID() : 0, 71 display_languages); 72 73 infobars::InfoBar* infobar = ConfirmInfoBarDelegate::CreateInfoBar( 74 scoped_ptr<ConfirmInfoBarDelegate>(delegate)).release(); 75 return infobar_service->AddInfoBar(scoped_ptr<infobars::InfoBar>(infobar)); 76} 77 78GeolocationInfoBarDelegate::GeolocationInfoBarDelegate( 79 PermissionQueueController* controller, 80 const PermissionRequestID& id, 81 const GURL& requesting_frame, 82 int contents_unique_id, 83 const std::string& display_languages) 84 : ConfirmInfoBarDelegate(), 85 controller_(controller), 86 id_(id), 87 requesting_frame_(requesting_frame.GetOrigin()), 88 contents_unique_id_(contents_unique_id), 89 display_languages_(display_languages), 90 user_has_interacted_(false) { 91} 92 93GeolocationInfoBarDelegate::~GeolocationInfoBarDelegate() { 94 if (!user_has_interacted_) 95 RecordUmaEvent(GEOLOCATION_INFO_BAR_DELEGATE_EVENT_IGNORED); 96} 97 98bool GeolocationInfoBarDelegate::Accept() { 99 RecordUmaEvent(GEOLOCATION_INFO_BAR_DELEGATE_EVENT_ALLOW); 100 set_user_has_interacted(); 101 SetPermission(true, true); 102 return true; 103} 104 105void GeolocationInfoBarDelegate::SetPermission(bool update_content_setting, 106 bool allowed) { 107 content::WebContents* web_contents = 108 InfoBarService::WebContentsFromInfoBar(infobar()); 109 controller_->OnPermissionSet( 110 id_, requesting_frame_, 111 web_contents->GetLastCommittedURL().GetOrigin(), 112 update_content_setting, allowed); 113} 114 115void GeolocationInfoBarDelegate::InfoBarDismissed() { 116 RecordUmaEvent(GEOLOCATION_INFO_BAR_DELEGATE_EVENT_DISMISS); 117 set_user_has_interacted(); 118 SetPermission(false, false); 119} 120 121int GeolocationInfoBarDelegate::GetIconID() const { 122 return IDR_INFOBAR_GEOLOCATION; 123} 124 125infobars::InfoBarDelegate::Type GeolocationInfoBarDelegate::GetInfoBarType() 126 const { 127 return PAGE_ACTION_TYPE; 128} 129 130bool GeolocationInfoBarDelegate::ShouldExpireInternal( 131 const NavigationDetails& details) const { 132 // This implementation matches InfoBarDelegate::ShouldExpireInternal(), but 133 // uses the unique ID we set in the constructor instead of that stored in the 134 // base class. 135 return (contents_unique_id_ != details.entry_id) || details.is_reload; 136} 137 138base::string16 GeolocationInfoBarDelegate::GetMessageText() const { 139 return l10n_util::GetStringFUTF16(IDS_GEOLOCATION_INFOBAR_QUESTION, 140 net::FormatUrl(requesting_frame_, display_languages_, 141 net::kFormatUrlOmitUsernamePassword | 142 net::kFormatUrlOmitTrailingSlashOnBareHostname, 143 net::UnescapeRule::SPACES, NULL, NULL, NULL)); 144} 145 146base::string16 GeolocationInfoBarDelegate::GetButtonLabel( 147 InfoBarButton button) const { 148 return l10n_util::GetStringUTF16((button == BUTTON_OK) ? 149 IDS_GEOLOCATION_ALLOW_BUTTON : IDS_GEOLOCATION_DENY_BUTTON); 150} 151 152bool GeolocationInfoBarDelegate::Cancel() { 153 RecordUmaEvent(GEOLOCATION_INFO_BAR_DELEGATE_EVENT_DENY); 154 set_user_has_interacted(); 155 SetPermission(true, false); 156 return true; 157} 158