OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/renderer/plugins/plugin_placeholder.h" | 5 #include "components/plugins/renderer/plugin_placeholder.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/json/string_escape.h" | 9 #include "base/json/string_escape.h" |
10 #include "base/strings/string_piece.h" | 10 #include "base/strings/string_piece.h" |
11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
13 #include "base/values.h" | 13 #include "base/values.h" |
14 #include "chrome/common/prerender_messages.h" | 14 #include "components/plugins/renderer/plugin_uma.h" |
15 #include "chrome/common/render_messages.h" | |
16 #include "chrome/renderer/chrome_content_renderer_client.h" | |
17 #include "chrome/renderer/custom_menu_commands.h" | |
18 #include "chrome/renderer/plugins/plugin_uma.h" | |
19 #include "content/public/common/content_constants.h" | 15 #include "content/public/common/content_constants.h" |
20 #include "content/public/common/context_menu_params.h" | 16 #include "content/public/common/context_menu_params.h" |
21 #include "content/public/renderer/render_thread.h" | 17 #include "content/public/renderer/render_thread.h" |
22 #include "content/public/renderer/render_view.h" | 18 #include "content/public/renderer/render_view.h" |
23 #include "grit/generated_resources.h" | |
24 #include "grit/renderer_resources.h" | |
25 #include "grit/webkit_strings.h" | |
26 #include "third_party/WebKit/public/platform/WebData.h" | |
27 #include "third_party/WebKit/public/platform/WebPoint.h" | |
28 #include "third_party/WebKit/public/platform/WebURLRequest.h" | |
29 #include "third_party/WebKit/public/platform/WebVector.h" | |
30 #include "third_party/WebKit/public/web/WebContextMenuData.h" | |
31 #include "third_party/WebKit/public/web/WebDocument.h" | 19 #include "third_party/WebKit/public/web/WebDocument.h" |
32 #include "third_party/WebKit/public/web/WebElement.h" | 20 #include "third_party/WebKit/public/web/WebElement.h" |
33 #include "third_party/WebKit/public/web/WebFrame.h" | 21 #include "third_party/WebKit/public/web/WebFrame.h" |
34 #include "third_party/WebKit/public/web/WebInputEvent.h" | 22 #include "third_party/WebKit/public/web/WebInputEvent.h" |
35 #include "third_party/WebKit/public/web/WebPluginContainer.h" | 23 #include "third_party/WebKit/public/web/WebPluginContainer.h" |
36 #include "third_party/WebKit/public/web/WebScriptSource.h" | 24 #include "third_party/WebKit/public/web/WebScriptSource.h" |
37 #include "third_party/WebKit/public/web/WebView.h" | 25 #include "third_party/WebKit/public/web/WebView.h" |
38 #include "third_party/re2/re2/re2.h" | 26 #include "third_party/re2/re2/re2.h" |
39 #include "ui/base/l10n/l10n_util.h" | |
40 #include "ui/base/resource/resource_bundle.h" | |
41 #include "ui/webui/jstemplate_builder.h" | |
42 | 27 |
43 using content::RenderThread; | 28 using content::RenderThread; |
44 using content::RenderView; | |
45 using WebKit::WebContextMenuData; | |
46 using WebKit::WebDocument; | |
47 using WebKit::WebElement; | 29 using WebKit::WebElement; |
48 using WebKit::WebFrame; | 30 using WebKit::WebFrame; |
49 using WebKit::WebMouseEvent; | 31 using WebKit::WebMouseEvent; |
50 using WebKit::WebNode; | 32 using WebKit::WebNode; |
51 using WebKit::WebPlugin; | 33 using WebKit::WebPlugin; |
52 using WebKit::WebPluginContainer; | 34 using WebKit::WebPluginContainer; |
53 using WebKit::WebPluginParams; | 35 using WebKit::WebPluginParams; |
54 using WebKit::WebPoint; | |
55 using WebKit::WebScriptSource; | 36 using WebKit::WebScriptSource; |
56 using WebKit::WebString; | |
57 using WebKit::WebURLRequest; | 37 using WebKit::WebURLRequest; |
58 using WebKit::WebVector; | |
59 using webkit_glue::CppArgumentList; | 38 using webkit_glue::CppArgumentList; |
60 using webkit_glue::CppVariant; | 39 using webkit_glue::CppVariant; |
61 | 40 |
62 const char* const kPluginPlaceholderDataURL = | 41 const char* const kPluginPlaceholderDataURL = "chrome://pluginplaceholderdata/"; |
Bernhard Bauer
2013/09/13 20:04:10
Why are you moving this?
aberent
2013/09/13 20:11:30
Because it is not an appropriate URL for Webview.
Bernhard Bauer
2013/09/13 20:37:41
But content does, and WebView uses content. WebVie
| |
63 "chrome://pluginplaceholderdata/"; | |
64 | |
65 #if defined(ENABLE_MOBILE_YOUTUBE_PLUGIN) | |
66 // Strings we used to parse the youtube plugin url. | |
67 const char* const kSlashVSlash = "/v/"; | |
68 const char* const kSlashESlash = "/e/"; | |
69 #endif | |
70 | |
71 namespace { | |
72 const PluginPlaceholder* g_last_active_menu = NULL; | |
73 | |
74 #if defined(ENABLE_MOBILE_YOUTUBE_PLUGIN) | |
75 // Helper function to get the youtube id from plugin params for old style | |
76 // embedded youtube video. | |
77 std::string GetYoutubeVideoId(const WebPluginParams& params) { | |
78 GURL url(params.url); | |
79 std::string video_id = url.path().substr(strlen(kSlashVSlash)); | |
80 | |
81 // Extract just the video id | |
82 size_t video_id_end = video_id.find('&'); | |
83 if (video_id_end != std::string::npos) | |
84 video_id = video_id.substr(0, video_id_end); | |
85 return video_id; | |
86 } | |
87 #endif | |
88 } // namespace | |
89 | |
90 // static | |
91 PluginPlaceholder* PluginPlaceholder::CreateMissingPlugin( | |
92 RenderView* render_view, | |
93 WebFrame* frame, | |
94 const WebPluginParams& params) { | |
95 const base::StringPiece template_html( | |
96 ResourceBundle::GetSharedInstance().GetRawDataResource( | |
97 IDR_BLOCKED_PLUGIN_HTML)); | |
98 | |
99 base::DictionaryValue values; | |
100 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
101 values.SetString("message", l10n_util::GetStringUTF8(IDS_PLUGIN_SEARCHING)); | |
102 #else | |
103 values.SetString("message", | |
104 l10n_util::GetStringUTF8(IDS_PLUGIN_NOT_SUPPORTED)); | |
105 #endif | |
106 | |
107 std::string html_data = webui::GetI18nTemplateHtml(template_html, &values); | |
108 | |
109 // |missing_plugin| will destroy itself when its WebViewPlugin is going away. | |
110 PluginPlaceholder* missing_plugin = new PluginPlaceholder( | |
111 render_view, frame, params, html_data, params.mimeType); | |
112 missing_plugin->set_allow_loading(true); | |
113 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
114 RenderThread::Get()->Send(new ChromeViewHostMsg_FindMissingPlugin( | |
115 missing_plugin->routing_id(), missing_plugin->CreateRoutingId(), | |
116 params.mimeType.utf8())); | |
117 #endif | |
118 return missing_plugin; | |
119 } | |
120 | |
121 PluginPlaceholder* PluginPlaceholder::CreateErrorPlugin( | |
122 RenderView* render_view, | |
123 const base::FilePath& file_path) { | |
124 base::DictionaryValue values; | |
125 values.SetString("message", | |
126 l10n_util::GetStringUTF8(IDS_PLUGIN_INITIALIZATION_ERROR)); | |
127 | |
128 const base::StringPiece template_html( | |
129 ResourceBundle::GetSharedInstance().GetRawDataResource( | |
130 IDR_BLOCKED_PLUGIN_HTML)); | |
131 std::string html_data = webui::GetI18nTemplateHtml(template_html, &values); | |
132 | |
133 WebPluginParams params; | |
134 // |missing_plugin| will destroy itself when its WebViewPlugin is going away. | |
135 PluginPlaceholder* plugin = new PluginPlaceholder( | |
136 render_view, NULL, params, html_data, params.mimeType); | |
137 | |
138 RenderThread::Get()->Send( | |
139 new ChromeViewHostMsg_CouldNotLoadPlugin(plugin->routing_id(), | |
140 file_path)); | |
141 return plugin; | |
142 } | |
143 | |
144 // static | |
145 PluginPlaceholder* PluginPlaceholder::CreateBlockedPlugin( | |
146 RenderView* render_view, | |
147 WebFrame* frame, | |
148 const WebPluginParams& params, | |
149 const content::WebPluginInfo& plugin, | |
150 const std::string& identifier, | |
151 const string16& name, | |
152 int template_id, | |
153 const string16& message) { | |
154 base::DictionaryValue values; | |
155 values.SetString("message", message); | |
156 values.SetString("name", name); | |
157 values.SetString("hide", l10n_util::GetStringUTF8(IDS_PLUGIN_HIDE)); | |
158 | |
159 const base::StringPiece template_html( | |
160 ResourceBundle::GetSharedInstance().GetRawDataResource( | |
161 template_id)); | |
162 | |
163 DCHECK(!template_html.empty()) << "unable to load template. ID: " | |
164 << template_id; | |
165 std::string html_data = webui::GetI18nTemplateHtml(template_html, &values); | |
166 | |
167 // |blocked_plugin| will destroy itself when its WebViewPlugin is going away. | |
168 PluginPlaceholder* blocked_plugin = new PluginPlaceholder( | |
169 render_view, frame, params, html_data, name); | |
170 blocked_plugin->plugin_info_ = plugin; | |
171 blocked_plugin->identifier_ = identifier; | |
172 return blocked_plugin; | |
173 } | |
174 | |
175 #if defined(ENABLE_MOBILE_YOUTUBE_PLUGIN) | |
176 // static | |
177 PluginPlaceholder* PluginPlaceholder::CreateMobileYoutubePlugin( | |
178 content::RenderView* render_view, | |
179 WebFrame* frame, | |
180 const WebPluginParams& params) { | |
181 const base::StringPiece template_html( | |
182 ResourceBundle::GetSharedInstance().GetRawDataResource( | |
183 IDR_MOBILE_YOUTUBE_PLUGIN_HTML)); | |
184 | |
185 base::DictionaryValue values; | |
186 values.SetString("video_id", GetYoutubeVideoId(params)); | |
187 std::string html_data = webui::GetI18nTemplateHtml(template_html, &values); | |
188 | |
189 // |youtube_plugin| will destroy itself when its WebViewPlugin is going away. | |
190 PluginPlaceholder* youtube_plugin = new PluginPlaceholder( | |
191 render_view, frame, params, html_data, params.mimeType); | |
192 return youtube_plugin; | |
193 } | |
194 #endif | |
195 | 42 |
196 PluginPlaceholder::PluginPlaceholder(content::RenderView* render_view, | 43 PluginPlaceholder::PluginPlaceholder(content::RenderView* render_view, |
197 WebFrame* frame, | 44 WebFrame* frame, |
198 const WebPluginParams& params, | 45 const WebPluginParams& params, |
199 const std::string& html_data, | 46 const std::string& html_data) |
200 const string16& title) | |
201 : content::RenderViewObserver(render_view), | 47 : content::RenderViewObserver(render_view), |
202 frame_(frame), | 48 frame_(frame), |
203 plugin_params_(params), | 49 plugin_params_(params), |
204 plugin_(WebViewPlugin::Create( | 50 plugin_(WebViewPlugin::Create(this, |
205 this, render_view->GetWebkitPreferences(), html_data, | 51 render_view->GetWebkitPreferences(), |
206 GURL(kPluginPlaceholderDataURL))), | 52 html_data, |
207 title_(title), | 53 GURL(kPluginPlaceholderDataURL))), |
208 status_(new ChromeViewHostMsg_GetPluginInfo_Status), | |
209 is_blocked_for_prerendering_(false), | 54 is_blocked_for_prerendering_(false), |
210 allow_loading_(false), | 55 allow_loading_(false), |
211 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
212 placeholder_routing_id_(MSG_ROUTING_NONE), | |
213 #endif | |
214 hidden_(false), | 56 hidden_(false), |
215 has_host_(false), | 57 finished_loading_(false) {} |
216 finished_loading_(false), | |
217 context_menu_request_id_(0) { | |
218 RenderThread::Get()->AddObserver(this); | |
219 } | |
220 | 58 |
221 PluginPlaceholder::~PluginPlaceholder() { | 59 PluginPlaceholder::~PluginPlaceholder() {} |
222 RenderThread::Get()->RemoveObserver(this); | |
223 if (context_menu_request_id_) | |
224 render_view()->CancelContextMenu(context_menu_request_id_); | |
225 | |
226 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
227 if (placeholder_routing_id_ == MSG_ROUTING_NONE) | |
228 return; | |
229 RenderThread::Get()->RemoveRoute(placeholder_routing_id_); | |
230 if (has_host_) { | |
231 RenderThread::Get()->Send( | |
232 new ChromeViewHostMsg_RemovePluginPlaceholderHost( | |
233 routing_id(), placeholder_routing_id_)); | |
234 } | |
235 #endif | |
236 } | |
237 | |
238 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
239 int32 PluginPlaceholder::CreateRoutingId() { | |
240 placeholder_routing_id_ = RenderThread::Get()->GenerateRoutingID(); | |
241 RenderThread::Get()->AddRoute(placeholder_routing_id_, this); | |
242 return placeholder_routing_id_; | |
243 } | |
244 #endif | |
245 | |
246 void PluginPlaceholder::SetStatus( | |
247 const ChromeViewHostMsg_GetPluginInfo_Status& status) { | |
248 status_->value = status.value; | |
249 } | |
250 | 60 |
251 void PluginPlaceholder::BindWebFrame(WebFrame* frame) { | 61 void PluginPlaceholder::BindWebFrame(WebFrame* frame) { |
252 BindToJavascript(frame, "plugin"); | 62 BindToJavascript(frame, "plugin"); |
253 BindCallback("load", base::Bind(&PluginPlaceholder::LoadCallback, | 63 BindCallback( |
254 base::Unretained(this))); | 64 "load", |
255 BindCallback("hide", base::Bind(&PluginPlaceholder::HideCallback, | 65 base::Bind(&PluginPlaceholder::LoadCallback, base::Unretained(this))); |
256 base::Unretained(this))); | 66 BindCallback( |
257 BindCallback("openAboutPlugins", | 67 "hide", |
258 base::Bind(&PluginPlaceholder::OpenAboutPluginsCallback, | 68 base::Bind(&PluginPlaceholder::HideCallback, base::Unretained(this))); |
259 base::Unretained(this))); | |
260 BindCallback("didFinishLoading", | 69 BindCallback("didFinishLoading", |
261 base::Bind(&PluginPlaceholder::DidFinishLoadingCallback, | 70 base::Bind(&PluginPlaceholder::DidFinishLoadingCallback, |
262 base::Unretained(this))); | 71 base::Unretained(this))); |
263 #if defined(ENABLE_MOBILE_YOUTUBE_PLUGIN) | |
264 BindCallback("openYoutubeURL", | |
265 base::Bind(&PluginPlaceholder::OpenYoutubeUrlCallback, | |
266 base::Unretained(this))); | |
267 #endif | |
268 } | |
269 | |
270 bool PluginPlaceholder::OnMessageReceived(const IPC::Message& message) { | |
271 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
272 bool handled = true; | |
273 IPC_BEGIN_MESSAGE_MAP(PluginPlaceholder, message) | |
274 IPC_MESSAGE_HANDLER(ChromeViewMsg_FoundMissingPlugin, | |
275 OnFoundMissingPlugin) | |
276 IPC_MESSAGE_HANDLER(ChromeViewMsg_DidNotFindMissingPlugin, | |
277 OnDidNotFindMissingPlugin) | |
278 IPC_MESSAGE_HANDLER(ChromeViewMsg_StartedDownloadingPlugin, | |
279 OnStartedDownloadingPlugin) | |
280 IPC_MESSAGE_HANDLER(ChromeViewMsg_FinishedDownloadingPlugin, | |
281 OnFinishedDownloadingPlugin) | |
282 IPC_MESSAGE_HANDLER(ChromeViewMsg_ErrorDownloadingPlugin, | |
283 OnErrorDownloadingPlugin) | |
284 IPC_MESSAGE_HANDLER(ChromeViewMsg_CancelledDownloadingPlugin, | |
285 OnCancelledDownloadingPlugin) | |
286 IPC_MESSAGE_UNHANDLED(handled = false) | |
287 IPC_END_MESSAGE_MAP() | |
288 | |
289 if (handled) | |
290 return true; | |
291 #endif | |
292 | |
293 // We don't swallow these messages because multiple blocked plugins have an | |
294 // interest in them. | |
295 IPC_BEGIN_MESSAGE_MAP(PluginPlaceholder, message) | |
296 IPC_MESSAGE_HANDLER(ChromeViewMsg_LoadBlockedPlugins, OnLoadBlockedPlugins) | |
297 IPC_MESSAGE_HANDLER(PrerenderMsg_SetIsPrerendering, OnSetIsPrerendering) | |
298 IPC_END_MESSAGE_MAP() | |
299 | |
300 return false; | |
301 } | 72 } |
302 | 73 |
303 void PluginPlaceholder::ReplacePlugin(WebPlugin* new_plugin) { | 74 void PluginPlaceholder::ReplacePlugin(WebPlugin* new_plugin) { |
304 CHECK(plugin_); | 75 CHECK(plugin_); |
305 if (!new_plugin) { | 76 if (!new_plugin) { |
306 PluginUMAReporter::GetInstance()->ReportPluginMissing( | 77 PluginUMAReporter::GetInstance()->ReportPluginMissing( |
307 plugin_params_.mimeType.utf8(), | 78 plugin_params_.mimeType.utf8(), plugin_params_.url); |
308 plugin_params_.url); | |
309 return; | 79 return; |
310 } | 80 } |
311 | 81 |
312 WebPluginContainer* container = plugin_->container(); | 82 WebPluginContainer* container = plugin_->container(); |
313 // Set the new plug-in on the container before initializing it. | 83 // Set the new plug-in on the container before initializing it. |
314 container->setPlugin(new_plugin); | 84 container->setPlugin(new_plugin); |
315 // Save the element in case the plug-in is removed from the page during | 85 // Save the element in case the plug-in is removed from the page during |
316 // initialization. | 86 // initialization. |
317 WebElement element = container->element(); | 87 WebElement element = container->element(); |
318 if (!new_plugin->initialize(container)) { | 88 if (!new_plugin->initialize(container)) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
379 if (element.hasAttribute("style")) { | 149 if (element.hasAttribute("style")) { |
380 std::string style_str = element.getAttribute("style").utf8(); | 150 std::string style_str = element.getAttribute("style").utf8(); |
381 if (RE2::PartialMatch(style_str, width_str) && | 151 if (RE2::PartialMatch(style_str, width_str) && |
382 RE2::PartialMatch(style_str, height_str)) | 152 RE2::PartialMatch(style_str, height_str)) |
383 element.setAttribute("style", "display: none;"); | 153 element.setAttribute("style", "display: none;"); |
384 } | 154 } |
385 } | 155 } |
386 } | 156 } |
387 } | 157 } |
388 | 158 |
389 void PluginPlaceholder::WillDestroyPlugin() { | 159 void PluginPlaceholder::WillDestroyPlugin() { delete this; } |
390 delete this; | |
391 } | |
392 | |
393 #if defined(ENABLE_PLUGIN_INSTALLATION) | |
394 void PluginPlaceholder::OnDidNotFindMissingPlugin() { | |
395 SetMessage(l10n_util::GetStringUTF16(IDS_PLUGIN_NOT_FOUND)); | |
396 } | |
397 | |
398 void PluginPlaceholder::OnFoundMissingPlugin(const string16& plugin_name) { | |
399 if (status_->value == ChromeViewHostMsg_GetPluginInfo_Status::kNotFound) | |
400 SetMessage(l10n_util::GetStringFUTF16(IDS_PLUGIN_FOUND, plugin_name)); | |
401 has_host_ = true; | |
402 plugin_name_ = plugin_name; | |
403 } | |
404 | |
405 void PluginPlaceholder::OnStartedDownloadingPlugin() { | |
406 SetMessage(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOADING, plugin_name_)); | |
407 } | |
408 | |
409 void PluginPlaceholder::OnFinishedDownloadingPlugin() { | |
410 bool is_installing = | |
411 status_->value == ChromeViewHostMsg_GetPluginInfo_Status::kNotFound; | |
412 SetMessage(l10n_util::GetStringFUTF16( | |
413 is_installing ? IDS_PLUGIN_INSTALLING : IDS_PLUGIN_UPDATING, | |
414 plugin_name_)); | |
415 } | |
416 | |
417 void PluginPlaceholder::OnErrorDownloadingPlugin(const std::string& error) { | |
418 SetMessage(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_ERROR, | |
419 UTF8ToUTF16(error))); | |
420 } | |
421 | |
422 void PluginPlaceholder::OnCancelledDownloadingPlugin() { | |
423 SetMessage(l10n_util::GetStringFUTF16(IDS_PLUGIN_DOWNLOAD_CANCELLED, | |
424 plugin_name_)); | |
425 } | |
426 #endif // defined(ENABLE_PLUGIN_INSTALLATION) | |
427 | |
428 void PluginPlaceholder::PluginListChanged() { | |
429 if (!frame_) | |
430 return; | |
431 WebDocument document = frame_->top()->document(); | |
432 if (document.isNull()) | |
433 return; | |
434 | |
435 ChromeViewHostMsg_GetPluginInfo_Output output; | |
436 std::string mime_type(plugin_params_.mimeType.utf8()); | |
437 render_view()->Send(new ChromeViewHostMsg_GetPluginInfo( | |
438 routing_id(), GURL(plugin_params_.url), document.url(), | |
439 mime_type, &output)); | |
440 if (output.status.value == status_->value) | |
441 return; | |
442 WebPlugin* new_plugin = chrome::ChromeContentRendererClient::CreatePlugin( | |
443 render_view(), frame_, plugin_params_, output); | |
444 ReplacePlugin(new_plugin); | |
445 } | |
446 | |
447 void PluginPlaceholder::OnMenuAction(int request_id, unsigned action) { | |
448 DCHECK_EQ(context_menu_request_id_, request_id); | |
449 if (g_last_active_menu != this) | |
450 return; | |
451 switch (action) { | |
452 case chrome::MENU_COMMAND_PLUGIN_RUN: { | |
453 RenderThread::Get()->RecordUserMetrics("Plugin_Load_Menu"); | |
454 LoadPlugin(); | |
455 break; | |
456 } | |
457 case chrome::MENU_COMMAND_PLUGIN_HIDE: { | |
458 RenderThread::Get()->RecordUserMetrics("Plugin_Hide_Menu"); | |
459 HidePlugin(); | |
460 break; | |
461 } | |
462 default: | |
463 NOTREACHED(); | |
464 } | |
465 } | |
466 | |
467 void PluginPlaceholder::OnMenuClosed(int request_id) { | |
468 DCHECK_EQ(context_menu_request_id_, request_id); | |
469 context_menu_request_id_ = 0; | |
470 } | |
471 | 160 |
472 void PluginPlaceholder::SetMessage(const string16& message) { | 161 void PluginPlaceholder::SetMessage(const string16& message) { |
473 message_ = message; | 162 message_ = message; |
474 if (finished_loading_) | 163 if (finished_loading_) |
475 UpdateMessage(); | 164 UpdateMessage(); |
476 } | 165 } |
477 | 166 |
478 void PluginPlaceholder::UpdateMessage() { | 167 void PluginPlaceholder::UpdateMessage() { |
479 std::string script = "window.setMessage(" + | 168 std::string script = |
480 base::GetDoubleQuotedJson(message_) + ")"; | 169 "window.setMessage(" + base::GetDoubleQuotedJson(message_) + ")"; |
481 plugin_->web_view()->mainFrame()->executeScript( | 170 plugin_->web_view()->mainFrame()->executeScript( |
482 WebScriptSource(ASCIIToUTF16(script))); | 171 WebScriptSource(ASCIIToUTF16(script))); |
483 } | 172 } |
484 | 173 |
485 void PluginPlaceholder::ShowContextMenu(const WebMouseEvent& event) { | 174 void PluginPlaceholder::ShowContextMenu(const WebMouseEvent& event) { |
486 if (context_menu_request_id_) | 175 // Does nothing by default. Will be overridden if a specific browser wants |
487 return; // Don't allow nested context menu requests. | 176 // a context menu. |
488 | 177 return; |
489 content::ContextMenuParams params; | |
490 | |
491 content::MenuItem name_item; | |
492 name_item.label = title_; | |
493 params.custom_items.push_back(name_item); | |
494 | |
495 content::MenuItem separator_item; | |
496 separator_item.type = content::MenuItem::SEPARATOR; | |
497 params.custom_items.push_back(separator_item); | |
498 | |
499 if (!plugin_info_.path.value().empty()) { | |
500 content::MenuItem run_item; | |
501 run_item.action = chrome::MENU_COMMAND_PLUGIN_RUN; | |
502 // Disable this menu item if the plugin is blocked by policy. | |
503 run_item.enabled = allow_loading_; | |
504 run_item.label = l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLUGIN_RUN); | |
505 params.custom_items.push_back(run_item); | |
506 } | |
507 | |
508 content::MenuItem hide_item; | |
509 hide_item.action = chrome::MENU_COMMAND_PLUGIN_HIDE; | |
510 hide_item.enabled = true; | |
511 hide_item.label = l10n_util::GetStringUTF16(IDS_CONTENT_CONTEXT_PLUGIN_HIDE); | |
512 params.custom_items.push_back(hide_item); | |
513 | |
514 params.x = event.windowX; | |
515 params.y = event.windowY; | |
516 | |
517 context_menu_request_id_ = render_view()->ShowContextMenu(this, params); | |
518 g_last_active_menu = this; | |
519 } | 178 } |
520 | 179 |
521 void PluginPlaceholder::OnLoadBlockedPlugins(const std::string& identifier) { | 180 void PluginPlaceholder::OnLoadBlockedPlugins(const std::string& identifier) { |
522 if (!identifier.empty() && identifier != identifier_) | 181 if (!identifier.empty() && identifier != identifier_) |
523 return; | 182 return; |
524 | 183 |
525 RenderThread::Get()->RecordUserMetrics("Plugin_Load_UI"); | 184 RenderThread::Get()->RecordUserMetrics("Plugin_Load_UI"); |
526 LoadPlugin(); | 185 LoadPlugin(); |
527 } | 186 } |
528 | 187 |
(...skipping 28 matching lines...) Expand all Loading... | |
557 RenderThread::Get()->RecordUserMetrics("Plugin_Load_Click"); | 216 RenderThread::Get()->RecordUserMetrics("Plugin_Load_Click"); |
558 LoadPlugin(); | 217 LoadPlugin(); |
559 } | 218 } |
560 | 219 |
561 void PluginPlaceholder::HideCallback(const CppArgumentList& args, | 220 void PluginPlaceholder::HideCallback(const CppArgumentList& args, |
562 CppVariant* result) { | 221 CppVariant* result) { |
563 RenderThread::Get()->RecordUserMetrics("Plugin_Hide_Click"); | 222 RenderThread::Get()->RecordUserMetrics("Plugin_Hide_Click"); |
564 HidePlugin(); | 223 HidePlugin(); |
565 } | 224 } |
566 | 225 |
567 void PluginPlaceholder::OpenAboutPluginsCallback(const CppArgumentList& args, | |
568 CppVariant* result) { | |
569 RenderThread::Get()->Send( | |
570 new ChromeViewHostMsg_OpenAboutPlugins(routing_id())); | |
571 } | |
572 | |
573 void PluginPlaceholder::DidFinishLoadingCallback(const CppArgumentList& args, | 226 void PluginPlaceholder::DidFinishLoadingCallback(const CppArgumentList& args, |
574 CppVariant* result) { | 227 CppVariant* result) { |
575 finished_loading_ = true; | 228 finished_loading_ = true; |
576 if (message_.length() > 0) | 229 if (message_.length() > 0) |
577 UpdateMessage(); | 230 UpdateMessage(); |
578 } | 231 } |
579 | 232 |
580 #if defined(ENABLE_MOBILE_YOUTUBE_PLUGIN) | 233 void PluginPlaceholder::SetPluginInfo( |
581 void PluginPlaceholder::OpenYoutubeUrlCallback(const CppArgumentList& args, | 234 const content::WebPluginInfo& plugin_info) { |
582 CppVariant* result) { | 235 plugin_info_ = plugin_info; |
583 std::string youtube("vnd.youtube:"); | |
584 GURL url(youtube.append(GetYoutubeVideoId(plugin_params_))); | |
585 WebURLRequest request; | |
586 request.initialize(); | |
587 request.setURL(url); | |
588 render_view()->LoadURLExternally( | |
589 frame_, request, WebKit::WebNavigationPolicyNewForegroundTab); | |
590 } | 236 } |
591 | 237 |
592 bool PluginPlaceholder::IsValidYouTubeVideo(const std::string& path) { | 238 const content::WebPluginInfo& PluginPlaceholder::GetPluginInfo() const { |
593 unsigned len = strlen(kSlashVSlash); | 239 return plugin_info_; |
594 | |
595 // check for more than just /v/ or /e/. | |
596 if (path.length() <= len) | |
597 return false; | |
598 | |
599 std::string str = StringToLowerASCII(path); | |
600 // Youtube flash url can start with /v/ or /e/. | |
601 if (strncmp(str.data(), kSlashVSlash, len) != 0 && | |
602 strncmp(str.data(), kSlashESlash, len) != 0) | |
603 return false; | |
604 | |
605 // Start after /v/ | |
606 for (unsigned i = len; i < path.length(); i++) { | |
607 char c = str[i]; | |
608 if (isalpha(c) || isdigit(c) || c == '_' || c == '-') | |
609 continue; | |
610 // The url can have more parameters such as &hl=en after the video id. | |
611 // Once we start seeing extra parameters we can return true. | |
612 return c == '&' && i > len; | |
613 } | |
614 return true; | |
615 } | 240 } |
616 | 241 |
617 bool PluginPlaceholder::IsYouTubeURL(const GURL& url, | 242 void PluginPlaceholder::SetIdentifier(const std::string& identifier) { |
618 const std::string& mime_type) { | 243 identifier_ = identifier; |
619 std::string host = url.host(); | 244 } |
620 bool is_youtube = EndsWith(host, "youtube.com", true) || | |
621 EndsWith(host, "youtube-nocookie.com", true); | |
622 | 245 |
623 return is_youtube && IsValidYouTubeVideo(url.path()) && | 246 WebKit::WebFrame* PluginPlaceholder::GetFrame() { return frame_; } |
624 LowerCaseEqualsASCII(mime_type, content::kFlashPluginSwfMimeType); | 247 |
248 const WebKit::WebPluginParams& PluginPlaceholder::GetPluginParams() const { | |
249 return plugin_params_; | |
625 } | 250 } |
626 #endif | |
OLD | NEW |