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