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 if MouseEvents triggered by TrayIcon are visible
31 *          by an AWTEventListener added to the Toolkit. It also
32 *          checks if all listeners are triggered when AWTEventListeners
33 *          and MouseListeners are added.
34 * @author Dmitriy Ermashov (dmitriy.ermashov@oracle.com)
35 * @modules java.desktop/java.awt:open
36 * @library /java/awt/patchlib
37 * @library ../../../../lib/testlibrary ../
38 * @build java.desktop/java.awt.Helper
39 * @build ExtendedRobot SystemTrayIconHelper
40 * @run main MouseEventMaskTest
41 */
42
43public class MouseEventMaskTest {
44
45    TrayIcon icon;
46    Robot robot;
47    int[] buttonTypes = {
48        InputEvent.BUTTON1_MASK,
49        InputEvent.BUTTON2_MASK,
50        InputEvent.BUTTON3_MASK
51    };
52
53    String[] buttonNames = {
54        "BUTTON1",
55        "BUTTON2",
56        "BUTTON3"
57    };
58
59    boolean mouseEventTriggered = false;
60    boolean mouseMotionEventTriggered = false;
61    Object mouseEventLock = new Object();
62    Object mouseMotionEventLock = new Object();
63    boolean mouseMotionTest, mouseTest;
64
65    public static void main(String[] args) throws Exception {
66        if (! SystemTray.isSupported()) {
67            System.out.println("SystemTray not supported on the platform under test. " +
68                    "Marking the test passed");
69        } else {
70            if (System.getProperty("os.name").toLowerCase().startsWith("win")) {
71                System.err.println("Test can fail if the icon hides to a tray icons pool " +
72                        "in Windows 7, which is behavior by default.\n" +
73                        "Set \"Right mouse click\" -> \"Customize notification icons\" -> " +
74                        "\"Always show all icons and notifications on the taskbar\" true " +
75                        "to avoid this problem. Or change behavior only for Java SE tray " +
76                        "icon and rerun test.");
77            } else if (SystemTrayIconHelper.isOel7()) {
78                return;
79            }
80            new MouseEventMaskTest().doTest();
81        }
82    }
83
84    public MouseEventMaskTest() throws Exception{
85        EventQueue.invokeAndWait(this::initializeGUI);
86    }
87
88    void initializeGUI() {
89
90        SystemTray tray = SystemTray.getSystemTray();
91        icon = new TrayIcon(new BufferedImage(20, 20, BufferedImage.TYPE_INT_RGB), "Sample Icon");
92
93        Toolkit.getDefaultToolkit().addAWTEventListener(event -> {
94            if (mouseTest) {
95                if (! event.getSource().getClass().getName().contains("Canvas")) {
96                    if (!icon.equals(event.getSource()))
97                        throw new RuntimeException("FAIL: MouseEvent not triggered for icon " + event);
98
99                    mouseEventTriggered = true;
100                    synchronized (mouseEventLock) {
101                        try {
102                            mouseEventLock.notifyAll();
103                        } catch (Exception e) {
104                        }
105                    }
106                }
107            }
108        }, AWTEvent.MOUSE_EVENT_MASK);
109        Toolkit.getDefaultToolkit().addAWTEventListener(event -> {
110            if (mouseMotionTest) {
111                if (! event.getSource().getClass().getName().contains("Canvas")) {
112                    if (!icon.equals(event.getSource()))
113                        throw new RuntimeException("FAIL: MouseMotionEvent not triggered for icon " + event);
114
115                    mouseMotionEventTriggered = true;
116                    synchronized (mouseMotionEventLock) {
117                        try {
118                            mouseMotionEventLock.notifyAll();
119                        } catch (Exception e) {
120                        }
121                    }
122                }
123            }
124        }, AWTEvent.MOUSE_MOTION_EVENT_MASK);
125
126        try {
127            tray.add(icon);
128        } catch (AWTException e) {
129            throw new RuntimeException(e);
130        }
131    }
132
133    void doTest() throws Exception {
134
135        robot = new Robot();
136
137        Point iconPosition = SystemTrayIconHelper.getTrayIconLocation(icon);
138        if (iconPosition == null)
139            throw new RuntimeException("Unable to find the icon location!");
140
141        robot.mouseMove(iconPosition.x, iconPosition.y);
142        robot.waitForIdle();
143
144        for (int i = 0; i < buttonTypes.length; i++) {
145            System.out.println("Verify button "+buttonTypes[i]);
146            mouseTest = true;
147            mouseEventTriggered = false;
148            robot.mousePress(buttonTypes[i]);
149
150            if (! mouseEventTriggered) {
151                synchronized (mouseEventLock) {
152                    try {
153                        mouseEventLock.wait(3000);
154                    } catch (Exception e) {
155                    }
156                }
157            }
158            if (! mouseEventTriggered)
159                if (! SystemTrayIconHelper.skip(buttonTypes[i]) )
160                    throw new RuntimeException("FAIL: AWTEventListener not notified when " +
161                        buttonNames[i] + " pressed on TrayIcon");
162
163            mouseEventTriggered = false;
164            robot.mouseRelease(buttonTypes[i]);
165            if (! mouseEventTriggered) {
166                synchronized (mouseEventLock) {
167                    try {
168                        mouseEventLock.wait(3000);
169                    } catch (Exception e) {
170                    }
171                }
172            }
173
174            if (! mouseEventTriggered)
175                throw new RuntimeException("FAIL: AWTEventListener not notified when " +
176                        buttonNames[i] + " released on TrayIcon");
177        }
178
179        mouseMotionTest = true;
180        mouseTest = false;
181        mouseMotionEventTriggered = false;
182
183        for (int i = 0; i < 20; i++) {
184            robot.mouseMove(iconPosition.x + i, iconPosition.y);
185            robot.delay(25);
186        }
187        if (! mouseMotionEventTriggered) {
188            synchronized (mouseMotionEventLock) {
189                try {
190                    mouseMotionEventLock.wait(3000);
191                } catch (Exception e) {
192                }
193            }
194        }
195        if (! mouseMotionEventTriggered)
196            if (! SystemTrayIconHelper.skip(0) )
197                throw new RuntimeException("FAIL: AWTEventListener not notified when " +
198                        "mouse moved");
199    }
200}
201