Home | History | Annotate | Download | only in browser
      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/three_d_api_observer.h"
      6 
      7 #include "base/metrics/histogram.h"
      8 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
      9 #include "chrome/browser/infobars/infobar_service.h"
     10 #include "chrome/browser/tab_contents/tab_util.h"
     11 #include "content/public/browser/gpu_data_manager.h"
     12 #include "grit/generated_resources.h"
     13 #include "ui/base/l10n/l10n_util.h"
     14 
     15 
     16 // ThreeDAPIInfoBarDelegate ---------------------------------------------------
     17 
     18 class ThreeDAPIInfoBarDelegate : public ConfirmInfoBarDelegate {
     19  public:
     20   // Creates a 3D API infobar delegate and adds it to |infobar_service|.
     21   static void Create(InfoBarService* infobar_service,
     22                      const GURL& url,
     23                      content::ThreeDAPIType requester);
     24 
     25  private:
     26   enum DismissalHistogram {
     27     IGNORED,
     28     RELOADED,
     29     CLOSED_WITHOUT_ACTION,
     30     DISMISSAL_MAX
     31   };
     32 
     33   ThreeDAPIInfoBarDelegate(InfoBarService* owner,
     34                            const GURL& url,
     35                            content::ThreeDAPIType requester);
     36   virtual ~ThreeDAPIInfoBarDelegate();
     37 
     38   // ConfirmInfoBarDelegate:
     39   virtual bool EqualsDelegate(InfoBarDelegate* delegate) const OVERRIDE;
     40   virtual ThreeDAPIInfoBarDelegate* AsThreeDAPIInfoBarDelegate() OVERRIDE;
     41   virtual string16 GetMessageText() const OVERRIDE;
     42   virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
     43   virtual bool Accept() OVERRIDE;
     44   virtual bool Cancel() OVERRIDE;
     45   virtual string16 GetLinkText() const OVERRIDE;
     46   virtual bool LinkClicked(WindowOpenDisposition disposition) OVERRIDE;
     47 
     48   GURL url_;
     49   content::ThreeDAPIType requester_;
     50   // Basically indicates whether the infobar was displayed at all, or
     51   // was a temporary instance thrown away by the InfobarService.
     52   mutable bool message_text_queried_;
     53   bool action_taken_;
     54 
     55   DISALLOW_COPY_AND_ASSIGN(ThreeDAPIInfoBarDelegate);
     56 };
     57 
     58 // static
     59 void ThreeDAPIInfoBarDelegate::Create(InfoBarService* infobar_service,
     60                                       const GURL& url,
     61                                       content::ThreeDAPIType requester) {
     62   if (!infobar_service)
     63     return;  // NULL for apps.
     64   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
     65       new ThreeDAPIInfoBarDelegate(infobar_service, url, requester)));
     66 }
     67 
     68 ThreeDAPIInfoBarDelegate::ThreeDAPIInfoBarDelegate(
     69     InfoBarService* owner,
     70     const GURL& url,
     71     content::ThreeDAPIType requester)
     72     : ConfirmInfoBarDelegate(owner),
     73       url_(url),
     74       requester_(requester),
     75       message_text_queried_(false),
     76       action_taken_(false) {
     77 }
     78 
     79 ThreeDAPIInfoBarDelegate::~ThreeDAPIInfoBarDelegate() {
     80   if (message_text_queried_ && !action_taken_) {
     81     UMA_HISTOGRAM_ENUMERATION("GPU.ThreeDAPIInfoBarDismissal",
     82                               CLOSED_WITHOUT_ACTION, DISMISSAL_MAX);
     83   }
     84 }
     85 
     86 bool ThreeDAPIInfoBarDelegate::EqualsDelegate(InfoBarDelegate* delegate) const {
     87   // For the time being, if a given web page is actually using both
     88   // WebGL and Pepper 3D and both APIs are blocked, just leave the
     89   // first infobar up. If the user selects "try again", both APIs will
     90   // be unblocked and the web page reload will succeed.
     91   return (delegate->AsThreeDAPIInfoBarDelegate() != NULL);
     92 }
     93 
     94 ThreeDAPIInfoBarDelegate*
     95     ThreeDAPIInfoBarDelegate::AsThreeDAPIInfoBarDelegate() {
     96   return this;
     97 }
     98 
     99 string16 ThreeDAPIInfoBarDelegate::GetMessageText() const {
    100   message_text_queried_ = true;
    101 
    102   string16 api_name;
    103   switch (requester_) {
    104     case content::THREE_D_API_TYPE_WEBGL:
    105       api_name = l10n_util::GetStringUTF16(IDS_3D_APIS_WEBGL_NAME);
    106       break;
    107     case content::THREE_D_API_TYPE_PEPPER_3D:
    108       api_name = l10n_util::GetStringUTF16(IDS_3D_APIS_PEPPER_3D_NAME);
    109       break;
    110   }
    111 
    112   return l10n_util::GetStringFUTF16(IDS_3D_APIS_BLOCKED_TEXT,
    113                                     api_name);
    114 }
    115 
    116 string16 ThreeDAPIInfoBarDelegate::GetButtonLabel(
    117     InfoBarButton button) const {
    118   return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
    119       IDS_3D_APIS_BLOCKED_OK_BUTTON_LABEL :
    120       IDS_3D_APIS_BLOCKED_TRY_AGAIN_BUTTON_LABEL);
    121 }
    122 
    123 bool ThreeDAPIInfoBarDelegate::Accept() {
    124   action_taken_ = true;
    125   UMA_HISTOGRAM_ENUMERATION("GPU.ThreeDAPIInfoBarDismissal", IGNORED,
    126                             DISMISSAL_MAX);
    127   return true;
    128 }
    129 
    130 bool ThreeDAPIInfoBarDelegate::Cancel() {
    131   action_taken_ = true;
    132   UMA_HISTOGRAM_ENUMERATION("GPU.ThreeDAPIInfoBarDismissal", RELOADED,
    133                             DISMISSAL_MAX);
    134   content::GpuDataManager::GetInstance()->UnblockDomainFrom3DAPIs(url_);
    135   web_contents()->GetController().Reload(true);
    136   return true;
    137 }
    138 
    139 string16 ThreeDAPIInfoBarDelegate::GetLinkText() const {
    140   return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
    141 }
    142 
    143 bool ThreeDAPIInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition) {
    144   web_contents()->OpenURL(content::OpenURLParams(
    145       GURL("https://support.google.com/chrome/?p=ib_webgl"),
    146       content::Referrer(),
    147       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
    148       content::PAGE_TRANSITION_LINK,
    149       false));
    150   return false;
    151 }
    152 
    153 
    154 // ThreeDAPIObserver ----------------------------------------------------------
    155 
    156 ThreeDAPIObserver::ThreeDAPIObserver() {
    157   content::GpuDataManager::GetInstance()->AddObserver(this);
    158 }
    159 
    160 ThreeDAPIObserver::~ThreeDAPIObserver() {
    161   content::GpuDataManager::GetInstance()->RemoveObserver(this);
    162 }
    163 
    164 void ThreeDAPIObserver::DidBlock3DAPIs(const GURL& url,
    165                                        int render_process_id,
    166                                        int render_view_id,
    167                                        content::ThreeDAPIType requester) {
    168   content::WebContents* web_contents = tab_util::GetWebContentsByID(
    169       render_process_id, render_view_id);
    170   ThreeDAPIInfoBarDelegate::Create(
    171       InfoBarService::FromWebContents(web_contents), url, requester);
    172 }
    173