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.sampled.AudioFormat;
  25 import javax.sound.sampled.AudioSystem;
  26 import javax.sound.sampled.Line;
  27 import javax.sound.sampled.LineUnavailableException;
  28 import javax.sound.sampled.Mixer;
  29 import javax.sound.sampled.SourceDataLine;
  30 
  31 /**
  32  * @test
  33  * @bug 4681384
  34  * @summary SourceDataLine.write() causes Unexpected Signal 11 in native code
  35  *          outside the VM
  36  */
  37 public class SourceDataLineDefaultBufferSizeCrash {
  38 
  39     static final int STATUS_PASSED = 0;
  40     static final int STATUS_FAILED = 2;
  41     static final int STATUS_TEMP = 95;
  42 
  43     public static void main(String argv[]) throws Exception {
  44         int testExitStatus = run(argv, System.out) + STATUS_TEMP;
  45     }
  46 
  47     public static int run(String argv[], java.io.PrintStream out) throws Exception {
  48         int testResult = STATUS_PASSED;
  49 
  50         int framesNumberToExceed = 2;
  51         if ( argv.length > 0 ) {
  52             try {
  53                 framesNumberToExceed = Integer.parseInt(argv[0]);
  54             }
  55             catch (NumberFormatException e) {
  56             }
  57         }
  58 
  59         out.println
  60             ("\n==> Test for SourceDataLine.write() method:");
  61 
  62         Mixer.Info[] installedMixersInfo = AudioSystem.getMixerInfo();
  63 
  64         if ( installedMixersInfo == null ) {
  65             out.println("## AudioSystem.getMixerInfo() returned unexpected result:");
  66             out.println("#  expected: an array of Mixer.Info objects (may be array of length 0);");
  67             out.println("#  produced: null;");
  68             return STATUS_FAILED;
  69         }
  70 
  71         if ( installedMixersInfo.length == 0 ) {
  72             // there are no mixers installed on the system -
  73             // so this testcase can not be tested
  74             out.println("\n>>>  There are no mixers installed on the system!");
  75             return STATUS_PASSED;
  76         }
  77 
  78         out.println("\n>>>  Number of mixers installed on the system = "
  79             + installedMixersInfo.length);
  80         Mixer installedMixer = null;
  81         for (int i=0; i < installedMixersInfo.length; i++) {
  82             try {
  83                 installedMixer = AudioSystem.getMixer(installedMixersInfo[i]);
  84             } catch (SecurityException securityException) {
  85                 // installed Mixer is unavailable because of security restrictions
  86                 out.println("\n>>>  installedMixer[" + i
  87                     + "] is unavailable because of security restrictions");
  88                 continue;
  89             } catch (Throwable thrown) {
  90                 out.println("\n##  installedMixer[" + i + "] is unavailable because of");
  91                 out.println("#  AudioSystem.getMixer() threw unexpected exception:");
  92                 thrown.printStackTrace(out);
  93                 testResult = STATUS_FAILED;
  94                 continue;
  95             }
  96 
  97             out.println("\n>>>  installedMixer["+i+"] = " + installedMixer);
  98             try {
  99                 installedMixer.open();
 100             } catch (LineUnavailableException lineUnavailableException) {
 101                 // installedMixer is not available due to resource restrictions
 102                 out.println(">>   installedMixer[" + i
 103                     + "] is not opened because of resource restrictions");
 104                 continue;
 105             } catch (SecurityException securityException) {
 106                 // installedMixer is not available due to security restrictions
 107                 out.println(">>   installedMixer[" + i
 108                     + "] is not opened because of security restrictions");
 109                 continue;
 110             } catch (Throwable thrown) {
 111                 out.println("## installedMixer.open() throws unexpected exception:");
 112                 thrown.printStackTrace(out);
 113                 testResult = STATUS_FAILED;
 114                 continue;
 115             }
 116             Line.Info supportedSourceLineInfo[] = null;
 117             try {
 118                 supportedSourceLineInfo = installedMixer.getSourceLineInfo();
 119             } catch (Throwable thrown) {
 120                 out.println("## installedMixer.getSourceLineInfo() throws "
 121                     + "unexpected exception:");
 122                 thrown.printStackTrace(out);
 123                 testResult = STATUS_FAILED;
 124                 installedMixer.close();
 125                 continue;
 126             }
 127             if ( supportedSourceLineInfo == null ) {
 128                 out.println("## installedMixer.getSourceLineInfo() returned null array");
 129                 out.println("#  Mixer = " + installedMixer);
 130                 testResult = STATUS_FAILED;
 131                 installedMixer.close();
 132                 continue;
 133             }
 134             out.println("\n>>  Number of SourceLineInfo supported by installedMixer ="
 135                 + supportedSourceLineInfo.length);
 136 
 137             for (int j=0; j < supportedSourceLineInfo.length; j++) {
 138                 Line.Info testSourceLineInfo = supportedSourceLineInfo[j];
 139 
 140                 out.println("\n>  testSourceLineInfo["+j+"] = " + testSourceLineInfo);
 141                 Line testSourceLine = null;
 142                 try {
 143                     testSourceLine = installedMixer.getLine(testSourceLineInfo);
 144                 } catch (LineUnavailableException lineUnavailableException) {
 145                     // line is not available due to resource restrictions
 146                     out.println(">  Line for this SourceLine Info is not available "
 147                         + "due to resource restrictions");
 148                     continue;
 149                 } catch (SecurityException securityException) {
 150                     // line is not available due to security restrictions
 151                     out.println(">  Line for this SourceLine Info is not available "
 152                         + "due to security restrictions");
 153                     continue;
 154                 } catch (Throwable thrown) {
 155                     out.println("## installedMixer.getLine(testSourceLineInfo) throws"
 156                         + "unexpected Exception:");
 157                     thrown.printStackTrace(out);
 158                     testResult = STATUS_FAILED;
 159                     continue;
 160                 }
 161 
 162                 out.println(">  testedSourceLine = " + testSourceLine);
 163                 if ( ! (testSourceLine instanceof SourceDataLine) ) {
 164                     out.println(">  testSourceLine is not SourceDataLine");
 165                     continue;
 166                 }
 167 
 168                 SourceDataLine testedSourceLine = (SourceDataLine)testSourceLine;
 169                 AudioFormat lineAudioFormat = testedSourceLine.getFormat();
 170 
 171                 out.println("\n>  opening tested SourceLine:");
 172                 try {
 173                     //testedSourceLine.open(lineAudioFormat, 2048);
 174                     testedSourceLine.open(lineAudioFormat);
 175                     out.println(">  OK - line is opened with "+testedSourceLine.getBufferSize()+" bytes buffer");
 176                 } catch (LineUnavailableException lineUnavailableException) {
 177                     out.println(">  Line is not available due to resource restrictions:");
 178                     lineUnavailableException.printStackTrace(out);
 179                     continue;
 180                 } catch (SecurityException securityException) {
 181                     out.println("> Line is not available due to security restrictions:");
 182                     securityException.printStackTrace(out);
 183                     continue;
 184                 } catch (Throwable thrown) {
 185                     out.println("## SourceDataLine.open(AudioFormat format) failed:");
 186                     out.println("#  Unexpected Exception is thrown");
 187                     out.println("#  Mixer = " + installedMixer);
 188                     out.println("#  SourceDataLine = " + testedSourceLine);
 189                     thrown.printStackTrace(out);
 190                     testResult = STATUS_FAILED;
 191                     continue;
 192                 }
 193 
 194                 testedSourceLine.start();
 195 
 196                 int frameSize = 1;
 197                 if ( lineAudioFormat.getFrameSize() != AudioSystem.NOT_SPECIFIED ) {
 198                     frameSize = lineAudioFormat.getFrameSize();
 199                 } else {
 200                     if ( lineAudioFormat.getSampleSizeInBits() != AudioSystem.NOT_SPECIFIED ) {
 201                         frameSize = lineAudioFormat.getSampleSizeInBits()/8;
 202                         if ( lineAudioFormat.getSampleSizeInBits()%8 != 0 ) {
 203                             frameSize++;
 204                         }
 205                     }
 206                 }
 207                 int bufferSizeToWrite = testedSourceLine.available()
 208                     + (frameSize * framesNumberToExceed);
 209                 byte[] dataToWrite = new byte[bufferSizeToWrite];
 210                 for (int k=0; k < bufferSizeToWrite; k++) {
 211                     dataToWrite[k] = (byte)1;
 212                 }
 213                 int offsetToWrite = 0;
 214 
 215                 out.println("\n>  check SourceDataLine.write() to write more data "
 216                     + "than can currently be written:");
 217 
 218                 out.println(">  testedSourceLine.available() = " + testedSourceLine.available());
 219                 out.println(">  frame size = " + frameSize);
 220                 out.println(">  number of bytes to write = " + bufferSizeToWrite);
 221                 int writtenBytes = -1;
 222                 try {
 223                     writtenBytes =
 224                         testedSourceLine.write(dataToWrite, offsetToWrite, bufferSizeToWrite);
 225                     out.println(">  OK - number of written bytes = " + writtenBytes);
 226                 } catch (Throwable thrown) {
 227                     out.println("## SourceDataLine.write(byte[] b, int off, int len) failed:");
 228                     out.println("#  Unexpected Exception is thrown");
 229                     thrown.printStackTrace(out);
 230                     testResult = STATUS_FAILED;
 231                 }
 232 
 233                 testedSourceLine.close();
 234 
 235             }  // for (int j=0; j < supportedSourceLineInfo.length; j++)
 236             installedMixer.close();
 237 
 238         }  // for (int i=0; i < installedMixersInfo.length; i++)
 239 
 240         if ( testResult == STATUS_FAILED ) {
 241             throw new Exception("Test FAILED!");
 242         } else {
 243             out.println("\n==> test PASSED!");
 244         }
 245         return testResult;
 246     }
 247 
 248 }