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
24import java.awt.*;
25import java.awt.event.*;
26import 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 */
39public 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}
328