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.
5 #include "chrome/browser/gpu/three_d_api_observer.h"
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"
19 // ThreeDAPIInfoBarDelegate ---------------------------------------------------
21 class ThreeDAPIInfoBarDelegate
: public ConfirmInfoBarDelegate
{
23 // Creates a 3D API infobar and delegate and adds the infobar to
25 static void Create(InfoBarService
* infobar_service
,
27 content::ThreeDAPIType requester
);
30 enum DismissalHistogram
{
33 CLOSED_WITHOUT_ACTION
,
37 ThreeDAPIInfoBarDelegate(const GURL
& url
, content::ThreeDAPIType requester
);
38 ~ThreeDAPIInfoBarDelegate() override
;
40 // ConfirmInfoBarDelegate:
41 bool EqualsDelegate(infobars::InfoBarDelegate
* delegate
) const override
;
42 int GetIconID() const override
;
43 base::string16
GetMessageText() const override
;
44 base::string16
GetButtonLabel(InfoBarButton button
) const override
;
45 bool Accept() override
;
46 bool Cancel() override
;
47 base::string16
GetLinkText() const override
;
48 bool LinkClicked(WindowOpenDisposition disposition
) override
;
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_
;
57 DISALLOW_COPY_AND_ASSIGN(ThreeDAPIInfoBarDelegate
);
61 void ThreeDAPIInfoBarDelegate::Create(InfoBarService
* infobar_service
,
63 content::ThreeDAPIType requester
) {
65 return; // NULL for apps.
66 infobar_service
->AddInfoBar(
67 infobar_service
->CreateConfirmInfoBar(scoped_ptr
<ConfirmInfoBarDelegate
>(
68 new ThreeDAPIInfoBarDelegate(url
, requester
))));
71 ThreeDAPIInfoBarDelegate::ThreeDAPIInfoBarDelegate(
73 content::ThreeDAPIType requester
)
74 : ConfirmInfoBarDelegate(),
76 requester_(requester
),
77 message_text_queried_(false),
78 action_taken_(false) {
81 ThreeDAPIInfoBarDelegate::~ThreeDAPIInfoBarDelegate() {
82 if (message_text_queried_
&& !action_taken_
) {
83 UMA_HISTOGRAM_ENUMERATION("GPU.ThreeDAPIInfoBarDismissal",
84 CLOSED_WITHOUT_ACTION
, DISMISSAL_MAX
);
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();
97 int ThreeDAPIInfoBarDelegate::GetIconID() const {
98 return IDR_INFOBAR_3D_BLOCKED
;
101 base::string16
ThreeDAPIInfoBarDelegate::GetMessageText() const {
102 message_text_queried_
= true;
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
);
109 case content::THREE_D_API_TYPE_PEPPER_3D
:
110 api_name
= l10n_util::GetStringUTF16(IDS_3D_APIS_PEPPER_3D_NAME
);
114 return l10n_util::GetStringFUTF16(IDS_3D_APIS_BLOCKED_TEXT
,
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
);
125 bool ThreeDAPIInfoBarDelegate::Accept() {
126 action_taken_
= true;
127 UMA_HISTOGRAM_ENUMERATION("GPU.ThreeDAPIInfoBarDismissal", IGNORED
,
132 bool ThreeDAPIInfoBarDelegate::Cancel() {
133 action_taken_
= true;
134 UMA_HISTOGRAM_ENUMERATION("GPU.ThreeDAPIInfoBarDismissal", RELOADED
,
136 content::GpuDataManager::GetInstance()->UnblockDomainFrom3DAPIs(url_
);
137 InfoBarService::WebContentsFromInfoBar(infobar())->GetController().Reload(
142 base::string16
ThreeDAPIInfoBarDelegate::GetLinkText() const {
143 return l10n_util::GetStringUTF16(IDS_LEARN_MORE
);
146 bool ThreeDAPIInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition
) {
147 InfoBarService::WebContentsFromInfoBar(infobar())->OpenURL(
148 content::OpenURLParams(
149 GURL("https://support.google.com/chrome/?p=ib_webgl"),
151 (disposition
== CURRENT_TAB
) ? NEW_FOREGROUND_TAB
: disposition
,
152 ui::PAGE_TRANSITION_LINK
, false));
157 // ThreeDAPIObserver ----------------------------------------------------------
159 ThreeDAPIObserver::ThreeDAPIObserver() {
160 content::GpuDataManager::GetInstance()->AddObserver(this);
163 ThreeDAPIObserver::~ThreeDAPIObserver() {
164 content::GpuDataManager::GetInstance()->RemoveObserver(this);
167 void ThreeDAPIObserver::DidBlock3DAPIs(const GURL
& url
,
168 int render_process_id
,
170 content::ThreeDAPIType requester
) {
171 content::WebContents
* web_contents
= tab_util::GetWebContentsByID(
172 render_process_id
, render_view_id
);
175 ThreeDAPIInfoBarDelegate::Create(
176 InfoBarService::FromWebContents(web_contents
), url
, requester
);