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