1 /*
   2 * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
   3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4 *
   5 * This code is free software; you can redistribute it and/or modify it
   6 * under the terms of the GNU General Public License version 2 only, as
   7 * published by the Free Software Foundation.
   8 *
   9 * This code is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12 * version 2 for more details (a copy is included in the LICENSE file that
  13 * accompanied this code).
  14 *
  15 * You should have received a copy of the GNU General Public License version
  16 * 2 along with this work; if not, write to the Free Software Foundation,
  17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18 *
  19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20 * or visit www.oracle.com if you need additional information or have any
  21 * questions.
  22 */
  23 
  24 /*
  25   @test
  26   @bug 4980592
  27   @summary switching user in XP causes an NPE in sun.awt.windows.WWindowPeer.displayChanged
  28   @requires (os.family == "windows")
  29   @modules java.desktop/java.awt.peer
  30   @modules java.desktop/sun.awt.windows
  31   @modules java.desktop/sun.awt
  32   @author son@sparc.spb.su: area=embedded
  33   @run main DisplayChangedTest
  34 */
  35 
  36 /**
  37  * DisplayChangedTest.java
  38  *
  39  * summary: switching user in XP causes an NPE in sun.awt.windows.WWindowPeer.displayChanged
  40  */
  41 
  42 import java.awt.Frame;
  43 import java.awt.Dialog;
  44 import java.awt.TextArea;
  45 import java.awt.peer.ComponentPeer;
  46 import java.awt.peer.FramePeer;
  47 
  48 import java.lang.reflect.Constructor;
  49 import java.lang.reflect.Method;
  50 import java.lang.reflect.Field;
  51 
  52 import sun.awt.AWTAccessor;
  53 
  54 public class DisplayChangedTest
  55 {
  56     private static void init()
  57     {
  58         if (!System.getProperty("os.name").startsWith("Windows")) {
  59             System.out.println("This is Windows only test.");
  60             DisplayChangedTest.pass();
  61             return;
  62         }
  63 
  64         try {
  65             Frame frame = new Frame("AWT Frame");
  66             frame.pack();
  67 
  68             FramePeer frame_peer = AWTAccessor.getComponentAccessor().getPeer(frame);
  69             System.out.println("frame's peer = " + frame_peer);
  70             Class comp_peer_class =
  71                 Class.forName("sun.awt.windows.WComponentPeer");
  72             System.out.println("comp peer class = " + comp_peer_class);
  73             Field hwnd_field = comp_peer_class.getDeclaredField("hwnd");
  74             hwnd_field.setAccessible(true);
  75             System.out.println("hwnd_field =" + hwnd_field);
  76             long hwnd = hwnd_field.getLong(frame_peer);
  77             System.out.println("hwnd = " + hwnd);
  78 
  79             Class clazz = Class.forName("sun.awt.windows.WEmbeddedFrame");
  80             Constructor constructor = clazz.getConstructor (new Class [] {long.class});
  81             Frame embedded_frame =
  82                 (Frame) constructor.newInstance (new Object[] {new Long(hwnd)});;
  83             System.out.println("embedded_frame = " + embedded_frame);
  84             frame.setVisible(true);
  85 
  86             ComponentPeer peer = AWTAccessor.getComponentAccessor().getPeer(embedded_frame);
  87             System.out.println("peer = " + peer);
  88             Class peerClass = peer.getClass();
  89             System.out.println("peer's class = " + peerClass);
  90 
  91             Method displayChangedM =
  92                 peerClass.getMethod("displayChanged", new Class[0]);
  93             displayChangedM.invoke(peer, null);
  94             embedded_frame.dispose();
  95             frame.dispose();
  96         } catch (Throwable thr) {
  97             thr.printStackTrace();
  98             DisplayChangedTest.fail("TEST FAILED: " + thr);
  99         }
 100         DisplayChangedTest.pass();
 101 
 102     }//End  init()
 103 
 104 
 105 
 106     /*****************************************************
 107      * Standard Test Machinery Section
 108      * DO NOT modify anything in this section -- it's a
 109      * standard chunk of code which has all of the
 110      * synchronisation necessary for the test harness.
 111      * By keeping it the same in all tests, it is easier
 112      * to read and understand someone else's test, as
 113      * well as insuring that all tests behave correctly
 114      * with the test harness.
 115      * There is a section following this for test-
 116      * classes
 117      ******************************************************/
 118     private static boolean theTestPassed = false;
 119     private static boolean testGeneratedInterrupt = false;
 120     private static String failureMessage = "";
 121 
 122     private static Thread mainThread = null;
 123 
 124     private static int sleepTime = 300000;
 125 
 126     // Not sure about what happens if multiple of this test are
 127     //  instantiated in the same VM.  Being static (and using
 128     //  static vars), it aint gonna work.  Not worrying about
 129     //  it for now.
 130     public static void main( String args[] ) throws InterruptedException
 131     {
 132         mainThread = Thread.currentThread();
 133         try
 134         {
 135             init();
 136         }
 137         catch( TestPassedException e )
 138         {
 139             //The test passed, so just return from main and harness will
 140             // interepret this return as a pass
 141             return;
 142         }
 143         //At this point, neither test pass nor test fail has been
 144         // called -- either would have thrown an exception and ended the
 145         // test, so we know we have multiple threads.
 146 
 147         //Test involves other threads, so sleep and wait for them to
 148         // called pass() or fail()
 149         try
 150         {
 151             Thread.sleep( sleepTime );
 152             //Timed out, so fail the test
 153             throw new RuntimeException( "Timed out after " + sleepTime/1000 + " seconds" );
 154         }
 155         catch (InterruptedException e)
 156         {
 157             //The test harness may have interrupted the test.  If so, rethrow the exception
 158             // so that the harness gets it and deals with it.
 159             if( ! testGeneratedInterrupt ) throw e;
 160 
 161             //reset flag in case hit this code more than once for some reason (just safety)
 162             testGeneratedInterrupt = false;
 163 
 164             if ( theTestPassed == false )
 165             {
 166                 throw new RuntimeException( failureMessage );
 167             }
 168         }
 169 
 170     }//main
 171 
 172     public static synchronized void setTimeoutTo( int seconds )
 173     {
 174         sleepTime = seconds * 1000;
 175     }
 176 
 177     public static synchronized void pass()
 178     {
 179         System.out.println( "The test passed." );
 180         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 181         //first check if this is executing in main thread
 182         if ( mainThread == Thread.currentThread() )
 183         {
 184             //Still in the main thread, so set the flag just for kicks,
 185             // and throw a test passed exception which will be caught
 186             // and end the test.
 187             theTestPassed = true;
 188             throw new TestPassedException();
 189         }
 190         theTestPassed = true;
 191         testGeneratedInterrupt = true;
 192         mainThread.interrupt();
 193     }//pass()
 194 
 195     public static synchronized void fail()
 196     {
 197         //test writer didn't specify why test failed, so give generic
 198         fail( "it just plain failed! :-)" );
 199     }
 200 
 201     public static synchronized void fail( String whyFailed )
 202     {
 203         System.out.println( "The test failed: " + whyFailed );
 204         System.out.println( "The test is over, hit  Ctl-C to stop Java VM" );
 205         //check if this called from main thread
 206         if ( mainThread == Thread.currentThread() )
 207         {
 208             //If main thread, fail now 'cause not sleeping
 209             throw new RuntimeException( whyFailed );
 210         }
 211         theTestPassed = false;
 212         testGeneratedInterrupt = true;
 213         failureMessage = whyFailed;
 214         mainThread.interrupt();
 215     }//fail()
 216 
 217 }// class DisplayChangedTest
 218 
 219 //This exception is used to exit from any level of call nesting
 220 // when it's determined that the test has passed, and immediately
 221 // end the test.
 222 class TestPassedException extends RuntimeException
 223 {
 224 }
 225 
 226 //*********** End Standard Test Machinery Section **********
 227 
 228 
 229 //************ Begin classes defined for the test ****************
 230 
 231 // if want to make listeners, here is the recommended place for them, then instantiate
 232 //  them in init()
 233 
 234 /* Example of a class which may be written as part of a test
 235 class NewClass implements anInterface
 236  {
 237    static int newVar = 0;
 238 
 239    public void eventDispatched(AWTEvent e)
 240     {
 241       //Counting events to see if we get enough
 242       eventCount++;
 243 
 244       if( eventCount == 20 )
 245        {
 246          //got enough events, so pass
 247 
 248          DisplayChangedTest.pass();
 249        }
 250       else if( tries == 20 )
 251        {
 252          //tried too many times without getting enough events so fail
 253 
 254          DisplayChangedTest.fail();
 255        }
 256 
 257     }// eventDispatched()
 258 
 259  }// NewClass class
 260 
 261 */