Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / renderer / browser_plugin / browser_plugin_browsertest.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 "content/renderer/browser_plugin/browser_plugin_browsertest.h"
6
7 #include "base/debug/leak_annotations.h"
8 #include "base/files/file_path.h"
9 #include "base/memory/singleton.h"
10 #include "base/path_service.h"
11 #include "base/pickle.h"
12 #include "content/public/common/content_constants.h"
13 #include "content/public/renderer/content_renderer_client.h"
14 #include "content/renderer/browser_plugin/browser_plugin.h"
15 #include "content/renderer/browser_plugin/browser_plugin_manager_factory.h"
16 #include "content/renderer/browser_plugin/mock_browser_plugin.h"
17 #include "content/renderer/browser_plugin/mock_browser_plugin_manager.h"
18 #include "content/renderer/render_thread_impl.h"
19 #include "content/renderer/renderer_webkitplatformsupport_impl.h"
20 #include "skia/ext/platform_canvas.h"
21 #include "third_party/WebKit/public/platform/WebCursorInfo.h"
22 #include "third_party/WebKit/public/web/WebInputEvent.h"
23 #include "third_party/WebKit/public/web/WebLocalFrame.h"
24 #include "third_party/WebKit/public/web/WebScriptSource.h"
25
26 namespace content {
27
28 namespace {
29 const char kHTMLForBrowserPluginObject[] =
30     "<object id='browserplugin' width='640px' height='480px'"
31     " src='foo' type='%s'></object>"
32     "<script>document.querySelector('object').nonExistentAttribute;</script>";
33
34 const char kHTMLForBrowserPluginWithAllAttributes[] =
35     "<object id='browserplugin' width='640' height='480' type='%s'"
36     " autosize maxheight='600' maxwidth='800' minheight='240'"
37     " minwidth='320' name='Jim' partition='someid' src='foo'>";
38
39 const char kHTMLForSourcelessPluginObject[] =
40     "<object id='browserplugin' width='640px' height='480px' type='%s'>";
41
42 const char kHTMLForPartitionedPluginObject[] =
43     "<object id='browserplugin' width='640px' height='480px'"
44     "  src='foo' type='%s' partition='someid'>";
45
46 const char kHTMLForInvalidPartitionedPluginObject[] =
47     "<object id='browserplugin' width='640px' height='480px'"
48     "  type='%s' partition='persist:'>";
49
50 const char kHTMLForPartitionedPersistedPluginObject[] =
51     "<object id='browserplugin' width='640px' height='480px'"
52     "  src='foo' type='%s' partition='persist:someid'>";
53
54 std::string GetHTMLForBrowserPluginObject() {
55   return base::StringPrintf(kHTMLForBrowserPluginObject,
56                             kBrowserPluginMimeType);
57 }
58
59 }  // namespace
60
61 class TestContentRendererClient : public ContentRendererClient {
62  public:
63   TestContentRendererClient() : ContentRendererClient() {
64   }
65   virtual ~TestContentRendererClient() {
66   }
67   virtual bool AllowBrowserPlugin(
68       blink::WebPluginContainer* container) OVERRIDE {
69     // Allow BrowserPlugin for tests.
70     return true;
71   }
72 };
73
74 // Test factory for creating test instances of BrowserPluginManager.
75 class TestBrowserPluginManagerFactory : public BrowserPluginManagerFactory {
76  public:
77   virtual MockBrowserPluginManager* CreateBrowserPluginManager(
78       RenderViewImpl* render_view) OVERRIDE {
79     return new MockBrowserPluginManager(render_view);
80   }
81
82   // Singleton getter.
83   static TestBrowserPluginManagerFactory* GetInstance() {
84     return Singleton<TestBrowserPluginManagerFactory>::get();
85   }
86
87  protected:
88   TestBrowserPluginManagerFactory() {}
89   virtual ~TestBrowserPluginManagerFactory() {}
90
91  private:
92   // For Singleton.
93   friend struct DefaultSingletonTraits<TestBrowserPluginManagerFactory>;
94
95   DISALLOW_COPY_AND_ASSIGN(TestBrowserPluginManagerFactory);
96 };
97
98 BrowserPluginTest::BrowserPluginTest() {}
99
100 BrowserPluginTest::~BrowserPluginTest() {}
101
102 void BrowserPluginTest::SetUp() {
103   BrowserPluginManager::set_factory_for_testing(
104       TestBrowserPluginManagerFactory::GetInstance());
105   content::RenderViewTest::SetUp();
106 }
107
108 void BrowserPluginTest::TearDown() {
109   BrowserPluginManager::set_factory_for_testing(
110       TestBrowserPluginManagerFactory::GetInstance());
111 #if defined(LEAK_SANITIZER)
112   // Do this before shutting down V8 in RenderViewTest::TearDown().
113   // http://crbug.com/328552
114   __lsan_do_leak_check();
115 #endif
116   RenderViewTest::TearDown();
117 }
118
119 ContentRendererClient* BrowserPluginTest::CreateContentRendererClient() {
120   return new TestContentRendererClient;
121 }
122
123 std::string BrowserPluginTest::ExecuteScriptAndReturnString(
124     const std::string& script) {
125   v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
126   v8::Handle<v8::Value> value = GetMainFrame()->executeScriptAndReturnValue(
127       blink::WebScriptSource(blink::WebString::fromUTF8(script.c_str())));
128   if (value.IsEmpty() || !value->IsString())
129     return std::string();
130
131   v8::Local<v8::String> v8_str = value->ToString();
132   int length = v8_str->Utf8Length() + 1;
133   scoped_ptr<char[]> str(new char[length]);
134   v8_str->WriteUtf8(str.get(), length);
135   return str.get();
136 }
137
138 int BrowserPluginTest::ExecuteScriptAndReturnInt(
139     const std::string& script) {
140   v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
141   v8::Handle<v8::Value> value = GetMainFrame()->executeScriptAndReturnValue(
142       blink::WebScriptSource(blink::WebString::fromUTF8(script.c_str())));
143   if (value.IsEmpty() || !value->IsInt32())
144     return 0;
145
146   return value->Int32Value();
147 }
148
149 // A return value of false means that a value was not present. The return value
150 // of the script is stored in |result|
151 bool BrowserPluginTest::ExecuteScriptAndReturnBool(
152     const std::string& script, bool* result) {
153   v8::HandleScope handle_scope(v8::Isolate::GetCurrent());
154   v8::Handle<v8::Value> value = GetMainFrame()->executeScriptAndReturnValue(
155       blink::WebScriptSource(blink::WebString::fromUTF8(script.c_str())));
156   if (value.IsEmpty() || !value->IsBoolean())
157     return false;
158
159   *result = value->BooleanValue();
160   return true;
161 }
162
163 MockBrowserPlugin* BrowserPluginTest::GetCurrentPlugin() {
164   BrowserPluginHostMsg_Attach_Params params;
165   return GetCurrentPluginWithAttachParams(&params);
166 }
167
168 MockBrowserPlugin* BrowserPluginTest::GetCurrentPluginWithAttachParams(
169     BrowserPluginHostMsg_Attach_Params* params) {
170   int instance_id = 0;
171   const IPC::Message* msg =
172       browser_plugin_manager()->sink().GetUniqueMessageMatching(
173           BrowserPluginHostMsg_Attach::ID);
174   if (!msg)
175     return NULL;
176
177   PickleIterator iter(*msg);
178   if (!iter.ReadInt(&instance_id))
179     return NULL;
180
181   if (!IPC::ParamTraits<BrowserPluginHostMsg_Attach_Params>::Read(
182       msg, &iter, params))
183     return NULL;
184
185   MockBrowserPlugin* browser_plugin = static_cast<MockBrowserPlugin*>(
186       browser_plugin_manager()->GetBrowserPlugin(instance_id));
187
188   BrowserPluginMsg_Attach_ACK_Params attach_ack_params;
189   browser_plugin->OnAttachACK(instance_id, attach_ack_params);
190
191   return browser_plugin;
192 }
193
194 // This test verifies that an initial resize occurs when we instantiate the
195 // browser plugin.
196 TEST_F(BrowserPluginTest, InitialResize) {
197   LoadHTML(GetHTMLForBrowserPluginObject().c_str());
198   // Verify that the information in Attach is correct.
199   BrowserPluginHostMsg_Attach_Params params;
200   MockBrowserPlugin* browser_plugin = GetCurrentPluginWithAttachParams(&params);
201
202   EXPECT_EQ(640, params.resize_guest_params.view_rect.width());
203   EXPECT_EQ(480, params.resize_guest_params.view_rect.height());
204   ASSERT_TRUE(browser_plugin);
205 }
206
207 // This test verifies that all attributes (present at the time of writing) are
208 // parsed on initialization. However, this test does minimal checking of
209 // correct behavior.
210 TEST_F(BrowserPluginTest, ParseAllAttributes) {
211   std::string html = base::StringPrintf(kHTMLForBrowserPluginWithAllAttributes,
212                                         kBrowserPluginMimeType);
213   LoadHTML(html.c_str());
214   bool result;
215   bool has_value = ExecuteScriptAndReturnBool(
216       "document.getElementById('browserplugin').autosize", &result);
217   EXPECT_TRUE(has_value);
218   EXPECT_TRUE(result);
219   int maxHeight = ExecuteScriptAndReturnInt(
220       "document.getElementById('browserplugin').maxheight");
221   EXPECT_EQ(600, maxHeight);
222   int maxWidth = ExecuteScriptAndReturnInt(
223       "document.getElementById('browserplugin').maxwidth");
224   EXPECT_EQ(800, maxWidth);
225   int minHeight = ExecuteScriptAndReturnInt(
226       "document.getElementById('browserplugin').minheight");
227   EXPECT_EQ(240, minHeight);
228   int minWidth = ExecuteScriptAndReturnInt(
229       "document.getElementById('browserplugin').minwidth");
230   EXPECT_EQ(320, minWidth);
231   std::string name = ExecuteScriptAndReturnString(
232       "document.getElementById('browserplugin').name");
233   EXPECT_STREQ("Jim", name.c_str());
234   std::string partition = ExecuteScriptAndReturnString(
235       "document.getElementById('browserplugin').partition");
236   EXPECT_STREQ("someid", partition.c_str());
237   std::string src = ExecuteScriptAndReturnString(
238       "document.getElementById('browserplugin').src");
239   EXPECT_STREQ("foo", src.c_str());
240 }
241
242 // Verify that the src attribute on the browser plugin works as expected.
243 TEST_F(BrowserPluginTest, SrcAttribute) {
244   LoadHTML(GetHTMLForBrowserPluginObject().c_str());
245   // Verify that we're reporting the correct URL to navigate to based on the
246   // src attribute.
247   {
248     BrowserPluginHostMsg_Attach_Params params;
249     MockBrowserPlugin* browser_plugin =
250         GetCurrentPluginWithAttachParams(&params);
251     ASSERT_TRUE(browser_plugin);
252     EXPECT_EQ("foo", params.src);
253   }
254
255   browser_plugin_manager()->sink().ClearMessages();
256   // Navigate to bar and observe the associated
257   // BrowserPluginHostMsg_NavigateGuest message.
258   // Verify that the src attribute is updated as well.
259   ExecuteJavaScript("document.getElementById('browserplugin').src = 'bar'");
260   {
261     // Verify that we do not get a Attach on subsequent navigations.
262     const IPC::Message* create_msg =
263         browser_plugin_manager()->sink().GetUniqueMessageMatching(
264             BrowserPluginHostMsg_Attach::ID);
265     ASSERT_FALSE(create_msg);
266
267     const IPC::Message* msg =
268         browser_plugin_manager()->sink().GetUniqueMessageMatching(
269             BrowserPluginHostMsg_NavigateGuest::ID);
270     ASSERT_TRUE(msg);
271
272     int instance_id = 0;
273     std::string src;
274     BrowserPluginHostMsg_NavigateGuest::Read(msg, &instance_id, &src);
275     EXPECT_EQ("bar", src);
276     std::string src_value =
277         ExecuteScriptAndReturnString(
278             "document.getElementById('browserplugin').src");
279     EXPECT_EQ("bar", src_value);
280   }
281 }
282
283 TEST_F(BrowserPluginTest, ResizeFlowControl) {
284   LoadHTML(GetHTMLForBrowserPluginObject().c_str());
285   MockBrowserPlugin* browser_plugin = GetCurrentPlugin();
286   ASSERT_TRUE(browser_plugin);
287   int instance_id = browser_plugin->guest_instance_id();
288   // Send an UpdateRect to the BrowserPlugin to make sure the browser sees a
289   // resize related (SetAutoSize) message.
290   {
291     // We send a stale UpdateRect to the BrowserPlugin.
292     BrowserPluginMsg_UpdateRect_Params update_rect_params;
293     update_rect_params.view_size = gfx::Size(640, 480);
294     update_rect_params.scale_factor = 1.0f;
295     update_rect_params.is_resize_ack = true;
296     BrowserPluginMsg_UpdateRect msg(instance_id, update_rect_params);
297     browser_plugin->OnMessageReceived(msg);
298   }
299
300   browser_plugin_manager()->sink().ClearMessages();
301
302   // Resize the browser plugin three times.
303
304   ExecuteJavaScript("document.getElementById('browserplugin').width = '641px'");
305   GetMainFrame()->view()->layout();
306   ProcessPendingMessages();
307
308   ExecuteJavaScript("document.getElementById('browserplugin').width = '642px'");
309   GetMainFrame()->view()->layout();
310   ProcessPendingMessages();
311
312   ExecuteJavaScript("document.getElementById('browserplugin').width = '643px'");
313   GetMainFrame()->view()->layout();
314   ProcessPendingMessages();
315
316   // Expect to see one resize messsage in the sink. BrowserPlugin will not issue
317   // subsequent resize requests until the first request is satisfied by the
318   // guest. The rest of the messages could be
319   // BrowserPluginHostMsg_UpdateGeometry msgs.
320   EXPECT_LE(1u, browser_plugin_manager()->sink().message_count());
321   for (size_t i = 0; i < browser_plugin_manager()->sink().message_count();
322        ++i) {
323     const IPC::Message* msg = browser_plugin_manager()->sink().GetMessageAt(i);
324     if (msg->type() != BrowserPluginHostMsg_ResizeGuest::ID)
325       EXPECT_EQ(msg->type(), BrowserPluginHostMsg_UpdateGeometry::ID);
326   }
327   const IPC::Message* msg =
328       browser_plugin_manager()->sink().GetUniqueMessageMatching(
329           BrowserPluginHostMsg_ResizeGuest::ID);
330   ASSERT_TRUE(msg);
331   BrowserPluginHostMsg_ResizeGuest_Params params;
332   BrowserPluginHostMsg_ResizeGuest::Read(msg, &instance_id, &params);
333   EXPECT_EQ(641, params.view_rect.width());
334   EXPECT_EQ(480, params.view_rect.height());
335
336   {
337     // We send a stale UpdateRect to the BrowserPlugin.
338     BrowserPluginMsg_UpdateRect_Params update_rect_params;
339     update_rect_params.view_size = gfx::Size(641, 480);
340     update_rect_params.scale_factor = 1.0f;
341     update_rect_params.is_resize_ack = true;
342     BrowserPluginMsg_UpdateRect msg(instance_id, update_rect_params);
343     browser_plugin->OnMessageReceived(msg);
344   }
345   // Send the BrowserPlugin another UpdateRect, but this time with a size
346   // that matches the size of the container.
347   {
348     BrowserPluginMsg_UpdateRect_Params update_rect_params;
349     update_rect_params.view_size = gfx::Size(643, 480);
350     update_rect_params.scale_factor = 1.0f;
351     update_rect_params.is_resize_ack = true;
352     BrowserPluginMsg_UpdateRect msg(instance_id, update_rect_params);
353     browser_plugin->OnMessageReceived(msg);
354   }
355 }
356
357 TEST_F(BrowserPluginTest, RemovePlugin) {
358   LoadHTML(GetHTMLForBrowserPluginObject().c_str());
359   EXPECT_FALSE(browser_plugin_manager()->sink().GetUniqueMessageMatching(
360       BrowserPluginHostMsg_PluginDestroyed::ID));
361   ExecuteJavaScript("x = document.getElementById('browserplugin'); "
362                     "x.parentNode.removeChild(x);");
363   ProcessPendingMessages();
364   EXPECT_TRUE(browser_plugin_manager()->sink().GetUniqueMessageMatching(
365       BrowserPluginHostMsg_PluginDestroyed::ID));
366 }
367
368 // This test verifies that PluginDestroyed messages do not get sent from a
369 // BrowserPlugin that has never navigated.
370 TEST_F(BrowserPluginTest, RemovePluginBeforeNavigation) {
371   std::string html = base::StringPrintf(kHTMLForSourcelessPluginObject,
372                                         kBrowserPluginMimeType);
373   LoadHTML(html.c_str());
374   EXPECT_FALSE(browser_plugin_manager()->sink().GetUniqueMessageMatching(
375       BrowserPluginHostMsg_PluginDestroyed::ID));
376   ExecuteJavaScript("x = document.getElementById('browserplugin'); "
377                     "x.parentNode.removeChild(x);");
378   ProcessPendingMessages();
379   EXPECT_FALSE(browser_plugin_manager()->sink().GetUniqueMessageMatching(
380       BrowserPluginHostMsg_PluginDestroyed::ID));
381 }
382
383 // Verify that the 'partition' attribute on the browser plugin is parsed
384 // correctly.
385 TEST_F(BrowserPluginTest, PartitionAttribute) {
386   std::string html = base::StringPrintf(kHTMLForPartitionedPluginObject,
387                                         kBrowserPluginMimeType);
388   LoadHTML(html.c_str());
389   std::string partition_value = ExecuteScriptAndReturnString(
390       "document.getElementById('browserplugin').partition");
391   EXPECT_STREQ("someid", partition_value.c_str());
392
393   html = base::StringPrintf(kHTMLForPartitionedPersistedPluginObject,
394                             kBrowserPluginMimeType);
395   LoadHTML(html.c_str());
396   partition_value = ExecuteScriptAndReturnString(
397       "document.getElementById('browserplugin').partition");
398   EXPECT_STREQ("persist:someid", partition_value.c_str());
399
400   // Verify that once HTML has defined a source and partition, we cannot change
401   // the partition anymore.
402   ExecuteJavaScript(
403       "try {"
404       "  document.getElementById('browserplugin').partition = 'foo';"
405       "  document.title = 'success';"
406       "} catch (e) { document.title = e.message; }");
407   std::string title = ExecuteScriptAndReturnString("document.title");
408   EXPECT_STREQ(
409       "The object has already navigated, so its partition cannot be changed.",
410       title.c_str());
411
412   // Load a browser tag without 'src' defined.
413   html = base::StringPrintf(kHTMLForSourcelessPluginObject,
414                             kBrowserPluginMimeType);
415   LoadHTML(html.c_str());
416
417   // Ensure we don't parse just "persist:" string and return exception.
418   ExecuteJavaScript(
419       "try {"
420       "  document.getElementById('browserplugin').partition = 'persist:';"
421       "  document.title = 'success';"
422       "} catch (e) { document.title = e.message; }");
423   title = ExecuteScriptAndReturnString("document.title");
424   EXPECT_STREQ("Invalid partition attribute.", title.c_str());
425 }
426
427 // This test verifies that BrowserPlugin enters an error state when the
428 // partition attribute is invalid.
429 TEST_F(BrowserPluginTest, InvalidPartition) {
430   std::string html = base::StringPrintf(kHTMLForInvalidPartitionedPluginObject,
431                                         kBrowserPluginMimeType);
432   LoadHTML(html.c_str());
433   // Attempt to navigate with an invalid partition.
434   {
435     ExecuteJavaScript(
436         "try {"
437         "  document.getElementById('browserplugin').src = 'bar';"
438         "  document.title = 'success';"
439         "} catch (e) { document.title = e.message; }");
440     std::string title = ExecuteScriptAndReturnString("document.title");
441     EXPECT_STREQ("Invalid partition attribute.", title.c_str());
442     // Verify that the 'src' attribute has not been updated.
443     EXPECT_EQ("", ExecuteScriptAndReturnString(
444         "document.getElementById('browserplugin').src"));
445   }
446
447   // Verify that the BrowserPlugin accepts changes to its src attribue after
448   // setting the partition to a valid value.
449   ExecuteJavaScript(
450       "document.getElementById('browserplugin').partition = 'persist:foo'");
451   ExecuteJavaScript("document.getElementById('browserplugin').src = 'bar'");
452   EXPECT_EQ("bar", ExecuteScriptAndReturnString(
453       "document.getElementById('browserplugin').src"));
454   ProcessPendingMessages();
455   // Verify that the BrowserPlugin does not 'deadlock': it can recover from
456   // the partition ID error state.
457   {
458     ExecuteJavaScript(
459         "try {"
460         "  document.getElementById('browserplugin').partition = 'persist:1337';"
461         "  document.title = 'success';"
462         "} catch (e) { document.title = e.message; }");
463     std::string title = ExecuteScriptAndReturnString("document.title");
464     EXPECT_STREQ(
465         "The object has already navigated, so its partition cannot be changed.",
466         title.c_str());
467     ExecuteJavaScript("document.getElementById('browserplugin').src = '42'");
468     EXPECT_EQ("42", ExecuteScriptAndReturnString(
469         "document.getElementById('browserplugin').src"));
470   }
471 }
472
473 // Test to verify that after the first navigation, the partition attribute
474 // cannot be modified.
475 TEST_F(BrowserPluginTest, ImmutableAttributesAfterNavigation) {
476   std::string html = base::StringPrintf(kHTMLForSourcelessPluginObject,
477                                         kBrowserPluginMimeType);
478   LoadHTML(html.c_str());
479
480   ExecuteJavaScript(
481       "document.getElementById('browserplugin').partition = 'storage'");
482   std::string partition_value = ExecuteScriptAndReturnString(
483       "document.getElementById('browserplugin').partition");
484   EXPECT_STREQ("storage", partition_value.c_str());
485
486   std::string src_value = ExecuteScriptAndReturnString(
487       "document.getElementById('browserplugin').src");
488   EXPECT_STREQ("", src_value.c_str());
489
490   ExecuteJavaScript("document.getElementById('browserplugin').src = 'bar'");
491   ProcessPendingMessages();
492   {
493     BrowserPluginHostMsg_Attach_Params params;
494     MockBrowserPlugin* browser_plugin =
495         GetCurrentPluginWithAttachParams(&params);
496     ASSERT_TRUE(browser_plugin);
497
498     EXPECT_STREQ("storage", params.storage_partition_id.c_str());
499     EXPECT_FALSE(params.persist_storage);
500     EXPECT_STREQ("bar", params.src.c_str());
501   }
502
503   // Setting the partition should throw an exception and the value should not
504   // change.
505   ExecuteJavaScript(
506       "try {"
507       "  document.getElementById('browserplugin').partition = 'someid';"
508       "  document.title = 'success';"
509       "} catch (e) { document.title = e.message; }");
510
511   std::string title = ExecuteScriptAndReturnString("document.title");
512   EXPECT_STREQ(
513       "The object has already navigated, so its partition cannot be changed.",
514       title.c_str());
515
516   partition_value = ExecuteScriptAndReturnString(
517       "document.getElementById('browserplugin').partition");
518   EXPECT_STREQ("storage", partition_value.c_str());
519 }
520
521 TEST_F(BrowserPluginTest, AutoSizeAttributes) {
522   std::string html = base::StringPrintf(kHTMLForSourcelessPluginObject,
523                                         kBrowserPluginMimeType);
524   LoadHTML(html.c_str());
525   const char* kSetAutoSizeParametersAndNavigate =
526     "var browserplugin = document.getElementById('browserplugin');"
527     "browserplugin.autosize = true;"
528     "browserplugin.minwidth = 42;"
529     "browserplugin.minheight = 43;"
530     "browserplugin.maxwidth = 1337;"
531     "browserplugin.maxheight = 1338;"
532     "browserplugin.src = 'foobar';";
533   const char* kDisableAutoSize =
534     "document.getElementById('browserplugin').removeAttribute('autosize');";
535
536   int instance_id = 0;
537   // Set some autosize parameters before navigating then navigate.
538   // Verify that the BrowserPluginHostMsg_Attach message contains
539   // the correct autosize parameters.
540   ExecuteJavaScript(kSetAutoSizeParametersAndNavigate);
541   ProcessPendingMessages();
542
543   BrowserPluginHostMsg_Attach_Params params;
544   MockBrowserPlugin* browser_plugin =
545       GetCurrentPluginWithAttachParams(&params);
546   ASSERT_TRUE(browser_plugin);
547
548   EXPECT_TRUE(params.auto_size_params.enable);
549   EXPECT_EQ(42, params.auto_size_params.min_size.width());
550   EXPECT_EQ(43, params.auto_size_params.min_size.height());
551   EXPECT_EQ(1337, params.auto_size_params.max_size.width());
552   EXPECT_EQ(1338, params.auto_size_params.max_size.height());
553
554   // Disable autosize. AutoSize state will not be sent to the guest until
555   // the guest has responded to the last resize request.
556   ExecuteJavaScript(kDisableAutoSize);
557   ProcessPendingMessages();
558
559   const IPC::Message* auto_size_msg =
560   browser_plugin_manager()->sink().GetUniqueMessageMatching(
561       BrowserPluginHostMsg_SetAutoSize::ID);
562   EXPECT_FALSE(auto_size_msg);
563
564   // Send the BrowserPlugin an UpdateRect equal to its |max_size|.
565   BrowserPluginMsg_UpdateRect_Params update_rect_params;
566   update_rect_params.view_size = gfx::Size(1337, 1338);
567   update_rect_params.scale_factor = 1.0f;
568   update_rect_params.is_resize_ack = true;
569   BrowserPluginMsg_UpdateRect msg(instance_id, update_rect_params);
570   browser_plugin->OnMessageReceived(msg);
571
572   // Verify that the autosize state has been updated.
573   {
574     const IPC::Message* auto_size_msg =
575         browser_plugin_manager()->sink().GetUniqueMessageMatching(
576             BrowserPluginHostMsg_SetAutoSize::ID);
577     ASSERT_TRUE(auto_size_msg);
578
579     int instance_id = 0;
580     BrowserPluginHostMsg_AutoSize_Params auto_size_params;
581     BrowserPluginHostMsg_ResizeGuest_Params resize_params;
582     BrowserPluginHostMsg_SetAutoSize::Read(auto_size_msg,
583                                            &instance_id,
584                                            &auto_size_params,
585                                            &resize_params);
586     EXPECT_FALSE(auto_size_params.enable);
587     // These value are not populated (as an optimization) if autosize is
588     // disabled.
589     EXPECT_EQ(0, auto_size_params.min_size.width());
590     EXPECT_EQ(0, auto_size_params.min_size.height());
591     EXPECT_EQ(0, auto_size_params.max_size.width());
592     EXPECT_EQ(0, auto_size_params.max_size.height());
593   }
594 }
595
596 }  // namespace content