8249183: JVM crash in "AwtFrame::WmSize" method

Reviewed-by: serb, aivanov
This commit is contained in:
Anton Litvinov 2020-08-31 17:06:41 +01:00
parent 62cc45c3df
commit 4e3d9e3944
5 changed files with 57 additions and 33 deletions

View File

@ -32,6 +32,7 @@ import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
@ -58,6 +59,7 @@ import sun.awt.AWTAccessor;
import sun.awt.AppContext;
import sun.awt.DisplayChangedListener;
import sun.awt.SunToolkit;
import sun.awt.TimedWindowEvent;
import sun.awt.Win32GraphicsConfig;
import sun.awt.Win32GraphicsDevice;
import sun.awt.Win32GraphicsEnvironment;
@ -387,6 +389,40 @@ public class WWindowPeer extends WPanelPeer implements WindowPeer,
}
}
private void notifyWindowStateChanged(int oldState, int newState) {
int changed = oldState ^ newState;
if (changed == 0) {
return;
}
if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Reporting state change %x -> %x", oldState, newState);
}
if (target instanceof Frame) {
// Sync target with peer.
AWTAccessor.getFrameAccessor().setExtendedState((Frame) target,
newState);
}
// Report (de)iconification to old clients.
if ((changed & Frame.ICONIFIED) > 0) {
if ((newState & Frame.ICONIFIED) > 0) {
postEvent(new TimedWindowEvent((Window) target,
WindowEvent.WINDOW_ICONIFIED, null, 0, 0,
System.currentTimeMillis()));
} else {
postEvent(new TimedWindowEvent((Window) target,
WindowEvent.WINDOW_DEICONIFIED, null, 0, 0,
System.currentTimeMillis()));
}
}
// New (since 1.4) state change event.
postEvent(new TimedWindowEvent((Window) target,
WindowEvent.WINDOW_STATE_CHANGED, null, oldState, newState,
System.currentTimeMillis()));
}
synchronized void addWindowListener(WindowListener l) {
windowListener = AWTEventMulticaster.add(windowListener, l);
}

View File

@ -99,7 +99,6 @@ jfieldID AwtFrame::handleID;
jfieldID AwtFrame::undecoratedID;
jmethodID AwtFrame::getExtendedStateMID;
jmethodID AwtFrame::setExtendedStateMID;
jmethodID AwtFrame::activateEmbeddingTopLevelMID;
jfieldID AwtFrame::isEmbeddedInIEID;
@ -813,13 +812,6 @@ AwtFrame::Show()
}
}
void
AwtFrame::SendWindowStateEvent(int oldState, int newState)
{
SendWindowEvent(java_awt_event_WindowEvent_WINDOW_STATE_CHANGED,
NULL, oldState, newState);
}
void
AwtFrame::ClearMaximizedBounds()
{
@ -973,24 +965,7 @@ MsgRouting AwtFrame::WmSize(UINT type, int w, int h)
jint changed = oldState ^ newState;
if (changed != 0) {
DTRACE_PRINTLN2("AwtFrame::WmSize: reporting state change %x -> %x",
oldState, newState);
// sync target with peer
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
env->CallVoidMethod(GetPeer(env), AwtFrame::setExtendedStateMID, newState);
// report (de)iconification to old clients
if (changed & java_awt_Frame_ICONIFIED) {
if (newState & java_awt_Frame_ICONIFIED) {
SendWindowEvent(java_awt_event_WindowEvent_WINDOW_ICONIFIED);
} else {
SendWindowEvent(java_awt_event_WindowEvent_WINDOW_DEICONIFIED);
}
}
// New (since 1.4) state change event
SendWindowStateEvent(oldState, newState);
NotifyWindowStateChanged(oldState, newState);
}
// If window is in iconic state, do not send COMPONENT_RESIZED event
@ -1696,10 +1671,6 @@ Java_sun_awt_windows_WFramePeer_initIDs(JNIEnv *env, jclass cls)
{
TRY;
AwtFrame::setExtendedStateMID = env->GetMethodID(cls, "setExtendedState", "(I)V");
DASSERT(AwtFrame::setExtendedStateMID);
CHECK_NULL(AwtFrame::setExtendedStateMID);
AwtFrame::getExtendedStateMID = env->GetMethodID(cls, "getExtendedState", "()I");
DASSERT(AwtFrame::getExtendedStateMID);

View File

@ -54,7 +54,6 @@ public:
/* sun.awt.windows.WEmbeddedFrame fields and method IDs */
static jfieldID handleID;
static jmethodID setExtendedStateMID;
static jmethodID getExtendedStateMID;
/* method id for WEmbeddedFrame.requestActivate() method */
@ -88,8 +87,6 @@ public:
INLINE BOOL isZoomed() { return m_zoomed; }
INLINE void setZoomed(BOOL b) { m_zoomed = b; }
void SendWindowStateEvent(int oldState, int newState);
void Show();
INLINE void DrawMenuBar() { VERIFY(::DrawMenuBar(GetHWnd())); }

View File

@ -184,6 +184,7 @@ jfieldID AwtWindow::sysYID;
jfieldID AwtWindow::sysWID;
jfieldID AwtWindow::sysHID;
jfieldID AwtWindow::windowTypeID;
jmethodID AwtWindow::notifyWindowStateChangedMID;
jmethodID AwtWindow::getWarningStringMID;
jmethodID AwtWindow::calculateSecurityWarningPositionMID;
@ -1641,6 +1642,16 @@ void AwtWindow::SendWindowEvent(jint id, HWND opposite,
env->DeleteLocalRef(event);
}
void AwtWindow::NotifyWindowStateChanged(jint oldState, jint newState)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject peer = GetPeer(env);
if (peer != NULL) {
env->CallVoidMethod(peer, AwtWindow::notifyWindowStateChangedMID,
oldState, newState);
}
}
BOOL AwtWindow::AwtSetActiveWindow(BOOL isMouseEventCause, UINT hittest)
{
// We used to reject non mouse window activation if our app wasn't active.
@ -3344,6 +3355,11 @@ Java_sun_awt_windows_WWindowPeer_initIDs(JNIEnv *env, jclass cls)
AwtWindow::windowTypeID = env->GetFieldID(cls, "windowType",
"Ljava/awt/Window$Type;");
AwtWindow::notifyWindowStateChangedMID =
env->GetMethodID(cls, "notifyWindowStateChanged", "(II)V");
DASSERT(AwtWindow::notifyWindowStateChangedMID);
CHECK_NULL(AwtWindow::notifyWindowStateChangedMID);
CATCH_BAD_ALLOC;
}

View File

@ -57,6 +57,7 @@ public:
static jfieldID securityWarningWidthID;
static jfieldID securityWarningHeightID;
/* sun.awt.windows.WWindowPeer field and method IDs */
// The coordinates at the peer.
static jfieldID sysXID;
static jfieldID sysYID;
@ -64,7 +65,9 @@ public:
static jfieldID sysHID;
static jfieldID windowTypeID;
static jmethodID notifyWindowStateChangedMID;
/* java.awt.Window method IDs */
static jmethodID getWarningStringMID;
static jmethodID calculateSecurityWarningPositionMID;
static jmethodID windowTypeNameMID;
@ -149,6 +152,7 @@ public:
void SendComponentEvent(jint eventId);
void SendWindowEvent(jint id, HWND opposite = NULL,
jint oldState = 0, jint newState = 0);
void NotifyWindowStateChanged(jint oldState, jint newState);
BOOL IsFocusableWindow();