java-topology/test/jdk/java/awt/SplashScreen/MultiResolutionSplash/MultiResolutionSplashTest.java
russell@unturf.com 0a580b313d undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
2026-03-26 17:11:57 -04:00

243 lines
8.5 KiB
Java

/*
* Copyright (c) 2014, 2026, 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.
*/
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.SplashScreen;
import java.awt.TextField;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
/*
* @test
* @key headful
* @bug 8043869 8075244 8078082 8145173 8151787 8212213
* @summary Tests the HiDPI splash screen support for windows and MAC
* @run main MultiResolutionSplashTest GENERATE_IMAGES
* @run main/othervm -splash:splash1.png MultiResolutionSplashTest TEST_SPLASH 0
* @run main/othervm -splash:splash2 MultiResolutionSplashTest TEST_SPLASH 1
* @run main/othervm -splash:splash3. MultiResolutionSplashTest TEST_SPLASH 2
* @run main/othervm -splash:splash1.png MultiResolutionSplashTest TEST_FOCUS
*/
public class MultiResolutionSplashTest {
private static final int IMAGE_WIDTH = 300;
private static final int IMAGE_HEIGHT = 200;
private static final boolean isMac = System.getProperty("os.name")
.contains("OS X");
private static final ImageInfo[] tests = {
new ImageInfo("splash1", ".png", Color.BLUE, Color.GREEN),
new ImageInfo("splash2", "", Color.WHITE, Color.BLACK),
new ImageInfo("splash3", ".", Color.YELLOW, Color.RED)
};
public static void main(String[] args) throws Exception {
switch (args[0]) {
case "GENERATE_IMAGES":
generateImages();
break;
case "TEST_SPLASH":
testSplash(tests[Integer.parseInt(args[1])]);
break;
case "TEST_FOCUS":
testFocus();
break;
default:
throw new RuntimeException("Unknown test: " + args[0]);
}
}
static void testSplash(ImageInfo test) throws Exception {
SplashScreen splashScreen = SplashScreen.getSplashScreen();
if (splashScreen == null) {
throw new RuntimeException("Splash screen is not shown!");
}
final Rectangle splashBounds = splashScreen.getBounds();
final double scaleFactor = getScreenScaleFactor();
final Robot robot = new Robot();
// Allow time for the splash screen to show
robot.delay(100);
BufferedImage splashCapture = robot.createScreenCapture(splashBounds);
String captureFileName = "splashscreen-%1.2f-%s.png"
.formatted(scaleFactor, test.name1x);
saveImageNoError(splashCapture, new File(captureFileName));
// Close the splash screen; this gives time for it to be fully removed
splashScreen.close();
robot.waitForIdle();
if (splashBounds.width != IMAGE_WIDTH) {
throw new RuntimeException(
"SplashScreen#getBounds has wrong width");
}
if (splashBounds.height != IMAGE_HEIGHT) {
throw new RuntimeException(
"SplashScreen#getBounds has wrong height");
}
Color splashScreenColor =
new Color(splashCapture.getRGB(splashBounds.width / 2,
splashBounds.height / 2));
Color testColor = (1 < scaleFactor) ? test.color2x : test.color1x;
if (!compare(testColor, splashScreenColor)) {
throw new RuntimeException(
"Image with wrong resolution is used for splash screen! "
+ "Refer to " + captureFileName);
}
}
static void testFocus() throws Exception {
Robot robot = new Robot();
robot.setAutoWaitForIdle(true);
robot.setAutoDelay(50);
Frame frame = new Frame();
frame.setSize(100, 100);
String test = "123";
TextField textField = new TextField(test);
textField.selectAll();
frame.add(textField);
frame.setVisible(true);
robot.waitForIdle();
robot.delay(1000);
robot.keyPress(KeyEvent.VK_A);
robot.keyRelease(KeyEvent.VK_A);
robot.keyPress(KeyEvent.VK_B);
robot.keyRelease(KeyEvent.VK_B);
robot.waitForIdle();
frame.dispose();
if (!textField.getText().equals("ab")) {
throw new RuntimeException("Focus is lost! " +
"Expected 'ab' got " + "'" + textField.getText() + "'.");
}
}
static boolean compare(Color c1, Color c2) {
return compare(c1.getRed(), c2.getRed())
&& compare(c1.getGreen(), c2.getGreen())
&& compare(c1.getBlue(), c2.getBlue());
}
static boolean compare(int n, int m) {
return Math.abs(n - m) <= 50;
}
static void generateImages() throws Exception {
for (ImageInfo test : tests) {
generateImage(test.name1x, test.color1x, 1.0);
// Ensure the second image uses scale greater than 1.0
double scale = getAdjustedScaleFactor();
generateImage(test.name2x, test.color2x, scale);
}
}
static void generateImage(final String name,
final Color color,
final double scale) throws Exception {
File file = new File(name);
if (file.exists()) {
return;
}
final int width = (int) (scale * IMAGE_WIDTH);
final int height = (int) (scale * IMAGE_HEIGHT);
BufferedImage image = new BufferedImage(width,
height,
BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setColor(color);
g.fillRect(0, 0, width, height);
saveImage(image, file);
}
private static void saveImage(BufferedImage image,
File file) throws IOException {
ImageIO.write(image, "png", file);
}
private static void saveImageNoError(BufferedImage image,
File file) {
try {
saveImage(image, file);
} catch (IOException ignored) {
}
}
static double getScreenScaleFactor() {
return GraphicsEnvironment
.getLocalGraphicsEnvironment()
.getDefaultScreenDevice()
.getDefaultConfiguration()
.getDefaultTransform()
.getScaleX();
}
// Ensure the second image uses scale greater than 1.0
static double getAdjustedScaleFactor() {
double scale = getScreenScaleFactor();
return scale < 1.25 ? 2.0 : scale;
}
static class ImageInfo {
final String name1x;
final String name2x;
final Color color1x;
final Color color2x;
public ImageInfo(String baseName, String ext,
Color color1x, Color color2x) {
this.name1x = baseName + ext;
this.name2x = createName2x(baseName, ext);
this.color1x = color1x;
this.color2x = color2x;
}
private static String createName2x(String baseName, String ext) {
double scale = getAdjustedScaleFactor();
if (!isMac && (((int) (scale * 100)) % 100 != 0)) {
return baseName + "@" + ((int) (scale * 100)) + "pct" + ext;
} else {
return baseName + "@" + ((int) scale) + "x" + ext;
}
}
}
}