diff options
author | lazyboy@chromium.org <lazyboy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-15 23:55:04 +0000 |
---|---|---|
committer | lazyboy@chromium.org <lazyboy@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-15 23:55:04 +0000 |
commit | 32deec6509deb789265c50ba2943bc575b7f547c (patch) | |
tree | bc0bbbecb4d843daa9bca2808990658440edefaf | |
parent | 38fa08719c97f7cd60c3379883488cb50b6fcb73 (diff) | |
download | chromium_src-32deec6509deb789265c50ba2943bc575b7f547c.zip chromium_src-32deec6509deb789265c50ba2943bc575b7f547c.tar.gz chromium_src-32deec6509deb789265c50ba2943bc575b7f547c.tar.bz2 |
Make renderer aware of browser plugin position.
We need to send updated screen rects to renderer whenever the embedder's browser side has screen rect updates. This informs webkit/renderer about the correct position of browser plugin.
Fix view bounds/coordinates for RWHViewGuest.
Both changes together should fix
a) datalist/html5 popups appearing in correct position: i. initially, ii: after moving app window, iii: after resizing app window.
b) window.screenX/Y/Left/Top for guests as well.
BUG=233285, 226653
TEST=Added tests, ran them on trybots. Ran PopupPositioning test in trybot for 50 times on each run, still found few flaky occurrences, will work on it more.
Review URL: https://chromiumcodereview.appspot.com/14123006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@200393 0039d316-1c4b-4281-b951-d872f2087c98
33 files changed, 701 insertions, 38 deletions
diff --git a/chrome/browser/extensions/web_view_browsertest.cc b/chrome/browser/extensions/web_view_browsertest.cc index e8a3ed8..4d830c5 100644 --- a/chrome/browser/extensions/web_view_browsertest.cc +++ b/chrome/browser/extensions/web_view_browsertest.cc @@ -890,6 +890,14 @@ IN_PROC_BROWSER_TEST_F(WebViewTest, MAYBE_MediaAccessAPIAllow) { } } +// Checks that window.screenX/screenY/screenLeft/screenTop works correctly for +// guests. +IN_PROC_BROWSER_TEST_F(WebViewTest, ScreenCoordinates) { + ASSERT_TRUE(StartTestServer()); // For serving guest pages. + ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/screen_coordinates")) + << message_; +} + IN_PROC_BROWSER_TEST_F(WebViewTest, SpeechRecognition) { ASSERT_TRUE(StartTestServer()); content::WebContents* guest_web_contents = LoadGuest( diff --git a/chrome/browser/extensions/web_view_interactive_browsertest.cc b/chrome/browser/extensions/web_view_interactive_browsertest.cc index 8ad9ace..88e1fa23 100644 --- a/chrome/browser/extensions/web_view_interactive_browsertest.cc +++ b/chrome/browser/extensions/web_view_interactive_browsertest.cc @@ -12,6 +12,8 @@ #include "chrome/test/base/ui_controls.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" +#include "content/public/browser/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_view.h" #include "content/public/test/browser_test_utils.h" @@ -86,8 +88,8 @@ class WebViewInteractiveTest void SetupTest(const std::string& app_name, const std::string& guest_url_spec) { ASSERT_TRUE(StartTestServer()); - std::string host_str("localhost"); // Must stay in scope with replace_host. GURL::Replacements replace_host; + std::string host_str("localhost"); // Must stay in scope with replace_host. replace_host.SetHostStr(host_str); GURL guest_url = test_server()->GetURL(guest_url_spec); @@ -128,6 +130,116 @@ class WebViewInteractiveTest return corner_; } + void SimulateRWHMouseClick(content::RenderWidgetHost* rwh, int x, int y) { + WebKit::WebMouseEvent mouse_event; + mouse_event.button = WebKit::WebMouseEvent::ButtonLeft; + mouse_event.x = mouse_event.windowX = x; + mouse_event.y = mouse_event.windowY = y; + mouse_event.modifiers = 0; + + mouse_event.type = WebKit::WebInputEvent::MouseDown; + rwh->ForwardMouseEvent(mouse_event); + mouse_event.type = WebKit::WebInputEvent::MouseUp; + rwh->ForwardMouseEvent(mouse_event); + } + + class PopupCreatedObserver { + public: + PopupCreatedObserver() : created_(false), last_render_widget_host_(NULL) { + created_callback_ = base::Bind( + &PopupCreatedObserver::CreatedCallback, base::Unretained(this)); + content::RenderWidgetHost::AddCreatedCallback(created_callback_); + } + virtual ~PopupCreatedObserver() { + content::RenderWidgetHost::RemoveCreatedCallback(created_callback_); + } + void Reset() { + created_ = false; + } + void Start() { + if (created_) + return; + message_loop_ = new content::MessageLoopRunner; + message_loop_->Run(); + } + content::RenderWidgetHost* last_render_widget_host() { + return last_render_widget_host_; + } + + private: + void CreatedCallback(content::RenderWidgetHost* rwh) { + last_render_widget_host_ = rwh; + if (message_loop_) + message_loop_->Quit(); + else + created_ = true; + } + content::RenderWidgetHost::CreatedCallback created_callback_; + scoped_refptr<content::MessageLoopRunner> message_loop_; + bool created_; + content::RenderWidgetHost* last_render_widget_host_; + }; + + void WaitForTitle(const char* title) { + string16 expected_title(ASCIIToUTF16(title)); + string16 error_title(ASCIIToUTF16("FAILED")); + content::TitleWatcher title_watcher(guest_web_contents(), expected_title); + title_watcher.AlsoWaitForTitle(error_title); + ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle()); + } + + void PopupTestHelper(const gfx::Point& padding) { + PopupCreatedObserver popup_created_observer; + popup_created_observer.Reset(); + + content::SimulateKeyPress( + guest_web_contents(), + ui::VKEY_C, // C to autocomplete. + false, false, false, false); + + WaitForTitle("PASSED1"); + + popup_created_observer.Start(); + + content::RenderWidgetHost* popup_rwh = NULL; + popup_rwh = popup_created_observer.last_render_widget_host(); + // Popup must be present. + ASSERT_TRUE(popup_rwh); + ASSERT_TRUE(!popup_rwh->IsRenderView()); + ASSERT_TRUE(popup_rwh->GetView()); + + string16 expected_title = ASCIIToUTF16("PASSED2"); + string16 error_title = ASCIIToUTF16("FAILED"); + content::TitleWatcher title_watcher(guest_web_contents(), expected_title); + title_watcher.AlsoWaitForTitle(error_title); + EXPECT_TRUE(content::ExecuteScript(guest_web_contents(), + "changeTitle();")); + ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle()); + + gfx::Rect popup_bounds = popup_rwh->GetView()->GetViewBounds(); + // (2, 2) is expected to lie on the first datalist element. + SimulateRWHMouseClick(popup_rwh, 2, 2); + + content::RenderViewHost* embedder_rvh = + GetFirstShellWindowWebContents()->GetRenderViewHost(); + gfx::Rect embedder_bounds = embedder_rvh->GetView()->GetViewBounds(); + gfx::Vector2d diff = popup_bounds.origin() - embedder_bounds.origin(); + LOG(INFO) << "DIFF: x = " << diff.x() << ", y = " << diff.y(); + + const int left_spacing = 40 + padding.x(); // div.style.paddingLeft = 40px. + // div.style.paddingTop = 50px + (input box height = 26px). + const int top_spacing = 50 + 26 + padding.y(); + + // If the popup is placed within |threshold_px| of the expected position, + // then we consider the test as a pass. + const int threshold_px = 10; + + EXPECT_LE(std::abs(diff.x() - left_spacing), threshold_px); + EXPECT_LE(std::abs(diff.y() - top_spacing), threshold_px); + + WaitForTitle("PASSED3"); + } + private: content::WebContents* guest_web_contents_; content::WebContents* embedder_web_contents_; @@ -250,3 +362,29 @@ IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, ExecuteCode) { ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/execute_code")) << message_; } + +IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, PopupPositioning) { + SetupTest( + "web_view/popup_positioning", + "files/extensions/platform_apps/web_view/popup_positioning/guest.html"); + ASSERT_TRUE(guest_web_contents()); + + PopupTestHelper(gfx::Point()); + + // moveTo a random location and run the steps again. + EXPECT_TRUE(content::ExecuteScript(embedder_web_contents(), + "window.moveTo(16, 20);")); + PopupTestHelper(gfx::Point()); +} + +// Tests that moving browser plugin (without resize/UpdateRects) correctly +// repositions popup. +IN_PROC_BROWSER_TEST_F(WebViewInteractiveTest, PopupPositioningMoved) { + SetupTest( + "web_view/popup_positioning_moved", + "files/extensions/platform_apps/web_view/popup_positioning_moved" + "/guest.html"); + ASSERT_TRUE(guest_web_contents()); + + PopupTestHelper(gfx::Point(20, 0)); +} diff --git a/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/guest.html b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/guest.html new file mode 100644 index 0000000..2e08d33 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/guest.html @@ -0,0 +1,57 @@ +<!doctype html> +<!-- + * Copyright 2013 The Chromium Authors. All rights reserved. Use of this + * source code is governed by a BSD-style license that can be found in the + * LICENSE file. +--> +<html> +<head> + <title>WAITING</title> + <style type="text/css"> + body { margin: 0; padding: 0; } + </style> +</head> +<body> + <div> + <input type="text" list="items" style="height: 20px;"/> + <datalist id="items"> + <option value="Chromium"></option> + <option value="ChromiumB"></option> + <option value="ChromiumC"></option> + <option value="Molybdenum"></option> + <option value="Seaborgium"></option> + <option value="Tungsten"></option> + </datalist> + </div> + + <script> + // TODO(lazyboy): Apps do not support <input> + datalist with id attribute. + var inputElement = document.querySelector('input'); + var step = 1; + + var onInput = function(e) { + var value = inputElement.value; + window.console.log('onInput, value: ' + value); + if (step == 1) { + document.title = 'PASSED1'; + } else if (step == 2) { + if (value == 'Chromium') { + inputElement.value = ''; + document.title = 'PASSED3'; + step = 0; + } else { + document.title = 'FAILED'; + } + } + ++step; + }; + + inputElement.oninput = onInput; + inputElement.focus(); + + window['changeTitle'] = function() { + window.setTimeout(function() { document.title = 'PASSED2'; }, 0); + }; + </script> +</body> +</html> diff --git a/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/main.html b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/main.html new file mode 100644 index 0000000..4cfc4fb --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/main.html @@ -0,0 +1,18 @@ +<!doctype html> +<!-- + * Copyright 2013 The Chromium Authors. All rights reserved. Use of this + * source code is governed by a BSD-style license that can be found in the + * LICENSE file. +--> +<html> +<head> +<style type="text/css"> +body { margin:0; padding:0; } +</style> +</head> +<body> + <div id="webview-tag-container" + style="padding-left: 40px; padding-top: 60px;"></div> + <script src="main.js"></script> +</body> +</html> diff --git a/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/main.js b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/main.js new file mode 100644 index 0000000..eb11e9f --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/main.js @@ -0,0 +1,25 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var startTest = function() { + chrome.test.sendMessage('connected'); +}; + +chrome.test.getConfig(function(config) { + var guestURL = 'http://localhost:' + config.testServer.port + + '/files/extensions/platform_apps/web_view/popup_positioning/guest.html'; + var webview = document.createElement('webview'); + var loaded = false; + webview.addEventListener('loadstop', function(e) { + window.console.log('webview.loadstop'); + if (!loaded) { + loaded = true; + startTest(); + } + }); + webview.style.width = '200px'; + webview.style.height = '200px'; + webview.setAttribute('src', guestURL); + document.querySelector('#webview-tag-container').appendChild(webview); +}); diff --git a/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/manifest.json b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/manifest.json new file mode 100644 index 0000000..f093c67 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/manifest.json @@ -0,0 +1,13 @@ +{ + "name": "<webview> html5 popup.", + "description": "Test that checks popup positioning correctness", + "version": "1", + "permissions": [ + "webview" + ], + "app": { + "background": { + "scripts": ["test.js"] + } + } +} diff --git a/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/test.js b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/test.js new file mode 100644 index 0000000..8c4cd9b --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning/test.js @@ -0,0 +1,16 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +chrome.app.runtime.onLaunched.addListener(function() { + chrome.app.window.create('main.html', { + bounds: { + width: 400, + height: 400, + // Prefer close to top left on screen so we have enough space for + // rendering popup. + left: 20, + top: 20 + } + }, function (win) {}); +}); diff --git a/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/guest.html b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/guest.html new file mode 100644 index 0000000..6741085 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/guest.html @@ -0,0 +1,60 @@ +<!doctype html> +<!-- + * Copyright 2013 The Chromium Authors. All rights reserved. Use of this + * source code is governed by a BSD-style license that can be found in the + * LICENSE file. +--> +<html> +<head> + <title>WAITING</title> + <style type="text/css"> + body { margin: 0; padding: 0; } + </style> +</head> +<body> + <div> + <input type="text" list="items" style="height: 20px;"/> + <datalist id="items"> + <option value="Chromium"></option> + <option value="ChromiumB"></option> + <option value="ChromiumC"></option> + <option value="Molybdenum"></option> + <option value="Seaborgium"></option> + <option value="Tungsten"></option> + </datalist> + </div> + + <script> + var inputElement = document.querySelector('input'); + var step = 1; + + var onInput = function(e) { + var value = inputElement.value; + window.console.log('onInput, value: ' + value + ', step = ' + step); + if (step == 1) { + // TODO(lazyboy): We don't have a way to reliably wait for a + // RenderWidgetHost to be added to a WebContents, hence the 500ms + // timeout below. Bad, fix. + window.setTimeout(function() { + document.title = 'PASSED1'; + }, 500); + } else if (step == 2) { + if (value == 'Chromium') { + inputElement.value = ''; + document.title = 'PASSED3'; + } else { + document.title = 'FAILED'; + } + } + ++step; + }; + + window['changeTitle'] = function() { + window.setTimeout(function() { document.title = 'PASSED2'; }, 0); + }; + + inputElement.oninput = onInput; + inputElement.focus(); + </script> +</body> +</html> diff --git a/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/main.html b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/main.html new file mode 100644 index 0000000..4cfc4fb --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/main.html @@ -0,0 +1,18 @@ +<!doctype html> +<!-- + * Copyright 2013 The Chromium Authors. All rights reserved. Use of this + * source code is governed by a BSD-style license that can be found in the + * LICENSE file. +--> +<html> +<head> +<style type="text/css"> +body { margin:0; padding:0; } +</style> +</head> +<body> + <div id="webview-tag-container" + style="padding-left: 40px; padding-top: 60px;"></div> + <script src="main.js"></script> +</body> +</html> diff --git a/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/main.js b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/main.js new file mode 100644 index 0000000..870bbc7 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/main.js @@ -0,0 +1,34 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var startTest = function() { + chrome.test.sendMessage('connected'); +}; + +chrome.test.getConfig(function(config) { + var guestURL = 'http://localhost:' + config.testServer.port + + '/files/extensions/platform_apps/web_view/popup_positioning_moved' + + '/guest.html'; + var webview = document.createElement('webview'); + var loaded = false; + + + var onWebViewLoadStop = function(e) { + window.console.log('webview.loadstop'); + if (loaded) { + return; + } + loaded = true; + // We move the <webview> in a way, this would trigger + // BrowserPlugin::updateGeometry but no UpdateRects. + webview.style.paddingLeft = '20px'; + startTest(); + }; + webview.addEventListener('loadstop', onWebViewLoadStop); + + webview.style.width = '200px'; + webview.style.height = '200px'; + webview.setAttribute('src', guestURL); + document.querySelector('#webview-tag-container').appendChild(webview); +}); diff --git a/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/manifest.json b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/manifest.json new file mode 100644 index 0000000..68e79f7 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/manifest.json @@ -0,0 +1,13 @@ +{ + "name": "<webview> html5 popup + move.", + "description": "Test that checks popup positioning correctness after moving plugin", + "version": "1", + "permissions": [ + "webview" + ], + "app": { + "background": { + "scripts": ["test.js"] + } + } +} diff --git a/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/test.js b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/test.js new file mode 100644 index 0000000..8c4cd9b --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/popup_positioning_moved/test.js @@ -0,0 +1,16 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +chrome.app.runtime.onLaunched.addListener(function() { + chrome.app.window.create('main.html', { + bounds: { + width: 400, + height: 400, + // Prefer close to top left on screen so we have enough space for + // rendering popup. + left: 20, + top: 20 + } + }, function (win) {}); +}); diff --git a/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/guest.html b/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/guest.html new file mode 100644 index 0000000..a2b2ac2 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/guest.html @@ -0,0 +1,35 @@ +<!doctype html> +<!-- + * Copyright 2013 The Chromium Authors. All rights reserved. Use of this + * source code is governed by a BSD-style license that can be found in the + * LICENSE file. +--> +<html> + <head> + <script type="text/javascript"> + // Notifies the embedder about the result of the request (success/fail) + // via post message. Note that the embedder has to initiate a postMessage + // first so that guest has a reference to the embedder's window. + var onPostMessageReceived = function(e) { + var data = JSON.parse(e.data); + if (data[0] == 'test1') { + var screenInfo = { + 'screenX': window.screenX, + 'screenY': window.screenY, + 'screenLeft': window.screenLeft, + 'screenTop': window.screenTop + }; + var responseArray = []; + responseArray.push(data[0]); + responseArray.push(screenInfo); + e.source.postMessage(JSON.stringify(responseArray), '*'); + + } + }; + window.addEventListener('message', onPostMessageReceived, false); + </script> + </head> + <body> + <div>This is guest</div> + </body> +</html> diff --git a/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/main.html b/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/main.html new file mode 100644 index 0000000..d1ec7d8 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/main.html @@ -0,0 +1,17 @@ +<!doctype html> +<!-- + * Copyright 2013 The Chromium Authors. All rights reserved. Use of this + * source code is governed by a BSD-style license that can be found in the + * LICENSE file. +--> +<html> +<head> +<style type="text/css"> + body { margin: 0; padding: 0; } +</style> +</head> +<body> + <div id="webview-tag-container"></div> + <script src="main.js"></script> +</body> +</html> diff --git a/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/main.js b/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/main.js new file mode 100644 index 0000000..43483c1 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/main.js @@ -0,0 +1,91 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var embedder = {}; +embedder.tests = {}; +embedder.baseGuestURL = ''; +embedder.guestURL = ''; + +embedder.setUp = function(config) { + embedder.baseGuestURL = 'http://localhost:' + config.testServer.port; + embedder.guestURL = embedder.baseGuestURL + + '/files/extensions/platform_apps/web_view/screen_coordinates' + + '/guest.html'; + chrome.test.log('Guest url is: ' + embedder.guestURL); +}; + +/** @private */ +embedder.setUpGuest_ = function() { + document.querySelector('#webview-tag-container').innerHTML = + '<webview style="width: 100px; height: 100px;"' + + ' src="' + embedder.guestURL + '"' + + '></webview>'; + var webview = document.querySelector('webview'); + if (!webview) { + chrome.test.fail('No <webview> element created'); + } + return webview; +}; + +/** @private */ +embedder.setUpLoadStop_ = function(webview, testName) { + var onWebViewLoadStop = function(e) { + // Send post message to <webview> when it's ready to receive them. + webview.contentWindow.postMessage( + JSON.stringify(['' + testName, 'get-screen-info']), '*'); + }; + webview.addEventListener('loadstop', onWebViewLoadStop); +}; + +/** + * @private + * @param {Number} mn Expected range's min value. + * @param {Number} mx Expected range's max value. + * @param {Number} a Actual value. + */ +embedder.assertCorrectCoordinateValue_ = function(mn, mx, a, msg) { + chrome.test.assertTrue( + a >= mn && a <= mx, + 'Actual value [' + a + '] is not within interval ' + + '[' + mn + ', ' + mx + ']'); +}; + +/** @private */ +embedder.registerAndWaitForPostMessage_ = function( + webview, expectedData) { + var testName = expectedData[0]; + var onPostMessageReceived = function(e) { + var data = JSON.parse(e.data); + if (data[0] == '' + testName) { + embedder.assertCorrectCoordinateValue_( + window.screenX, window.screenX + window.innerWidth, + data[1].screenX, 'screenX'); + embedder.assertCorrectCoordinateValue_( + window.screenY, window.screenY + window.innerHeight, + data[1].screenY, 'screenY'); + embedder.assertCorrectCoordinateValue_( + window.screenLeft, window.screenLeft + window.innerWidth, + data[1].screenLeft, 'screenLeft'); + embedder.assertCorrectCoordinateValue_( + window.screenTop, window.screenTop + window.innerHeight, + data[1].screenTop, 'screenTop'); + chrome.test.succeed(); + } + }; + window.addEventListener('message', onPostMessageReceived); +}; + + +onload = function() { + chrome.test.getConfig(function(config) { + embedder.setUp(config); + chrome.test.runTests([ + function testScreenCoordinates() { + var webview = embedder.setUpGuest_(); + embedder.setUpLoadStop_(webview, 'test1'); + embedder.registerAndWaitForPostMessage_(webview, ['test1']); + } + ]); + }); +}; diff --git a/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/manifest.json b/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/manifest.json new file mode 100644 index 0000000..7234400 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/manifest.json @@ -0,0 +1,13 @@ +{ + "name": "<webview> Guest screenX/Y", + "description": "Test that checks window.screenX/Y correctness for guest.", + "version": "1", + "permissions": [ + "webview" + ], + "app": { + "background": { + "scripts": ["test.js"] + } + } +} diff --git a/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/test.js b/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/test.js new file mode 100644 index 0000000..2f9f855 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/web_view/screen_coordinates/test.js @@ -0,0 +1,7 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +chrome.app.runtime.onLaunched.addListener(function() { + chrome.app.window.create('main.html', {}, function () {}); +}); diff --git a/content/browser/browser_plugin/browser_plugin_embedder.cc b/content/browser/browser_plugin/browser_plugin_embedder.cc index 12de8ef..ba8b10a 100644 --- a/content/browser/browser_plugin/browser_plugin_embedder.cc +++ b/content/browser/browser_plugin/browser_plugin_embedder.cc @@ -75,6 +75,10 @@ void BrowserPluginEmbedder::GetRenderViewHostAtPosition( ++next_get_render_view_request_id_; } +void BrowserPluginEmbedder::DidSendScreenRects(RenderWidgetHostImpl* rwh) { + GetBrowserPluginGuestManager()->DidSendScreenRects(web_contents(), rwh); +} + void BrowserPluginEmbedder::RenderViewGone(base::TerminationStatus status) { CleanUp(); } diff --git a/content/browser/browser_plugin/browser_plugin_embedder.h b/content/browser/browser_plugin/browser_plugin_embedder.h index 1b6c8b2..3dbb3f3 100644 --- a/content/browser/browser_plugin/browser_plugin_embedder.h +++ b/content/browser/browser_plugin/browser_plugin_embedder.h @@ -33,6 +33,7 @@ namespace content { class BrowserPluginGuest; class BrowserPluginGuestManager; class BrowserPluginHostFactory; +class RenderWidgetHostImpl; class WebContentsImpl; class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver { @@ -49,6 +50,9 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver { int y, const WebContents::GetRenderViewHostCallback& callback); + // Called when embedder's |rwh| has sent screen rects to renderer. + void DidSendScreenRects(RenderWidgetHostImpl* rwh); + // Overrides factory for testing. Default (NULL) value indicates regular // (non-test) environment. static void set_factory_for_testing(BrowserPluginHostFactory* factory) { diff --git a/content/browser/browser_plugin/browser_plugin_guest.cc b/content/browser/browser_plugin/browser_plugin_guest.cc index ea8ce65..d1c6caa 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.cc +++ b/content/browser/browser_plugin/browser_plugin_guest.cc @@ -356,6 +356,7 @@ bool BrowserPluginGuest::OnMessageReceivedFromEmbedder( IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_Stop, OnStop) IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_TerminateGuest, OnTerminateGuest) IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UnlockMouse_ACK, OnUnlockMouseAck) + IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateGeometry, OnUpdateGeometry) IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateRect_ACK, OnUpdateRectACK) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() @@ -367,6 +368,8 @@ void BrowserPluginGuest::Initialize( const BrowserPluginHostMsg_Attach_Params& params) { focused_ = params.focused; guest_visible_ = params.visible; + guest_window_rect_ = params.resize_guest_params.view_rect; + if (!params.name.empty()) name_ = params.name; auto_size_enabled_ = params.auto_size_params.enable; @@ -472,6 +475,13 @@ void BrowserPluginGuest::UpdateVisibility() { OnSetVisibility(instance_id_, visible()); } +// screen. +gfx::Rect BrowserPluginGuest::ToGuestRect(const gfx::Rect& bounds) { + gfx::Rect guest_rect(bounds); + guest_rect.Offset(guest_window_rect_.OffsetFromOrigin()); + return guest_rect; +} + void BrowserPluginGuest::Observe(int type, const NotificationSource& source, const NotificationDetails& details) { @@ -667,7 +677,7 @@ void BrowserPluginGuest::SetDamageBuffer( DCHECK(*static_cast<unsigned int*>(damage_buffer_->memory()) == 0xdeadbeef); damage_buffer_sequence_id_ = params.damage_buffer_sequence_id; damage_buffer_size_ = params.damage_buffer_size; - damage_view_size_ = params.view_size; + damage_view_size_ = params.view_rect.size(); damage_buffer_scale_factor_ = params.scale_factor; } @@ -972,6 +982,7 @@ bool BrowserPluginGuest::ShouldForwardToBrowserPluginGuest( case BrowserPluginHostMsg_Stop::ID: case BrowserPluginHostMsg_TerminateGuest::ID: case BrowserPluginHostMsg_UnlockMouse_ACK::ID: + case BrowserPluginHostMsg_UpdateGeometry::ID: case BrowserPluginHostMsg_UpdateRect_ACK::ID: return true; default: @@ -1251,16 +1262,16 @@ void BrowserPluginGuest::OnResizeGuest( // Invalid damage buffer means we are in HW compositing mode, // so just resize the WebContents and repaint if needed. if (!base::SharedMemory::IsHandleValid(params.damage_buffer_handle)) { - if (!params.view_size.IsEmpty()) - GetWebContents()->GetView()->SizeContents(params.view_size); + if (!params.view_rect.size().IsEmpty()) + GetWebContents()->GetView()->SizeContents(params.view_rect.size()); if (params.repaint) - Send(new ViewMsg_Repaint(routing_id(), params.view_size)); + Send(new ViewMsg_Repaint(routing_id(), params.view_rect.size())); return; } SetDamageBuffer(params); - GetWebContents()->GetView()->SizeContents(params.view_size); + GetWebContents()->GetView()->SizeContents(params.view_rect.size()); if (params.repaint) - Send(new ViewMsg_Repaint(routing_id(), params.view_size)); + Send(new ViewMsg_Repaint(routing_id(), params.view_rect.size())); } void BrowserPluginGuest::OnSetFocus(int instance_id, bool focused) { @@ -1304,7 +1315,7 @@ void BrowserPluginGuest::OnSetSize( Send(new ViewMsg_Repaint(routing_id(), max_auto_size_)); } else if (!auto_size_enabled_ && old_auto_size_enabled) { GetWebContents()->GetRenderViewHost()->DisableAutoResize( - resize_guest_params.view_size); + resize_guest_params.view_rect.size()); } OnResizeGuest(instance_id_, resize_guest_params); } @@ -1386,6 +1397,17 @@ void BrowserPluginGuest::OnUpdateRectACK( OnSetSize(instance_id_, auto_size_params, resize_guest_params); } +void BrowserPluginGuest::OnUpdateGeometry(int instance_id, + const gfx::Rect& view_rect) { + // The plugin has moved within the embedder without resizing or the + // embedder/container's view rect changing. + guest_window_rect_ = view_rect; + RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>( + GetWebContents()->GetRenderViewHost()); + if (rvh) + rvh->SendScreenRects(); +} + void BrowserPluginGuest::OnHasTouchEventHandlers(bool accept) { SendMessageToEmbedder( new BrowserPluginMsg_ShouldAcceptTouchEvents(instance_id(), accept)); @@ -1415,9 +1437,7 @@ void BrowserPluginGuest::OnShowPopup( void BrowserPluginGuest::OnShowWidget(int route_id, const gfx::Rect& initial_pos) { - gfx::Rect screen_pos(initial_pos); - screen_pos.Offset(guest_screen_rect_.OffsetFromOrigin()); - GetWebContents()->ShowCreatedWidget(route_id, screen_pos); + GetWebContents()->ShowCreatedWidget(route_id, initial_pos); } void BrowserPluginGuest::OnTakeFocus(bool reverse) { @@ -1482,8 +1502,7 @@ void BrowserPluginGuest::OnUpdateRect( // The scaling change can happen due to asynchronous updates of the DPI on a // resolution change. if (((auto_size_enabled_ && InAutoSizeBounds(params.view_size)) || - (params.view_size.width() == damage_view_size().width() && - params.view_size.height() == damage_view_size().height())) && + (params.view_size == damage_view_size())) && params.scale_factor == damage_buffer_scale_factor()) { TransportDIB* dib = GetWebContents()->GetRenderProcessHost()-> GetTransportDIB(params.bitmap); diff --git a/content/browser/browser_plugin/browser_plugin_guest.h b/content/browser/browser_plugin/browser_plugin_guest.h index 155d9f3..a298922 100644 --- a/content/browser/browser_plugin/browser_plugin_guest.h +++ b/content/browser/browser_plugin/browser_plugin_guest.h @@ -254,6 +254,7 @@ class CONTENT_EXPORT BrowserPluginGuest // Returns whether BrowserPluginGuest is interested in receiving the given // |message|. static bool ShouldForwardToBrowserPluginGuest(const IPC::Message& message); + gfx::Rect ToGuestRect(const gfx::Rect& rect); void DragSourceEndedAt(int client_x, int client_y, int screen_x, int screen_y, WebKit::WebDragOperation operation); @@ -391,6 +392,7 @@ class CONTENT_EXPORT BrowserPluginGuest void OnTerminateGuest(int instance_id); void OnUnlockMouse(); void OnUnlockMouseAck(int instance_id); + void OnUpdateGeometry(int instance_id, const gfx::Rect& view_rect); void OnUpdateRectACK( int instance_id, const BrowserPluginHostMsg_AutoSize_Params& auto_size_params, diff --git a/content/browser/browser_plugin/browser_plugin_guest_manager.cc b/content/browser/browser_plugin/browser_plugin_guest_manager.cc index 081f332..1a33e9a 100644 --- a/content/browser/browser_plugin/browser_plugin_guest_manager.cc +++ b/content/browser/browser_plugin/browser_plugin_guest_manager.cc @@ -230,4 +230,19 @@ void BrowserPluginGuestManager::OnUnhandledSwapBuffersACK( sync_point); } +void BrowserPluginGuestManager::DidSendScreenRects( + WebContents* embedder_web_contents, RenderWidgetHostImpl* rwh) { + // TODO(lazyboy): Generalize iterating over guest instances and performing + // actions on the guests. + for (GuestInstanceMap::iterator it = + guest_web_contents_by_instance_id_.begin(); + it != guest_web_contents_by_instance_id_.end(); ++it) { + BrowserPluginGuest* guest = it->second->GetBrowserPluginGuest(); + if (embedder_web_contents == guest->embedder_web_contents()) { + static_cast<RenderViewHostImpl*>( + guest->GetWebContents()->GetRenderViewHost())->SendScreenRects(); + } + } +} + } // namespace content diff --git a/content/browser/browser_plugin/browser_plugin_guest_manager.h b/content/browser/browser_plugin/browser_plugin_guest_manager.h index 4e1ba28..f915362 100644 --- a/content/browser/browser_plugin/browser_plugin_guest_manager.h +++ b/content/browser/browser_plugin/browser_plugin_guest_manager.h @@ -31,6 +31,7 @@ namespace content { class BrowserPluginGuest; class BrowserPluginHostFactory; class RenderProcessHostImpl; +class RenderWidgetHostImpl; class SiteInstance; class WebContents; class WebContentsImpl; @@ -79,6 +80,9 @@ class CONTENT_EXPORT BrowserPluginGuestManager : bool CanEmbedderAccessInstanceIDMaybeKill(int embedder_render_process_id, int instance_id) const; + void DidSendScreenRects(WebContents* embedder_web_contents, + RenderWidgetHostImpl* rwh); + void OnMessageReceived(const IPC::Message& message, int render_process_id); private: diff --git a/content/browser/browser_plugin/test_browser_plugin_guest.cc b/content/browser/browser_plugin/test_browser_plugin_guest.cc index 083ea5a..5205752 100644 --- a/content/browser/browser_plugin/test_browser_plugin_guest.cc +++ b/content/browser/browser_plugin/test_browser_plugin_guest.cc @@ -265,10 +265,10 @@ void TestBrowserPluginGuest::OnStop(int instance_id) { void TestBrowserPluginGuest::SetDamageBuffer( const BrowserPluginHostMsg_ResizeGuest_Params& params) { ++damage_buffer_call_count_; - last_damage_buffer_size_ = params.view_size; + last_damage_buffer_size_ = params.view_rect.size(); if (waiting_for_damage_buffer_with_size_ && - expected_damage_buffer_size_ == params.view_size && + expected_damage_buffer_size_ == params.view_rect.size() && damage_buffer_message_loop_runner_) { damage_buffer_message_loop_runner_->Quit(); waiting_for_damage_buffer_with_size_ = false; diff --git a/content/browser/renderer_host/render_widget_host_delegate.h b/content/browser/renderer_host/render_widget_host_delegate.h index fa41727..9e8d36e 100644 --- a/content/browser/renderer_host/render_widget_host_delegate.h +++ b/content/browser/renderer_host/render_widget_host_delegate.h @@ -46,6 +46,9 @@ class CONTENT_EXPORT RenderWidgetHostDelegate { // Returns true if the |event| was handled. virtual bool PreHandleWheelEvent(const WebKit::WebMouseWheelEvent& event); + // Notifies that screen rects were sent to renderer process. + virtual void DidSendScreenRects(RenderWidgetHostImpl* rwh) {} + #if defined(OS_WIN) && defined(USE_AURA) // Returns the widget's parent's NativeViewAccessible. virtual gfx::NativeViewAccessible GetParentNativeViewAccessible(); diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 5c09f18..87d8aa0 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc @@ -318,6 +318,8 @@ void RenderWidgetHostImpl::SendScreenRects() { last_window_screen_rect_ = view_->GetBoundsInRootWindow(); Send(new ViewMsg_UpdateScreenRects( GetRoutingID(), last_view_screen_rect_, last_window_screen_rect_)); + if (delegate_) + delegate_->DidSendScreenRects(this); waiting_for_screen_rects_ack_ = true; } diff --git a/content/browser/renderer_host/render_widget_host_view_guest.cc b/content/browser/renderer_host/render_widget_host_view_guest.cc index 6f02367..2e00453 100644 --- a/content/browser/renderer_host/render_widget_host_view_guest.cc +++ b/content/browser/renderer_host/render_widget_host_view_guest.cc @@ -81,7 +81,8 @@ void RenderWidgetHostViewGuest::SetSize(const gfx::Size& size) { } gfx::Rect RenderWidgetHostViewGuest::GetBoundsInRootWindow() { - return gfx::Rect(size_); + // We do not have any root window specific parts in this view. + return GetViewBounds(); } gfx::GLSurfaceHandle RenderWidgetHostViewGuest::GetCompositingSurface() { @@ -125,7 +126,12 @@ bool RenderWidgetHostViewGuest::IsShowing() { } gfx::Rect RenderWidgetHostViewGuest::GetViewBounds() const { - return gfx::Rect(size_); + gfx::Rect embedder_bounds = static_cast<RenderWidgetHostViewPort*>( + guest_->GetEmbedderRenderWidgetHostView())->GetViewBounds(); + gfx::Rect shifted_rect = guest_->ToGuestRect(embedder_bounds); + shifted_rect.set_width(size_.width()); + shifted_rect.set_height(size_.height()); + return shifted_rect; } void RenderWidgetHostViewGuest::RenderViewGone(base::TerminationStatus status, diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 4969576..d8e4d6e2 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc @@ -1596,6 +1596,11 @@ void WebContentsImpl::RequestMediaAccessPermission( callback.Run(MediaStreamDevices(), scoped_ptr<MediaStreamUI>()); } +void WebContentsImpl::DidSendScreenRects(RenderWidgetHostImpl* rwh) { + if (browser_plugin_embedder_) + browser_plugin_embedder_->DidSendScreenRects(rwh); +} + void WebContentsImpl::UpdatePreferredSize(const gfx::Size& pref_size) { preferred_size_ = pref_size; if (delegate_) diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h index 3cca074..529b363 100644 --- a/content/browser/web_contents/web_contents_impl.h +++ b/content/browser/web_contents/web_contents_impl.h @@ -448,6 +448,7 @@ class CONTENT_EXPORT WebContentsImpl const NativeWebKeyboardEvent& event) OVERRIDE; virtual bool PreHandleWheelEvent( const WebKit::WebMouseWheelEvent& event) OVERRIDE; + virtual void DidSendScreenRects(RenderWidgetHostImpl* rwh) OVERRIDE; #if defined(OS_WIN) && defined(USE_AURA) virtual gfx::NativeViewAccessible GetParentNativeViewAccessible() OVERRIDE; #endif diff --git a/content/common/browser_plugin/browser_plugin_messages.h b/content/common/browser_plugin/browser_plugin_messages.h index f10453b..61c970d 100644 --- a/content/common/browser_plugin/browser_plugin_messages.h +++ b/content/common/browser_plugin/browser_plugin_messages.h @@ -50,8 +50,8 @@ IPC_STRUCT_BEGIN(BrowserPluginHostMsg_ResizeGuest_Params) IPC_STRUCT_MEMBER(base::SharedMemoryHandle, damage_buffer_handle) // The size of the damage buffer. IPC_STRUCT_MEMBER(size_t, damage_buffer_size) - // The new size of the guest view area. - IPC_STRUCT_MEMBER(gfx::Size, view_size) + // The new rect of the guest view area. + IPC_STRUCT_MEMBER(gfx::Rect, view_rect) // Indicates the scale factor of the embedder WebView. IPC_STRUCT_MEMBER(float, scale_factor) // Indicates a request for a full repaint of the page. @@ -284,6 +284,11 @@ IPC_MESSAGE_ROUTED2(BrowserPluginHostMsg_LockMouse_ACK, // Sends a PointerLock Unlock ACK to the BrowserPluginGuest. IPC_MESSAGE_ROUTED1(BrowserPluginHostMsg_UnlockMouse_ACK, int /* instance_id */) +// Sent when plugin's position has changed without UpdateRect. +IPC_MESSAGE_ROUTED2(BrowserPluginHostMsg_UpdateGeometry, + int /* instance_id */, + gfx::Rect /* view_rect */) + // ----------------------------------------------------------------------------- // These messages are from the guest renderer to the browser process diff --git a/content/renderer/browser_plugin/browser_plugin.cc b/content/renderer/browser_plugin/browser_plugin.cc index d3aa325..46b9ec4 100644 --- a/content/renderer/browser_plugin/browser_plugin.cc +++ b/content/renderer/browser_plugin/browser_plugin.cc @@ -922,7 +922,7 @@ void BrowserPlugin::UpdateDeviceScaleFactor(float device_scale_factor) { return; BrowserPluginHostMsg_ResizeGuest_Params params; - PopulateResizeGuestParameters(¶ms, gfx::Size(width(), height())); + PopulateResizeGuestParameters(¶ms, plugin_rect()); browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest( render_view_routing_id_, instance_id_, @@ -1166,7 +1166,7 @@ void BrowserPlugin::EnableCompositing(bool enable) { // We're switching back to the software path. We create a new damage // buffer that can accommodate the current size of the container. BrowserPluginHostMsg_ResizeGuest_Params params; - PopulateResizeGuestParameters(¶ms, gfx::Size(width(), height())); + PopulateResizeGuestParameters(¶ms, plugin_rect()); // Request a full repaint from the guest even if its size is not actually // changing. params.repaint = true; @@ -1307,21 +1307,26 @@ void BrowserPlugin::updateGeometry( int old_width = width(); int old_height = height(); plugin_rect_ = window_rect; + if (!HasGuest()) + return; + // In AutoSize mode, guests don't care when the BrowserPlugin container is // resized. If |!resize_ack_received_|, then we are still waiting on a // previous resize to be ACK'ed and so we don't issue additional resizes // until the previous one is ACK'ed. // TODO(mthiesse): Assess the performance of calling GetAutoSizeAttribute() on // resize. - if (!HasGuest() || - !resize_ack_received_ || + if (!resize_ack_received_ || (old_width == window_rect.width && old_height == window_rect.height) || GetAutoSizeAttribute()) { + // Let the browser know about the updated view rect. + browser_plugin_manager()->Send(new BrowserPluginHostMsg_UpdateGeometry( + render_view_routing_id_, instance_id_, plugin_rect_)); return; } BrowserPluginHostMsg_ResizeGuest_Params params; - PopulateResizeGuestParameters(¶ms, gfx::Size(width(), height())); + PopulateResizeGuestParameters(¶ms, plugin_rect()); resize_ack_received_ = false; browser_plugin_manager()->Send(new BrowserPluginHostMsg_ResizeGuest( render_view_routing_id_, @@ -1336,8 +1341,8 @@ void BrowserPlugin::SwapDamageBuffers() { void BrowserPlugin::PopulateResizeGuestParameters( BrowserPluginHostMsg_ResizeGuest_Params* params, - const gfx::Size& view_size) { - params->view_size = view_size; + const gfx::Rect& view_rect) { + params->view_rect = view_rect; params->scale_factor = GetDeviceScaleFactor(); if (last_device_scale_factor_ != params->scale_factor){ params->repaint = true; @@ -1348,12 +1353,12 @@ void BrowserPlugin::PopulateResizeGuestParameters( if (compositing_enabled_) return; - const size_t stride = skia::PlatformCanvasStrideForWidth(view_size.width()); + const size_t stride = skia::PlatformCanvasStrideForWidth(view_rect.width()); // Make sure the size of the damage buffer is at least four bytes so that we // can fit in a magic word to verify that the memory is shared correctly. size_t size = std::max(sizeof(unsigned int), - static_cast<size_t>(view_size.height() * + static_cast<size_t>(view_rect.height() * stride * GetDeviceScaleFactor() * GetDeviceScaleFactor())); @@ -1376,7 +1381,8 @@ void BrowserPlugin::GetDamageBufferWithSizeParams( if (view_size.IsEmpty()) return; resize_ack_received_ = false; - PopulateResizeGuestParameters(resize_guest_params, view_size); + gfx::Rect view_rect = gfx::Rect(plugin_rect_.origin(), view_size); + PopulateResizeGuestParameters(resize_guest_params, view_rect); } #if defined(OS_POSIX) diff --git a/content/renderer/browser_plugin/browser_plugin.h b/content/renderer/browser_plugin/browser_plugin.h index 72c618c..3d7ee9a 100644 --- a/content/renderer/browser_plugin/browser_plugin.h +++ b/content/renderer/browser_plugin/browser_plugin.h @@ -239,6 +239,7 @@ class CONTENT_EXPORT BrowserPlugin : int width() const { return plugin_rect_.width(); } int height() const { return plugin_rect_.height(); } + gfx::Rect plugin_rect() { return plugin_rect_; } // Gets the Max Height value used for auto size. int GetAdjustedMaxHeight() const; // Gets the Max Width value used for auto size. @@ -274,7 +275,7 @@ class CONTENT_EXPORT BrowserPlugin : // allocates a new |pending_damage_buffer_| if in software rendering mode. void PopulateResizeGuestParameters( BrowserPluginHostMsg_ResizeGuest_Params* params, - const gfx::Size& view_size); + const gfx::Rect& view_size); // Populates BrowserPluginHostMsg_AutoSize_Params object with autosize state. void PopulateAutoSizeParameters( diff --git a/content/renderer/browser_plugin/browser_plugin_browsertest.cc b/content/renderer/browser_plugin/browser_plugin_browsertest.cc index dbc8523..7b79cea 100644 --- a/content/renderer/browser_plugin/browser_plugin_browsertest.cc +++ b/content/renderer/browser_plugin/browser_plugin_browsertest.cc @@ -167,8 +167,8 @@ TEST_F(BrowserPluginTest, InitialResize) { ASSERT_TRUE(msg); BrowserPluginHostMsg_Attach_Params params; BrowserPluginHostMsg_Attach::Read(msg, &instance_id, ¶ms); - EXPECT_EQ(640, params.resize_guest_params.view_size.width()); - EXPECT_EQ(480, params.resize_guest_params.view_size.height()); + EXPECT_EQ(640, params.resize_guest_params.view_rect.width()); + EXPECT_EQ(480, params.resize_guest_params.view_rect.height()); } MockBrowserPlugin* browser_plugin = @@ -320,18 +320,25 @@ TEST_F(BrowserPluginTest, ResizeFlowControl) { ExecuteJavaScript("document.getElementById('browserplugin').width = '643px'"); ProcessPendingMessages(); - // Expect to see one messsage in the sink. BrowserPlugin will not issue + // Expect to see one resize messsage in the sink. BrowserPlugin will not issue // subsequent resize requests until the first request is satisfied by the - // guest. - EXPECT_EQ(1u, browser_plugin_manager()->sink().message_count()); + // guest. The rest of the messages could be + // BrowserPluginHostMsg_UpdateGeometry msgs. + EXPECT_LE(1u, browser_plugin_manager()->sink().message_count()); + for (size_t i = 0; i < browser_plugin_manager()->sink().message_count(); + ++i) { + const IPC::Message* msg = browser_plugin_manager()->sink().GetMessageAt(i); + if (msg->type() != BrowserPluginHostMsg_ResizeGuest::ID) + EXPECT_EQ(msg->type(), BrowserPluginHostMsg_UpdateGeometry::ID); + } const IPC::Message* msg = - browser_plugin_manager()->sink().GetFirstMessageMatching( + browser_plugin_manager()->sink().GetUniqueMessageMatching( BrowserPluginHostMsg_ResizeGuest::ID); ASSERT_TRUE(msg); BrowserPluginHostMsg_ResizeGuest_Params params; BrowserPluginHostMsg_ResizeGuest::Read(msg, &instance_id, ¶ms); - EXPECT_EQ(641, params.view_size.width()); - EXPECT_EQ(480, params.view_size.height()); + EXPECT_EQ(641, params.view_rect.width()); + EXPECT_EQ(480, params.view_rect.height()); // This indicates that the BrowserPlugin has sent out a previous resize // request but has not yet received an UpdateRect for that request. EXPECT_TRUE(browser_plugin->pending_damage_buffer_.get()); |