From 91d30a9b6cc453815e813e87b410e6332cb99eb6 Mon Sep 17 00:00:00 2001 From: Byungwoo Lee Date: Thu, 6 Sep 2012 15:14:36 +0900 Subject: [PATCH] Block UI events not to be sent to the WebProcess while js popup is displayed. [Title] Block UI events not to be sent to the WebProcess while js popup is displayed. [Issue#] N_SE-8944 / N_SE-8828 / N_SE-8867 / N_SE-8935 / N_SE-8935 (tizendev.org/bugs) [Problem] UI Process is terminated when js popup is displayed. [Cause] Not permitted IPC messages about user event (touch, mouse, guesture, keyboard) can be sent to the WebProcess while js popup is displayed [Solution] Add blocking code for the events while js popup is displayed. [Developer] bw80.lee Change-Id: Ieb7f91760db7c3a22389409b537064ce26d7b756 --- Source/WebKit2/UIProcess/WebPageProxy.cpp | 101 +++++++++++++++++++++++ Source/WebKit2/UIProcess/WebPageProxy.h | 32 +++++++ Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp | 4 + 3 files changed, 137 insertions(+) diff --git a/Source/WebKit2/UIProcess/WebPageProxy.cpp b/Source/WebKit2/UIProcess/WebPageProxy.cpp index fd6b7fc..87f7110 100755 --- a/Source/WebKit2/UIProcess/WebPageProxy.cpp +++ b/Source/WebKit2/UIProcess/WebPageProxy.cpp @@ -1167,6 +1167,27 @@ void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event) LOG(KeyHandling, "WebPageProxy::handleKeyboardEvent: %s", webKeyboardEventTypeString(event.type())); +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) + if (!isWaitingForJavaScriptPopupReply()) { + m_keyEventQueue.append(event); + + process()->responsivenessTimer()->start(); + if (m_shouldSendEventsSynchronously) { + bool handled = false; + process()->sendSync(Messages::WebPage::KeyEventSyncForTesting(event), Messages::WebPage::KeyEventSyncForTesting::Reply(handled), m_pageID); + didReceiveEvent(event.type(), handled); + } else + process()->send(Messages::WebPage::KeyEvent(event), m_pageID); + } else { + if (m_keyEventQueue.isEmpty()) { + bool handled = false; + didReceiveEvent(event.type(), handled); + } else { + QueuedUIEvents& lastEvent = m_keyEventQueue.last(); + lastEvent.deferredEvents.append(event); + } + } +#else m_keyEventQueue.append(event); process()->responsivenessTimer()->start(); @@ -1176,6 +1197,7 @@ void WebPageProxy::handleKeyboardEvent(const NativeWebKeyboardEvent& event) didReceiveEvent(event.type(), handled); } else process()->send(Messages::WebPage::KeyEvent(event), m_pageID); +#endif } #if ENABLE(GESTURE_EVENTS) @@ -1184,10 +1206,27 @@ void WebPageProxy::handleGestureEvent(const WebGestureEvent& event) if (!isValid()) return; +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) + if (!isWaitingForJavaScriptPopupReply()) { + m_gestureEventQueue.append(event); + + process()->responsivenessTimer()->start(); + process()->send(Messages::EventDispatcher::GestureEvent(m_pageID, event), 0); + } else { + if (m_gestureEventQueue.isEmpty()) { + bool isEventHandled = false; + m_pageClient->doneWithGestureEvent(event, handled); + } else { + QueuedUIEvents& lastEvent = m_gestureEventQueue.last(); + lastEvent.deferredEvents.append(event); + } + } +#else m_gestureEventQueue.append(event); process()->responsivenessTimer()->start(); process()->send(Messages::EventDispatcher::GestureEvent(m_pageID, event), 0); +#endif } #endif @@ -1207,7 +1246,11 @@ void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event) // If the page is suspended, which should be the case during panning, pinching // and animation on the page itself (kinetic scrolling, tap to zoom) etc, then // we do not send any of the events to the page even if is has listeners. +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) + if (m_needTouchEvents && !m_isPageSuspended && !isWaitingForJavaScriptPopupReply()) { +#else if (m_needTouchEvents && !m_isPageSuspended) { +#endif #if OS(TIZEN) // Do not send the TouchMove event if last TouchMove is not processed yet. // TouchMove event will be sent too many times without below codes, @@ -1232,8 +1275,13 @@ void WebPageProxy::handleTouchEvent(const NativeWebTouchEvent& event) } else { // We attach the incoming events to the newest queued event so that all // the events are delivered in the correct order when the event is dequed. +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) + QueuedUIEvents& lastEvent = m_touchEventQueue.last(); + lastEvent.deferredEvents.append(event); +#else QueuedTouchEvents& lastEvent = m_touchEventQueue.last(); lastEvent.deferredTouchEvents.append(event); +#endif } } } @@ -2468,6 +2516,13 @@ void WebPageProxy::closePage(bool stopResponsivenessTimer) m_uiClient.close(this); } +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) +bool WebPageProxy::isWaitingForJavaScriptPopupReply() +{ + return m_alertReply || m_confirmReply || m_promptReply; +} +#endif + #if OS(TIZEN) void WebPageProxy::runJavaScriptAlert(uint64_t frameID, const String& message, PassRefPtr reply) { @@ -3440,11 +3495,23 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) case WebEvent::GestureScrollBegin: case WebEvent::GestureScrollEnd: case WebEvent::GestureSingleTap: { +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) + QueuedUIEvents queuedEvents = m_gestureEventQueue.first(); + MESSAGE_CHECK(type == queuedEvents.forwardedEvent.type()); + m_gestureEventQueue.removeFirst(); + + m_pageClient->doneWithGestureEvent(queuedEvents.forwardedEvent, handled); + for (size_t i = 0; i < queuedEvents.deferredEvents.size(); ++i) { + bool isEventHandled = false; + m_pageClient->doneWithGuestureEvent(queuedEvents.deferredEvents.at(i), isEventHandled); + } +#else WebGestureEvent event = m_gestureEventQueue.first(); MESSAGE_CHECK(type == event.type()); m_gestureEventQueue.removeFirst(); m_pageClient->doneWithGestureEvent(event, handled); +#endif break; } #endif @@ -3472,6 +3539,27 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) case WebEvent::Char: { LOG(KeyHandling, "WebPageProxy::didReceiveEvent: %s", webKeyboardEventTypeString(type)); +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) + QueuedUIEvents queuedEvents = m_keyEventQueue.first(); + MESSAGE_CHECK(type == queuedEvents.forwardedEvent.type()); + m_keyEventQueue.removeFirst(); + + m_pageClient->doneWithKeyEvent(queuedEvents.forwardedEvent, handled); + + if (!handled) { + if (m_uiClient.implementsDidNotHandleKeyEvent()) + m_uiClient.didNotHandleKeyEvent(this, queuedEvents.forwardedEvent); +#if PLATFORM(WIN) + else + ::TranslateMessage(queuedEvents.forwardedEvent.nativeEvent()); +#endif + } + + for (size_t i = 0; i < queuedEvents.deferredEvents.size(); ++i) { + bool isEventHandled = false; + m_pageClient->doneWithKeyEvent(queuedEvents.deferredEvents.at(i), isEventHandled); + } +#else NativeWebKeyboardEvent event = m_keyEventQueue.first(); MESSAGE_CHECK(type == event.type()); @@ -3488,6 +3576,7 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) else ::TranslateMessage(event.nativeEvent()); #endif +#endif // #if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) break; } #if ENABLE(TOUCH_EVENTS) @@ -3495,6 +3584,17 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) case WebEvent::TouchMove: case WebEvent::TouchEnd: case WebEvent::TouchCancel: { +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) + QueuedUIEvents queuedEvents = m_touchEventQueue.first(); + MESSAGE_CHECK(type == queuedEvents.forwardedEvent.type()); + m_touchEventQueue.removeFirst(); + + m_pageClient->doneWithTouchEvent(queuedEvents.forwardedEvent, handled); + for (size_t i = 0; i < queuedEvents.deferredEvents.size(); ++i) { + bool isEventHandled = false; + m_pageClient->doneWithTouchEvent(queuedEvents.deferredEvents.at(i), isEventHandled); + } +#else QueuedTouchEvents queuedEvents = m_touchEventQueue.first(); MESSAGE_CHECK(type == queuedEvents.forwardedEvent.type()); m_touchEventQueue.removeFirst(); @@ -3504,6 +3604,7 @@ void WebPageProxy::didReceiveEvent(uint32_t opaqueType, bool handled) bool isEventHandled = false; m_pageClient->doneWithTouchEvent(queuedEvents.deferredTouchEvents.at(i), isEventHandled); } +#endif break; } #endif diff --git a/Source/WebKit2/UIProcess/WebPageProxy.h b/Source/WebKit2/UIProcess/WebPageProxy.h index 700104a..f377a15 100755 --- a/Source/WebKit2/UIProcess/WebPageProxy.h +++ b/Source/WebKit2/UIProcess/WebPageProxy.h @@ -35,6 +35,9 @@ #if ENABLE(TOUCH_EVENTS) #include "NativeWebTouchEvent.h" #endif +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) +#include "NativeWebKeyboardEvent.h" +#endif #if PLATFORM(QT) #include "QtNetworkRequestData.h" #endif @@ -134,7 +137,9 @@ class WKView; namespace WebKit { +#if !ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) class NativeWebKeyboardEvent; +#endif class NativeWebMouseEvent; class NativeWebWheelEvent; class PageClient; @@ -183,6 +188,17 @@ typedef GenericCallback WebStorageQuotaCallback; typedef GenericCallback PrintFinishedCallback; #endif +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) +template +struct QueuedUIEvents { + QueuedUIEvents(const T& event) + : forwardedEvent(event) + { + } + T forwardedEvent; + Vector deferredEvents; +}; +#else #if ENABLE(TOUCH_EVENTS) struct QueuedTouchEvents { QueuedTouchEvents(const NativeWebTouchEvent& event) @@ -193,6 +209,7 @@ struct QueuedTouchEvents { Vector deferredTouchEvents; }; #endif +#endif // FIXME: Make a version of CallbackBase with three arguments, and define ValidateCommandCallback as a specialization. class ValidateCommandCallback : public CallbackBase { @@ -1202,6 +1219,10 @@ private: void decidePolicyForCertificateError(bool isTrusted, const String& url, const String& certificate, int error, bool& canContinue); #endif +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) + bool isWaitingForJavaScriptPopupReply(); +#endif + PageClient* m_pageClient; WebLoaderClient m_loaderClient; WebPolicyClient m_policyClient; @@ -1332,10 +1353,17 @@ private: WebCore::PolicyAction m_syncNavigationActionPolicyAction; uint64_t m_syncNavigationActionPolicyDownloadID; +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) +#if ENABLE(GESTURE_EVENTS) + Deque > m_gestureEventQueue; +#endif + Deque > m_keyEventQueue; +#else #if ENABLE(GESTURE_EVENTS) Deque m_gestureEventQueue; #endif Deque m_keyEventQueue; +#endif Deque m_wheelEventQueue; Deque > > m_currentlyProcessedWheelEvents; @@ -1345,8 +1373,12 @@ private: #if ENABLE(TOUCH_EVENTS) bool m_needTouchEvents; +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) + Deque > m_touchEventQueue; +#else Deque m_touchEventQueue; #endif +#endif #if ENABLE(INPUT_TYPE_COLOR) RefPtr m_colorChooser; #endif diff --git a/Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp b/Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp index 273bdb6..62e8393 100755 --- a/Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp +++ b/Source/WebKit2/UIProcess/efl/WebPageProxyEfl.cpp @@ -268,7 +268,11 @@ void WebPageProxy::handleInputMethodKeydown(bool& handled) static_cast(m_pageClient)->handleInputMethodKeydown(); #if ENABLE(TIZEN_ISF_PORT) +#if ENABLE(TIZEN_WEBKIT2_ROTATION_WHILE_JAVASCRIPT_POPUP) + NativeWebKeyboardEvent event = m_keyEventQueue.first().forwardedEvent; +#else NativeWebKeyboardEvent event = m_keyEventQueue.first(); +#endif handled = event.isFiltered(); #endif } -- 2.7.4