Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / plugins / plugin_infobar_delegates.cc
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.
4
5 #include "chrome/browser/plugins/plugin_infobar_delegates.h"
6
7 #include "base/bind.h"
8 #include "base/path_service.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/content_settings/host_content_settings_map.h"
11 #include "chrome/browser/google/google_util.h"
12 #include "chrome/browser/infobars/infobar.h"
13 #include "chrome/browser/infobars/infobar_service.h"
14 #include "chrome/browser/lifetime/application_lifetime.h"
15 #include "chrome/browser/plugins/chrome_plugin_service_filter.h"
16 #include "chrome/browser/plugins/plugin_metadata.h"
17 #include "chrome/browser/profiles/profile.h"
18 #include "chrome/browser/shell_integration.h"
19 #include "chrome/browser/ui/browser_commands.h"
20 #include "chrome/common/url_constants.h"
21 #include "content/public/browser/render_process_host.h"
22 #include "content/public/browser/render_view_host.h"
23 #include "content/public/browser/user_metrics.h"
24 #include "content/public/browser/web_contents.h"
25 #include "grit/generated_resources.h"
26 #include "grit/locale_settings.h"
27 #include "grit/theme_resources.h"
28 #include "ui/base/l10n/l10n_util.h"
29
30 #if defined(ENABLE_PLUGIN_INSTALLATION)
31 #if defined(OS_WIN)
32 #include "base/win/metro.h"
33 #endif
34 #include "chrome/browser/plugins/plugin_installer.h"
35 #endif
36
37 #if defined(OS_WIN)
38 #include <shellapi.h>
39 #include "ui/base/win/shell.h"
40
41 #if defined(USE_AURA)
42 #include "ui/aura/remote_window_tree_host_win.h"
43 #endif
44 #endif
45
46 using base::UserMetricsAction;
47
48
49 // PluginInfoBarDelegate ------------------------------------------------------
50
51 PluginInfoBarDelegate::PluginInfoBarDelegate(const std::string& identifier)
52     : ConfirmInfoBarDelegate(),
53       identifier_(identifier) {
54 }
55
56 PluginInfoBarDelegate::~PluginInfoBarDelegate() {
57 }
58
59 bool PluginInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition) {
60   web_contents()->OpenURL(content::OpenURLParams(
61       GURL(GetLearnMoreURL()), content::Referrer(),
62       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
63       content::PAGE_TRANSITION_LINK, false));
64   return false;
65 }
66
67 void PluginInfoBarDelegate::LoadBlockedPlugins() {
68   ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins(
69       web_contents(), true, identifier_);
70 }
71
72 int PluginInfoBarDelegate::GetIconID() const {
73   return IDR_INFOBAR_PLUGIN_INSTALL;
74 }
75
76 base::string16 PluginInfoBarDelegate::GetLinkText() const {
77   return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
78 }
79
80
81 // UnauthorizedPluginInfoBarDelegate ------------------------------------------
82
83 // static
84 void UnauthorizedPluginInfoBarDelegate::Create(
85     InfoBarService* infobar_service,
86     HostContentSettingsMap* content_settings,
87     const base::string16& name,
88     const std::string& identifier) {
89   infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
90       scoped_ptr<ConfirmInfoBarDelegate>(new UnauthorizedPluginInfoBarDelegate(
91           content_settings, name, identifier))));
92
93   content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Shown"));
94   std::string utf8_name(base::UTF16ToUTF8(name));
95   if (utf8_name == PluginMetadata::kJavaGroupName) {
96     content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Shown.Java"));
97   } else if (utf8_name == PluginMetadata::kQuickTimeGroupName) {
98     content::RecordAction(
99         UserMetricsAction("BlockedPluginInfobar.Shown.QuickTime"));
100   } else if (utf8_name == PluginMetadata::kShockwaveGroupName) {
101     content::RecordAction(
102         UserMetricsAction("BlockedPluginInfobar.Shown.Shockwave"));
103   } else if (utf8_name == PluginMetadata::kRealPlayerGroupName) {
104     content::RecordAction(
105         UserMetricsAction("BlockedPluginInfobar.Shown.RealPlayer"));
106   } else if (utf8_name == PluginMetadata::kWindowsMediaPlayerGroupName) {
107     content::RecordAction(
108         UserMetricsAction("BlockedPluginInfobar.Shown.WindowsMediaPlayer"));
109   }
110 }
111
112 UnauthorizedPluginInfoBarDelegate::UnauthorizedPluginInfoBarDelegate(
113     HostContentSettingsMap* content_settings,
114     const base::string16& name,
115     const std::string& identifier)
116     : PluginInfoBarDelegate(identifier),
117       content_settings_(content_settings),
118       name_(name) {
119 }
120
121 UnauthorizedPluginInfoBarDelegate::~UnauthorizedPluginInfoBarDelegate() {
122   content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Closed"));
123 }
124
125 std::string UnauthorizedPluginInfoBarDelegate::GetLearnMoreURL() const {
126   return chrome::kBlockedPluginLearnMoreURL;
127 }
128
129 base::string16 UnauthorizedPluginInfoBarDelegate::GetMessageText() const {
130   return l10n_util::GetStringFUTF16(IDS_PLUGIN_NOT_AUTHORIZED, name_);
131 }
132
133 base::string16 UnauthorizedPluginInfoBarDelegate::GetButtonLabel(
134     InfoBarButton button) const {
135   return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
136       IDS_PLUGIN_ENABLE_TEMPORARILY : IDS_PLUGIN_ENABLE_ALWAYS);
137 }
138
139 bool UnauthorizedPluginInfoBarDelegate::Accept() {
140   content::RecordAction(
141       UserMetricsAction("BlockedPluginInfobar.AllowThisTime"));
142   LoadBlockedPlugins();
143   return true;
144 }
145
146 bool UnauthorizedPluginInfoBarDelegate::Cancel() {
147   content::RecordAction(UserMetricsAction("BlockedPluginInfobar.AlwaysAllow"));
148   const GURL& url = web_contents()->GetURL();
149   content_settings_->AddExceptionForURL(url, url, CONTENT_SETTINGS_TYPE_PLUGINS,
150                                         CONTENT_SETTING_ALLOW);
151   LoadBlockedPlugins();
152   return true;
153 }
154
155 void UnauthorizedPluginInfoBarDelegate::InfoBarDismissed() {
156   content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Dismissed"));
157 }
158
159 bool UnauthorizedPluginInfoBarDelegate::LinkClicked(
160     WindowOpenDisposition disposition) {
161   content::RecordAction(UserMetricsAction("BlockedPluginInfobar.LearnMore"));
162   return PluginInfoBarDelegate::LinkClicked(disposition);
163 }
164
165
166 #if defined(ENABLE_PLUGIN_INSTALLATION)
167
168 // OutdatedPluginInfoBarDelegate ----------------------------------------------
169
170 void OutdatedPluginInfoBarDelegate::Create(
171     InfoBarService* infobar_service,
172     PluginInstaller* installer,
173     scoped_ptr<PluginMetadata> plugin_metadata) {
174   // Copy the name out of |plugin_metadata| now, since the Pass() call below
175   // will make it impossible to get at.
176   base::string16 name(plugin_metadata->name());
177   infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
178       scoped_ptr<ConfirmInfoBarDelegate>(new OutdatedPluginInfoBarDelegate(
179           installer, plugin_metadata.Pass(), l10n_util::GetStringFUTF16(
180               (installer->state() == PluginInstaller::INSTALLER_STATE_IDLE) ?
181                   IDS_PLUGIN_OUTDATED_PROMPT : IDS_PLUGIN_DOWNLOADING,
182               name)))));
183 }
184
185 OutdatedPluginInfoBarDelegate::OutdatedPluginInfoBarDelegate(
186     PluginInstaller* installer,
187     scoped_ptr<PluginMetadata> plugin_metadata,
188     const base::string16& message)
189     : PluginInfoBarDelegate(plugin_metadata->identifier()),
190       WeakPluginInstallerObserver(installer),
191       plugin_metadata_(plugin_metadata.Pass()),
192       message_(message) {
193   content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Shown"));
194   std::string name = base::UTF16ToUTF8(plugin_metadata_->name());
195   if (name == PluginMetadata::kJavaGroupName) {
196     content::RecordAction(
197         UserMetricsAction("OutdatedPluginInfobar.Shown.Java"));
198   } else if (name == PluginMetadata::kQuickTimeGroupName) {
199     content::RecordAction(
200         UserMetricsAction("OutdatedPluginInfobar.Shown.QuickTime"));
201   } else if (name == PluginMetadata::kShockwaveGroupName) {
202     content::RecordAction(
203         UserMetricsAction("OutdatedPluginInfobar.Shown.Shockwave"));
204   } else if (name == PluginMetadata::kRealPlayerGroupName) {
205     content::RecordAction(
206         UserMetricsAction("OutdatedPluginInfobar.Shown.RealPlayer"));
207   } else if (name == PluginMetadata::kSilverlightGroupName) {
208     content::RecordAction(
209         UserMetricsAction("OutdatedPluginInfobar.Shown.Silverlight"));
210   } else if (name == PluginMetadata::kAdobeReaderGroupName) {
211     content::RecordAction(
212         UserMetricsAction("OutdatedPluginInfobar.Shown.Reader"));
213   }
214 }
215
216 OutdatedPluginInfoBarDelegate::~OutdatedPluginInfoBarDelegate() {
217   content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Closed"));
218 }
219
220 std::string OutdatedPluginInfoBarDelegate::GetLearnMoreURL() const {
221   return chrome::kOutdatedPluginLearnMoreURL;
222 }
223
224 base::string16 OutdatedPluginInfoBarDelegate::GetMessageText() const {
225   return message_;
226 }
227
228 base::string16 OutdatedPluginInfoBarDelegate::GetButtonLabel(
229     InfoBarButton button) const {
230   return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
231       IDS_PLUGIN_UPDATE : IDS_PLUGIN_ENABLE_TEMPORARILY);
232 }
233
234 bool OutdatedPluginInfoBarDelegate::Accept() {
235   DCHECK_EQ(PluginInstaller::INSTALLER_STATE_IDLE, installer()->state());
236   content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Update"));
237   // A call to any of |OpenDownloadURL()| or |StartInstalling()| will
238   // result in deleting ourselves. Accordingly, we make sure to
239   // not pass a reference to an object that can go away.
240   GURL plugin_url(plugin_metadata_->plugin_url());
241   if (plugin_metadata_->url_for_display())
242     installer()->OpenDownloadURL(plugin_url, web_contents());
243   else
244     installer()->StartInstalling(plugin_url, web_contents());
245   return false;
246 }
247
248 bool OutdatedPluginInfoBarDelegate::Cancel() {
249   content::RecordAction(
250       UserMetricsAction("OutdatedPluginInfobar.AllowThisTime"));
251   LoadBlockedPlugins();
252   return true;
253 }
254
255 void OutdatedPluginInfoBarDelegate::InfoBarDismissed() {
256   content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Dismissed"));
257 }
258
259 bool OutdatedPluginInfoBarDelegate::LinkClicked(
260     WindowOpenDisposition disposition) {
261   content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.LearnMore"));
262   return PluginInfoBarDelegate::LinkClicked(disposition);
263 }
264
265 void OutdatedPluginInfoBarDelegate::DownloadStarted() {
266   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING,
267                                                 plugin_metadata_->name()));
268 }
269
270 void OutdatedPluginInfoBarDelegate::DownloadError(const std::string& message) {
271   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR_SHORT,
272                                                 plugin_metadata_->name()));
273 }
274
275 void OutdatedPluginInfoBarDelegate::DownloadCancelled() {
276   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_CANCELLED,
277                                                 plugin_metadata_->name()));
278 }
279
280 void OutdatedPluginInfoBarDelegate::DownloadFinished() {
281   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_UPDATING,
282                                                 plugin_metadata_->name()));
283 }
284
285 void OutdatedPluginInfoBarDelegate::OnlyWeakObserversLeft() {
286   infobar()->RemoveSelf();
287 }
288
289 void OutdatedPluginInfoBarDelegate::ReplaceWithInfoBar(
290     const base::string16& message) {
291   // Return early if the message doesn't change. This is important in case the
292   // PluginInstaller is still iterating over its observers (otherwise we would
293   // keep replacing infobar delegates infinitely).
294   if ((message_ == message) || !infobar()->owner())
295     return;
296   PluginInstallerInfoBarDelegate::Replace(
297       infobar(), installer(), plugin_metadata_->Clone(), false, message);
298 }
299
300
301 // PluginInstallerInfoBarDelegate ---------------------------------------------
302
303 void PluginInstallerInfoBarDelegate::Create(
304     InfoBarService* infobar_service,
305     PluginInstaller* installer,
306     scoped_ptr<PluginMetadata> plugin_metadata,
307     const InstallCallback& callback) {
308   base::string16 name(plugin_metadata->name());
309 #if defined(OS_WIN)
310   if (base::win::IsMetroProcess()) {
311     PluginMetroModeInfoBarDelegate::Create(
312         infobar_service, PluginMetroModeInfoBarDelegate::MISSING_PLUGIN, name);
313     return;
314   }
315 #endif
316   infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
317       scoped_ptr<ConfirmInfoBarDelegate>(new PluginInstallerInfoBarDelegate(
318           installer, plugin_metadata.Pass(), callback, true,
319           l10n_util::GetStringFUTF16(
320               (installer->state() == PluginInstaller::INSTALLER_STATE_IDLE) ?
321                   IDS_PLUGININSTALLER_INSTALLPLUGIN_PROMPT :
322                   IDS_PLUGIN_DOWNLOADING,
323               name)))));
324 }
325
326
327 void PluginInstallerInfoBarDelegate::Replace(
328     InfoBar* infobar,
329     PluginInstaller* installer,
330     scoped_ptr<PluginMetadata> plugin_metadata,
331     bool new_install,
332     const base::string16& message) {
333   DCHECK(infobar->owner());
334   infobar->owner()->ReplaceInfoBar(infobar,
335       ConfirmInfoBarDelegate::CreateInfoBar(scoped_ptr<ConfirmInfoBarDelegate>(
336           new PluginInstallerInfoBarDelegate(
337               installer, plugin_metadata.Pass(),
338               PluginInstallerInfoBarDelegate::InstallCallback(), new_install,
339               message))));
340 }
341
342 PluginInstallerInfoBarDelegate::PluginInstallerInfoBarDelegate(
343     PluginInstaller* installer,
344     scoped_ptr<PluginMetadata> plugin_metadata,
345     const InstallCallback& callback,
346     bool new_install,
347     const base::string16& message)
348     : ConfirmInfoBarDelegate(),
349       WeakPluginInstallerObserver(installer),
350       plugin_metadata_(plugin_metadata.Pass()),
351       callback_(callback),
352       new_install_(new_install),
353       message_(message) {
354 }
355
356 PluginInstallerInfoBarDelegate::~PluginInstallerInfoBarDelegate() {
357 }
358
359 int PluginInstallerInfoBarDelegate::GetIconID() const {
360   return IDR_INFOBAR_PLUGIN_INSTALL;
361 }
362
363 base::string16 PluginInstallerInfoBarDelegate::GetMessageText() const {
364   return message_;
365 }
366
367 int PluginInstallerInfoBarDelegate::GetButtons() const {
368   return callback_.is_null() ? BUTTON_NONE : BUTTON_OK;
369 }
370
371 base::string16 PluginInstallerInfoBarDelegate::GetButtonLabel(
372     InfoBarButton button) const {
373   DCHECK_EQ(BUTTON_OK, button);
374   return l10n_util::GetStringUTF16(IDS_PLUGININSTALLER_INSTALLPLUGIN_BUTTON);
375 }
376
377 bool PluginInstallerInfoBarDelegate::Accept() {
378   callback_.Run(plugin_metadata_.get());
379   return false;
380 }
381
382 base::string16 PluginInstallerInfoBarDelegate::GetLinkText() const {
383   return l10n_util::GetStringUTF16(new_install_ ?
384       IDS_PLUGININSTALLER_PROBLEMSINSTALLING :
385       IDS_PLUGININSTALLER_PROBLEMSUPDATING);
386 }
387
388 bool PluginInstallerInfoBarDelegate::LinkClicked(
389     WindowOpenDisposition disposition) {
390   GURL url(plugin_metadata_->help_url());
391   if (url.is_empty()) {
392     url = google_util::AppendGoogleLocaleParam(GURL(
393         "https://www.google.com/support/chrome/bin/answer.py?answer=142064"));
394   }
395   web_contents()->OpenURL(content::OpenURLParams(
396       url, content::Referrer(),
397       (disposition == CURRENT_TAB) ? NEW_FOREGROUND_TAB : disposition,
398       content::PAGE_TRANSITION_LINK, false));
399   return false;
400 }
401
402 void PluginInstallerInfoBarDelegate::DownloadStarted() {
403   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING,
404                                                 plugin_metadata_->name()));
405 }
406
407 void PluginInstallerInfoBarDelegate::DownloadCancelled() {
408   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_CANCELLED,
409                                                 plugin_metadata_->name()));
410 }
411
412 void PluginInstallerInfoBarDelegate::DownloadError(const std::string& message) {
413   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR_SHORT,
414                                                 plugin_metadata_->name()));
415 }
416
417 void PluginInstallerInfoBarDelegate::DownloadFinished() {
418   ReplaceWithInfoBar(
419       l10n_util::GetStringFUTF16(
420           new_install_ ? IDS_PLUGIN_INSTALLING : IDS_PLUGIN_UPDATING,
421           plugin_metadata_->name()));
422 }
423
424 void PluginInstallerInfoBarDelegate::OnlyWeakObserversLeft() {
425   infobar()->RemoveSelf();
426 }
427
428 void PluginInstallerInfoBarDelegate::ReplaceWithInfoBar(
429     const base::string16& message) {
430   // Return early if the message doesn't change. This is important in case the
431   // PluginInstaller is still iterating over its observers (otherwise we would
432   // keep replacing infobar delegates infinitely).
433   if ((message_ == message) || !infobar()->owner())
434     return;
435   Replace(infobar(), installer(), plugin_metadata_->Clone(), new_install_,
436           message);
437 }
438
439
440 #if defined(OS_WIN)
441
442 // PluginMetroModeInfoBarDelegate ---------------------------------------------
443
444 // static
445 void PluginMetroModeInfoBarDelegate::Create(
446     InfoBarService* infobar_service,
447     PluginMetroModeInfoBarDelegate::Mode mode,
448     const base::string16& name) {
449   infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
450       scoped_ptr<ConfirmInfoBarDelegate>(
451           new PluginMetroModeInfoBarDelegate(mode, name))));
452 }
453
454 PluginMetroModeInfoBarDelegate::PluginMetroModeInfoBarDelegate(
455     PluginMetroModeInfoBarDelegate::Mode mode,
456     const base::string16& name)
457     : ConfirmInfoBarDelegate(),
458       mode_(mode),
459       name_(name) {
460 }
461
462 PluginMetroModeInfoBarDelegate::~PluginMetroModeInfoBarDelegate() {
463 }
464
465 int PluginMetroModeInfoBarDelegate::GetIconID() const {
466   return IDR_INFOBAR_PLUGIN_INSTALL;
467 }
468
469 base::string16 PluginMetroModeInfoBarDelegate::GetMessageText() const {
470   return l10n_util::GetStringFUTF16((mode_ == MISSING_PLUGIN) ?
471       IDS_METRO_MISSING_PLUGIN_PROMPT : IDS_METRO_NPAPI_PLUGIN_PROMPT, name_);
472 }
473
474 int PluginMetroModeInfoBarDelegate::GetButtons() const {
475   return BUTTON_OK;
476 }
477
478 base::string16 PluginMetroModeInfoBarDelegate::GetButtonLabel(
479     InfoBarButton button) const {
480 #if defined(USE_AURA) && defined(USE_ASH)
481   return l10n_util::GetStringUTF16(IDS_WIN8_DESKTOP_RESTART);
482 #else
483   return l10n_util::GetStringUTF16((mode_ == MISSING_PLUGIN) ?
484       IDS_WIN8_DESKTOP_RESTART : IDS_WIN8_DESKTOP_OPEN);
485 #endif
486 }
487
488 #if defined(USE_AURA) && defined(USE_ASH)
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));
495
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);
501 }
502 #endif
503
504 bool PluginMetroModeInfoBarDelegate::Accept() {
505   chrome::AttemptRestartToDesktopMode();
506   return true;
507 }
508
509 base::string16 PluginMetroModeInfoBarDelegate::GetLinkText() const {
510   return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
511 }
512
513 bool PluginMetroModeInfoBarDelegate::LinkClicked(
514     WindowOpenDisposition disposition) {
515   // TODO(shrikant): We may need to change language a little at following
516   // support URLs. With new approach we will just restart for both missing
517   // and not missing mode.
518   web_contents()->OpenURL(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       content::PAGE_TRANSITION_LINK, false));
525   return false;
526 }
527
528 #endif  // defined(OS_WIN)
529
530 #endif  // defined(ENABLE_PLUGIN_INSTALLATION)