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"
8 #include "base/path_service.h"
9 #include "base/strings/utf_string_conversions.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/browser/shell_integration.h"
16 #include "chrome/browser/ui/browser_commands.h"
17 #include "chrome/common/url_constants.h"
18 #include "chrome/grit/generated_resources.h"
19 #include "chrome/grit/locale_settings.h"
20 #include "components/content_settings/core/browser/host_content_settings_map.h"
21 #include "components/google/core/browser/google_util.h"
22 #include "components/infobars/core/infobar.h"
23 #include "content/public/browser/render_process_host.h"
24 #include "content/public/browser/render_view_host.h"
25 #include "content/public/browser/user_metrics.h"
26 #include "content/public/browser/web_contents.h"
27 #include "grit/components_strings.h"
28 #include "grit/theme_resources.h"
29 #include "ui/base/l10n/l10n_util.h"
31 #if defined(ENABLE_PLUGIN_INSTALLATION)
33 #include "base/win/metro.h"
35 #include "chrome/browser/plugins/plugin_installer.h"
40 #include "ui/base/win/shell.h"
43 #include "ui/aura/remote_window_tree_host_win.h"
47 using base::UserMetricsAction
;
50 // PluginInfoBarDelegate ------------------------------------------------------
52 PluginInfoBarDelegate::PluginInfoBarDelegate(const std::string
& identifier
)
53 : ConfirmInfoBarDelegate(),
54 identifier_(identifier
) {
57 PluginInfoBarDelegate::~PluginInfoBarDelegate() {
60 bool PluginInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition
) {
61 InfoBarService::WebContentsFromInfoBar(infobar())->OpenURL(
62 content::OpenURLParams(
63 GURL(GetLearnMoreURL()), content::Referrer(),
64 (disposition
== CURRENT_TAB
) ? NEW_FOREGROUND_TAB
: disposition
,
65 ui::PAGE_TRANSITION_LINK
, false));
69 void PluginInfoBarDelegate::LoadBlockedPlugins() {
70 content::WebContents
* web_contents
=
71 InfoBarService::WebContentsFromInfoBar(infobar());
72 ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins(
73 web_contents
, true, identifier_
);
76 int PluginInfoBarDelegate::GetIconID() const {
77 return IDR_INFOBAR_PLUGIN_INSTALL
;
80 base::string16
PluginInfoBarDelegate::GetLinkText() const {
81 return l10n_util::GetStringUTF16(IDS_LEARN_MORE
);
85 // UnauthorizedPluginInfoBarDelegate ------------------------------------------
88 void UnauthorizedPluginInfoBarDelegate::Create(
89 InfoBarService
* infobar_service
,
90 HostContentSettingsMap
* content_settings
,
91 const base::string16
& name
,
92 const std::string
& identifier
) {
93 infobar_service
->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
94 scoped_ptr
<ConfirmInfoBarDelegate
>(new UnauthorizedPluginInfoBarDelegate(
95 content_settings
, name
, identifier
))));
97 content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Shown"));
98 std::string
utf8_name(base::UTF16ToUTF8(name
));
99 if (utf8_name
== PluginMetadata::kJavaGroupName
) {
100 content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Shown.Java"));
101 } else if (utf8_name
== PluginMetadata::kQuickTimeGroupName
) {
102 content::RecordAction(
103 UserMetricsAction("BlockedPluginInfobar.Shown.QuickTime"));
104 } else if (utf8_name
== PluginMetadata::kShockwaveGroupName
) {
105 content::RecordAction(
106 UserMetricsAction("BlockedPluginInfobar.Shown.Shockwave"));
107 } else if (utf8_name
== PluginMetadata::kRealPlayerGroupName
) {
108 content::RecordAction(
109 UserMetricsAction("BlockedPluginInfobar.Shown.RealPlayer"));
110 } else if (utf8_name
== PluginMetadata::kWindowsMediaPlayerGroupName
) {
111 content::RecordAction(
112 UserMetricsAction("BlockedPluginInfobar.Shown.WindowsMediaPlayer"));
116 UnauthorizedPluginInfoBarDelegate::UnauthorizedPluginInfoBarDelegate(
117 HostContentSettingsMap
* content_settings
,
118 const base::string16
& name
,
119 const std::string
& identifier
)
120 : PluginInfoBarDelegate(identifier
),
121 content_settings_(content_settings
),
125 UnauthorizedPluginInfoBarDelegate::~UnauthorizedPluginInfoBarDelegate() {
126 content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Closed"));
129 std::string
UnauthorizedPluginInfoBarDelegate::GetLearnMoreURL() const {
130 return chrome::kBlockedPluginLearnMoreURL
;
133 base::string16
UnauthorizedPluginInfoBarDelegate::GetMessageText() const {
134 return l10n_util::GetStringFUTF16(IDS_PLUGIN_NOT_AUTHORIZED
, name_
);
137 base::string16
UnauthorizedPluginInfoBarDelegate::GetButtonLabel(
138 InfoBarButton button
) const {
139 return l10n_util::GetStringUTF16((button
== BUTTON_OK
) ?
140 IDS_PLUGIN_ENABLE_TEMPORARILY
: IDS_PLUGIN_ENABLE_ALWAYS
);
143 bool UnauthorizedPluginInfoBarDelegate::Accept() {
144 content::RecordAction(
145 UserMetricsAction("BlockedPluginInfobar.AllowThisTime"));
146 LoadBlockedPlugins();
150 bool UnauthorizedPluginInfoBarDelegate::Cancel() {
151 content::RecordAction(UserMetricsAction("BlockedPluginInfobar.AlwaysAllow"));
152 const GURL
& url
= InfoBarService::WebContentsFromInfoBar(infobar())->GetURL();
153 content_settings_
->AddExceptionForURL(url
, url
, CONTENT_SETTINGS_TYPE_PLUGINS
,
154 CONTENT_SETTING_ALLOW
);
155 LoadBlockedPlugins();
159 void UnauthorizedPluginInfoBarDelegate::InfoBarDismissed() {
160 content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Dismissed"));
163 bool UnauthorizedPluginInfoBarDelegate::LinkClicked(
164 WindowOpenDisposition disposition
) {
165 content::RecordAction(UserMetricsAction("BlockedPluginInfobar.LearnMore"));
166 return PluginInfoBarDelegate::LinkClicked(disposition
);
170 #if defined(ENABLE_PLUGIN_INSTALLATION)
172 // OutdatedPluginInfoBarDelegate ----------------------------------------------
174 void OutdatedPluginInfoBarDelegate::Create(
175 InfoBarService
* infobar_service
,
176 PluginInstaller
* installer
,
177 scoped_ptr
<PluginMetadata
> plugin_metadata
) {
178 // Copy the name out of |plugin_metadata| now, since the Pass() call below
179 // will make it impossible to get at.
180 base::string16
name(plugin_metadata
->name());
181 infobar_service
->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
182 scoped_ptr
<ConfirmInfoBarDelegate
>(new OutdatedPluginInfoBarDelegate(
183 installer
, plugin_metadata
.Pass(), l10n_util::GetStringFUTF16(
184 (installer
->state() == PluginInstaller::INSTALLER_STATE_IDLE
) ?
185 IDS_PLUGIN_OUTDATED_PROMPT
: IDS_PLUGIN_DOWNLOADING
,
189 OutdatedPluginInfoBarDelegate::OutdatedPluginInfoBarDelegate(
190 PluginInstaller
* installer
,
191 scoped_ptr
<PluginMetadata
> plugin_metadata
,
192 const base::string16
& message
)
193 : PluginInfoBarDelegate(plugin_metadata
->identifier()),
194 WeakPluginInstallerObserver(installer
),
195 plugin_metadata_(plugin_metadata
.Pass()),
197 content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Shown"));
198 std::string name
= base::UTF16ToUTF8(plugin_metadata_
->name());
199 if (name
== PluginMetadata::kJavaGroupName
) {
200 content::RecordAction(
201 UserMetricsAction("OutdatedPluginInfobar.Shown.Java"));
202 } else if (name
== PluginMetadata::kQuickTimeGroupName
) {
203 content::RecordAction(
204 UserMetricsAction("OutdatedPluginInfobar.Shown.QuickTime"));
205 } else if (name
== PluginMetadata::kShockwaveGroupName
) {
206 content::RecordAction(
207 UserMetricsAction("OutdatedPluginInfobar.Shown.Shockwave"));
208 } else if (name
== PluginMetadata::kRealPlayerGroupName
) {
209 content::RecordAction(
210 UserMetricsAction("OutdatedPluginInfobar.Shown.RealPlayer"));
211 } else if (name
== PluginMetadata::kSilverlightGroupName
) {
212 content::RecordAction(
213 UserMetricsAction("OutdatedPluginInfobar.Shown.Silverlight"));
214 } else if (name
== PluginMetadata::kAdobeReaderGroupName
) {
215 content::RecordAction(
216 UserMetricsAction("OutdatedPluginInfobar.Shown.Reader"));
220 OutdatedPluginInfoBarDelegate::~OutdatedPluginInfoBarDelegate() {
221 content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Closed"));
224 std::string
OutdatedPluginInfoBarDelegate::GetLearnMoreURL() const {
225 return chrome::kOutdatedPluginLearnMoreURL
;
228 base::string16
OutdatedPluginInfoBarDelegate::GetMessageText() const {
232 base::string16
OutdatedPluginInfoBarDelegate::GetButtonLabel(
233 InfoBarButton button
) const {
234 return l10n_util::GetStringUTF16((button
== BUTTON_OK
) ?
235 IDS_PLUGIN_UPDATE
: IDS_PLUGIN_ENABLE_TEMPORARILY
);
238 bool OutdatedPluginInfoBarDelegate::Accept() {
239 DCHECK_EQ(PluginInstaller::INSTALLER_STATE_IDLE
, installer()->state());
240 content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Update"));
241 // A call to any of |OpenDownloadURL()| or |StartInstalling()| will
242 // result in deleting ourselves. Accordingly, we make sure to
243 // not pass a reference to an object that can go away.
244 GURL
plugin_url(plugin_metadata_
->plugin_url());
245 content::WebContents
* web_contents
=
246 InfoBarService::WebContentsFromInfoBar(infobar());
247 if (plugin_metadata_
->url_for_display())
248 installer()->OpenDownloadURL(plugin_url
, web_contents
);
250 installer()->StartInstalling(plugin_url
, web_contents
);
254 bool OutdatedPluginInfoBarDelegate::Cancel() {
255 content::RecordAction(
256 UserMetricsAction("OutdatedPluginInfobar.AllowThisTime"));
257 LoadBlockedPlugins();
261 void OutdatedPluginInfoBarDelegate::InfoBarDismissed() {
262 content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Dismissed"));
265 bool OutdatedPluginInfoBarDelegate::LinkClicked(
266 WindowOpenDisposition disposition
) {
267 content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.LearnMore"));
268 return PluginInfoBarDelegate::LinkClicked(disposition
);
271 void OutdatedPluginInfoBarDelegate::DownloadStarted() {
272 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING
,
273 plugin_metadata_
->name()));
276 void OutdatedPluginInfoBarDelegate::DownloadError(const std::string
& message
) {
277 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR_SHORT
,
278 plugin_metadata_
->name()));
281 void OutdatedPluginInfoBarDelegate::DownloadCancelled() {
282 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_CANCELLED
,
283 plugin_metadata_
->name()));
286 void OutdatedPluginInfoBarDelegate::DownloadFinished() {
287 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_UPDATING
,
288 plugin_metadata_
->name()));
291 void OutdatedPluginInfoBarDelegate::OnlyWeakObserversLeft() {
292 infobar()->RemoveSelf();
295 void OutdatedPluginInfoBarDelegate::ReplaceWithInfoBar(
296 const base::string16
& message
) {
297 // Return early if the message doesn't change. This is important in case the
298 // PluginInstaller is still iterating over its observers (otherwise we would
299 // keep replacing infobar delegates infinitely).
300 if ((message_
== message
) || !infobar()->owner())
302 PluginInstallerInfoBarDelegate::Replace(
303 infobar(), installer(), plugin_metadata_
->Clone(), false, message
);
307 // PluginInstallerInfoBarDelegate ---------------------------------------------
309 void PluginInstallerInfoBarDelegate::Create(
310 InfoBarService
* infobar_service
,
311 PluginInstaller
* installer
,
312 scoped_ptr
<PluginMetadata
> plugin_metadata
,
313 const InstallCallback
& callback
) {
314 base::string16
name(plugin_metadata
->name());
316 if (base::win::IsMetroProcess()) {
317 PluginMetroModeInfoBarDelegate::Create(
318 infobar_service
, PluginMetroModeInfoBarDelegate::MISSING_PLUGIN
, name
);
322 infobar_service
->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
323 scoped_ptr
<ConfirmInfoBarDelegate
>(new PluginInstallerInfoBarDelegate(
324 installer
, plugin_metadata
.Pass(), callback
, true,
325 l10n_util::GetStringFUTF16(
326 (installer
->state() == PluginInstaller::INSTALLER_STATE_IDLE
) ?
327 IDS_PLUGININSTALLER_INSTALLPLUGIN_PROMPT
:
328 IDS_PLUGIN_DOWNLOADING
,
332 void PluginInstallerInfoBarDelegate::Replace(
333 infobars::InfoBar
* infobar
,
334 PluginInstaller
* installer
,
335 scoped_ptr
<PluginMetadata
> plugin_metadata
,
337 const base::string16
& message
) {
338 DCHECK(infobar
->owner());
339 infobar
->owner()->ReplaceInfoBar(infobar
,
340 ConfirmInfoBarDelegate::CreateInfoBar(scoped_ptr
<ConfirmInfoBarDelegate
>(
341 new PluginInstallerInfoBarDelegate(
342 installer
, plugin_metadata
.Pass(),
343 PluginInstallerInfoBarDelegate::InstallCallback(), new_install
,
347 PluginInstallerInfoBarDelegate::PluginInstallerInfoBarDelegate(
348 PluginInstaller
* installer
,
349 scoped_ptr
<PluginMetadata
> plugin_metadata
,
350 const InstallCallback
& callback
,
352 const base::string16
& message
)
353 : ConfirmInfoBarDelegate(),
354 WeakPluginInstallerObserver(installer
),
355 plugin_metadata_(plugin_metadata
.Pass()),
357 new_install_(new_install
),
361 PluginInstallerInfoBarDelegate::~PluginInstallerInfoBarDelegate() {
364 int PluginInstallerInfoBarDelegate::GetIconID() const {
365 return IDR_INFOBAR_PLUGIN_INSTALL
;
368 base::string16
PluginInstallerInfoBarDelegate::GetMessageText() const {
372 int PluginInstallerInfoBarDelegate::GetButtons() const {
373 return callback_
.is_null() ? BUTTON_NONE
: BUTTON_OK
;
376 base::string16
PluginInstallerInfoBarDelegate::GetButtonLabel(
377 InfoBarButton button
) const {
378 DCHECK_EQ(BUTTON_OK
, button
);
379 return l10n_util::GetStringUTF16(IDS_PLUGININSTALLER_INSTALLPLUGIN_BUTTON
);
382 bool PluginInstallerInfoBarDelegate::Accept() {
383 callback_
.Run(plugin_metadata_
.get());
387 base::string16
PluginInstallerInfoBarDelegate::GetLinkText() const {
388 return l10n_util::GetStringUTF16(new_install_
?
389 IDS_PLUGININSTALLER_PROBLEMSINSTALLING
:
390 IDS_PLUGININSTALLER_PROBLEMSUPDATING
);
393 bool PluginInstallerInfoBarDelegate::LinkClicked(
394 WindowOpenDisposition disposition
) {
395 GURL
url(plugin_metadata_
->help_url());
396 if (url
.is_empty()) {
398 "https://www.google.com/support/chrome/bin/answer.py?answer=142064");
400 InfoBarService::WebContentsFromInfoBar(infobar())->OpenURL(
401 content::OpenURLParams(
402 url
, content::Referrer(),
403 (disposition
== CURRENT_TAB
) ? NEW_FOREGROUND_TAB
: disposition
,
404 ui::PAGE_TRANSITION_LINK
, false));
408 void PluginInstallerInfoBarDelegate::DownloadStarted() {
409 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING
,
410 plugin_metadata_
->name()));
413 void PluginInstallerInfoBarDelegate::DownloadCancelled() {
414 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_CANCELLED
,
415 plugin_metadata_
->name()));
418 void PluginInstallerInfoBarDelegate::DownloadError(const std::string
& message
) {
419 ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR_SHORT
,
420 plugin_metadata_
->name()));
423 void PluginInstallerInfoBarDelegate::DownloadFinished() {
425 l10n_util::GetStringFUTF16(
426 new_install_
? IDS_PLUGIN_INSTALLING
: IDS_PLUGIN_UPDATING
,
427 plugin_metadata_
->name()));
430 void PluginInstallerInfoBarDelegate::OnlyWeakObserversLeft() {
431 infobar()->RemoveSelf();
434 void PluginInstallerInfoBarDelegate::ReplaceWithInfoBar(
435 const base::string16
& message
) {
436 // Return early if the message doesn't change. This is important in case the
437 // PluginInstaller is still iterating over its observers (otherwise we would
438 // keep replacing infobar delegates infinitely).
439 if ((message_
== message
) || !infobar()->owner())
441 Replace(infobar(), installer(), plugin_metadata_
->Clone(), new_install_
,
448 // PluginMetroModeInfoBarDelegate ---------------------------------------------
451 void PluginMetroModeInfoBarDelegate::Create(
452 InfoBarService
* infobar_service
,
453 PluginMetroModeInfoBarDelegate::Mode mode
,
454 const base::string16
& name
) {
455 infobar_service
->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
456 scoped_ptr
<ConfirmInfoBarDelegate
>(
457 new PluginMetroModeInfoBarDelegate(mode
, name
))));
460 PluginMetroModeInfoBarDelegate::PluginMetroModeInfoBarDelegate(
461 PluginMetroModeInfoBarDelegate::Mode mode
,
462 const base::string16
& name
)
463 : ConfirmInfoBarDelegate(),
468 PluginMetroModeInfoBarDelegate::~PluginMetroModeInfoBarDelegate() {
471 int PluginMetroModeInfoBarDelegate::GetIconID() const {
472 return IDR_INFOBAR_PLUGIN_INSTALL
;
475 base::string16
PluginMetroModeInfoBarDelegate::GetMessageText() const {
476 return l10n_util::GetStringFUTF16((mode_
== MISSING_PLUGIN
) ?
477 IDS_METRO_MISSING_PLUGIN_PROMPT
: IDS_METRO_NPAPI_PLUGIN_PROMPT
, name_
);
480 int PluginMetroModeInfoBarDelegate::GetButtons() const {
484 base::string16
PluginMetroModeInfoBarDelegate::GetButtonLabel(
485 InfoBarButton button
) const {
486 return l10n_util::GetStringUTF16(IDS_WIN_DESKTOP_RESTART
);
489 void LaunchDesktopInstanceHelper(const base::string16
& url
) {
490 base::FilePath exe_path
;
491 if (!PathService::Get(base::FILE_EXE
, &exe_path
))
493 base::FilePath
shortcut_path(
494 ShellIntegration::GetStartMenuShortcut(exe_path
));
496 // Actually launching the process needs to happen in the metro viewer,
497 // otherwise it won't automatically transition to desktop. So we have
498 // to send an IPC to the viewer to do the ShellExecute.
499 aura::RemoteWindowTreeHostWin::Instance()->HandleOpenURLOnDesktop(
503 bool PluginMetroModeInfoBarDelegate::Accept() {
504 chrome::AttemptRestartToDesktopMode();
508 base::string16
PluginMetroModeInfoBarDelegate::GetLinkText() const {
509 return l10n_util::GetStringUTF16(IDS_LEARN_MORE
);
512 bool PluginMetroModeInfoBarDelegate::LinkClicked(
513 WindowOpenDisposition disposition
) {
514 // TODO(shrikant): We may need to change language a little at following
515 // support URLs. With new approach we will just restart for both missing
516 // and not missing mode.
517 InfoBarService::WebContentsFromInfoBar(infobar())->OpenURL(
518 content::OpenURLParams(
519 GURL((mode_
== MISSING_PLUGIN
) ?
520 "https://support.google.com/chrome/?p=ib_display_in_desktop" :
521 "https://support.google.com/chrome/?p=ib_redirect_to_desktop"),
523 (disposition
== CURRENT_TAB
) ? NEW_FOREGROUND_TAB
: disposition
,
524 ui::PAGE_TRANSITION_LINK
, false));
528 #endif // defined(OS_WIN)
530 #endif // defined(ENABLE_PLUGIN_INSTALLATION)