1 /* 2 * Copyright (c) 2018, 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 24 import java.applet.AudioClip; 25 import java.io.ByteArrayInputStream; 26 import java.io.File; 27 import java.io.IOException; 28 import java.io.InputStream; 29 import java.nio.file.Files; 30 import java.util.concurrent.TimeUnit; 31 32 import javax.sound.sampled.AudioFileFormat.Type; 33 import javax.sound.sampled.AudioFormat; 34 import javax.sound.sampled.AudioInputStream; 35 import javax.sound.sampled.AudioSystem; 36 37 import static javax.sound.sampled.AudioFormat.Encoding.PCM_SIGNED; 38 import static javax.sound.sampled.AudioSystem.NOT_SPECIFIED; 39 40 /** 41 * @test 42 * @bug 8202264 43 */ 44 public final class AutoCloseTimeCheck { 45 46 public static void main(final String[] args) throws Exception { 47 // Prepare the audio file 48 File file = new File("audio.wav"); 49 try { 50 AudioFormat format = 51 new AudioFormat(PCM_SIGNED, 44100, 8, 1, 1, 44100, false); 52 AudioSystem.write(getStream(format), Type.WAVE, file); 53 } catch (final Exception ignored) { 54 return; // the test is not applicable 55 } 56 try { 57 testSmallDelay(file); 58 testBigDelay(file); 59 } finally { 60 Files.delete(file.toPath()); 61 } 62 } 63 64 /** 65 * Checks that after a big period of non-activity the clip will be closed 66 * and the "Direct Clip" thread will stop. 67 */ 68 private static void testBigDelay(final File file) throws Exception { 69 AudioClip clip = (AudioClip) file.toURL().getContent(); 70 clip.loop(); 71 clip.stop(); 72 sleep(20000); // 20 sec for slow systems 73 if (count() != 0) { 74 throw new RuntimeException("Thread was found"); 75 } 76 } 77 78 /** 79 * Checks that after small period of non-activity the clip will not be 80 * closed and the "Direct Clip" thread will alive. 81 */ 82 private static void testSmallDelay(final File file) throws IOException { 83 AudioClip clip = (AudioClip) file.toURL().getContent(); 84 long threadID = 0; 85 // Will run the test no more than 15 seconds 86 long endtime = System.nanoTime() + TimeUnit.SECONDS.toNanos(15); 87 while (endtime - System.nanoTime() > 0) { 88 clip.loop(); 89 sleep(500); 90 91 long data = count(); 92 if (data != threadID) { 93 System.out.println("Playing on new thread: " + data + " at " 94 + new java.util.Date()); 95 if (threadID == 0) { 96 threadID = data; 97 } else { 98 throw new RuntimeException("Thread was changed"); 99 } 100 } 101 102 clip.stop(); 103 sleep(500); 104 } 105 } 106 107 private static void sleep(int millis) { 108 try { 109 Thread.sleep(millis); 110 } catch (InterruptedException ignored) { 111 } 112 } 113 114 private static long count() { 115 for (final Thread t : Thread.getAllStackTraces().keySet()) { 116 if (t.getName().equals("Direct Clip")) { 117 return t.getId(); 118 } 119 } 120 return 0; 121 } 122 123 private static AudioInputStream getStream(final AudioFormat format) { 124 final int dataSize = 5000 * format.getFrameSize(); 125 final InputStream in = new ByteArrayInputStream(new byte[dataSize]); 126 return new AudioInputStream(in, format, NOT_SPECIFIED); 127 } 128 }