Update To 11.40.268.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/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"
30
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
37
38 #if defined(OS_WIN)
39 #include <shellapi.h>
40 #include "ui/base/win/shell.h"
41
42 #if defined(USE_AURA)
43 #include "ui/aura/remote_window_tree_host_win.h"
44 #endif
45 #endif
46
47 using base::UserMetricsAction;
48
49
50 // PluginInfoBarDelegate ------------------------------------------------------
51
52 PluginInfoBarDelegate::PluginInfoBarDelegate(const std::string& identifier)
53     : ConfirmInfoBarDelegate(),
54       identifier_(identifier) {
55 }
56
57 PluginInfoBarDelegate::~PluginInfoBarDelegate() {
58 }
59
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;
67 }
68
69 void PluginInfoBarDelegate::LoadBlockedPlugins() {
70   content::WebContents* web_contents =
71       InfoBarService::WebContentsFromInfoBar(infobar());
72   ChromePluginServiceFilter::GetInstance()->AuthorizeAllPlugins(
73       web_contents, true, identifier_);
74 }
75
76 int PluginInfoBarDelegate::GetIconID() const {
77   return IDR_INFOBAR_PLUGIN_INSTALL;
78 }
79
80 base::string16 PluginInfoBarDelegate::GetLinkText() const {
81   return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
82 }
83
84
85 // UnauthorizedPluginInfoBarDelegate ------------------------------------------
86
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))));
96
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"));
113   }
114 }
115
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) {
123 }
124
125 UnauthorizedPluginInfoBarDelegate::~UnauthorizedPluginInfoBarDelegate() {
126   content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Closed"));
127 }
128
129 std::string UnauthorizedPluginInfoBarDelegate::GetLearnMoreURL() const {
130   return chrome::kBlockedPluginLearnMoreURL;
131 }
132
133 base::string16 UnauthorizedPluginInfoBarDelegate::GetMessageText() const {
134   return l10n_util::GetStringFUTF16(IDS_PLUGIN_NOT_AUTHORIZED, name_);
135 }
136
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);
141 }
142
143 bool UnauthorizedPluginInfoBarDelegate::Accept() {
144   content::RecordAction(
145       UserMetricsAction("BlockedPluginInfobar.AllowThisTime"));
146   LoadBlockedPlugins();
147   return true;
148 }
149
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;
157 }
158
159 void UnauthorizedPluginInfoBarDelegate::InfoBarDismissed() {
160   content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Dismissed"));
161 }
162
163 bool UnauthorizedPluginInfoBarDelegate::LinkClicked(
164     WindowOpenDisposition disposition) {
165   content::RecordAction(UserMetricsAction("BlockedPluginInfobar.LearnMore"));
166   return PluginInfoBarDelegate::LinkClicked(disposition);
167 }
168
169
170 #if defined(ENABLE_PLUGIN_INSTALLATION)
171
172 // OutdatedPluginInfoBarDelegate ----------------------------------------------
173
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)))));
187 }
188
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"));
217   }
218 }
219
220 OutdatedPluginInfoBarDelegate::~OutdatedPluginInfoBarDelegate() {
221   content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Closed"));
222 }
223
224 std::string OutdatedPluginInfoBarDelegate::GetLearnMoreURL() const {
225   return chrome::kOutdatedPluginLearnMoreURL;
226 }
227
228 base::string16 OutdatedPluginInfoBarDelegate::GetMessageText() const {
229   return message_;
230 }
231
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);
236 }
237
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;
252 }
253
254 bool OutdatedPluginInfoBarDelegate::Cancel() {
255   content::RecordAction(
256       UserMetricsAction("OutdatedPluginInfobar.AllowThisTime"));
257   LoadBlockedPlugins();
258   return true;
259 }
260
261 void OutdatedPluginInfoBarDelegate::InfoBarDismissed() {
262   content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Dismissed"));
263 }
264
265 bool OutdatedPluginInfoBarDelegate::LinkClicked(
266     WindowOpenDisposition disposition) {
267   content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.LearnMore"));
268   return PluginInfoBarDelegate::LinkClicked(disposition);
269 }
270
271 void OutdatedPluginInfoBarDelegate::DownloadStarted() {
272   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING,
273                                                 plugin_metadata_->name()));
274 }
275
276 void OutdatedPluginInfoBarDelegate::DownloadError(const std::string& message) {
277   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR_SHORT,
278                                                 plugin_metadata_->name()));
279 }
280
281 void OutdatedPluginInfoBarDelegate::DownloadCancelled() {
282   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_CANCELLED,
283                                                 plugin_metadata_->name()));
284 }
285
286 void OutdatedPluginInfoBarDelegate::DownloadFinished() {
287   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_UPDATING,
288                                                 plugin_metadata_->name()));
289 }
290
291 void OutdatedPluginInfoBarDelegate::OnlyWeakObserversLeft() {
292   infobar()->RemoveSelf();
293 }
294
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);
304 }
305
306
307 // PluginInstallerInfoBarDelegate ---------------------------------------------
308
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;
320   }
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)))));
330 }
331
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))));
345 }
346
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) {
359 }
360
361 PluginInstallerInfoBarDelegate::~PluginInstallerInfoBarDelegate() {
362 }
363
364 int PluginInstallerInfoBarDelegate::GetIconID() const {
365   return IDR_INFOBAR_PLUGIN_INSTALL;
366 }
367
368 base::string16 PluginInstallerInfoBarDelegate::GetMessageText() const {
369   return message_;
370 }
371
372 int PluginInstallerInfoBarDelegate::GetButtons() const {
373   return callback_.is_null() ? BUTTON_NONE : BUTTON_OK;
374 }
375
376 base::string16 PluginInstallerInfoBarDelegate::GetButtonLabel(
377     InfoBarButton button) const {
378   DCHECK_EQ(BUTTON_OK, button);
379   return l10n_util::GetStringUTF16(IDS_PLUGININSTALLER_INSTALLPLUGIN_BUTTON);
380 }
381
382 bool PluginInstallerInfoBarDelegate::Accept() {
383   callback_.Run(plugin_metadata_.get());
384   return false;
385 }
386
387 base::string16 PluginInstallerInfoBarDelegate::GetLinkText() const {
388   return l10n_util::GetStringUTF16(new_install_ ?
389       IDS_PLUGININSTALLER_PROBLEMSINSTALLING :
390       IDS_PLUGININSTALLER_PROBLEMSUPDATING);
391 }
392
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");
399   }
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;
406 }
407
408 void PluginInstallerInfoBarDelegate::DownloadStarted() {
409   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING,
410                                                 plugin_metadata_->name()));
411 }
412
413 void PluginInstallerInfoBarDelegate::DownloadCancelled() {
414   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_CANCELLED,
415                                                 plugin_metadata_->name()));
416 }
417
418 void PluginInstallerInfoBarDelegate::DownloadError(const std::string& message) {
419   ReplaceWithInfoBar(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR_SHORT,
420                                                 plugin_metadata_->name()));
421 }
422
423 void PluginInstallerInfoBarDelegate::DownloadFinished() {
424   ReplaceWithInfoBar(
425       l10n_util::GetStringFUTF16(
426           new_install_ ? IDS_PLUGIN_INSTALLING : IDS_PLUGIN_UPDATING,
427           plugin_metadata_->name()));
428 }
429
430 void PluginInstallerInfoBarDelegate::OnlyWeakObserversLeft() {
431   infobar()->RemoveSelf();
432 }
433
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);
443 }
444
445
446 #if defined(OS_WIN)
447
448 // PluginMetroModeInfoBarDelegate ---------------------------------------------
449
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))));
458 }
459
460 PluginMetroModeInfoBarDelegate::PluginMetroModeInfoBarDelegate(
461     PluginMetroModeInfoBarDelegate::Mode mode,
462     const base::string16& name)
463     : ConfirmInfoBarDelegate(),
464       mode_(mode),
465       name_(name) {
466 }
467
468 PluginMetroModeInfoBarDelegate::~PluginMetroModeInfoBarDelegate() {
469 }
470
471 int PluginMetroModeInfoBarDelegate::GetIconID() const {
472   return IDR_INFOBAR_PLUGIN_INSTALL;
473 }
474
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_);
478 }
479
480 int PluginMetroModeInfoBarDelegate::GetButtons() const {
481   return BUTTON_OK;
482 }
483
484 base::string16 PluginMetroModeInfoBarDelegate::GetButtonLabel(
485     InfoBarButton button) const {
486   return l10n_util::GetStringUTF16(IDS_WIN_DESKTOP_RESTART);
487 }
488
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
503 bool PluginMetroModeInfoBarDelegate::Accept() {
504   chrome::AttemptRestartToDesktopMode();
505   return true;
506 }
507
508 base::string16 PluginMetroModeInfoBarDelegate::GetLinkText() const {
509   return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
510 }
511
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;
526 }
527
528 #endif  // defined(OS_WIN)
529
530 #endif  // defined(ENABLE_PLUGIN_INSTALLATION)