OLD | NEW |
| (Empty) |
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/plugin_observer.h" | |
6 | |
7 #include "base/auto_reset.h" | |
8 #include "base/bind.h" | |
9 #include "base/stl_util.h" | |
10 #include "base/utf_string_conversions.h" | |
11 #include "chrome/browser/api/infobars/confirm_infobar_delegate.h" | |
12 #include "chrome/browser/api/infobars/simple_alert_infobar_delegate.h" | |
13 #include "chrome/browser/browser_process.h" | |
14 #include "chrome/browser/content_settings/host_content_settings_map.h" | |
15 #include "chrome/browser/infobars/infobar_tab_helper.h" | |
16 #include "chrome/browser/metrics/metrics_service.h" | |
17 #include "chrome/browser/plugin_finder.h" | |
18 #include "chrome/browser/plugin_infobar_delegates.h" | |
19 #include "chrome/browser/profiles/profile.h" | |
20 #include "chrome/browser/ui/browser_dialogs.h" | |
21 #include "chrome/browser/ui/tab_contents/tab_contents.h" | |
22 #include "chrome/common/render_messages.h" | |
23 #include "chrome/common/url_constants.h" | |
24 #include "content/public/browser/plugin_service.h" | |
25 #include "content/public/browser/render_view_host.h" | |
26 #include "content/public/browser/web_contents.h" | |
27 #include "content/public/browser/web_contents_delegate.h" | |
28 #include "grit/generated_resources.h" | |
29 #include "grit/theme_resources.h" | |
30 #include "ui/base/l10n/l10n_util.h" | |
31 #include "ui/base/resource/resource_bundle.h" | |
32 #include "webkit/plugins/webplugininfo.h" | |
33 | |
34 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
35 #include "chrome/browser/plugin_installer.h" | |
36 #include "chrome/browser/plugin_installer_observer.h" | |
37 #include "chrome/browser/ui/tab_modal_confirm_dialog_delegate.h" | |
38 #endif // defined(ENABLE_PLUGIN_INSTALLATION) | |
39 | |
40 #if defined(OS_WIN) | |
41 #include "base/win/metro.h" | |
42 #endif | |
43 | |
44 using content::OpenURLParams; | |
45 using content::PluginService; | |
46 using content::Referrer; | |
47 using content::WebContents; | |
48 | |
49 namespace { | |
50 | |
51 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
52 | |
53 // ConfirmInstallDialogDelegate ------------------------------------------------ | |
54 | |
55 class ConfirmInstallDialogDelegate : public TabModalConfirmDialogDelegate, | |
56 public WeakPluginInstallerObserver { | |
57 public: | |
58 ConfirmInstallDialogDelegate(TabContents* tab_contents, | |
59 PluginInstaller* installer); | |
60 | |
61 // TabModalConfirmDialogDelegate methods: | |
62 virtual string16 GetTitle() OVERRIDE; | |
63 virtual string16 GetMessage() OVERRIDE; | |
64 virtual string16 GetAcceptButtonTitle() OVERRIDE; | |
65 virtual void OnAccepted() OVERRIDE; | |
66 virtual void OnCanceled() OVERRIDE; | |
67 | |
68 // WeakPluginInstallerObserver methods: | |
69 virtual void DownloadStarted() OVERRIDE; | |
70 virtual void OnlyWeakObserversLeft() OVERRIDE; | |
71 | |
72 private: | |
73 TabContents* tab_contents_; | |
74 }; | |
75 | |
76 ConfirmInstallDialogDelegate::ConfirmInstallDialogDelegate( | |
77 TabContents* tab_contents, | |
78 PluginInstaller* installer) | |
79 : TabModalConfirmDialogDelegate(tab_contents->web_contents()), | |
80 WeakPluginInstallerObserver(installer), | |
81 tab_contents_(tab_contents) { | |
82 } | |
83 | |
84 string16 ConfirmInstallDialogDelegate::GetTitle() { | |
85 return l10n_util::GetStringFUTF16( | |
86 IDS_PLUGIN_CONFIRM_INSTALL_DIALOG_TITLE, installer()->name()); | |
87 } | |
88 | |
89 string16 ConfirmInstallDialogDelegate::GetMessage() { | |
90 return l10n_util::GetStringFUTF16(IDS_PLUGIN_CONFIRM_INSTALL_DIALOG_MSG, | |
91 installer()->name()); | |
92 } | |
93 | |
94 string16 ConfirmInstallDialogDelegate::GetAcceptButtonTitle() { | |
95 return l10n_util::GetStringUTF16( | |
96 IDS_PLUGIN_CONFIRM_INSTALL_DIALOG_ACCEPT_BUTTON); | |
97 } | |
98 | |
99 void ConfirmInstallDialogDelegate::OnAccepted() { | |
100 installer()->StartInstalling(tab_contents_); | |
101 } | |
102 | |
103 void ConfirmInstallDialogDelegate::OnCanceled() { | |
104 } | |
105 | |
106 void ConfirmInstallDialogDelegate::DownloadStarted() { | |
107 Cancel(); | |
108 } | |
109 | |
110 void ConfirmInstallDialogDelegate::OnlyWeakObserversLeft() { | |
111 Cancel(); | |
112 } | |
113 #endif // defined(ENABLE_PLUGIN_INSTALLATION) | |
114 | |
115 } // namespace | |
116 | |
117 // PluginObserver ------------------------------------------------------------- | |
118 | |
119 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
120 class PluginObserver::PluginPlaceholderHost : public PluginInstallerObserver { | |
121 public: | |
122 PluginPlaceholderHost(PluginObserver* observer, | |
123 int routing_id, | |
124 PluginInstaller* installer) | |
125 : PluginInstallerObserver(installer), | |
126 observer_(observer), | |
127 routing_id_(routing_id) { | |
128 DCHECK(installer); | |
129 switch (installer->state()) { | |
130 case PluginInstaller::INSTALLER_STATE_IDLE: { | |
131 observer->Send(new ChromeViewMsg_FoundMissingPlugin(routing_id_, | |
132 installer->name())); | |
133 break; | |
134 } | |
135 case PluginInstaller::INSTALLER_STATE_DOWNLOADING: { | |
136 DownloadStarted(); | |
137 break; | |
138 } | |
139 } | |
140 } | |
141 | |
142 // PluginInstallerObserver methods: | |
143 virtual void DownloadStarted() OVERRIDE { | |
144 observer_->Send(new ChromeViewMsg_StartedDownloadingPlugin(routing_id_)); | |
145 } | |
146 | |
147 virtual void DownloadError(const std::string& msg) OVERRIDE { | |
148 observer_->Send(new ChromeViewMsg_ErrorDownloadingPlugin(routing_id_, msg)); | |
149 } | |
150 | |
151 virtual void DownloadCancelled() OVERRIDE { | |
152 observer_->Send(new ChromeViewMsg_CancelledDownloadingPlugin(routing_id_)); | |
153 } | |
154 | |
155 virtual void DownloadFinished() OVERRIDE { | |
156 observer_->Send(new ChromeViewMsg_FinishedDownloadingPlugin(routing_id_)); | |
157 } | |
158 | |
159 private: | |
160 // Weak pointer; owns us. | |
161 PluginObserver* observer_; | |
162 | |
163 int routing_id_; | |
164 }; | |
165 #endif // defined(ENABLE_PLUGIN_INSTALLATION) | |
166 | |
167 PluginObserver::PluginObserver(TabContents* tab_contents) | |
168 : content::WebContentsObserver(tab_contents->web_contents()), | |
169 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)), | |
170 tab_contents_(tab_contents) { | |
171 } | |
172 | |
173 PluginObserver::~PluginObserver() { | |
174 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
175 STLDeleteValues(&plugin_placeholders_); | |
176 #endif | |
177 } | |
178 | |
179 void PluginObserver::PluginCrashed(const FilePath& plugin_path) { | |
180 DCHECK(!plugin_path.value().empty()); | |
181 | |
182 string16 plugin_name = | |
183 PluginService::GetInstance()->GetPluginDisplayNameByPath(plugin_path); | |
184 gfx::Image* icon = &ResourceBundle::GetSharedInstance().GetNativeImageNamed( | |
185 IDR_INFOBAR_PLUGIN_CRASHED); | |
186 InfoBarTabHelper* infobar_helper = tab_contents_->infobar_tab_helper(); | |
187 infobar_helper->AddInfoBar( | |
188 new SimpleAlertInfoBarDelegate( | |
189 infobar_helper, | |
190 icon, | |
191 l10n_util::GetStringFUTF16(IDS_PLUGIN_CRASHED_PROMPT, plugin_name), | |
192 true)); | |
193 } | |
194 | |
195 bool PluginObserver::OnMessageReceived(const IPC::Message& message) { | |
196 IPC_BEGIN_MESSAGE_MAP(PluginObserver, message) | |
197 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedOutdatedPlugin, | |
198 OnBlockedOutdatedPlugin) | |
199 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_BlockedUnauthorizedPlugin, | |
200 OnBlockedUnauthorizedPlugin) | |
201 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
202 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FindMissingPlugin, | |
203 OnFindMissingPlugin) | |
204 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RemovePluginPlaceholderHost, | |
205 OnRemovePluginPlaceholderHost) | |
206 #endif | |
207 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_OpenAboutPlugins, | |
208 OnOpenAboutPlugins) | |
209 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_CouldNotLoadPlugin, | |
210 OnCouldNotLoadPlugin) | |
211 | |
212 IPC_MESSAGE_UNHANDLED(return false) | |
213 IPC_END_MESSAGE_MAP() | |
214 | |
215 return true; | |
216 } | |
217 | |
218 void PluginObserver::OnBlockedUnauthorizedPlugin( | |
219 const string16& name, | |
220 const std::string& identifier) { | |
221 InfoBarTabHelper* infobar_helper = tab_contents_->infobar_tab_helper(); | |
222 infobar_helper->AddInfoBar( | |
223 new UnauthorizedPluginInfoBarDelegate( | |
224 infobar_helper, | |
225 tab_contents_->profile()->GetHostContentSettingsMap(), | |
226 name, identifier)); | |
227 } | |
228 | |
229 void PluginObserver::OnBlockedOutdatedPlugin(int placeholder_id, | |
230 const std::string& identifier) { | |
231 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
232 PluginFinder::Get(base::Bind(&PluginObserver::FindPluginToUpdate, | |
233 weak_ptr_factory_.GetWeakPtr(), | |
234 placeholder_id, identifier)); | |
235 #else | |
236 // If we don't support third-party plug-in installation, we shouldn't have | |
237 // outdated plug-ins. | |
238 NOTREACHED(); | |
239 #endif // defined(ENABLE_PLUGIN_INSTALLATION) | |
240 } | |
241 | |
242 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
243 void PluginObserver::FindPluginToUpdate(int placeholder_id, | |
244 const std::string& identifier, | |
245 PluginFinder* plugin_finder) { | |
246 PluginInstaller* installer = | |
247 plugin_finder->FindPluginWithIdentifier(identifier); | |
248 DCHECK(installer) << "Couldn't find PluginInstaller for identifier " | |
249 << identifier; | |
250 plugin_placeholders_[placeholder_id] = | |
251 new PluginPlaceholderHost(this, placeholder_id, installer); | |
252 InfoBarTabHelper* infobar_helper = tab_contents_->infobar_tab_helper(); | |
253 infobar_helper->AddInfoBar( | |
254 OutdatedPluginInfoBarDelegate::Create(this, installer)); | |
255 } | |
256 | |
257 void PluginObserver::OnFindMissingPlugin(int placeholder_id, | |
258 const std::string& mime_type) { | |
259 PluginFinder::Get(base::Bind(&PluginObserver::FindMissingPlugin, | |
260 weak_ptr_factory_.GetWeakPtr(), | |
261 placeholder_id, mime_type)); | |
262 } | |
263 | |
264 void PluginObserver::FindMissingPlugin(int placeholder_id, | |
265 const std::string& mime_type, | |
266 PluginFinder* plugin_finder) { | |
267 std::string lang = "en-US"; // Oh yes. | |
268 PluginInstaller* installer = plugin_finder->FindPlugin(mime_type, lang); | |
269 if (!installer) { | |
270 Send(new ChromeViewMsg_DidNotFindMissingPlugin(placeholder_id)); | |
271 return; | |
272 } | |
273 | |
274 plugin_placeholders_[placeholder_id] = | |
275 new PluginPlaceholderHost(this, placeholder_id, installer); | |
276 InfoBarTabHelper* infobar_helper = tab_contents_->infobar_tab_helper(); | |
277 InfoBarDelegate* delegate; | |
278 #if !defined(OS_WIN) | |
279 delegate = PluginInstallerInfoBarDelegate::Create( | |
280 infobar_helper, installer, | |
281 base::Bind(&PluginObserver::InstallMissingPlugin, | |
282 weak_ptr_factory_.GetWeakPtr(), installer)); | |
283 #else | |
284 delegate = base::win::IsMetroProcess() ? | |
285 PluginMetroModeInfoBarDelegate::Create( | |
286 infobar_helper, installer->name()) : | |
287 PluginInstallerInfoBarDelegate::Create( | |
288 infobar_helper, installer, | |
289 base::Bind(&PluginObserver::InstallMissingPlugin, | |
290 weak_ptr_factory_.GetWeakPtr(), installer)); | |
291 #endif | |
292 infobar_helper->AddInfoBar(delegate); | |
293 } | |
294 | |
295 void PluginObserver::InstallMissingPlugin(PluginInstaller* installer) { | |
296 if (installer->url_for_display()) { | |
297 installer->OpenDownloadURL(web_contents()); | |
298 } else { | |
299 chrome::ShowTabModalConfirmDialog( | |
300 new ConfirmInstallDialogDelegate(tab_contents_, installer), | |
301 tab_contents_); | |
302 } | |
303 } | |
304 | |
305 void PluginObserver::OnRemovePluginPlaceholderHost(int placeholder_id) { | |
306 std::map<int, PluginPlaceholderHost*>::iterator it = | |
307 plugin_placeholders_.find(placeholder_id); | |
308 if (it == plugin_placeholders_.end()) { | |
309 NOTREACHED(); | |
310 return; | |
311 } | |
312 delete it->second; | |
313 plugin_placeholders_.erase(it); | |
314 } | |
315 #endif // defined(ENABLE_PLUGIN_INSTALLATION) | |
316 | |
317 void PluginObserver::OnOpenAboutPlugins() { | |
318 web_contents()->OpenURL(OpenURLParams( | |
319 GURL(chrome::kAboutPluginsURL), | |
320 content::Referrer(web_contents()->GetURL(), | |
321 WebKit::WebReferrerPolicyDefault), | |
322 NEW_FOREGROUND_TAB, content::PAGE_TRANSITION_AUTO_BOOKMARK, false)); | |
323 } | |
324 | |
325 void PluginObserver::OnCouldNotLoadPlugin(const FilePath& plugin_path) { | |
326 g_browser_process->metrics_service()->LogPluginLoadingError(plugin_path); | |
327 string16 plugin_name = | |
328 PluginService::GetInstance()->GetPluginDisplayNameByPath(plugin_path); | |
329 InfoBarTabHelper* infobar_helper = tab_contents_->infobar_tab_helper(); | |
330 infobar_helper->AddInfoBar(new SimpleAlertInfoBarDelegate( | |
331 infobar_helper, | |
332 &ResourceBundle::GetSharedInstance().GetNativeImageNamed( | |
333 IDR_INFOBAR_PLUGIN_CRASHED), | |
334 l10n_util::GetStringFUTF16(IDS_PLUGIN_INITIALIZATION_ERROR_PROMPT, | |
335 plugin_name), | |
336 true /* auto_expire */)); | |
337 } | |
338 | |
OLD | NEW |