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