Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/java/awt/FullScreen/AltTabCrashTest/AltTabCrashTest.java
38828 views
/*1* Copyright (c) 2005, 2014 Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24@test25@bug 6275887 6429971 645979226@summary Test that we don't crash when alt+tabbing in and out of27fullscreen app28@author [email protected]: area=FullScreen29@run main/othervm/timeout=100 AltTabCrashTest -auto -changedm30@run main/othervm/timeout=100 -Dsun.java2d.d3d=True AltTabCrashTest -auto -changedm31@run main/othervm/timeout=100 -Dsun.java2d.d3d=True AltTabCrashTest -auto -usebs -changedm32@run main/othervm/timeout=100 -Dsun.java2d.opengl=True AltTabCrashTest -auto33*/3435import java.awt.AWTException;36import java.awt.Color;37import java.awt.DisplayMode;38import java.awt.Frame;39import java.awt.Graphics;40import java.awt.Graphics2D;41import java.awt.GraphicsDevice;42import java.awt.GraphicsEnvironment;43import java.awt.Image;44import java.awt.RenderingHints;45import java.awt.Robot;46import java.awt.event.KeyAdapter;47import java.awt.event.KeyEvent;48import java.awt.event.MouseAdapter;49import java.awt.event.MouseEvent;50import java.awt.image.BufferStrategy;51import java.awt.image.BufferedImage;52import java.awt.image.VolatileImage;53import java.util.Random;54import java.util.Vector;5556/**57* Note that the alt+tabbing in and out part will most likely only work58* on Windows, and only if there are no interventions.59*/6061public class AltTabCrashTest extends Frame {62public static int width;63public static int height;64public static volatile boolean autoMode;65public static boolean useBS;66public static final int NUM_OF_BALLS = 70;67// number of times to alt+tab in and out of the app68public static int altTabs = 5;69private final Vector<Ball> balls = new Vector<>();70GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment()71.getDefaultScreenDevice();72VolatileImage vimg = null;73BufferStrategy bufferStrategy = null;74volatile boolean timeToQuit = false;75static final Object lock = new Object();7677enum SpriteType {78OVALS, VIMAGES, BIMAGES, AAOVALS, TEXT79}8081private static boolean changeDM = false;82private static SpriteType spriteType;83static Random rnd = new Random();8485public AltTabCrashTest( ) {86addKeyListener(new KeyAdapter() {87public void keyPressed(KeyEvent e) {88if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {89timeToQuit = true;90}91}92});93setIgnoreRepaint(true);94addMouseListener(new MouseHandler());95for (int i = 0; i < NUM_OF_BALLS; i++) {96int x = 50 + rnd.nextInt(550), y = 50 + rnd.nextInt(400);9798balls.addElement(createRandomBall(y, x));99}100setUndecorated(true);101gd.setFullScreenWindow(this);102GraphicsDevice gd = getGraphicsConfiguration().getDevice();103if (gd.isDisplayChangeSupported() && changeDM) {104DisplayMode dm = findDisplayMode();105if (dm != null) {106try {107gd.setDisplayMode(dm);108} catch (IllegalArgumentException iae) {109System.err.println("Error setting display mode");110}111}112}113if (useBS) {114createBufferStrategy(2);115bufferStrategy = getBufferStrategy();116} else {117Graphics2D g = (Graphics2D) getGraphics();118render(g);119g.dispose();120}121Thread t = new BallThread();122t.start();123if (autoMode) {124Thread tt = new AltTabberThread();125tt.start();126synchronized (lock) {127while (!timeToQuit) {128try {129lock.wait(200);130} catch (InterruptedException ex) {131ex.printStackTrace();132}133}134}135t = null;136dispose();137}138}139140private Ball createRandomBall(final int y, final int x) {141Ball b;142SpriteType type;143144if (spriteType == null) {145int index = rnd.nextInt(SpriteType.values().length);146type = SpriteType.values()[index];147} else {148type = spriteType;149}150switch (type) {151case VIMAGES: b = new VISpriteBall(x, y); break;152case AAOVALS: b = new AAOvalBall(x, y); break;153case BIMAGES: b = new BISpriteBall(x, y); break;154case TEXT: b = new TextBall(x,y, "Text Sprite!"); break;155default: b = new Ball(x, y); break;156}157return b;158}159160private class MouseHandler extends MouseAdapter {161public void mousePressed(MouseEvent e) {162synchronized (balls) {163balls.addElement(createRandomBall(e.getX(), e.getY()));164}165}166}167168private class AltTabberThread extends Thread {169Robot robot;170171void pressAltTab() {172robot.keyPress(KeyEvent.VK_ALT);173robot.keyPress(KeyEvent.VK_TAB);174robot.keyRelease(KeyEvent.VK_TAB);175robot.keyRelease(KeyEvent.VK_ALT);176}177void pressShiftAltTab() {178robot.keyPress(KeyEvent.VK_SHIFT);179pressAltTab();180robot.keyRelease(KeyEvent.VK_SHIFT);181}182public void run() {183try {184robot = new Robot();185robot.setAutoDelay(200);186} catch (AWTException e) {187throw new RuntimeException("Can't create robot");188}189boolean out = true;190while (altTabs-- > 0 && !timeToQuit) {191System.err.println("Alt+tabber Iteration: "+altTabs);192try { Thread.sleep(2500); } catch (InterruptedException ex) {}193194if (out) {195System.err.println("Issuing alt+tab");196pressAltTab();197} else {198System.err.println("Issuing shift ");199pressShiftAltTab();200}201out = !out;202}203System.err.println("Alt+tabber finished.");204synchronized (lock) {205timeToQuit = true;206lock.notify();207}208}209}210211private class BallThread extends Thread {212public void run() {213while (!timeToQuit) {214if (useBS) {215renderToBS();216bufferStrategy.show();217} else {218Graphics g = AltTabCrashTest.this.getGraphics();219render(g);220g.dispose();221}222}223gd.setFullScreenWindow(null);224AltTabCrashTest.this.dispose();225}226}227228static class Ball {229230int x, y; // current location231int dx, dy; // motion delta232int diameter = 40;233Color color = Color.red;234235public Ball() {236}237238public Ball(int x, int y) {239this.x = x;240this.y = y;241dx = x % 20 + 1;242dy = y % 20 + 1;243color = new Color(rnd.nextInt(0x00ffffff));244}245246public void move() {247if (x < 10 || x >= AltTabCrashTest.width - 20)248dx = -dx;249if (y < 10 || y > AltTabCrashTest.height - 20)250dy = -dy;251x += dx;252y += dy;253}254255public void paint(Graphics g, Color c) {256if (c == null) {257g.setColor(color);258} else {259g.setColor(c);260}261g.fillOval(x, y, diameter, diameter);262}263264}265266static class TextBall extends Ball {267String text;268public TextBall(int x, int y, String text) {269super(x, y);270this.text = text;271}272273public void paint(Graphics g, Color c) {274if (c == null) {275g.setColor(color);276} else {277g.setColor(c);278}279g.drawString(text, x, y);280}281}282283static class AAOvalBall extends Ball {284public AAOvalBall(int x, int y) {285super(x, y);286}287public void paint(Graphics g, Color c) {288if (c == null) {289Graphics2D g2d = (Graphics2D)g.create();290g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,291RenderingHints.VALUE_ANTIALIAS_ON);292g2d.setColor(color);293g2d.fillOval(x, y, diameter, diameter);294} else {295g.setColor(c);296g.fillOval(x-2, y-2, diameter+4, diameter+4);297}298}299}300301static abstract class SpriteBall extends Ball {302Image image;303public SpriteBall(int x, int y) {304super(x, y);305image = createSprite();306Graphics g = image.getGraphics();307g.setColor(color);308g.fillRect(0, 0, image.getWidth(null), image.getHeight(null));309}310public void paint(Graphics g, Color c) {311if (c != null) {312g.setColor(c);313g.fillRect(x, y, image.getWidth(null), image.getHeight(null));314} else do {315validateSprite();316g.drawImage(image, x, y, null);317} while (renderingIncomplete());318}319public abstract Image createSprite();320public void validateSprite() {}321public boolean renderingIncomplete() { return false; }322}323class VISpriteBall extends SpriteBall {324325public VISpriteBall(int x, int y) {326super(x, y);327}328public boolean renderingIncomplete() {329return ((VolatileImage)image).contentsLost();330}331332public Image createSprite() {333return gd.getDefaultConfiguration().334createCompatibleVolatileImage(20, 20);335}336public void validateSprite() {337int result =338((VolatileImage)image).validate(getGraphicsConfiguration());339if (result == VolatileImage.IMAGE_INCOMPATIBLE) {340image = createSprite();341result = VolatileImage.IMAGE_RESTORED;342}343if (result == VolatileImage.IMAGE_RESTORED) {344Graphics g = image.getGraphics();345g.setColor(color);346g.fillRect(0, 0, image.getWidth(null), image.getHeight(null));347}348}349}350class BISpriteBall extends SpriteBall {351public BISpriteBall(int x, int y) {352super(x, y);353}354public Image createSprite() {355return new BufferedImage(20, 20, BufferedImage.TYPE_INT_RGB);356}357}358359360public void renderOffscreen() {361Graphics2D g2d = (Graphics2D) vimg.getGraphics();362synchronized (balls) {363for (Ball b : balls) {364b.paint(g2d, getBackground());365b.move();366b.paint(g2d, null);367}368}369g2d.dispose();370}371372public void renderToBS() {373width = getWidth();374height = getHeight();375376do {377Graphics2D g2d = (Graphics2D)bufferStrategy.getDrawGraphics();378379g2d.clearRect(0, 0, width, height);380synchronized (balls) {381for (Ball b : balls) {382b.move();383b.paint(g2d, null);384}385}386g2d.dispose();387} while (bufferStrategy.contentsLost() ||388bufferStrategy.contentsRestored());389}390391public void render(Graphics g) {392do {393height = getBounds().height;394width = getBounds().width;395if (vimg == null) {396vimg = createVolatileImage(width, height);397renderOffscreen();398}399int returnCode = vimg.validate(getGraphicsConfiguration());400if (returnCode == VolatileImage.IMAGE_RESTORED) {401renderOffscreen();402} else if (returnCode == VolatileImage.IMAGE_INCOMPATIBLE) {403vimg = getGraphicsConfiguration().404createCompatibleVolatileImage(width, height);405renderOffscreen();406} else if (returnCode == VolatileImage.IMAGE_OK) {407renderOffscreen();408}409g.drawImage(vimg, 0, 0, this);410} while (vimg.contentsLost());411}412413public static void main(String args[]) {414for (String arg : args) {415if (arg.equalsIgnoreCase("-auto")) {416autoMode = true;417System.err.println("Running in automatic mode using Robot");418} else if (arg.equalsIgnoreCase("-usebs")) {419useBS = true;420System.err.println("Using BufferStrategy instead of VI");421} else if (arg.equalsIgnoreCase("-changedm")) {422changeDM= true;423System.err.println("The test will change display mode");424} else if (arg.equalsIgnoreCase("-vi")) {425spriteType = SpriteType.VIMAGES;426} else if (arg.equalsIgnoreCase("-bi")) {427spriteType = SpriteType.BIMAGES;428} else if (arg.equalsIgnoreCase("-ov")) {429spriteType = SpriteType.OVALS;430} else if (arg.equalsIgnoreCase("-aaov")) {431spriteType = SpriteType.AAOVALS;432} else if (arg.equalsIgnoreCase("-tx")) {433spriteType = SpriteType.TEXT;434} else {435System.err.println("Usage: AltTabCrashTest [-usebs][-auto]" +436"[-changedm][-vi|-bi|-ov|-aaov|-tx]");437System.err.println(" -usebs: use BufferStrategy instead of VI");438System.err.println(" -auto: automatically alt+tab in and out" +439" of the application ");440System.err.println(" -changedm: change display mode");441System.err.println(" -(vi|bi|ov|tx|aaov) : use only VI, BI, " +442"text or [AA] [draw]Oval sprites");443System.exit(0);444}445}446if (spriteType != null) {447System.err.println("The test will only use "+spriteType+" sprites.");448}449new AltTabCrashTest();450}451452private DisplayMode findDisplayMode() {453GraphicsDevice gd = getGraphicsConfiguration().getDevice();454DisplayMode dms[] = gd.getDisplayModes();455DisplayMode currentDM = gd.getDisplayMode();456for (DisplayMode dm : dms) {457if (dm.getBitDepth() > 8 &&458dm.getBitDepth() != DisplayMode.BIT_DEPTH_MULTI &&459dm.getBitDepth() != currentDM.getBitDepth() &&460dm.getWidth() == currentDM.getWidth() &&461dm.getHeight() == currentDM.getHeight())462{463// found a mode which has the same dimensions but different464// depth465return dm;466}467if (dm.getBitDepth() == DisplayMode.BIT_DEPTH_MULTI &&468(dm.getWidth() != currentDM.getWidth() ||469dm.getHeight() != currentDM.getHeight()))470{471// found a mode which has the same depth but different472// dimensions473return dm;474}475}476477return null;478}479}480481482