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