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