jdk-24/test/jdk/java/awt/regtesthelpers/VisibilityValidator.java
2017-09-12 19:03:39 +02:00

308 lines
9.9 KiB
Java

/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @summary Utility routines that wait for a window to be displayed or for
colors to be visible
* @summary com.apple.junit.utils
*/
package test.java.awt.regtesthelpers;
import java.awt.*;
import java.awt.event.*;
//import junit.framework.Assert;
public class VisibilityValidator {
// Wait up to five seconds for our window events
static final int SETUP_PERIOD = 5000;
static final boolean DEBUG = false;
volatile Window win = null;
boolean activated = false;
boolean opened = false;
boolean focused = false;
volatile boolean valid = false;
//
// Utility functions that encapsulates normal usage patterns
//
public static void setVisibleAndConfirm(Frame testframe) throws Exception {
setVisibleAndConfirm(testframe, "Could not confirm test frame was "
+ "visible");
}
public static void setVisibleAndConfirm(Frame testframe, String msg)
throws Exception {
if (testframe.isVisible()) {
throw new RuntimeException("Frame is already visible");
}
VisibilityValidator checkpoint = new VisibilityValidator(testframe);
testframe.setVisible(true);
checkpoint.requireVisible();
if (!checkpoint.isValid()) {
//System.err.println(msg);
throw new Exception("Frame not visible after " + SETUP_PERIOD
+ " milliseconds");
}
}
//
// Add listeners to the window
//
public VisibilityValidator(Window win) {
this.win = win;
WindowAdapter watcher = new WindowAdapter() {
public void windowOpened(WindowEvent e) {
doOpen();
}
public void windowActivated(WindowEvent e) {
doActivate();
}
public void windowGainedFocus(WindowEvent e) {
doGainedFocus();
}
};
win.addWindowListener(watcher);
win.addWindowFocusListener(watcher);
}
// Make the window visible
//
// The only way to make it through this routine is for the window to
// generate BOTH a windowOpened, a windowActivated event and a
// windowGainedFocus, or to timeout.
//
synchronized public void requireVisible() {
int tries = 0;
// wait for windowOpened and windowActivated events
try {
while ((opened == false)
|| (activated == false)
|| (focused == false)) {
if (tries < 4) {
tries += 1;
wait(SETUP_PERIOD);
} else {
break;
}
}
if (opened && activated) {
valid = true;
} else {
valid = false;
}
} catch (InterruptedException ix) {
valid = false;
}
// Extra-super paranoid checks
if (win.isVisible() == false) {
valid = false;
}
if (win.isShowing() == false) {
valid = false;
}
if (win.isFocused() == false) {
valid = false;
}
if (DEBUG) {
if (!isValid()) {
System.out.println("\tactivated:" + new Boolean(activated));
System.out.println("\topened:" + new Boolean(opened));
System.out.println("\tfocused:" + new Boolean(focused));
System.out.println("\tvalid:" + new Boolean(valid));
System.out.println("\tisVisible():"
+ new Boolean(win.isVisible()));
System.out.println("\tisShowing():"
+ new Boolean(win.isShowing()));
System.out.println("\tisFocused():"
+ new Boolean(win.isFocused()));
}
}
}
synchronized void doOpen() {
opened = true;
notify();
}
synchronized void doActivate() {
activated = true;
notify();
}
synchronized void doGainedFocus() {
focused = true;
notify();
}
public boolean isValid() {
return valid;
}
public boolean isClear() {
return valid;
}
volatile static Robot robot = null;
// utility function that waits until a Component is shown with the
// appropriate color
public static boolean waitForColor(Component c,
Color expected) throws AWTException,
InterruptedException {
Dimension dim = c.getSize();
int xOff = dim.width / 2;
int yOff = dim.height / 2;
return waitForColor(c, xOff, yOff, expected);
}
// utility function that waits for 5 seconds for Component to be shown with
// the appropriate color
public static boolean waitForColor(Component c,
int xOff,
int yOff,
Color expected) throws AWTException, InterruptedException {
return waitForColor(c, xOff, yOff, expected, 5000L);
}
// utility function that waits until a Component is up with the appropriate
// color
public static boolean waitForColor(Component c,
int xOff,
int yOff,
Color expected,
long timeout) throws AWTException, InterruptedException {
Point p = c.getLocationOnScreen();
int x = (int) p.getX() + xOff;
int y = (int) p.getY() + yOff;
return waitForColor(x, y, expected, timeout);
}
// utility function that waits until specific screen coords have the
// appropriate color
public static boolean waitForColor(int locX,
int locY,
Color expected,
long timeout) throws AWTException, InterruptedException {
if (robot == null) {
robot = new Robot();
}
long endtime = System.currentTimeMillis() + timeout;
while (endtime > System.currentTimeMillis()) {
if (colorMatch(robot.getPixelColor(locX, locY), expected)) {
return true;
}
Thread.sleep(50);
}
return false;
}
// utility function that asserts that two colors are similar to each other
public static void assertColorEquals(final String message,
final Color actual,
final Color expected) {
System.out.println("actual color: " + actual);
System.out.println("expect color: " + expected);
//Assert.assertTrue(message, colorMatch(actual, expected));
}
// determines if two colors are close in hue and brightness
public static boolean colorMatch(final Color actual, final Color expected) {
final float[] actualHSB = getHSB(actual);
final float[] expectedHSB = getHSB(expected);
final float actualHue = actualHSB[0];
final float expectedHue = expectedHSB[0];
final boolean hueMatched = closeMatchHue(actualHue, expectedHue, 0.17f);
//System.out.println("hueMatched? " + hueMatched);
final float actualBrightness = actualHSB[2];
final float expectedBrightness = expectedHSB[2];
final boolean brightnessMatched = closeMatch(actualBrightness,
expectedBrightness, 0.15f);
//System.out.println("brightnessMatched? " + brightnessMatched);
// check to see if the brightness was so low or so high that the hue
// got clamped to red
if (brightnessMatched && !hueMatched) {
return (expectedBrightness < 0.15f);
}
return brightnessMatched && hueMatched;
}
static float[] getHSB(final Color color) {
final float[] hsb = new float[3];
Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), hsb);
return hsb;
}
// matches hues from 0.0 to 1.0, accounting for wrap-around at the 1.0/0.0
// boundry
static boolean closeMatchHue(final float actual,
final float expected,
final float tolerance) {
if (closeMatch(actual, expected, tolerance)) {
return true;
}
// all that remains is the overflow and underflow cases
final float expectedHigh = expected + tolerance;
final float expectedLow = expected - tolerance;
if (expectedHigh > 1.0f) {
// expected is too high, and actual was too low
//System.out.println("\thue expected too high, actual too low");
return closeMatch(actual + 0.5f, expected - 0.5f, tolerance);
}
if (expectedLow < 0.0f) {
// expected is too low, and actual was too high
//System.out.println("\thue expected too low, actual too high");
return closeMatch(actual - 0.5f, expected + 0.5f, tolerance);
}
//System.out.println("\tcloseMatchHue? " + false);
return false;
}
static boolean closeMatch(final float actual,
final float expected,
final float tolerance) {
return (expected + tolerance) > actual && (expected - tolerance) < actual;
}
}