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 "content/renderer/browser_plugin/tests/browser_plugin_browsertest.h" | |
6 | |
7 #include "base/file_path.h" | |
8 #include "base/file_util.h" | |
9 #include "base/path_service.h" | |
10 #include "content/common/browser_plugin_messages.h" | |
11 #include "content/renderer/browser_plugin/browser_plugin.h" | |
12 #include "content/renderer/browser_plugin/tests/mock_browser_plugin.h" | |
13 #include "content/renderer/browser_plugin/tests/mock_browser_plugin_manager.h" | |
14 #include "content/renderer/render_thread_impl.h" | |
15 #include "content/renderer/renderer_webkitplatformsupport_impl.h" | |
16 #include "skia/ext/platform_canvas.h" | |
17 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" | |
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" | |
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h" | |
20 | |
21 namespace { | |
22 const char kHTMLBrowserPluginObject[] = | |
23 "<object id='browserplugin' width='640px' height='480px'" | |
24 " src='foo' type='application/new-browser-plugin'>"; | |
25 const char kThreadName[] = "RenderThread"; | |
26 } | |
27 | |
28 namespace content { | |
29 namespace browser_plugin { | |
30 | |
31 BrowserPluginTest::BrowserPluginTest() {} | |
32 | |
33 void BrowserPluginTest::SetUp() { | |
34 GetContentClient()->set_renderer_for_testing(&content_renderer_client_); | |
35 content::RenderViewTest::SetUp(); | |
36 browser_plugin_manager_.reset(new MockBrowserPluginManager()); | |
37 } | |
38 | |
39 void BrowserPluginTest::TearDown() { | |
40 browser_plugin_manager_->Cleanup(); | |
41 content::RenderViewTest::TearDown(); | |
42 } | |
43 | |
44 std::string BrowserPluginTest::ExecuteScriptAndReturnString( | |
45 const std::string& script) { | |
46 v8::Handle<v8::Value> value = GetMainFrame()->executeScriptAndReturnValue( | |
47 WebKit::WebScriptSource(WebKit::WebString::fromUTF8(script.c_str()))); | |
48 if (value.IsEmpty() || !value->IsString()) | |
49 return std::string(); | |
50 | |
51 v8::Local<v8::String> v8_str = value->ToString(); | |
52 int length = v8_str->Utf8Length() + 1; | |
53 scoped_array<char> str(new char[length]); | |
54 v8_str->WriteUtf8(str.get(), length); | |
55 return str.get(); | |
56 } | |
57 | |
58 // This test verifies that an initial resize occurs when we instantiate the | |
59 // browser plugin. This test also verifies that the browser plugin is waiting | |
60 // for a BrowserPluginMsg_UpdateRect in response. We issue an UpdateRect, and | |
61 // we observe an UpdateRect_ACK, with the resize_pending_ reset, indiciating | |
62 // that the BrowserPlugin is not waiting for any more UpdateRects to | |
63 // satisfy its resize request. | |
64 TEST_F(BrowserPluginTest, InitialResize) { | |
65 LoadHTML(kHTMLBrowserPluginObject); | |
66 // Verify that the information based on ResizeGuest is correct, and | |
67 // use its TransportDIB::Id to paint. | |
68 const IPC::Message* msg = | |
69 browser_plugin_manager()->sink().GetUniqueMessageMatching( | |
70 BrowserPluginHostMsg_ResizeGuest::ID); | |
71 ASSERT_TRUE(msg); | |
72 PickleIterator iter = IPC::SyncMessage::GetDataIterator(msg); | |
73 BrowserPluginHostMsg_ResizeGuest::SendParam resize_params; | |
74 ASSERT_TRUE(IPC::ReadParam(msg, &iter, &resize_params)); | |
75 int instance_id = resize_params.a; | |
76 int width = resize_params.c; | |
77 int height = resize_params.d; | |
78 bool resize_pending = resize_params.e; | |
79 EXPECT_EQ(640, width); | |
80 EXPECT_EQ(480, height); | |
81 // Verify that the browser plugin wasn't already waiting on a resize when this | |
82 // resize happened. | |
83 EXPECT_EQ(false, resize_pending); | |
84 | |
85 MockBrowserPlugin* browser_plugin = | |
86 static_cast<MockBrowserPlugin*>( | |
87 browser_plugin_manager()->GetBrowserPlugin(instance_id)); | |
88 ASSERT_TRUE(browser_plugin); | |
89 // Now the browser plugin is expecting a UpdateRect resize. | |
90 EXPECT_TRUE(browser_plugin->resize_pending_); | |
91 | |
92 // Send the BrowserPlugin an UpdateRect equal to its container size. | |
93 // That should clear the resize_pending_ flag. | |
94 BrowserPluginMsg_UpdateRect_Params update_rect_params; | |
95 update_rect_params.view_size = gfx::Size(640, 480); | |
96 update_rect_params.scale_factor = 1.0f; | |
97 update_rect_params.is_resize_ack = true; | |
98 browser_plugin->UpdateRect(0, update_rect_params); | |
99 EXPECT_FALSE(browser_plugin->resize_pending_); | |
100 } | |
101 | |
102 // Verify that the src attribute on the browser plugin works as expected. | |
103 TEST_F(BrowserPluginTest, SrcAttribute) { | |
104 LoadHTML(kHTMLBrowserPluginObject); | |
105 // Verify that we're reporting the correct URL to navigate to based on the | |
106 // src attribute. | |
107 { | |
108 const IPC::Message* msg = | |
109 browser_plugin_manager()->sink().GetUniqueMessageMatching( | |
110 BrowserPluginHostMsg_NavigateFromEmbedder::ID); | |
111 ASSERT_TRUE(msg); | |
112 | |
113 int instance_id; | |
114 long long frame_id; | |
115 std::string src; | |
116 BrowserPluginHostMsg_NavigateFromEmbedder::Read( | |
117 msg, | |
118 &instance_id, | |
119 &frame_id, | |
120 &src); | |
121 EXPECT_EQ("foo", src); | |
122 } | |
123 | |
124 browser_plugin_manager()->sink().ClearMessages(); | |
125 // Navigate to bar and observe the associated | |
126 // BrowserPluginHostMsg_NavigateFromEmbedder message. | |
127 // Verify that the src attribute is updated as well. | |
128 ExecuteJavaScript("document.getElementById('browserplugin').src = 'bar'"); | |
129 { | |
130 const IPC::Message* msg = | |
131 browser_plugin_manager()->sink().GetUniqueMessageMatching( | |
132 BrowserPluginHostMsg_NavigateFromEmbedder::ID); | |
Charlie Reis
2012/08/01 23:20:51
Just trying to make sure I follow this correctly--
Fady Samuel
2012/08/02 18:32:47
Yup. We're checking to make sure that writing to a
| |
133 ASSERT_TRUE(msg); | |
134 | |
135 int instance_id; | |
136 long long frame_id; | |
137 std::string src; | |
138 BrowserPluginHostMsg_NavigateFromEmbedder::Read( | |
139 msg, | |
140 &instance_id, | |
141 &frame_id, | |
142 &src); | |
143 EXPECT_EQ("bar", src); | |
144 std::string src_value = | |
145 ExecuteScriptAndReturnString( | |
146 "document.getElementById('browserplugin').src"); | |
147 EXPECT_EQ("bar", src_value); | |
148 } | |
149 } | |
150 | |
151 TEST_F(BrowserPluginTest, ResizeFlowControl) { | |
152 LoadHTML(kHTMLBrowserPluginObject); | |
153 browser_plugin_manager()->sink().ClearMessages(); | |
154 | |
155 // Resize the browser plugin three times. | |
156 ExecuteJavaScript("document.getElementById('browserplugin').width = '641px'"); | |
157 ProcessPendingMessages(); | |
158 ExecuteJavaScript("document.getElementById('browserplugin').width = '642px'"); | |
159 ProcessPendingMessages(); | |
160 ExecuteJavaScript("document.getElementById('browserplugin').width = '643px'"); | |
161 ProcessPendingMessages(); | |
162 | |
163 // Expect to see three messsages in the sink. | |
164 EXPECT_EQ(3u, browser_plugin_manager()->sink().message_count()); | |
165 const IPC::Message* msg = | |
166 browser_plugin_manager()->sink().GetFirstMessageMatching( | |
167 BrowserPluginHostMsg_ResizeGuest::ID); | |
168 ASSERT_TRUE(msg); | |
169 PickleIterator iter = IPC::SyncMessage::GetDataIterator(msg); | |
170 BrowserPluginHostMsg_ResizeGuest::SendParam resize_params; | |
171 ASSERT_TRUE(IPC::ReadParam(msg, &iter, &resize_params)); | |
172 int instance_id = resize_params.a; | |
173 int width = resize_params.c; | |
174 int height = resize_params.d; | |
175 bool resize_pending = resize_params.e; | |
176 EXPECT_EQ(641, width); | |
177 EXPECT_EQ(480, height); | |
178 // This indicates that the BrowserPlugin has sent out a previous resize | |
179 // request but has not yet received an UpdateRect for that request. | |
180 // We send this resize regardless to update the damage buffer in the | |
181 // browser process, so it's ready when the guest sends the appropriate | |
182 // UpdateRect. | |
183 EXPECT_TRUE(resize_pending); | |
184 | |
185 MockBrowserPlugin* browser_plugin = | |
186 static_cast<MockBrowserPlugin*>( | |
187 browser_plugin_manager()->GetBrowserPlugin(instance_id)); | |
188 ASSERT_TRUE(browser_plugin); | |
189 { | |
190 // We send a stale UpdateRect to the BrowserPlugin. | |
191 BrowserPluginMsg_UpdateRect_Params update_rect_params; | |
192 update_rect_params.view_size = gfx::Size(640, 480); | |
193 update_rect_params.scale_factor = 1.0f; | |
194 update_rect_params.is_resize_ack = true; | |
195 browser_plugin->UpdateRect(0, update_rect_params); | |
196 // This tells us that the BrowserPlugin is still expecting another | |
197 // UpdateRect with the most recent size. | |
198 EXPECT_TRUE(browser_plugin->resize_pending_); | |
199 } | |
200 { | |
201 BrowserPluginMsg_UpdateRect_Params update_rect_params; | |
202 update_rect_params.view_size = gfx::Size(643, 480); | |
203 update_rect_params.scale_factor = 1.0f; | |
204 update_rect_params.is_resize_ack = true; | |
205 browser_plugin->UpdateRect(0, update_rect_params); | |
206 // The BrowserPlugin has finally received an UpdateRect that satisifes | |
207 // its current size, and so it is happy. | |
208 EXPECT_FALSE(browser_plugin->resize_pending_); | |
209 } | |
210 } | |
211 | |
212 TEST_F(BrowserPluginTest, GuestCrash) { | |
213 LoadHTML(kHTMLBrowserPluginObject); | |
214 | |
215 // Grab the BrowserPlugin's instance ID from its resize message. | |
216 const IPC::Message* msg = | |
217 browser_plugin_manager()->sink().GetFirstMessageMatching( | |
218 BrowserPluginHostMsg_ResizeGuest::ID); | |
219 ASSERT_TRUE(msg); | |
220 PickleIterator iter = IPC::SyncMessage::GetDataIterator(msg); | |
221 BrowserPluginHostMsg_ResizeGuest::SendParam resize_params; | |
222 ASSERT_TRUE(IPC::ReadParam(msg, &iter, &resize_params)); | |
223 int instance_id = resize_params.a; | |
224 | |
225 MockBrowserPlugin* browser_plugin = | |
226 static_cast<MockBrowserPlugin*>( | |
227 browser_plugin_manager()->GetBrowserPlugin(instance_id)); | |
228 ASSERT_TRUE(browser_plugin); | |
229 | |
230 WebKit::WebCursorInfo cursor_info; | |
231 // Send an event and verify that the event is deported. | |
232 browser_plugin->handleInputEvent(WebKit::WebMouseEvent(), | |
233 cursor_info); | |
234 EXPECT_TRUE(browser_plugin_manager()->sink().GetUniqueMessageMatching( | |
235 BrowserPluginHostMsg_HandleInputEvent::ID)); | |
236 browser_plugin_manager()->sink().ClearMessages(); | |
237 | |
238 // Pretend that the guest has crashed | |
239 browser_plugin->GuestCrashed(); | |
240 // Send an event and verify that events are no longer deported. | |
241 browser_plugin->handleInputEvent(WebKit::WebMouseEvent(), | |
242 cursor_info); | |
243 EXPECT_FALSE(browser_plugin_manager()->sink().GetUniqueMessageMatching( | |
244 BrowserPluginHostMsg_HandleInputEvent::ID)); | |
245 | |
246 // Navigate and verify that the guest_crashed_ flag has been reset. | |
247 browser_plugin->SetSrcAttribute("bar"); | |
248 EXPECT_FALSE(browser_plugin->guest_crashed_); | |
249 | |
250 } | |
251 | |
252 TEST_F(BrowserPluginTest, RemovePlugin) { | |
253 LoadHTML(kHTMLBrowserPluginObject); | |
254 EXPECT_FALSE(browser_plugin_manager()->sink().GetUniqueMessageMatching( | |
255 BrowserPluginHostMsg_PluginDestroyed::ID)); | |
256 ExecuteJavaScript("x = document.getElementById('browserplugin'); " | |
257 "x.parentNode.removeChild(x);"); | |
258 ProcessPendingMessages(); | |
259 EXPECT_TRUE(browser_plugin_manager()->sink().GetUniqueMessageMatching( | |
260 BrowserPluginHostMsg_PluginDestroyed::ID)); | |
261 } | |
262 | |
263 TEST_F(BrowserPluginTest, CustomEvents) { | |
264 const char* kAddEventListener = | |
265 "var url;" | |
266 "function nav(u) {" | |
267 " url = u;" | |
268 "}" | |
269 "document.getElementById('browserplugin')." | |
270 " addEventListener('navigation', nav);"; | |
271 const char* kRemoveEventListener = | |
272 "document.getElementById('browserplugin')." | |
273 " removeEventListener('navigation', nav);"; | |
274 const char* kGoogleURL = "http://www.google.com/"; | |
275 const char* kGoogleNewsURL = "http://news.google.com/"; | |
276 | |
277 LoadHTML(kHTMLBrowserPluginObject); | |
278 ExecuteJavaScript(kAddEventListener); | |
279 // Grab the BrowserPlugin's instance ID from its resize message. | |
280 const IPC::Message* msg = | |
281 browser_plugin_manager()->sink().GetFirstMessageMatching( | |
282 BrowserPluginHostMsg_ResizeGuest::ID); | |
283 ASSERT_TRUE(msg); | |
284 PickleIterator iter = IPC::SyncMessage::GetDataIterator(msg); | |
285 BrowserPluginHostMsg_ResizeGuest::SendParam resize_params; | |
286 ASSERT_TRUE(IPC::ReadParam(msg, &iter, &resize_params)); | |
287 int instance_id = resize_params.a; | |
288 | |
289 MockBrowserPlugin* browser_plugin = | |
290 static_cast<MockBrowserPlugin*>( | |
291 browser_plugin_manager()->GetBrowserPlugin(instance_id)); | |
292 ASSERT_TRUE(browser_plugin); | |
293 | |
294 browser_plugin->UpdateURL(GURL(kGoogleURL)); | |
295 EXPECT_EQ(kGoogleURL, ExecuteScriptAndReturnString("url")); | |
296 | |
297 ExecuteJavaScript(kRemoveEventListener); | |
298 browser_plugin->UpdateURL(GURL(kGoogleNewsURL)); | |
299 // The URL variable should not change because we've removed the event | |
300 // listener. | |
301 EXPECT_EQ(kGoogleURL, ExecuteScriptAndReturnString("url")); | |
302 } | |
303 | |
304 } | |
305 } | |
OLD | NEW |