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.
5 #include "chrome/browser/plugins/plugin_infobar_delegates.h"
7 #include "base/utf_string_conversions.h"
8 #include "chrome/browser/content_settings/host_content_settings_map.h"
9 #include "chrome/browser/google/google_util.h"
10 #include "chrome/browser/infobars/infobar_service.h"
11 #include "chrome/browser/lifetime/application_lifetime.h"
12 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
13 #include "chrome/browser/plugins/plugin_metadata.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/common/render_messages.h"
16 #include "chrome/common/url_constants.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/user_metrics.h"
20 #include "content/public/browser/web_contents.h"
21 #include "grit/generated_resources.h"
22 #include "grit/locale_settings.h"
23 #include "grit/theme_resources.h"
24 #include "ui/base/l10n/l10n_util.h"
25 #include "ui/base/resource/resource_bundle.h"
29 #include "ui/base/win/shell.h"
32 #if defined(ENABLE_PLUGIN_INSTALLATION)
34 #include "base/win/metro.h"
36 #include "chrome/browser/plugins/plugin_installer.h"
37 #endif // defined(ENABLE_PLUGIN_INSTALLATION)
39 using content::OpenURLParams
;
40 using content::Referrer
;
41 using content::UserMetricsAction
;
43 PluginInfoBarDelegate::PluginInfoBarDelegate(InfoBarService
* infobar_service
,
45 const std::string
& identifier
)
46 : ConfirmInfoBarDelegate(infobar_service
),
48 identifier_(identifier
) {
51 PluginInfoBarDelegate::~PluginInfoBarDelegate() {
54 bool PluginInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition
) {
56 GURL(GetLearnMoreURL()), Referrer(),
57 (disposition
== CURRENT_TAB
) ? NEW_FOREGROUND_TAB
: disposition
,
58 content::PAGE_TRANSITION_LINK
,
60 owner()->GetWebContents()->OpenURL(params
);
64 void PluginInfoBarDelegate::LoadBlockedPlugins() {
65 content::WebContents
* web_contents
= owner()->GetWebContents();
67 content::RenderViewHost
* host
= web_contents
->GetRenderViewHost();
68 ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins(
69 host
->GetProcess()->GetID());
70 host
->Send(new ChromeViewMsg_LoadBlockedPlugins(
71 host
->GetRoutingID(), identifier_
));
75 gfx::Image
* PluginInfoBarDelegate::GetIcon() const {
76 return &ResourceBundle::GetSharedInstance().GetNativeImageNamed(
77 IDR_INFOBAR_PLUGIN_INSTALL
);
80 string16
PluginInfoBarDelegate::GetLinkText() const {
81 return l10n_util::GetStringUTF16(IDS_LEARN_MORE
);
84 // UnauthorizedPluginInfoBarDelegate ------------------------------------------
87 void UnauthorizedPluginInfoBarDelegate::Create(
88 InfoBarService
* infobar_service
,
89 HostContentSettingsMap
* content_settings
,
90 const string16
& utf16_name
,
91 const std::string
& identifier
) {
92 infobar_service
->AddInfoBar(scoped_ptr
<InfoBarDelegate
>(
93 new UnauthorizedPluginInfoBarDelegate(infobar_service
, content_settings
,
94 utf16_name
, identifier
)));
96 content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Shown"));
97 std::string
name(UTF16ToUTF8(utf16_name
));
98 if (name
== PluginMetadata::kJavaGroupName
)
99 content::RecordAction(
100 UserMetricsAction("BlockedPluginInfobar.Shown.Java"));
101 else if (name
== PluginMetadata::kQuickTimeGroupName
)
102 content::RecordAction(
103 UserMetricsAction("BlockedPluginInfobar.Shown.QuickTime"));
104 else if (name
== PluginMetadata::kShockwaveGroupName
)
105 content::RecordAction(
106 UserMetricsAction("BlockedPluginInfobar.Shown.Shockwave"));
107 else if (name
== PluginMetadata::kRealPlayerGroupName
)
108 content::RecordAction(
109 UserMetricsAction("BlockedPluginInfobar.Shown.RealPlayer"));
110 else if (name
== PluginMetadata::kWindowsMediaPlayerGroupName
)
111 content::RecordAction(
112 UserMetricsAction("BlockedPluginInfobar.Shown.WindowsMediaPlayer"));
115 UnauthorizedPluginInfoBarDelegate::UnauthorizedPluginInfoBarDelegate(
116 InfoBarService
* infobar_service
,
117 HostContentSettingsMap
* content_settings
,
118 const string16
& utf16_name
,
119 const std::string
& identifier
)
120 : PluginInfoBarDelegate(infobar_service
, utf16_name
, identifier
),
121 content_settings_(content_settings
) {
124 UnauthorizedPluginInfoBarDelegate::~UnauthorizedPluginInfoBarDelegate() {
125 content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Closed"));
128 std::string
UnauthorizedPluginInfoBarDelegate::GetLearnMoreURL() const {
129 return chrome::kBlockedPluginLearnMoreURL
;
132 string16
UnauthorizedPluginInfoBarDelegate::GetMessageText() const {
133 return l10n_util::GetStringFUTF16(IDS_PLUGIN_NOT_AUTHORIZED
, name_
);
136 string16
UnauthorizedPluginInfoBarDelegate::GetButtonLabel(
137 InfoBarButton button
) const {
138 return l10n_util::GetStringUTF16((button
== BUTTON_OK
) ?
139 IDS_PLUGIN_ENABLE_TEMPORARILY
: IDS_PLUGIN_ENABLE_ALWAYS
);
142 bool UnauthorizedPluginInfoBarDelegate::Accept() {
143 content::RecordAction(
144 UserMetricsAction("BlockedPluginInfobar.AllowThisTime"));
145 LoadBlockedPlugins();
149 bool UnauthorizedPluginInfoBarDelegate::Cancel() {
150 content::RecordAction(
151 UserMetricsAction("BlockedPluginInfobar.AlwaysAllow"));
152 content_settings_
->AddExceptionForURL(owner()->GetWebContents()->GetURL(),
153 owner()->GetWebContents()->GetURL(),
154 CONTENT_SETTINGS_TYPE_PLUGINS
,
156 CONTENT_SETTING_ALLOW
);
157 LoadBlockedPlugins();
161 void UnauthorizedPluginInfoBarDelegate::InfoBarDismissed() {
162 content::RecordAction(
163 UserMetricsAction("BlockedPluginInfobar.Dismissed"));
166 bool UnauthorizedPluginInfoBarDelegate::LinkClicked(
167 WindowOpenDisposition disposition
) {
168 content::RecordAction(
169 UserMetricsAction("BlockedPluginInfobar.LearnMore"));
170 return PluginInfoBarDelegate::LinkClicked(disposition
);
173 #if defined(ENABLE_PLUGIN_INSTALLATION)
174 // OutdatedPluginInfoBarDelegate ----------------------------------------------
176 void OutdatedPluginInfoBarDelegate::Create(
177 InfoBarService
* infobar_service
,
178 PluginInstaller
* installer
,
179 scoped_ptr
<PluginMetadata
> plugin_metadata
) {
181 switch (installer
->state()) {
182 case PluginInstaller::INSTALLER_STATE_IDLE
:
183 message
= l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED_PROMPT
,
184 plugin_metadata
->name());
186 case PluginInstaller::INSTALLER_STATE_DOWNLOADING
:
187 message
= l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING
,
188 plugin_metadata
->name());
191 infobar_service
->AddInfoBar(scoped_ptr
<InfoBarDelegate
>(
192 new OutdatedPluginInfoBarDelegate(
193 infobar_service
, installer
, plugin_metadata
.Pass(), message
)));
196 OutdatedPluginInfoBarDelegate::OutdatedPluginInfoBarDelegate(
197 InfoBarService
* infobar_service
,
198 PluginInstaller
* installer
,
199 scoped_ptr
<PluginMetadata
> plugin_metadata
,
200 const string16
& message
)
201 : PluginInfoBarDelegate(
203 plugin_metadata
->name(),
204 plugin_metadata
->identifier()),
205 WeakPluginInstallerObserver(installer
),
206 plugin_metadata_(plugin_metadata
.Pass()),
208 content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Shown"));
209 std::string name
= UTF16ToUTF8(plugin_metadata_
->name());
210 if (name
== PluginMetadata::kJavaGroupName
)
211 content::RecordAction(
212 UserMetricsAction("OutdatedPluginInfobar.Shown.Java"));
213 else if (name
== PluginMetadata::kQuickTimeGroupName
)
214 content::RecordAction(
215 UserMetricsAction("OutdatedPluginInfobar.Shown.QuickTime"));
216 else if (name
== PluginMetadata::kShockwaveGroupName
)
217 content::RecordAction(
218 UserMetricsAction("OutdatedPluginInfobar.Shown.Shockwave"));
219 else if (name
== PluginMetadata::kRealPlayerGroupName
)
220 content::RecordAction(
221 UserMetricsAction("OutdatedPluginInfobar.Shown.RealPlayer"));
222 else if (name
== PluginMetadata::kSilverlightGroupName
)
223 content::RecordAction(
224 UserMetricsAction("OutdatedPluginInfobar.Shown.Silverlight"));
225 else if (name
== PluginMetadata::kAdobeReaderGroupName
)
226 content::RecordAction(
227 UserMetricsAction("OutdatedPluginInfobar.Shown.Reader"));
230 OutdatedPluginInfoBarDelegate::~OutdatedPluginInfoBarDelegate() {
231 content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Closed"));
234 std::string
OutdatedPluginInfoBarDelegate::GetLearnMoreURL() const {
235 return chrome::kOutdatedPluginLearnMoreURL
;
238 string16
OutdatedPluginInfoBarDelegate::GetMessageText() const {
242 string16
OutdatedPluginInfoBarDelegate::GetButtonLabel(
243 InfoBarButton button
) const {
244 return l10n_util::GetStringUTF16((button
== BUTTON_OK
) ?
245 IDS_PLUGIN_UPDATE
: IDS_PLUGIN_ENABLE_TEMPORARILY
);
248 bool OutdatedPluginInfoBarDelegate::Accept() {
249 content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Update"));
250 if (installer()->state() != PluginInstaller::INSTALLER_STATE_IDLE
) {
255 content::WebContents
* web_contents
= owner()->GetWebContents();
256 // A call to any of |OpenDownloadURL()| or |StartInstalling()| will
257 // result in deleting ourselves. Accordingly, we make sure to
258 // not pass a reference to an object that can go away.
259 // http://crbug.com/54167
260 GURL
plugin_url(plugin_metadata_
->plugin_url());
261 if (plugin_metadata_
->url_for_display()) {
262 installer()->OpenDownloadURL(plugin_url
, web_contents
);
264 installer()->StartInstalling(plugin_url
, web_contents
);
269 bool OutdatedPluginInfoBarDelegate::Cancel() {
270 content::RecordAction(
271 UserMetricsAction("OutdatedPluginInfobar.AllowThisTime"));
272 LoadBlockedPlugins();
276 void OutdatedPluginInfoBarDelegate::InfoBarDismissed() {
277 content::RecordAction(
278 UserMetricsAction("OutdatedPluginInfobar.Dismissed"));
281 bool OutdatedPluginInfoBarDelegate::LinkClicked(
282 WindowOpenDisposition disposition
) {
283 content::RecordAction(
284 UserMetricsAction("OutdatedPluginInfobar.LearnMore"));
285 return PluginInfoBarDelegate::LinkClicked(disposition
);
288 void OutdatedPluginInfoBarDelegate::DownloadStarted() {
289 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING
,
290 plugin_metadata_
->name()));
293 void OutdatedPluginInfoBarDelegate::DownloadError(const std::string
& message
) {
295 l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR_SHORT
,
296 plugin_metadata_
->name()));
299 void OutdatedPluginInfoBarDelegate::DownloadCancelled() {
300 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_CANCELLED
,
301 plugin_metadata_
->name()));
304 void OutdatedPluginInfoBarDelegate::DownloadFinished() {
305 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_UPDATING
,
306 plugin_metadata_
->name()));
309 void OutdatedPluginInfoBarDelegate::OnlyWeakObserversLeft() {
311 owner()->RemoveInfoBar(this);
314 void OutdatedPluginInfoBarDelegate::ReplaceWithInfoBar(
315 const string16
& message
) {
316 // Return early if the message doesn't change. This is important in case the
317 // PluginInstaller is still iterating over its observers (otherwise we would
318 // keep replacing infobar delegates infinitely).
319 if (message_
== message
)
323 PluginInstallerInfoBarDelegate::Replace(
324 this, installer(), plugin_metadata_
->Clone(), false, message
);
327 // PluginInstallerInfoBarDelegate ---------------------------------------------
329 void PluginInstallerInfoBarDelegate::Create(
330 InfoBarService
* infobar_service
,
331 PluginInstaller
* installer
,
332 scoped_ptr
<PluginMetadata
> plugin_metadata
,
333 const InstallCallback
& callback
) {
334 string16
name(plugin_metadata
->name());
336 if (base::win::IsMetroProcess()) {
337 PluginMetroModeInfoBarDelegate::Create(
338 infobar_service
, PluginMetroModeInfoBarDelegate::MISSING_PLUGIN
, name
);
343 switch (installer
->state()) {
344 case PluginInstaller::INSTALLER_STATE_IDLE
:
345 message
= l10n_util::GetStringFUTF16(
346 IDS_PLUGININSTALLER_INSTALLPLUGIN_PROMPT
, name
);
348 case PluginInstaller::INSTALLER_STATE_DOWNLOADING
:
349 message
= l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING
, name
);
352 infobar_service
->AddInfoBar(scoped_ptr
<InfoBarDelegate
>(
353 new PluginInstallerInfoBarDelegate(
354 infobar_service
, installer
, plugin_metadata
.Pass(), callback
, true,
358 void PluginInstallerInfoBarDelegate::Replace(
359 InfoBarDelegate
* infobar
,
360 PluginInstaller
* installer
,
361 scoped_ptr
<PluginMetadata
> plugin_metadata
,
363 const string16
& message
) {
364 DCHECK(infobar
->owner());
365 infobar
->owner()->ReplaceInfoBar(infobar
, scoped_ptr
<InfoBarDelegate
>(
366 new PluginInstallerInfoBarDelegate(
367 infobar
->owner(), installer
, plugin_metadata
.Pass(),
368 PluginInstallerInfoBarDelegate::InstallCallback(), new_install
,
372 PluginInstallerInfoBarDelegate::PluginInstallerInfoBarDelegate(
373 InfoBarService
* infobar_service
,
374 PluginInstaller
* installer
,
375 scoped_ptr
<PluginMetadata
> plugin_metadata
,
376 const InstallCallback
& callback
,
378 const string16
& message
)
379 : ConfirmInfoBarDelegate(infobar_service
),
380 WeakPluginInstallerObserver(installer
),
381 plugin_metadata_(plugin_metadata
.Pass()),
383 new_install_(new_install
),
387 PluginInstallerInfoBarDelegate::~PluginInstallerInfoBarDelegate() {
390 gfx::Image
* PluginInstallerInfoBarDelegate::GetIcon() const {
391 return &ResourceBundle::GetSharedInstance().GetNativeImageNamed(
392 IDR_INFOBAR_PLUGIN_INSTALL
);
395 string16
PluginInstallerInfoBarDelegate::GetMessageText() const {
399 int PluginInstallerInfoBarDelegate::GetButtons() const {
400 return callback_
.is_null() ? BUTTON_NONE
: BUTTON_OK
;
403 string16
PluginInstallerInfoBarDelegate::GetButtonLabel(
404 InfoBarButton button
) const {
405 DCHECK_EQ(BUTTON_OK
, button
);
406 return l10n_util::GetStringUTF16(IDS_PLUGININSTALLER_INSTALLPLUGIN_BUTTON
);
409 bool PluginInstallerInfoBarDelegate::Accept() {
410 callback_
.Run(plugin_metadata_
.get());
414 string16
PluginInstallerInfoBarDelegate::GetLinkText() const {
415 return l10n_util::GetStringUTF16(
416 new_install_
? IDS_PLUGININSTALLER_PROBLEMSINSTALLING
417 : IDS_PLUGININSTALLER_PROBLEMSUPDATING
);
420 bool PluginInstallerInfoBarDelegate::LinkClicked(
421 WindowOpenDisposition disposition
) {
422 GURL
url(plugin_metadata_
->help_url());
423 if (url
.is_empty()) {
424 url
= google_util::AppendGoogleLocaleParam(GURL(
425 "https://www.google.com/support/chrome/bin/answer.py?answer=142064"));
428 OpenURLParams
params(
430 (disposition
== CURRENT_TAB
) ? NEW_FOREGROUND_TAB
: disposition
,
431 content::PAGE_TRANSITION_LINK
, false);
432 owner()->GetWebContents()->OpenURL(params
);
436 void PluginInstallerInfoBarDelegate::DownloadStarted() {
437 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING
,
438 plugin_metadata_
->name()));
441 void PluginInstallerInfoBarDelegate::DownloadCancelled() {
442 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_CANCELLED
,
443 plugin_metadata_
->name()));
446 void PluginInstallerInfoBarDelegate::DownloadError(const std::string
& message
) {
448 l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR_SHORT
,
449 plugin_metadata_
->name()));
452 void PluginInstallerInfoBarDelegate::DownloadFinished() {
453 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(
454 new_install_
? IDS_PLUGIN_INSTALLING
: IDS_PLUGIN_UPDATING
,
455 plugin_metadata_
->name()));
458 void PluginInstallerInfoBarDelegate::OnlyWeakObserversLeft() {
460 owner()->RemoveInfoBar(this);
463 void PluginInstallerInfoBarDelegate::ReplaceWithInfoBar(
464 const string16
& message
) {
465 // Return early if the message doesn't change. This is important in case the
466 // PluginInstaller is still iterating over its observers (otherwise we would
467 // keep replacing infobar delegates infinitely).
468 if (message_
== message
)
472 Replace(this, installer(), plugin_metadata_
->Clone(), new_install_
, message
);
475 // PluginMetroModeInfoBarDelegate ---------------------------------------------
478 void PluginMetroModeInfoBarDelegate::Create(
479 InfoBarService
* infobar_service
,
480 PluginMetroModeInfoBarDelegate::Mode mode
,
481 const string16
& name
) {
482 infobar_service
->AddInfoBar(scoped_ptr
<InfoBarDelegate
>(
483 new PluginMetroModeInfoBarDelegate(infobar_service
, mode
, name
)));
486 PluginMetroModeInfoBarDelegate::PluginMetroModeInfoBarDelegate(
487 InfoBarService
* infobar_service
,
488 PluginMetroModeInfoBarDelegate::Mode mode
,
489 const string16
& name
)
490 : ConfirmInfoBarDelegate(infobar_service
),
495 PluginMetroModeInfoBarDelegate::~PluginMetroModeInfoBarDelegate() {
498 gfx::Image
* PluginMetroModeInfoBarDelegate::GetIcon() const {
499 return &ResourceBundle::GetSharedInstance().GetNativeImageNamed(
500 IDR_INFOBAR_PLUGIN_INSTALL
);
503 string16
PluginMetroModeInfoBarDelegate::GetMessageText() const {
504 return l10n_util::GetStringFUTF16((mode_
== MISSING_PLUGIN
) ?
505 IDS_METRO_MISSING_PLUGIN_PROMPT
: IDS_METRO_NPAPI_PLUGIN_PROMPT
, name_
);
508 int PluginMetroModeInfoBarDelegate::GetButtons() const {
509 return (mode_
== MISSING_PLUGIN
) ? BUTTON_OK
: (BUTTON_OK
| BUTTON_CANCEL
);
512 string16
PluginMetroModeInfoBarDelegate::GetButtonLabel(
513 InfoBarButton button
) const {
514 if (button
== BUTTON_CANCEL
)
515 return l10n_util::GetStringUTF16(IDS_DONT_ASK_AGAIN_INFOBAR_BUTTON_LABEL
);
516 return l10n_util::GetStringUTF16((mode_
== MISSING_PLUGIN
) ?
517 IDS_WIN8_DESKTOP_RESTART
: IDS_WIN8_RESTART
);
520 bool PluginMetroModeInfoBarDelegate::Accept() {
521 chrome::AttemptRestartWithModeSwitch();
525 bool PluginMetroModeInfoBarDelegate::Cancel() {
526 DCHECK_EQ(DESKTOP_MODE_REQUIRED
, mode_
);
527 content::WebContents
* web_contents
= owner()->GetWebContents();
529 Profile::FromBrowserContext(web_contents
->GetBrowserContext());
530 HostContentSettingsMap
* content_settings
=
531 profile
->GetHostContentSettingsMap();
532 GURL url
= web_contents
->GetURL();
533 content_settings
->SetContentSetting(
534 ContentSettingsPattern::FromURL(url
),
535 ContentSettingsPattern::Wildcard(),
536 CONTENT_SETTINGS_TYPE_METRO_SWITCH_TO_DESKTOP
,
538 CONTENT_SETTING_BLOCK
);
542 string16
PluginMetroModeInfoBarDelegate::GetLinkText() const {
543 return l10n_util::GetStringUTF16(IDS_LEARN_MORE
);
546 bool PluginMetroModeInfoBarDelegate::LinkClicked(
547 WindowOpenDisposition disposition
) {
548 OpenURLParams
params(
549 GURL((mode_
== MISSING_PLUGIN
) ?
550 "https://support.google.com/chrome/?p=ib_display_in_desktop" :
551 "https://support.google.com/chrome/?p=ib_redirect_to_desktop"),
553 (disposition
== CURRENT_TAB
) ? NEW_FOREGROUND_TAB
: disposition
,
554 content::PAGE_TRANSITION_LINK
, false);
555 owner()->GetWebContents()->OpenURL(params
);
558 #endif // defined(OS_WIN)
559 #endif // defined(ENABLE_PLUGIN_INSTALLATION)