1 // Copyright (c) 2011 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/plugin_observer.h"
8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/browser_process.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_tab_helper.h"
13 #include "chrome/browser/plugin_finder.h"
14 #include "chrome/browser/plugin_installer.h"
15 #include "chrome/browser/plugin_installer_infobar_delegate.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h"
18 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
19 #include "chrome/common/render_messages.h"
20 #include "chrome/common/url_constants.h"
21 #include "content/browser/renderer_host/render_view_host.h"
22 #include "content/browser/tab_contents/tab_contents.h"
23 #include "content/public/browser/user_metrics.h"
24 #include "content/public/browser/web_contents_delegate.h"
25 #include "grit/generated_resources.h"
26 #include "grit/theme_resources_standard.h"
27 #include "ui/base/l10n/l10n_util.h"
28 #include "ui/base/resource/resource_bundle.h"
29 #include "webkit/plugins/npapi/plugin_group.h"
30 #include "webkit/plugins/webplugininfo.h"
32 using content::UserMetricsAction
;
36 // PluginInfoBarDelegate ------------------------------------------------------
38 class PluginInfoBarDelegate
: public ConfirmInfoBarDelegate
{
40 PluginInfoBarDelegate(InfoBarTabHelper
* infobar_helper
, const string16
& name
);
43 virtual ~PluginInfoBarDelegate();
45 // ConfirmInfoBarDelegate:
46 virtual bool Cancel() OVERRIDE
;
47 virtual bool LinkClicked(WindowOpenDisposition disposition
) OVERRIDE
;
49 virtual std::string
GetLearnMoreURL() const = 0;
54 // ConfirmInfoBarDelegate:
55 virtual gfx::Image
* GetIcon() const OVERRIDE
;
56 virtual string16
GetLinkText() const OVERRIDE
;
58 DISALLOW_COPY_AND_ASSIGN(PluginInfoBarDelegate
);
61 PluginInfoBarDelegate::PluginInfoBarDelegate(InfoBarTabHelper
* infobar_helper
,
63 : ConfirmInfoBarDelegate(infobar_helper
),
67 PluginInfoBarDelegate::~PluginInfoBarDelegate() {
70 bool PluginInfoBarDelegate::Cancel() {
71 owner()->Send(new ChromeViewMsg_LoadBlockedPlugins(owner()->routing_id()));
75 bool PluginInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition
) {
76 owner()->tab_contents()->OpenURL(
77 google_util::AppendGoogleLocaleParam(GURL(GetLearnMoreURL())), GURL(),
78 (disposition
== CURRENT_TAB
) ? NEW_FOREGROUND_TAB
: disposition
,
79 content::PAGE_TRANSITION_LINK
);
83 gfx::Image
* PluginInfoBarDelegate::GetIcon() const {
84 return &ResourceBundle::GetSharedInstance().GetNativeImageNamed(
85 IDR_INFOBAR_PLUGIN_INSTALL
);
88 string16
PluginInfoBarDelegate::GetLinkText() const {
89 return l10n_util::GetStringUTF16(IDS_LEARN_MORE
);
93 // BlockedPluginInfoBarDelegate -----------------------------------------------
95 class BlockedPluginInfoBarDelegate
: public PluginInfoBarDelegate
{
97 BlockedPluginInfoBarDelegate(InfoBarTabHelper
* infobar_helper
,
98 HostContentSettingsMap
* content_settings
,
99 const string16
& name
);
102 virtual ~BlockedPluginInfoBarDelegate();
104 // PluginInfoBarDelegate:
105 virtual string16
GetMessageText() const OVERRIDE
;
106 virtual string16
GetButtonLabel(InfoBarButton button
) const OVERRIDE
;
107 virtual bool Accept() OVERRIDE
;
108 virtual bool Cancel() OVERRIDE
;
109 virtual void InfoBarDismissed() OVERRIDE
;
110 virtual bool LinkClicked(WindowOpenDisposition disposition
) OVERRIDE
;
111 virtual std::string
GetLearnMoreURL() const OVERRIDE
;
113 HostContentSettingsMap
* content_settings_
;
115 DISALLOW_COPY_AND_ASSIGN(BlockedPluginInfoBarDelegate
);
118 BlockedPluginInfoBarDelegate::BlockedPluginInfoBarDelegate(
119 InfoBarTabHelper
* infobar_helper
,
120 HostContentSettingsMap
* content_settings
,
121 const string16
& utf16_name
)
122 : PluginInfoBarDelegate(infobar_helper
, utf16_name
),
123 content_settings_(content_settings
) {
124 content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Shown"));
125 std::string name
= UTF16ToUTF8(utf16_name
);
126 if (name
== webkit::npapi::PluginGroup::kJavaGroupName
)
127 content::RecordAction(
128 UserMetricsAction("BlockedPluginInfobar.Shown.Java"));
129 else if (name
== webkit::npapi::PluginGroup::kQuickTimeGroupName
)
130 content::RecordAction(
131 UserMetricsAction("BlockedPluginInfobar.Shown.QuickTime"));
132 else if (name
== webkit::npapi::PluginGroup::kShockwaveGroupName
)
133 content::RecordAction(
134 UserMetricsAction("BlockedPluginInfobar.Shown.Shockwave"));
135 else if (name
== webkit::npapi::PluginGroup::kRealPlayerGroupName
)
136 content::RecordAction(
137 UserMetricsAction("BlockedPluginInfobar.Shown.RealPlayer"));
138 else if (name
== webkit::npapi::PluginGroup::kWindowsMediaPlayerGroupName
)
139 content::RecordAction(
140 UserMetricsAction("BlockedPluginInfobar.Shown.WindowsMediaPlayer"));
143 BlockedPluginInfoBarDelegate::~BlockedPluginInfoBarDelegate() {
144 content::RecordAction(UserMetricsAction("BlockedPluginInfobar.Closed"));
147 std::string
BlockedPluginInfoBarDelegate::GetLearnMoreURL() const {
148 return chrome::kBlockedPluginLearnMoreURL
;
151 string16
BlockedPluginInfoBarDelegate::GetMessageText() const {
152 return l10n_util::GetStringFUTF16(IDS_PLUGIN_NOT_AUTHORIZED
, name_
);
155 string16
BlockedPluginInfoBarDelegate::GetButtonLabel(
156 InfoBarButton button
) const {
157 return l10n_util::GetStringUTF16((button
== BUTTON_OK
) ?
158 IDS_PLUGIN_ENABLE_TEMPORARILY
: IDS_PLUGIN_ENABLE_ALWAYS
);
161 bool BlockedPluginInfoBarDelegate::Accept() {
162 content::RecordAction(
163 UserMetricsAction("BlockedPluginInfobar.AllowThisTime"));
164 return PluginInfoBarDelegate::Cancel();
167 bool BlockedPluginInfoBarDelegate::Cancel() {
168 content::RecordAction(
169 UserMetricsAction("BlockedPluginInfobar.AlwaysAllow"));
170 content_settings_
->AddExceptionForURL(owner()->tab_contents()->GetURL(),
171 owner()->tab_contents()->GetURL(),
172 CONTENT_SETTINGS_TYPE_PLUGINS
,
174 CONTENT_SETTING_ALLOW
);
175 return PluginInfoBarDelegate::Cancel();
178 void BlockedPluginInfoBarDelegate::InfoBarDismissed() {
179 content::RecordAction(
180 UserMetricsAction("BlockedPluginInfobar.Dismissed"));
183 bool BlockedPluginInfoBarDelegate::LinkClicked(
184 WindowOpenDisposition disposition
) {
185 content::RecordAction(
186 UserMetricsAction("BlockedPluginInfobar.LearnMore"));
187 return PluginInfoBarDelegate::LinkClicked(disposition
);
190 // OutdatedPluginInfoBarDelegate ----------------------------------------------
192 class OutdatedPluginInfoBarDelegate
: public PluginInfoBarDelegate
{
194 OutdatedPluginInfoBarDelegate(InfoBarTabHelper
* infobar_helper
,
195 const string16
& name
,
196 const GURL
& update_url
);
199 virtual ~OutdatedPluginInfoBarDelegate();
201 // PluginInfoBarDelegate:
202 virtual string16
GetMessageText() const OVERRIDE
;
203 virtual string16
GetButtonLabel(InfoBarButton button
) const OVERRIDE
;
204 virtual bool Accept() OVERRIDE
;
205 virtual bool Cancel() OVERRIDE
;
206 virtual void InfoBarDismissed() OVERRIDE
;
207 virtual bool LinkClicked(WindowOpenDisposition disposition
) OVERRIDE
;
208 virtual std::string
GetLearnMoreURL() const OVERRIDE
;
212 DISALLOW_COPY_AND_ASSIGN(OutdatedPluginInfoBarDelegate
);
215 OutdatedPluginInfoBarDelegate::OutdatedPluginInfoBarDelegate(
216 InfoBarTabHelper
* infobar_helper
,
217 const string16
& utf16_name
,
218 const GURL
& update_url
)
219 : PluginInfoBarDelegate(infobar_helper
, utf16_name
),
220 update_url_(update_url
) {
221 content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Shown"));
222 std::string name
= UTF16ToUTF8(utf16_name
);
223 if (name
== webkit::npapi::PluginGroup::kJavaGroupName
)
224 content::RecordAction(
225 UserMetricsAction("OutdatedPluginInfobar.Shown.Java"));
226 else if (name
== webkit::npapi::PluginGroup::kQuickTimeGroupName
)
227 content::RecordAction(
228 UserMetricsAction("OutdatedPluginInfobar.Shown.QuickTime"));
229 else if (name
== webkit::npapi::PluginGroup::kShockwaveGroupName
)
230 content::RecordAction(
231 UserMetricsAction("OutdatedPluginInfobar.Shown.Shockwave"));
232 else if (name
== webkit::npapi::PluginGroup::kRealPlayerGroupName
)
233 content::RecordAction(
234 UserMetricsAction("OutdatedPluginInfobar.Shown.RealPlayer"));
235 else if (name
== webkit::npapi::PluginGroup::kSilverlightGroupName
)
236 content::RecordAction(
237 UserMetricsAction("OutdatedPluginInfobar.Shown.Silverlight"));
238 else if (name
== webkit::npapi::PluginGroup::kAdobeReaderGroupName
)
239 content::RecordAction(
240 UserMetricsAction("OutdatedPluginInfobar.Shown.Reader"));
243 OutdatedPluginInfoBarDelegate::~OutdatedPluginInfoBarDelegate() {
244 content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Closed"));
247 std::string
OutdatedPluginInfoBarDelegate::GetLearnMoreURL() const {
248 return chrome::kOutdatedPluginLearnMoreURL
;
251 string16
OutdatedPluginInfoBarDelegate::GetMessageText() const {
252 return l10n_util::GetStringFUTF16(IDS_PLUGIN_OUTDATED_PROMPT
, name_
);
255 string16
OutdatedPluginInfoBarDelegate::GetButtonLabel(
256 InfoBarButton button
) const {
257 return l10n_util::GetStringUTF16((button
== BUTTON_OK
) ?
258 IDS_PLUGIN_UPDATE
: IDS_PLUGIN_ENABLE_TEMPORARILY
);
261 bool OutdatedPluginInfoBarDelegate::Accept() {
262 content::RecordAction(UserMetricsAction("OutdatedPluginInfobar.Update"));
263 owner()->tab_contents()->OpenURL(update_url_
, GURL(), NEW_FOREGROUND_TAB
,
264 content::PAGE_TRANSITION_LINK
);
268 bool OutdatedPluginInfoBarDelegate::Cancel() {
269 content::RecordAction(
270 UserMetricsAction("OutdatedPluginInfobar.AllowThisTime"));
271 return PluginInfoBarDelegate::Cancel();
274 void OutdatedPluginInfoBarDelegate::InfoBarDismissed() {
275 content::RecordAction(
276 UserMetricsAction("OutdatedPluginInfobar.Dismissed"));
279 bool OutdatedPluginInfoBarDelegate::LinkClicked(
280 WindowOpenDisposition disposition
) {
281 content::RecordAction(
282 UserMetricsAction("OutdatedPluginInfobar.LearnMore"));
283 return PluginInfoBarDelegate::LinkClicked(disposition
);
289 // PluginObserver -------------------------------------------------------------
291 PluginObserver::PluginObserver(TabContentsWrapper
* tab_contents
)
292 : TabContentsObserver(tab_contents
->tab_contents()),
293 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
294 tab_contents_(tab_contents
) {
297 PluginObserver::~PluginObserver() {
300 bool PluginObserver::OnMessageReceived(const IPC::Message
& message
) {
301 IPC_BEGIN_MESSAGE_MAP(PluginObserver
, message
)
302 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedOutdatedPlugin
,
303 OnBlockedOutdatedPlugin
)
304 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FindMissingPlugin
,
306 IPC_MESSAGE_UNHANDLED(return false)
307 IPC_END_MESSAGE_MAP()
312 void PluginObserver::OnBlockedOutdatedPlugin(const string16
& name
,
313 const GURL
& update_url
) {
314 InfoBarTabHelper
* infobar_helper
= tab_contents_
->infobar_tab_helper();
315 infobar_helper
->AddInfoBar(update_url
.is_empty() ?
316 static_cast<InfoBarDelegate
*>(new BlockedPluginInfoBarDelegate(
318 tab_contents_
->profile()->GetHostContentSettingsMap(),
320 new OutdatedPluginInfoBarDelegate(infobar_helper
, name
, update_url
));
323 void PluginObserver::OnFindMissingPlugin(int placeholder_id
,
324 const std::string
& mime_type
) {
325 PluginFinder
* plugin_finder
= PluginFinder::GetInstance();
326 std::string lang
= "en-US"; // Oh yes.
327 plugin_finder
->FindPlugin(
329 base::Bind(&PluginObserver::FoundMissingPlugin
,
330 weak_ptr_factory_
.GetWeakPtr(), placeholder_id
, mime_type
),
331 base::Bind(&PluginObserver::DidNotFindMissingPlugin
,
332 weak_ptr_factory_
.GetWeakPtr(), placeholder_id
, mime_type
));
335 void PluginObserver::FoundMissingPlugin(int placeholder_id
,
336 const std::string
& mime_type
,
337 PluginInstaller
* installer
) {
338 Send(new ChromeViewMsg_FoundMissingPlugin(placeholder_id
, installer
->name()));
339 InfoBarTabHelper
* infobar_helper
= tab_contents_
->infobar_tab_helper();
340 infobar_helper
->AddInfoBar(new PluginInstallerInfoBarDelegate(
343 installer
->help_url(),
344 base::Bind(&PluginObserver::InstallMissingPlugin
,
345 weak_ptr_factory_
.GetWeakPtr(), installer
)));
348 void PluginObserver::DidNotFindMissingPlugin(int placeholder_id
,
349 const std::string
& mime_type
) {
350 Send(new ChromeViewMsg_DidNotFindMissingPlugin(placeholder_id
));
353 void PluginObserver::InstallMissingPlugin(PluginInstaller
* installer
) {
354 if (installer
->url_for_display()) {
355 tab_contents()->OpenURL(OpenURLParams(
356 installer
->plugin_url(),
357 content::Referrer(tab_contents()->GetURL(),
358 WebKit::WebReferrerPolicyDefault
),
359 NEW_FOREGROUND_TAB
, content::PAGE_TRANSITION_TYPED
, false));