Roll src/third_party/WebKit 8b42d1d:744641d (svn 186770:186771)
[chromium-blink-merge.git] / chrome / browser / plugins / plugin_infobar_delegates.cc
blobca8efaf8b64f0a6eee11c85d69958b1e1df05a5e
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/bind.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)
32 #if defined(OS_WIN)
33 #include "base/win/metro.h"
34 #endif
35 #include "chrome/browser/plugins/plugin_installer.h"
36 #endif
38 #if defined(OS_WIN)
39 #include <shellapi.h>
40 #include "ui/base/win/shell.h"
42 #if defined(USE_AURA)
43 #include "ui/aura/remote_window_tree_host_win.h"
44 #endif
45 #endif
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));
66 return 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 ------------------------------------------
87 // static
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),
122 name_(name) {
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();
147 return true;
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();
156 return true;
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,
186 name)))));
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()),
196 message_(message) {
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 {
229 return message_;
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);
249 else
250 installer()->StartInstalling(plugin_url, web_contents);
251 return false;
254 bool OutdatedPluginInfoBarDelegate::Cancel() {
255 content::RecordAction(
256 UserMetricsAction("OutdatedPluginInfobar.AllowThisTime"));
257 LoadBlockedPlugins();
258 return true;
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())
301 return;
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());
315 #if defined(OS_WIN)
316 if (base::win::IsMetroProcess()) {
317 PluginMetroModeInfoBarDelegate::Create(
318 infobar_service, PluginMetroModeInfoBarDelegate::MISSING_PLUGIN, name);
319 return;
321 #endif
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,
329 name)))));
332 void PluginInstallerInfoBarDelegate::Replace(
333 infobars::InfoBar* infobar,
334 PluginInstaller* installer,
335 scoped_ptr<PluginMetadata> plugin_metadata,
336 bool new_install,
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,
344 message))));
347 PluginInstallerInfoBarDelegate::PluginInstallerInfoBarDelegate(
348 PluginInstaller* installer,
349 scoped_ptr<PluginMetadata> plugin_metadata,
350 const InstallCallback& callback,
351 bool new_install,
352 const base::string16& message)
353 : ConfirmInfoBarDelegate(),
354 WeakPluginInstallerObserver(installer),
355 plugin_metadata_(plugin_metadata.Pass()),
356 callback_(callback),
357 new_install_(new_install),
358 message_(message) {
361 PluginInstallerInfoBarDelegate::~PluginInstallerInfoBarDelegate() {
364 int PluginInstallerInfoBarDelegate::GetIconID() const {
365 return IDR_INFOBAR_PLUGIN_INSTALL;
368 base::string16 PluginInstallerInfoBarDelegate::GetMessageText() const {
369 return message_;
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());
384 return false;
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()) {
397 url = GURL(
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));
405 return 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() {
424 ReplaceWithInfoBar(
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())
440 return;
441 Replace(infobar(), installer(), plugin_metadata_->Clone(), new_install_,
442 message);
446 #if defined(OS_WIN)
448 // PluginMetroModeInfoBarDelegate ---------------------------------------------
450 // static
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(),
464 mode_(mode),
465 name_(name) {
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 {
481 return BUTTON_OK;
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))
492 return;
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(
500 shortcut_path, url);
503 bool PluginMetroModeInfoBarDelegate::Accept() {
504 chrome::AttemptRestartToDesktopMode();
505 return true;
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"),
522 content::Referrer(),
523 (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
524 ui::PAGE_TRANSITION_LINK, false));
525 return false;
528 #endif // defined(OS_WIN)
530 #endif // defined(ENABLE_PLUGIN_INSTALLATION)