diff options
-rw-r--r-- | chrome/test/data/npapi/execute_script_delete_in_mouse_move.html | 39 | ||||
-rw-r--r-- | chrome/test/ui/npapi_uitest.cpp | 38 | ||||
-rw-r--r-- | webkit/glue/plugins/test/plugin_client.cc | 7 | ||||
-rw-r--r-- | webkit/glue/plugins/test/plugin_execute_script_delete_test.cc | 52 | ||||
-rw-r--r-- | webkit/glue/plugins/test/plugin_execute_script_delete_test.h | 6 | ||||
-rw-r--r-- | webkit/glue/webplugin_impl.cc | 10 |
6 files changed, 131 insertions, 21 deletions
diff --git a/chrome/test/data/npapi/execute_script_delete_in_mouse_move.html b/chrome/test/data/npapi/execute_script_delete_in_mouse_move.html new file mode 100644 index 0000000..a82cde7 --- /dev/null +++ b/chrome/test/data/npapi/execute_script_delete_in_mouse_move.html @@ -0,0 +1,39 @@ +<html> + +<head> +<script src="npapi.js"></script> + +<script> +function DeletePluginWithinScript() { + var plugin_div = document.getElementById("PluginDiv"); + plugin_div.innerHTML = "Object Deleted"; + onSuccess("execute_script_delete_in_mouse_move", 1); +} +</script> +</head> + +<body> +<div id="statusPanel" style="border: 1px solid red; width: 100%"> +Test running.... +</div> + + +NPObject Proxy Test<p> + +Tests the case where a plugin instance is deleted in the context +of a synchronous mouse event. + +<DIV ID=PluginDiv> +<embed type="application/vnd.npapi-test" + src="foo" + name="execute_script_delete_in_mouse_move" + id="1" + mode="np_embed" +> +</DIV> +<script> + var height = document.body.offsetHeight; +</script> + +</body> +</html> diff --git a/chrome/test/ui/npapi_uitest.cpp b/chrome/test/ui/npapi_uitest.cpp index bce1497..58c6574 100644 --- a/chrome/test/ui/npapi_uitest.cpp +++ b/chrome/test/ui/npapi_uitest.cpp @@ -279,4 +279,40 @@ TEST_F(NPAPIVisiblePluginTester, OpenPopupWindowWithPlugin) { WaitForFinish("plugin_popup_with_plugin_target", "1", url, kTestCompleteCookie, kTestCompleteSuccess, kShortWaitTimeout); -}
\ No newline at end of file +} + +// Tests if a plugin executing a self deleting script in the context of +// a synchronous mousemove works correctly +TEST_F(NPAPIVisiblePluginTester, SelfDeletePluginInvokeInSynchronousMouseMove) { + if (!UITest::in_process_plugins() && !UITest::in_process_renderer()) { + scoped_ptr<TabProxy> tab_proxy(GetActiveTab()); + HWND tab_window = NULL; + tab_proxy->GetHWND(&tab_window); + + EXPECT_TRUE(IsWindow(tab_window)); + + show_window_ = true; + std::wstring test_case = L"execute_script_delete_in_mouse_move.html"; + GURL url = GetTestUrl(L"npapi", test_case); + NavigateToURL(url); + + POINT cursor_position = {130, 130}; + ClientToScreen(tab_window, &cursor_position); + + double screen_width = ::GetSystemMetrics( SM_CXSCREEN ) - 1; + double screen_height = ::GetSystemMetrics( SM_CYSCREEN ) - 1; + double location_x = cursor_position.x * (65535.0f / screen_width); + double location_y = cursor_position.y * (65535.0f / screen_height); + + INPUT input_info = {0}; + input_info.type = INPUT_MOUSE; + input_info.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; + input_info.mi.dx = static_cast<long>(location_x); + input_info.mi.dy = static_cast<long>(location_y); + ::SendInput(1, &input_info, sizeof(INPUT)); + + WaitForFinish("execute_script_delete_in_mouse_move", "1", url, + kTestCompleteCookie, kTestCompleteSuccess, + kShortWaitTimeout); + } +} diff --git a/webkit/glue/plugins/test/plugin_client.cc b/webkit/glue/plugins/test/plugin_client.cc index 868810e..b0e7e91 100644 --- a/webkit/glue/plugins/test/plugin_client.cc +++ b/webkit/glue/plugins/test/plugin_client.cc @@ -102,7 +102,7 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, } else if (base::strcasecmp(argv[name_index], "execute_script_delete_in_paint") == 0) { new_test = new NPAPIClient::ExecuteScriptDeleteTest(instance, - NPAPIClient::PluginClient::HostFunctions()); + NPAPIClient::PluginClient::HostFunctions(), argv[name_index]); windowless_plugin = true; } else if (base::strcasecmp(argv[name_index], "getjavascripturl") == 0) { new_test = new NPAPIClient::ExecuteGetJavascriptUrlTest(instance, @@ -137,6 +137,11 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, "plugin_popup_with_plugin_target") == 0) { new_test = new NPAPIClient::ExecuteJavascriptPopupWindowTargetPluginTest( instance, NPAPIClient::PluginClient::HostFunctions()); + } else if (base::strcasecmp(argv[name_index], + "execute_script_delete_in_mouse_move") == 0) { + new_test = new NPAPIClient::ExecuteScriptDeleteTest(instance, + NPAPIClient::PluginClient::HostFunctions(), argv[name_index]); + windowless_plugin = true; } else { // If we don't have a test case for this, create a // generic one which basically never fails. diff --git a/webkit/glue/plugins/test/plugin_execute_script_delete_test.cc b/webkit/glue/plugins/test/plugin_execute_script_delete_test.cc index 7137ceb..3f1d0e1 100644 --- a/webkit/glue/plugins/test/plugin_execute_script_delete_test.cc +++ b/webkit/glue/plugins/test/plugin_execute_script_delete_test.cc @@ -8,25 +8,47 @@ namespace NPAPIClient { -ExecuteScriptDeleteTest::ExecuteScriptDeleteTest(NPP id, NPNetscapeFuncs *host_functions) - : PluginTest(id, host_functions) { +ExecuteScriptDeleteTest::ExecuteScriptDeleteTest( + NPP id, NPNetscapeFuncs *host_functions, const std::string& test_name) + : PluginTest(id, host_functions), + test_name_(test_name) { } int16 ExecuteScriptDeleteTest::HandleEvent(void* event) { + + NPNetscapeFuncs* browser = NPAPIClient::PluginClient::HostFunctions(); + + NPBool supports_windowless = 0; + NPError result = browser->getvalue(id(), NPNVSupportsWindowless, + &supports_windowless); + if ((result != NPERR_NO_ERROR) || (supports_windowless != TRUE)) { + SetError("Failed to read NPNVSupportsWindowless value"); + SignalTestCompleted(); + return PluginTest::HandleEvent(event); + } + NPEvent* np_event = reinterpret_cast<NPEvent*>(event); - if (WM_PAINT == np_event->event ) { - NPNetscapeFuncs* browser = NPAPIClient::PluginClient::HostFunctions(); - - NPBool supports_windowless = 0; - NPError result = browser->getvalue(id(), NPNVSupportsWindowless, - &supports_windowless); - if ((result != NPERR_NO_ERROR) || (supports_windowless != TRUE)) { - SetError("Failed to read NPNVSupportsWindowless value"); - } else { - NPUTF8* urlString = "javascript:DeletePluginWithinScript()"; - NPUTF8* targetString = NULL; - browser->geturl(id(), urlString, targetString); - } + if (WM_PAINT == np_event->event && + base::strcasecmp(test_name_.c_str(), + "execute_script_delete_in_paint") == 0) { + NPUTF8* urlString = "javascript:DeletePluginWithinScript()"; + NPUTF8* targetString = NULL; + browser->geturl(id(), urlString, targetString); + SignalTestCompleted(); + } else if (WM_MOUSEMOVE == np_event->event && + base::strcasecmp(test_name_.c_str(), + "execute_script_delete_in_mouse_move") == 0) { + std::string script = "javascript:DeletePluginWithinScript()"; + NPString script_string; + script_string.UTF8Characters = script.c_str(); + script_string.UTF8Length = + static_cast<unsigned int>(script.length()); + + NPObject *window_obj = NULL; + browser->getvalue(id(), NPNVWindowNPObject, &window_obj); + NPVariant result_var; + NPError result = browser->evaluate(id(), window_obj, + &script_string, &result_var); SignalTestCompleted(); } // If this test failed, then we'd have crashed by now. diff --git a/webkit/glue/plugins/test/plugin_execute_script_delete_test.h b/webkit/glue/plugins/test/plugin_execute_script_delete_test.h index 5266d6d..92a1d04 100644 --- a/webkit/glue/plugins/test/plugin_execute_script_delete_test.h +++ b/webkit/glue/plugins/test/plugin_execute_script_delete_test.h @@ -14,9 +14,13 @@ namespace NPAPIClient { class ExecuteScriptDeleteTest : public PluginTest { public: // Constructor. - ExecuteScriptDeleteTest(NPP id, NPNetscapeFuncs *host_functions); + ExecuteScriptDeleteTest(NPP id, NPNetscapeFuncs *host_functions, + const std::string& test_name); // NPAPI HandleEvent handler virtual int16 HandleEvent(void* event); + + private: + std::string test_name_; }; } // namespace NPAPIClient diff --git a/webkit/glue/webplugin_impl.cc b/webkit/glue/webplugin_impl.cc index 496de7f..36d7fc6 100644 --- a/webkit/glue/webplugin_impl.cc +++ b/webkit/glue/webplugin_impl.cc @@ -786,9 +786,13 @@ void WebPluginImpl::handleEvent(WebCore::Event* event) { void WebPluginImpl::handleMouseEvent(WebCore::MouseEvent* event) { #if defined(OS_WIN) DCHECK(parent()->isFrameView()); + // We cache the parent FrameView here as the plugin widget could be deleted + // in the call to HandleEvent. See http://b/issue?id=1362948 + WebCore::FrameView* parent_view = static_cast<WebCore::FrameView*>(parent()); + WebCore::IntPoint p = - static_cast<WebCore::FrameView*>(parent())->contentsToWindow( - WebCore::IntPoint(event->pageX(), event->pageY())); + parent_view->contentsToWindow(WebCore::IntPoint(event->pageX(), + event->pageY())); NPEvent np_event; np_event.lParam = static_cast<uint32>(MAKELPARAM(p.x(), p.y())); np_event.wParam = 0; @@ -867,7 +871,7 @@ void WebPluginImpl::handleMouseEvent(WebCore::MouseEvent* event) { // A windowless plugin can change the cursor in response to the WM_MOUSEMOVE // event. We need to reflect the changed cursor in the frame view as the // the mouse is moved in the boundaries of the windowless plugin. - parent()->setCursor(WebCore::PlatformCursor(current_web_cursor)); + parent_view->setCursor(WebCore::PlatformCursor(current_web_cursor)); #else NOTIMPLEMENTED(); #endif |