1 /*
   2  * Copyright (c) 2007, 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 import java.awt.*;
  25 import java.awt.event.*;
  26 import java.awt.image.BufferedImage;
  27 
  28 /*
  29  * @test
  30  * @summary Check for MouseEvents with all mouse buttons
  31  * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com)
  32  * @modules java.desktop/java.awt:open
  33  * @library /java/awt/patchlib
  34  * @library ../../../../lib/testlibrary ../
  35  * @build ExtendedRobot SystemTrayIconHelper
  36  * @build java.desktop/java.awt.Helper
  37  * @run main ModalityTest
  38  */
  39 public class ModalityTest {
  40 
  41     private static boolean isOEL7;
  42     TrayIcon icon;
  43     ExtendedRobot robot;
  44     Dialog d;
  45 
  46     boolean actionPerformed = false;
  47 
  48     private boolean dialogVisible = false;
  49     private Object dialogLock = new Object();
  50 
  51     Object actionLock = new Object();
  52     Object pressLock = new Object();
  53     Object releaseLock = new Object();
  54     Object clickLock = new Object();
  55     Object moveLock = new Object();
  56     static final int clickDelay = 50;
  57 
  58     boolean mousePressed = false;
  59     boolean mouseReleased = false;
  60     boolean mouseClicked = false;
  61     boolean mouseMoved = false;
  62 
  63     int[] buttonTypes = {
  64         InputEvent.BUTTON1_MASK,
  65         InputEvent.BUTTON2_MASK,
  66         InputEvent.BUTTON3_MASK
  67     };
  68 
  69     String[] buttonNames = {
  70         "BUTTON1",
  71         "BUTTON2",
  72         "BUTTON3"
  73     };
  74 
  75     public static void main(String[] args) throws Exception {
  76         if (! SystemTray.isSupported()) {
  77             System.out.println("SystemTray not supported on the platform under test. " +
  78                                "Marking the test passed");
  79         } else {
  80             if (System.getProperty("os.name").toLowerCase().startsWith("win"))
  81                 System.err.println("Test can fail if the icon hides to a tray icons pool " +
  82                         "in Windows 7, which is behavior by default.\n" +
  83                         "Set \"Right mouse click\" -> \"Customize notification icons\" -> " +
  84                         "\"Always show all icons and notifications on the taskbar\" true " +
  85                         "to avoid this problem. Or change behavior only for Java SE tray " +
  86                         "icon and rerun test.");
  87             isOEL7 = SystemTrayIconHelper.isOel7();
  88             new ModalityTest().doTest();
  89         }
  90     }
  91 
  92     public ModalityTest() throws Exception {
  93         robot = new ExtendedRobot();
  94         EventQueue.invokeLater(this::initializeGUI);
  95     }
  96 
  97     void initializeGUI() {
  98         SystemTray tray = SystemTray.getSystemTray();
  99         icon = new TrayIcon(new BufferedImage(20, 20, BufferedImage.TYPE_INT_RGB), "Sample Icon");
 100         icon.addActionListener(event -> {
 101             actionPerformed = true;
 102             synchronized (actionLock) {
 103                 try {
 104                     actionLock.notifyAll();
 105                 } catch (Exception e) {
 106                 }
 107             }
 108         });
 109         icon.addMouseListener(new MouseAdapter() {
 110             public void mousePressed(MouseEvent event) {
 111                 mousePressed = true;
 112                 Point p = event.getPoint();
 113                 if (p.x != event.getX() || p.y != event.getY())
 114                     throw new RuntimeException("FAIL: MouseEvent.getPoint() did " +
 115                             "not return the same value as getX/getY " +
 116                             "for mousePressed");
 117 
 118                 if (! icon.equals(event.getSource()))
 119                     throw new RuntimeException("FAIL: mousePressed: MouseEvent.getSource " +
 120                             "did not return TrayIcon object");
 121 
 122                 synchronized (pressLock) {
 123                     try {
 124                         pressLock.notifyAll();
 125                     } catch (Exception e) {
 126                     }
 127                 }
 128             }
 129 
 130             public void mouseReleased(MouseEvent event) {
 131                 mouseReleased = true;
 132                 Point p = event.getPoint();
 133                 if (p.x != event.getX() || p.y != event.getY())
 134                     throw new RuntimeException("FAIL: MouseEvent.getPoint() did " +
 135                             "not return the same value as getX/getY " +
 136                             "for mouseReleased");
 137 
 138                 if (! icon.equals(event.getSource()))
 139                     throw new RuntimeException("FAIL: mouseReleased: MouseEvent.getSource " +
 140                             "did not return TrayIcon object");
 141 
 142                 synchronized (releaseLock) {
 143                     try {
 144                         releaseLock.notifyAll();
 145                     } catch (Exception e) {
 146                     }
 147                 }
 148             }
 149 
 150             public void mouseClicked(MouseEvent event) {
 151                 mouseClicked = true;
 152                 Point p = event.getPoint();
 153                 if (p.x != event.getX() || p.y != event.getY())
 154                     throw new RuntimeException("FAIL: MouseEvent.getPoint() did " +
 155                             "not return the same value as getX/getY " +
 156                             "for mouseClicked");
 157 
 158                 if (! icon.equals(event.getSource()))
 159                     throw new RuntimeException("FAIL: mouseClicked: MouseEvent.getSource " +
 160                             "did not return TrayIcon object");
 161 
 162                 synchronized (clickLock) {
 163                     try {
 164                         clickLock.notifyAll();
 165                     } catch (Exception e) {
 166                     }
 167                 }
 168             }
 169         });
 170 
 171         icon.addMouseMotionListener(new MouseMotionAdapter() {
 172             public void mouseMoved(MouseEvent event) {
 173                 mouseMoved = true;
 174                 Point p = event.getPoint();
 175                 if (p.x != event.getX() || p.y != event.getY())
 176                     throw new RuntimeException("FAIL: MouseEvent.getPoint() did " +
 177                             "not return the same value as getX/getY " +
 178                             "for mouseMoved");
 179 
 180                 if (!icon.equals(event.getSource()))
 181                     throw new RuntimeException("FAIL: mouseMoved: MouseEvent.getSource " +
 182                             "did not return TrayIcon object");
 183 
 184                 synchronized (moveLock) {
 185                     try {
 186                         moveLock.notifyAll();
 187                     } catch (Exception e) {
 188                     }
 189                 }
 190             }
 191         });
 192 
 193         try {
 194             tray.add(icon);
 195         } catch (AWTException e) {
 196             throw new RuntimeException(e);
 197         }
 198 
 199         d = new Dialog((Frame) null, "Modal Dialog");
 200         d.setLocation(200, 200);
 201         d.setSize(100, 100);
 202         d.setModalityType(Dialog.ModalityType.TOOLKIT_MODAL);
 203 
 204         dialogVisible = true;
 205         synchronized (dialogLock) {
 206             try {
 207                 dialogLock.notifyAll();
 208             } catch (Exception e) {
 209             }
 210         }
 211 
 212         d.setVisible(true);
 213     }
 214 
 215     void doTest() throws Exception {
 216 
 217         if (! dialogVisible) {
 218             synchronized (dialogLock) {
 219                 try {
 220                     dialogLock.wait(3000);
 221                 } catch (Exception e) {
 222                 }
 223             }
 224         }
 225 
 226         if (! dialogVisible)
 227             throw new RuntimeException("ERROR: TIMEOUT: The thread in EDT not yet complete");
 228 
 229         Point iconPosition = SystemTrayIconHelper.getTrayIconLocation(icon);
 230         if (iconPosition == null)
 231             throw new RuntimeException("Unable to find the icon location!");
 232         if (isOEL7) {
 233             // close tray
 234             robot.mouseMove(100,100);
 235             robot.click(InputEvent.BUTTON1_MASK);
 236             robot.waitForIdle(2000);
 237         }
 238 
 239         if (! d.isVisible())
 240             throw new RuntimeException("FAIL: The modal dialog is not yet visible");
 241 
 242         robot.mouseMove(iconPosition.x, iconPosition.y);
 243         robot.waitForIdle(2000);
 244 
 245         if(!isOEL7) {
 246             SystemTrayIconHelper.doubleClick(robot);
 247 
 248             if (!actionPerformed) {
 249                 synchronized (actionLock) {
 250                     try {
 251                         actionLock.wait(3000);
 252                     } catch (Exception e) {
 253                     }
 254                 }
 255             }
 256             if (!actionPerformed)
 257                 throw new RuntimeException("FAIL: ActionEvent not triggered when TrayIcon is double clicked");
 258         }
 259 
 260         for (int i = 0; i < buttonTypes.length; i++) {
 261             mousePressed = false;
 262             if(isOEL7) {
 263                 SystemTrayIconHelper.openTrayIfNeeded(robot);
 264                 robot.mouseMove(iconPosition.x, iconPosition.y);
 265                 robot.click(buttonTypes[i]);
 266             } else {
 267                 robot.mousePress(buttonTypes[i]);
 268             }
 269 
 270             if (! mousePressed) {
 271                 synchronized (pressLock) {
 272                     try {
 273                         pressLock.wait(6000);
 274                     } catch (Exception e) {
 275                     }
 276                 }
 277             }
 278             if (! mousePressed)
 279                 if (! SystemTrayIconHelper.skip(buttonTypes[i]) )
 280                     throw new RuntimeException("FAIL: mousePressed not triggered when " +
 281                             buttonNames[i] + " pressed");
 282 
 283             mouseReleased = false;
 284             mouseClicked = false;
 285             if(isOEL7) {
 286                 SystemTrayIconHelper.openTrayIfNeeded(robot);
 287                 robot.mouseMove(iconPosition.x, iconPosition.y);
 288                 robot.click(buttonTypes[i]);
 289             } else {
 290                 robot.mouseRelease(buttonTypes[i]);
 291             }
 292 
 293             if (! mouseReleased) {
 294                 synchronized (releaseLock) {
 295                     try {
 296                         releaseLock.wait(6000);
 297                     } catch (Exception e) {
 298                     }
 299                 }
 300             }
 301             if (! mouseReleased)
 302                 throw new RuntimeException("FAIL: mouseReleased not triggered when " +
 303                         buttonNames[i] + " released");
 304 
 305             if (! mouseClicked) {
 306                 synchronized (clickLock) {
 307                     try {
 308                         clickLock.wait(6000);
 309                     } catch (Exception e) {
 310                     }
 311                 }
 312             }
 313             if (! mouseClicked)
 314                 throw new RuntimeException("FAIL: mouseClicked not triggered when " +
 315                         buttonNames[i] + " pressed & released");
 316         }
 317         if (!isOEL7) {
 318             mouseMoved = false;
 319             robot.mouseMove(iconPosition.x, iconPosition.y);
 320             robot.glide(iconPosition.x + 100, iconPosition.y);
 321 
 322             if (!mouseMoved)
 323                 if (!SystemTrayIconHelper.skip(0))
 324                     throw new RuntimeException("FAIL: mouseMoved not triggered even when mouse moved over the icon");
 325         }
 326     }
 327 }