1 /*
2  * Copyright (c) 2003, 2016, 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 javax.sound.midi.MidiDevice;
25 import javax.sound.midi.MidiSystem;
26 import javax.sound.midi.Sequencer;
27 import javax.sound.midi.Synthesizer;
28 
29 /**
30  * @test
31  * @bug 4914667
32  * @summary Closing and reopening MIDI IN device on Linux throws
33  *          MidiUnavailableException
34  */
35 public class Reopen {
36 
37     private static boolean isTestExecuted;
38     private static boolean isTestPassed;
39 
40     /*
41      * run manually:
42      * java Reopen 100 in      for 100 iterations on the MIDI IN device
43      * java Reopen 16 out      for 16 iterations on the MIDI OUT device
44      */
main(String[] args)45     public static void main(String[] args) throws Exception {
46         if (args.length == 0) {
47             doAllTests();
48         } else if (args.length == 2) {
49             int numIterations = Integer.parseInt(args[0]);
50             if (args[1].equals("in")) {
51                 doTest(numIterations, true);
52             } else {
53                 doTest(numIterations, false);
54             }
55         } else {
56             out("usage: java Reopen <iterations> in|out");
57         }
58     }
59 
doAllTests()60     private static void doAllTests() throws Exception {
61         out("#4914667: Closing and reopening MIDI IN device on Linux throws MidiUnavailableException");
62         boolean success = true;
63         try {
64             success &= doTest(20, true); // MIDI IN
65             success &= doTest(20, false); // MIDI OUT
66             isTestExecuted = true;
67         } catch (Exception e) {
68             out(e);
69             isTestExecuted = false;
70         }
71         isTestPassed = success;
72         if (isTestExecuted) {
73             if (isTestPassed) {
74                 out("Test PASSED.");
75             } else {
76                 throw new Exception("Test FAILED.");
77             }
78         } else {
79             out("Test NOT FAILED");
80         }
81     }
82 
doTest(int numIterations, boolean input)83     private static boolean doTest(int numIterations, boolean input) throws Exception {
84         MidiDevice.Info[] infos = MidiSystem.getMidiDeviceInfo();
85         MidiDevice outDevice = null;
86         MidiDevice inDevice = null;
87         for (int i = 0; i < infos.length; i++) {
88             MidiDevice device = MidiSystem.getMidiDevice(infos[i]);
89             if (! (device instanceof Sequencer) &&
90                 ! (device instanceof Synthesizer)) {
91                 if (device.getMaxReceivers() != 0) {
92                     outDevice = device;
93                 }
94                 if (device.getMaxTransmitters() != 0) {
95                     inDevice = device;
96                 }
97             }
98         }
99         MidiDevice testDevice = null;
100         if (input) {
101             testDevice = inDevice;
102         } else {
103             testDevice = outDevice;
104         }
105         if (testDevice == null) {
106             out("Cannot test: device not available.");
107             return true;
108         }
109         out("Using Device: " + testDevice);
110 
111         for (int i = 0; i < numIterations; i++) {
112             out("@@@ ITERATION: " + i);
113             testDevice.open();
114             // This sleep ensures that the thread of MidiInDevice is started.
115             sleep(50);
116             testDevice.close();
117         }
118         return true;
119     }
120 
sleep(int milliseconds)121     private static void sleep(int milliseconds) {
122         try {
123             Thread.sleep(milliseconds);
124         } catch (InterruptedException e) {
125         }
126     }
127 
out(Throwable t)128     private static void out(Throwable t) {
129         t.printStackTrace(System.out);
130     }
131 
out(String message)132     private static void out(String message) {
133         System.out.println(message);
134     }
135 }
136