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