Index: modules/sound/src/test/java/org/apache/harmony/sound/tests/javax/sound/sampled/AudioSystemTest.java =================================================================== --- modules/sound/src/test/java/org/apache/harmony/sound/tests/javax/sound/sampled/AudioSystemTest.java (revision 0) +++ modules/sound/src/test/java/org/apache/harmony/sound/tests/javax/sound/sampled/AudioSystemTest.java (revision 0) @@ -0,0 +1,631 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.harmony.sound.tests.javax.sound.sampled; + +import java.io.File; +import java.net.URL; + +import javax.sound.sampled.AudioFileFormat; +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import javax.sound.sampled.Line; +import javax.sound.sampled.Mixer; + +import junit.framework.TestCase; + +/** + * + * Dummy sound provider located in soundProvider.jar is used for testing. + * Provider sources are provided at the comments at the end of this file. + * + */ +public class AudioSystemTest extends TestCase { + + public void testAudioFile() throws Exception { + boolean ok; + + assertTrue(AudioSystem.getAudioFileFormat(new URL("file:./myFile.txt")) != null); + + AudioFileFormat.Type[] types = AudioSystem.getAudioFileTypes(); + + ok = false; + for (int i = 0; i < types .length; i++) { + if (types[i].getExtension().equals("txt")) { + ok = true; + break; + } + } + assertTrue(ok); + } + + public void testMixer() throws Exception { + boolean ok; + + Mixer.Info[] minfos = AudioSystem.getMixerInfo(); + assertTrue(minfos.length > 0); + assertEquals(minfos[0].getName(), "NAME"); + assertEquals(minfos[0].getVersion(), "VERSION"); + + assertTrue(AudioSystem.getMixer(null) != null); + + Mixer mix = AudioSystem.getMixer(minfos[0]); + assertEquals(mix.getClass().getName(), + "org.apache.harmony.sound.testProvider.MyMixer"); + Line.Info[] mli= mix.getSourceLineInfo(); + assertEquals(mli.length, 4); + + Line.Info[] infos = AudioSystem.getSourceLineInfo( mli[0]); + ok = false; + for (int i = 0; i < infos.length; i++) { + if (infos[i].getLineClass().getName().equals( + "org.apache.harmony.sound.testProvider.myClip")) { + ok = true; + break; + } + } + assertTrue(ok); + + infos = AudioSystem.getTargetLineInfo(mli[0]); + ok = false; + for (int i = 0; i < infos.length; i++) { + if (infos[i].getLineClass().getName().equals( + "org.apache.harmony.sound.testProvider.myClip")) { + ok = true; + break; + } + } + assertTrue(ok); + } + + public void testAudioInputStream() throws Exception { + + AudioInputStream stream = AudioSystem.getAudioInputStream(new File("myFile.txt")); + assertTrue(stream != null); + + // no exception expected + AudioSystem.write(stream, new AudioFileFormat.Type("TXT", "txt"), System.out); + + assertEquals(AudioSystem.getAudioInputStream( + AudioFormat.Encoding.PCM_UNSIGNED, stream), stream); + } + + + // see TestFormatConversionProvider + public void testFormatConversion() throws Exception { + + boolean ok; + + AudioFormat af_source = new AudioFormat( + AudioFormat.Encoding.PCM_UNSIGNED, 1f, 2, 3, 4, 5f, true); + + AudioFormat.Encoding[] aafe = AudioSystem.getTargetEncodings( + AudioFormat.Encoding.PCM_UNSIGNED); + ok = false; + for (int i = 0; i < aafe .length; i++) { + // contains PCM_SIGNED (see TestFormatConversionProvider) + if (aafe[i].equals(AudioFormat.Encoding.PCM_SIGNED)) { + ok = true; + break; + } + } + assertTrue(ok); + + assertTrue(AudioSystem.isConversionSupported( + AudioFormat.Encoding.PCM_SIGNED, af_source)); + + AudioFormat[] aaf = AudioSystem.getTargetFormats( + AudioFormat.Encoding.PCM_UNSIGNED, af_source ); + + ok = false; + for (int i = 0; i < aaf.length; i++) { + if (aaf[i].getSampleRate() == 10f && + aaf[i].getSampleSizeInBits() == 2&& + aaf[i].getChannels() == 30 && + aaf[i].getFrameSize() == 40 && + aaf[i].getFrameRate() == 50f ) { + ok = true; + break; + } + } + assertTrue(ok); + } + + public void testGetLine() throws Exception { + + assertEquals( + AudioSystem.getLine(new Line.Info(javax.sound.sampled.Clip.class)).getClass().getName(), + "org.apache.harmony.sound.testProvider.myClip"); + assertEquals( + AudioSystem.getLine(new Line.Info(javax.sound.sampled.SourceDataLine.class)).getClass().getName(), + "org.apache.harmony.sound.testProvider.mySourceDataLine"); + assertEquals( + AudioSystem.getLine(new Line.Info(javax.sound.sampled.TargetDataLine.class)).getClass().getName(), + "org.apache.harmony.sound.testProvider.myTargetDataLine"); + assertEquals( + AudioSystem.getLine(new Line.Info(javax.sound.sampled.Port.class)).getClass().getName(), + "org.apache.harmony.sound.testProvider.myPort"); + + assertEquals(AudioSystem.getClip().getClass().getName(), + "org.apache.harmony.sound.testProvider.myClip"); + + } +} + + +// SOUND PROVIDER SOURCES: +// +// META-INF/services/ files: +// file META-INF/services/javax.sound.sampled.spi: +//org.apache.harmony.sound.testProvider.TestAudioFileWriter +// +// file META-INF/services/javax.sound.sampled.spi: +//org.apache.harmony.sound.testProvider.TestFormatConversionProvider +// +// file META-INF/services/javax.sound.sampled.spi: +//org.apache.harmony.sound.testProvider.TestMixerProvider +// +// file META-INF/services/javax.sound.sampled.spi.AudioFileReader: +//org.apache.harmony.sound.testProvider.TestAudioFileReader +// +//Source files: +// +//TestAudioFileReader.java +// +//package org.apache.harmony.sound.testProvider; +// +//import javax.sound.sampled.*; +//import javax.sound.sampled.spi.*; +//import java.util.*; +//import java.io.*; +//import java.net.*; +// +//public class TestAudioFileReader extends AudioFileReader { +// static AudioFileFormat aff; +// static AudioFormat af; +// +// static { +// AudioFormat.Encoding enc = AudioFormat.Encoding.PCM_UNSIGNED; +// AudioFileFormat.Type type = new AudioFileFormat.Type("TXT", "txt"); +// af = new AudioFormat(enc , 1f, 2, 3, 4, 5f, true); +// aff = new AudioFileFormat(type , af, 10); +// } +// +// public TestAudioFileReader() { +// super(); +// }; +// +// public AudioFileFormat getAudioFileFormat(InputStream stream) throws UnsupportedAudioFileException, IOException { +// return aff; +// } +// +// public AudioFileFormat getAudioFileFormat(URL url) throws UnsupportedAudioFileException, IOException { +// return aff; +// } +// public AudioFileFormat getAudioFileFormat(File file) throws UnsupportedAudioFileException, IOException { +// return aff; +// } +// public AudioInputStream getAudioInputStream(InputStream stream) throws UnsupportedAudioFileException, IOException { +// InputStream is = new ByteArrayInputStream(new byte[1001]); +// return new AudioInputStream(is, af, 10); +// } +// public AudioInputStream getAudioInputStream(URL url) throws UnsupportedAudioFileException, IOException { +// InputStream is = new ByteArrayInputStream(new byte[1001]); +// return new AudioInputStream(is, af, 10); +// } +// public AudioInputStream getAudioInputStream(File file) +// throws UnsupportedAudioFileException,IOException { +// InputStream is = new ByteArrayInputStream(new byte[1001]); +// return new AudioInputStream(is, af, 10); +// } +//} +// +//TestAudioFileWriter.java +// +//package org.apache.harmony.sound.testProvider; +// +//import javax.sound.sampled.*; +//import javax.sound.sampled.spi.*; +//import java.util.*; +//import java.io.*; +//import java.net.*; +// +//public class TestAudioFileWriter extends AudioFileWriter { +// +// static AudioFileFormat aff; +// static AudioFormat af; +// static AudioFileFormat.Type type; +// +// static { +// AudioFormat.Encoding enc = AudioFormat.Encoding.PCM_UNSIGNED; +// type = new AudioFileFormat.Type("TXT", "txt"); +// vaf = new AudioFormat(enc , 1f, 2, 3, 4, 5f, true); +// aff = new AudioFileFormat(type , af, 10); +// } +// +// public TestAudioFileWriter () { +// super(); +// }; +// +// public AudioFileFormat.Type[] getAudioFileTypes() { +// return new AudioFileFormat.Type[] {type}; +// } +// public AudioFileFormat.Type[] getAudioFileTypes(AudioInputStream stream) { +// return new AudioFileFormat.Type[] {type}; +// } +// public boolean isFileTypeSupported(AudioFileFormat.Type fileType) { +// return type.equals(fileType); +// } +// public boolean isFileTypeSupported(AudioFileFormat.Type fileType, AudioInputStream stream) { +// return type.equals(fileType); +// } +// public int write(AudioInputStream stream, AudioFileFormat.Type fileType, OutputStream out) throws IOException { +// return 10; +// } +// public int write(AudioInputStream stream, AudioFileFormat.Type fileType, File out) throws IOException { +// return 10; +// } +//} +// +//TestFormatConversionProvider.java +// +//package org.apache.harmony.sound.testProvider; +// +//import javax.sound.sampled.*; +//import javax.sound.sampled.spi.*; +//import java.util.*; +//import java.io.*; +//import java.net.*; +// +//public class TestFormatConversionProvider extends FormatConversionProvider{ +// +// static AudioFormat.Encoding[] enc_source; +// static AudioFormat.Encoding[] enc_target; +// static AudioFormat af_source; +// static AudioFormat af_target; +// +// static { +// enc_source = new AudioFormat.Encoding[] {AudioFormat.Encoding.PCM_UNSIGNED}; +// af_source = new AudioFormat(enc_source [0] , 1f, 2, 3, 4, 5f, true); +// enc_target= new AudioFormat.Encoding[] {AudioFormat.Encoding.PCM_SIGNED}; +// af_target= new AudioFormat(enc_target[0] , 10f, 2, 30, 40, 50f, false); +// } +// public TestFormatConversionProvider() { +// super(); +// }; +// public AudioInputStream getAudioInputStream( +// AudioFormat.Encoding targetEncoding, AudioInputStream sourceStream) { +// if (!enc_target[0].equals(targetEncoding) || +// !af_source.equals(sourceStream.getFormat())) { +// throw new IllegalArgumentException("conversion not supported"); +// } +// return sourceStream; +// } +// public AudioInputStream getAudioInputStream( +// AudioFormat targetFormat, AudioInputStream sourceStream) { +// if (!af_target.equals(targetFormat) || +// !af_source.equals(sourceStream.getFormat())) { +// throw new IllegalArgumentException("conversion not supported"); +// } +// return sourceStream; +// } +// public AudioFormat.Encoding[] getTargetEncodings( +// AudioFormat sourceFormat) { +// if (af_source.matches(sourceFormat)) { +// return enc_target; +// } else { +// return new AudioFormat.Encoding[0]; +// } +// } +// public AudioFormat[] getTargetFormats( +// AudioFormat.Encoding targetFormat, AudioFormat sourceFormat) { +// if (af_source.matches(sourceFormat)) { +// return new AudioFormat[] {af_target}; +// } else { +// return new AudioFormat[0]; +// } +// } +// public AudioFormat.Encoding[] getSourceEncodings() { +// return enc_source; +// } +// public AudioFormat.Encoding[] getTargetEncodings() { +// return enc_target; +// } +//} +// +//TestMixerProvider.java +// +//package org.apache.harmony.sound.testProvider; +// +//import javax.sound.sampled.*; +//import javax.sound.sampled.spi.*; +//import java.util.*; +//import java.io.*; +//import java.net.*; +// +//public class TestMixerProvider extends MixerProvider { +// static Mixer.Info info; +// static Mixer mixer; +// static { +// info = new MyMixerInfo("NAME", "VENDOR", "DESCRIPTION", "VERSION"); +// mixer = new MyMixer(info); +// } +// public TestMixerProvider () {super();} +// public boolean isMixerSupported(Mixer.Info info) { +// return this.info.equals(info); +// } +// public Mixer.Info[] getMixerInfo() { +// return new Mixer.Info[] {info}; +// } +// public Mixer getMixer(Mixer.Info info) { +// if (this.info.equals(info)) { +// return mixer; +// } +// throw new IllegalArgumentException("TestMixerProvider "); +// } +//} +// +//class MyMixerInfo extends Mixer.Info { +// public MyMixerInfo(String name, String vendor, String description, +// String version) { +// super(name, vendor, description, version); +// } +//} +// +//class MyMixer implements Mixer { +// private Mixer.Info minfo; +// private Line[] sourceLines = new Line[] {new myClip(), +// new mySourceDataLine(), +// new myTargetDataLine(), +// new myPort()}; +// private Line[] targetLines = new Line[] {new myClip(), +// new mySourceDataLine(), +// new myTargetDataLine(), +// new myPort()}; +// private Line.Info[] lineInfos = new Line.Info[] { +// new Line.Info(javax.sound.sampled.Clip.class), +// new Line.Info(javax.sound.sampled.SourceDataLine.class), +// new Line.Info(javax.sound.sampled.TargetDataLine.class), +// new Line.Info(javax.sound.sampled.Port.class) +// }; +// public MyMixer(Mixer.Info info) { +// minfo = info; +// } +// public Line getLine(Line.Info info) throws LineUnavailableException { +// for (int i = 0; i < lineInfos.length; i++) { +// if (lineInfos[i].matches(info)) { +// return sourceLines[i]; +// } +// } +// throw new IllegalArgumentException("not supported " + info); +// } +// public int getMaxLines(Line.Info info) { +// return AudioSystem.NOT_SPECIFIED; +// } +// public Mixer.Info getMixerInfo() { +// return minfo; +// } +// public Line.Info[] getSourceLineInfo() { +// return lineInfos; +// } +// public Line.Info[] getSourceLineInfo(Line.Info info) { +// for (int i = 0; i < lineInfos.length; i++) { +// if (lineInfos[i].matches(info)) { +// return new Line.Info[] {sourceLines[i].getLineInfo()}; +// } +// } +// throw new IllegalArgumentException("not supported " + info); +// } +// public Line[] getSourceLines() { +// return sourceLines; +// } +// public Line.Info[] getTargetLineInfo() { +// return lineInfos; +// } +// public Line.Info[] getTargetLineInfo(Line.Info info) { +// for (int i = 0; i < lineInfos.length; i++) { +// if (lineInfos[i].matches(info)) { +// return new Line.Info[] {targetLines[i].getLineInfo()}; +// } +// } +// throw new IllegalArgumentException("not supported " + info); +// } +// public Line[] getTargetLines() { +// return targetLines; +// } +// public boolean isLineSupported(Line.Info info) { +// for (int i = 0; i < lineInfos.length; i++) { +// if (lineInfos[i].matches(info)) { +// return true; +// } +// } +// return false; +// } +// public boolean isSynchronizationSupported(Line[] lines, boolean maintainSync) { +// return false; +// } +// public void synchronize(Line[] lines, boolean maintainSync) {} +// +// public void unsynchronize(Line[] lines) {} +// +// // methods of Line interface +// public void close() {} +// public Control getControl(Control.Type control) { +// throw new IllegalArgumentException("not supported "+ control); +// } +// public Control[] getControls() { +// return new Control[0]; +// } +// public Line.Info getLineInfo() { +// return new Line.Info(this.getClass()); +// } +// public boolean isControlSupported(Control.Type control) { +// return false; +// } +// public boolean isOpen() { +// return false; +// } +// public void open() throws LineUnavailableException {} +// public void removeLineListener(LineListener listener) {} +// public void addLineListener(LineListener listener) {} +//} +// +//class myClip implements Clip { +// public int getFrameLength() { return 10;} +// public long getMicrosecondLength() {return 100;} +// public void loop(int count) {} +// public void open(AudioFormat format, byte[] data, int offset, int bufferSize) +// throws LineUnavailableException {} +// public void open(AudioInputStream stream) throws LineUnavailableException, +// IOException {} +// public void setFramePosition(int frames) {} +// public void setLoopPoints(int start, int end) {} +// public void setMicrosecondPosition(long microseconds) {} +// public int available() {return 1;} +// public void drain() {} +// public void flush() {} +// public int getBufferSize() {return 1;} +// public AudioFormat getFormat() {return null;} +// public int getFramePosition() {return 1;} +// public float getLevel() {return 1f;} +// public long getLongFramePosition() {return 1;} +// public long getMicrosecondPosition() {return 10;} +// public boolean isActive() {return false;} +// public boolean isRunning(){return false;} +// public void start() {} +// public void stop(){} +// public void close() {} +// public Control getControl(Control.Type control) { +// throw new IllegalArgumentException("not supported "+ control); +// } +// public Control[] getControls() { +// return new Control[0]; +// } +// public Line.Info getLineInfo() { +// return new Line.Info(this.getClass()); +// } +// public boolean isControlSupported(Control.Type control) { +// return false; +// } +// public boolean isOpen() { +// return false; +// } +// public void open() throws LineUnavailableException {} +// public void removeLineListener(LineListener listener) {} +// public void addLineListener(LineListener listener) {} +//} +// +//class mySourceDataLine implements SourceDataLine{ +// public void open(AudioFormat format) throws LineUnavailableException {} +// public void open(AudioFormat format, int bufferSize) +// throws LineUnavailableException {} +// public int write(byte[] b, int off, int len) {return 1;} +// public int available() {return 1;} +// public void drain() {} +// public void flush() {} +// public int getBufferSize() {return 1;} +// public AudioFormat getFormat() {return null;} +// public int getFramePosition() {return 1;} +// public float getLevel() {return 1f;} +// public long getLongFramePosition() {return 1;} +// public long getMicrosecondPosition() {return 10;} +// public boolean isActive() {return false;} +// public boolean isRunning(){return false;} +// public void start() {} +// public void stop(){} +// public void close() {} +// public Control getControl(Control.Type control) { +// throw new IllegalArgumentException("not supported "+ control); +// } +// public Control[] getControls() { +// return new Control[0]; +// } +// public Line.Info getLineInfo() { +// return new Line.Info(this.getClass()); +// } +// public boolean isControlSupported(Control.Type control) { +// return false; +// } +// public boolean isOpen() { +// return false; +// } +// public void open() throws LineUnavailableException {} +// public void removeLineListener(LineListener listener) {} +// public void addLineListener(LineListener listener) {} +//} +// +//class myTargetDataLine implements TargetDataLine { +// public void open(AudioFormat format) throws LineUnavailableException{} +// public void open(AudioFormat format, int bufferSize) +// throws LineUnavailableException{} +// public int read(byte[] b, int off, int len) {return 1;} +// public int available() {return 1;} +// public void drain() {} +// public void flush() {} +// public int getBufferSize() {return 1;} +// public AudioFormat getFormat() {return null;} +// public int getFramePosition() {return 1;} +// public float getLevel() {return 1f;} +// public long getLongFramePosition() {return 1;} +// public long getMicrosecondPosition() {return 10;} +// public boolean isActive() {return false;} +// public boolean isRunning(){return false;} +// public void start() {} +// public void stop(){} +// public void close() {} +// public Control getControl(Control.Type control) { +// throw new IllegalArgumentException("not supported "+ control); +// } +// public Control[] getControls() { +// return new Control[0]; +// } +// public Line.Info getLineInfo() { +// return new Line.Info(this.getClass()); +// } +// public boolean isControlSupported(Control.Type control) { +// return false; +// } +// public boolean isOpen() { +// return false; +// } +// public void open() throws LineUnavailableException {} +// public void removeLineListener(LineListener listener) {} +// public void addLineListener(LineListener listener) {} +//} +// +//class myPort implements Port { +// public void close() {} +// public Control getControl(Control.Type control) { +// throw new IllegalArgumentException("not supported "+ control); +// } +// public Control[] getControls() { +// return new Control[0]; +// } +// public Line.Info getLineInfo() { +// return new Line.Info(this.getClass()); +// } +// public boolean isControlSupported(Control.Type control) { +// return false; +// } +// public boolean isOpen() { +// return false; +// } +// public void open() throws LineUnavailableException {} +// public void removeLineListener(LineListener listener) {} +// public void addLineListener(LineListener listener) {} +//} Index: modules/sound/src/main/java/org/apache/harmony/sound/utils/ProviderService.java =================================================================== --- modules/sound/src/main/java/org/apache/harmony/sound/utils/ProviderService.java (revision 504056) +++ modules/sound/src/main/java/org/apache/harmony/sound/utils/ProviderService.java (working copy) @@ -19,48 +19,64 @@ import java.io.File; import java.io.FileInputStream; +import java.io.InputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; import java.util.Properties; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -public class ProviderService { + +public class ProviderService { + + // Properties from sound.propertie file + private static Properties devices; + + static { + devices = new Properties(); + + FileInputStream fstream = + AccessController.doPrivileged(new PrivilegedAction(){ + + public FileInputStream run() { + //obtain the path to the file sound.properties + String soundPropertiesPath = System.getProperty("java.home") //$NON-NLS-1$ + + File.separator + "lib" + File.separator //$NON-NLS-1$ + + "sound.properties"; //$NON-NLS-1$ + try { + return new FileInputStream(soundPropertiesPath); + } catch (FileNotFoundException e) { + return null; + } + } + }); + + if (fstream != null) { + //reading file sound.properties + try { + devices.load(fstream); + } catch (IOException e) { + } + } + } + /** * this method return information about default device * @param deviceName * @return */ public static List getDefaultDeviceDescription(String deviceName) { - /* - * obtain the path to the file sound.properties - */ - String soundPropertiesPath = System.getProperty("java.home") + File.separator + "lib" + - File.separator + "sound.properties"; - Properties devices = new Properties(); - FileInputStream fstream; - /* - * variable that contain information about default device - */ + + // variable that contain information about default device List defaultDevice = new ArrayList(); String str; - int index; + int index; + /* - * reading file sound.properties - */ - try { - fstream = new FileInputStream(soundPropertiesPath); - devices.load(fstream); - } catch (FileNotFoundException e) { - throw new Error("Configuration file sound.properties doesn't exist!"); - } - catch (IOException e) { - throw new Error("An error while reading file sound.properties"); - } - /* * obtain the default device that describes by deviceName */ str = devices.getProperty(deviceName); @@ -74,7 +90,7 @@ * the separator between provider and name is '#'; * find separator of provider and name of device in the notation of default device */ - index = str.indexOf("#"); + index = str.indexOf("#"); //$NON-NLS-1$ /* * if separator doesn't find, so in the definition of default device contain only * name of provider, and so we add it @@ -104,107 +120,54 @@ * @return */ public static List getProviders(String providerName) { - //this variable contain providers - List providers = new ArrayList(); - List providerNames = getProviderNames(providerName); - Class cl; - /* - * obtain classes - */ - for (int i = 0; i < providerNames.size(); i++) { - try { - cl = Class.forName(providerNames.get(i)); - providers.add(cl.newInstance()); - } catch (ClassNotFoundException e) {} - catch (IllegalAccessException e) {} - catch (InstantiationException e) {} - } - return providers; - } - - /** - * this method return the list of provider names - * @param providerPath - * @return - */ - public static List getProviderNames(String providerPath) { - /* - * this variable contain providers that install in the system - */ - Properties providers = new Properties(); - /* - * this variable contain list of all jar-files that are contained in the java-home directory - */ - List jarFiles = new ArrayList(); - - File home = new File(System.getProperty("java.home")); - /* - * obtain all jar-files that contain in the java home directory; - * if we already find it, we don't find again - */ - find(home, jarFiles); - /* - * for the each obtained file we search providers in it - */ - for (int i = 0; i < jarFiles.size(); i++) { - try { - JarFile jFile = new JarFile(jarFiles.get(i)); - /* - * obtain contents of jar-file - */ - Enumeration files = jFile.entries(); + final String name = providerName; + + return AccessController.doPrivileged( + new PrivilegedAction>() { - /* - * the list of installed devices be found in the fixed place, and this place describes by - * parameter providerPath, so we search this place in each jar-file - */ - while (files.hasMoreElements()) { - JarEntry filePath = files.nextElement(); - if (filePath.toString().equals(providerPath)) { - /* - * if we found such place, we save providers in the variable 'providers' - * and exit from this iteration, because in each file it can be only one time - */ - providers.load(jFile.getInputStream(filePath)); - break; + public List run() { + List providers = new ArrayList(); + String className = null; + byte[] bytes; + + ClassLoader cl = ClassLoader.getSystemClassLoader(); + Enumeration urls = null; + try { + urls = cl.getResources(name); + } catch (IOException e) { + return providers; + } + for ( ; urls.hasMoreElements();) { + try { + InputStream in = urls.nextElement().openStream(); + bytes = new byte[in.available()]; + in.read(bytes); + in.close(); + } catch (IOException e) { + continue; } - } - } catch (IOException e) {} - } - - List listProviders = new ArrayList(); - Enumeration en = providers.propertyNames(); - while (en.hasMoreElements()) { - listProviders.add(en.nextElement().toString()); - } - return listProviders; - } - - /** - * This function search recursively in the Java home directory all jar-files - * @param parent - */ - static private void find(File parent, List jarFiles) { - /* - * Obtain the list of files that contains in the directory 'parent' - */ - String[] listFiles = parent.list(); - for (String element : listFiles) { - File file = new File(parent, element); - /* - * if new file is directory, than recursively go in it... - */ - if (file.isDirectory()) { - find(file, jarFiles); - } else { - /* - * else if it's file, we check up that it's jar-file. If it's true - * we save it - */ - if (element.endsWith(".jar")) { - jarFiles.add(parent.toString() + File.separator + element); + String[] astr = new String(bytes).split("\r\n"); //$NON-NLS-1$ + for (String str : astr) { + className = str.trim(); + if (!className.startsWith("#")) { // skip comments //$NON-NLS-1$ + try { + providers.add(Class.forName( + className.trim(), true, cl).newInstance()); + } catch (IllegalAccessException e) { + } catch (InstantiationException e) { + } catch (ClassNotFoundException e) { + } + } + } } + return providers; } - } + }); + } + + public static Properties getSoundProperties() { + return devices; + } + } Index: modules/sound/src/main/java/org/apache/harmony/sound/internal/nls/messages.properties =================================================================== --- modules/sound/src/main/java/org/apache/harmony/sound/internal/nls/messages.properties (revision 504056) +++ modules/sound/src/main/java/org/apache/harmony/sound/internal/nls/messages.properties (working copy) @@ -29,3 +29,11 @@ sound.0C=Frame size must be one byte sound.0D=The value is not supported sound.0F=value does not fall within the allowable range +sound.11=Could not get line +sound.12=Could not get audio input stream from source stream +sound.13=Could not get audio input stream from source stream +sound.14=File is not a supported file type +sound.15=Could not get audio input stream from input stream +sound.16=Could not get audio input stream from input URL +sound.17=Could not get audio input stream from input file +sound.18=Type is not supported Index: modules/sound/src/main/java/javax/sound/sampled/AudioSystem.java =================================================================== --- modules/sound/src/main/java/javax/sound/sampled/AudioSystem.java (revision 504056) +++ modules/sound/src/main/java/javax/sound/sampled/AudioSystem.java (working copy) @@ -17,6 +17,624 @@ package javax.sound.sampled; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.Iterator; +import java.util.Properties; + +import javax.sound.sampled.spi.AudioFileReader; +import javax.sound.sampled.spi.AudioFileWriter; +import javax.sound.sampled.spi.FormatConversionProvider; +import javax.sound.sampled.spi.MixerProvider; + +import org.apache.harmony.sound.utils.ProviderService; + +import org.apache.harmony.sound.internal.nls.Messages; + public class AudioSystem { public static final int NOT_SPECIFIED = -1; -} + + private final static String audioFileReaderPath = + "META-INF/services/javax.sound.sampled.spi.AudioFileReader"; //$NON-NLS-1$ + + private final static String audioFileWriterPath = + "META-INF/services/javax.sound.sampled.spi.AudioFileWriter"; //$NON-NLS-1$ + + private final static String formatConversionProviderPath = + "META-INF/services/javax.sound.sampled.spi.FormatConversionProvider"; //$NON-NLS-1$ + + private final static String mixerProviderPath = + "META-INF/services/javax.sound.sampled.spi.MixerProvider"; //$NON-NLS-1$ + + private final static String CLIP = "javax.sound.sampled.Clip"; //$NON-NLS-1$ + private final static String PORT = "javax.sound.sampled.Port"; //$NON-NLS-1$ + private final static String SOURCEDATALINE = "javax.sound.sampled.SourceDataLine"; //$NON-NLS-1$ + private final static String TARGETDATALINE = "javax.sound.sampled.TargetDataLine"; //$NON-NLS-1$ + + public static Mixer.Info[] getMixerInfo() { + List result = new ArrayList(); + for (Iterator providers = ProviderService.getProviders( + mixerProviderPath).iterator(); providers.hasNext();) { + try { + Mixer.Info[] infos = + ((MixerProvider) (providers.next())).getMixerInfo(); + for (Mixer.Info info : infos) { + result.add(info); + } + } catch (ClassCastException e) { + } + } + Mixer.Info[] temp = new Mixer.Info[result.size()]; + return result.toArray(temp); + } + + public static Mixer getMixer(Mixer.Info info) { + Mixer.Info[] infos; + Mixer.Info inf; + if (info == null) { + infos = getMixerInfo(); + if (infos == null) { + throw new IllegalArgumentException("No system default mixer installed"); //$NON-NLS-1$ + } + inf = infos[0]; + } else { + inf = info; + } + + for (Iterator providers = ProviderService.getProviders( + mixerProviderPath).iterator(); providers.hasNext();) { + try { + return ((MixerProvider) (providers.next())).getMixer(inf); + } catch (ClassCastException e) { + } catch (IllegalArgumentException e) { + } + } + throw new IllegalArgumentException("Mixer not supported: " + inf); //$NON-NLS-1$ + } + + public static Line.Info[] getSourceLineInfo(Line.Info info) { + List result = new ArrayList(); + for (Iterator providers = ProviderService.getProviders( + mixerProviderPath).iterator(); providers.hasNext();) { + try { + MixerProvider pr = (MixerProvider)providers.next(); + Mixer.Info[] mixinfos = pr.getMixerInfo(); + for (Mixer.Info mixinfo : mixinfos) { + Mixer mix = pr.getMixer(mixinfo); + Line.Info[] linfos = mix.getSourceLineInfo(info); + for (Line.Info linfo : linfos) { + result.add(linfo); + } + } + } catch (ClassCastException e) { + } + } + Line.Info[] temp = new Line.Info[result.size()]; + return result.toArray(temp); + } + + public static Line.Info[] getTargetLineInfo(Line.Info info) { + List result = new ArrayList(); + for (Iterator providers = ProviderService.getProviders( + mixerProviderPath).iterator(); providers.hasNext();) { + try { + MixerProvider pr = (MixerProvider)providers.next(); + Mixer.Info[] mixinfos = pr.getMixerInfo(); + for (Mixer.Info mixinfo : mixinfos) { + Mixer mix = pr.getMixer(mixinfo); + Line.Info[] linfos = mix.getTargetLineInfo(info); + for (Line.Info linfo : linfos) { + result.add(linfo); + } + } + } catch (ClassCastException e) { + } + } + Line.Info[] temp = new Line.Info[result.size()]; + return result.toArray(temp); + } + + public static boolean isLineSupported(Line.Info info) { + + for (Iterator providers = ProviderService.getProviders( + mixerProviderPath).iterator(); providers.hasNext();) { + try { + MixerProvider pr = (MixerProvider)providers.next(); + Mixer.Info[] mixinfos = pr.getMixerInfo(); + for (Mixer.Info mixinfo : mixinfos) { + Mixer mix = pr.getMixer(mixinfo); + if (mix.isLineSupported(info)) { + return true; + } + } + } catch (ClassCastException e) { + } + } + return false; + } + + private static Mixer getMixer(String propVal, Line.Info info, + List mixerProviders) { + + int index = propVal.indexOf("#"); //$NON-NLS-1$ + String className; + String mixName; + if (index == -1) { + className = propVal.trim(); + mixName = ""; //$NON-NLS-1$ + } else { + className = propVal.substring(0, index).trim(); + if (index == propVal.length()) { + mixName = ""; //$NON-NLS-1$ + } else { + mixName = propVal.substring(index + 1).trim(); + } + } + Mixer.Info[] minfos = null; + if (!className.equals("")) { //$NON-NLS-1$ + for (Iterator providers = mixerProviders.iterator(); + providers.hasNext();) { + try { + MixerProvider pr = (MixerProvider)(providers.next()); + if (className.equals(pr.getClass().getName())) { + minfos = pr.getMixerInfo(); + break; + } + } catch (ClassCastException e) { + } + } + } + if (minfos == null) { + minfos = getMixerInfo(); + } + + if (!mixName.equals("")) { //$NON-NLS-1$ + for (Mixer.Info minfo : minfos) { + if (mixName.equals(minfo.getName())) { + return getMixer(minfo); + } + } + } + if (minfos.length > 0) { + return getMixer(minfos[0]); + } + return null; + } + + + public static Line getLine(Line.Info info) throws LineUnavailableException { + String propName = null; + Class lineClass = info.getLineClass(); + + if (Clip.class.isAssignableFrom(lineClass)) { + propName = CLIP; + } else if (Port.class.isAssignableFrom(lineClass)) { + propName = PORT; + } else if (SourceDataLine.class.isAssignableFrom(lineClass)) { + propName = SOURCEDATALINE; + } else if (TargetDataLine.class.isAssignableFrom(lineClass)) { + propName = TARGETDATALINE; + } + return getLine(propName, info); + } + + private static Line getLine(String propName, Line.Info info) throws LineUnavailableException { + + List mixerProviders = ProviderService.getProviders(mixerProviderPath); + + if (propName != null) { + String propVal = System.getProperty(propName); + if (propVal != null) { + Mixer m = getMixer(propVal, info, mixerProviders); + if (m != null) { + Line l = m.getLine(info); + if (l != null) { + return l; + } + } + } + + Properties soundProperties = ProviderService.getSoundProperties(); + propVal = soundProperties.getProperty(propName); + if (propVal != null) { + Mixer m = getMixer(propVal, info, mixerProviders); + if (m != null) { + Line l = m.getLine(info); + if (l != null) { + return l; + } + } + } + } + + for (Iterator providers = ProviderService.getProviders( + mixerProviderPath).iterator(); providers.hasNext();) { + try { + MixerProvider pr = (MixerProvider)(providers.next()); + Mixer.Info[] mixinfos = pr.getMixerInfo(); + for (Mixer.Info mixinfo : mixinfos) { + try { + Mixer mix = pr.getMixer(mixinfo); + return mix.getLine(info); + } catch (IllegalArgumentException e) { + // continue + } + } + } catch (ClassCastException e) { + } + } + // sound.11=Could not get line + throw new IllegalArgumentException(Messages.getString("sound.11")); //$NON-NLS-1$ + } + + public static Clip getClip() throws LineUnavailableException { + return (Clip)getLine(new Line.Info(Clip.class)); + } + + public static Clip getClip(Mixer.Info mixerInfo) + throws LineUnavailableException { + return (Clip)(getMixer(mixerInfo).getLine( + new Line.Info(Clip.class))); + } + + public static SourceDataLine getSourceDataLine(AudioFormat format) + throws LineUnavailableException { + SourceDataLine line = (SourceDataLine)getLine( + new Line.Info(SourceDataLine.class)); + line.open(format); + return line; + } + + public static SourceDataLine getSourceDataLine(AudioFormat format, + Mixer.Info mixerinfo) throws LineUnavailableException { + + SourceDataLine line = (SourceDataLine)getMixer(mixerinfo).getLine( + new Line.Info(SourceDataLine.class)); + line.open(format); + return line; + } + + public static TargetDataLine getTargetDataLine(AudioFormat format) + throws LineUnavailableException { + TargetDataLine line = (TargetDataLine)getLine( + new Line.Info(TargetDataLine.class)); + line.open(format); + return line; + } + + public static TargetDataLine getTargetDataLine(AudioFormat format, + Mixer.Info mixerinfo) throws LineUnavailableException { + + TargetDataLine line = (TargetDataLine)getMixer(mixerinfo).getLine( + new Line.Info(TargetDataLine.class)); + line.open(format); + return line; + } + + public static AudioFormat.Encoding[] getTargetEncodings( + AudioFormat.Encoding sourceEncoding) { + + List result = new ArrayList(); + for (Iterator providers = ProviderService.getProviders( + formatConversionProviderPath).iterator(); providers.hasNext();) { + try { + FormatConversionProvider pr = + (FormatConversionProvider) providers.next(); + if (!pr.isSourceEncodingSupported(sourceEncoding)) { + continue; + } + AudioFormat.Encoding[] encodings = + pr.getTargetEncodings(); + for (AudioFormat.Encoding encoding : encodings) { + result.add(encoding); + } + } catch (ClassCastException e) { + } + } + AudioFormat.Encoding[] temp = new AudioFormat.Encoding[result.size()]; + return result.toArray(temp); + } + + public static AudioFormat.Encoding[] getTargetEncodings( + AudioFormat sourceFormat) { + + List result = new ArrayList(); + for (Iterator providers = ProviderService.getProviders( + formatConversionProviderPath).iterator(); providers.hasNext();) { + try { + AudioFormat.Encoding[] encodings = + ((FormatConversionProvider) (providers.next())) + .getTargetEncodings(sourceFormat); + for (AudioFormat.Encoding encoding : encodings) { + result.add(encoding); + } + } catch (ClassCastException e) { + } + } + AudioFormat.Encoding[] temp = new AudioFormat.Encoding[result.size()]; + return result.toArray(temp); + } + + public static boolean isConversionSupported( + AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat) { + + for (Iterator providers = ProviderService.getProviders( + formatConversionProviderPath).iterator(); providers.hasNext();) { + if (((FormatConversionProvider) (providers.next())) + .isConversionSupported(targetEncoding, sourceFormat)) { + return true; + } + } + return false; + } + + public static AudioInputStream getAudioInputStream( + AudioFormat.Encoding targetEncoding, AudioInputStream sourceStream) { + + if (sourceStream.getFormat().getEncoding().equals(targetEncoding)) { + return sourceStream; + } + for (Iterator providers = ProviderService.getProviders( + formatConversionProviderPath).iterator(); providers.hasNext();) { + try { + return ((FormatConversionProvider) (providers.next())) + .getAudioInputStream(targetEncoding, sourceStream); + } catch (ClassCastException e) { + } catch (IllegalArgumentException e) { + } + } + // sound.12=Could not get audio input stream from source stream + throw new IllegalArgumentException( + Messages.getString("sound.12")); //$NON-NLS-1$ + } + + public static AudioFormat[] getTargetFormats( + AudioFormat.Encoding targetEncoding, AudioFormat sourceFormat) { + + List result = new ArrayList(); + for (Iterator providers = ProviderService.getProviders( + formatConversionProviderPath).iterator(); providers.hasNext();) { + try { + AudioFormat[] formats = + ((FormatConversionProvider) (providers.next())) + .getTargetFormats(targetEncoding, sourceFormat); + for (AudioFormat format : formats) { + result.add(format); + } + } catch (ClassCastException e) { + } + } + AudioFormat[] temp = new AudioFormat[result.size()]; + return result.toArray(temp); + } + + public static boolean isConversionSupported(AudioFormat targetFormat, + AudioFormat sourceFormat) { + + for (Iterator providers = ProviderService.getProviders( + formatConversionProviderPath).iterator(); providers.hasNext();) { + if (((FormatConversionProvider) (providers.next())) + .isConversionSupported(targetFormat, sourceFormat)) { + return true; + } + } + return false; + } + + public static AudioInputStream getAudioInputStream( + AudioFormat targetFormat, AudioInputStream sourceStream) { + + if (sourceStream.getFormat().matches(targetFormat)) { + return sourceStream; + } + for (Iterator providers = ProviderService.getProviders( + formatConversionProviderPath).iterator(); providers.hasNext();) { + try { + return ((FormatConversionProvider) (providers.next())) + .getAudioInputStream(targetFormat, sourceStream); + } catch (ClassCastException e) { + } catch (IllegalArgumentException e) { + } + } + // sound.13=Could not get audio input stream from source stream + throw new IllegalArgumentException( + Messages.getString("sound.13")); //$NON-NLS-1$ + } + + public static AudioFileFormat getAudioFileFormat(InputStream stream) + throws UnsupportedAudioFileException, IOException { + + for (Iterator providers = ProviderService.getProviders( + audioFileReaderPath).iterator(); providers.hasNext();) { + try { + return ((AudioFileReader) (providers.next())) + .getAudioFileFormat(stream); + } catch (ClassCastException e) { + } catch (UnsupportedAudioFileException e) { + } + } + // sound.14=File is not a supported file type + throw new UnsupportedAudioFileException( + Messages.getString("sound.14")); //$NON-NLS-1$ + } + + public static AudioFileFormat getAudioFileFormat(URL url) + throws UnsupportedAudioFileException, IOException { + + for (Iterator providers = ProviderService.getProviders( + audioFileReaderPath).iterator(); providers.hasNext();) { + try { + return ((AudioFileReader) (providers.next())) + .getAudioFileFormat(url); + } catch (ClassCastException e) { + } catch (UnsupportedAudioFileException e) { + } + } + // sound.14=File is not a supported file type + throw new UnsupportedAudioFileException( + Messages.getString("sound.14")); //$NON-NLS-1$ + } + + public static AudioFileFormat getAudioFileFormat(File file) + throws UnsupportedAudioFileException, IOException { + + for (Iterator providers = ProviderService.getProviders( + audioFileReaderPath).iterator(); providers.hasNext();) { + try { + return ((AudioFileReader) (providers.next())) + .getAudioFileFormat(file); + } catch (ClassCastException e) { + } catch (UnsupportedAudioFileException e) { + } + } + // sound.14=File is not a supported file type + throw new UnsupportedAudioFileException( + Messages.getString("sound.14")); //$NON-NLS-1$ + } + + public static AudioInputStream getAudioInputStream(InputStream stream) + throws UnsupportedAudioFileException, IOException { + + if (stream instanceof AudioInputStream) { + return (AudioInputStream)stream; + } + for (Iterator providers = ProviderService.getProviders( + audioFileReaderPath).iterator(); providers.hasNext();) { + try { + return ((AudioFileReader) (providers.next())) + .getAudioInputStream(stream); + } catch (ClassCastException e) { + } catch (UnsupportedAudioFileException e) { + } + } + // sound.15=Could not get audio input stream from input stream + throw new UnsupportedAudioFileException( + Messages.getString("sound.15")); //$NON-NLS-1$ + } + + public static AudioInputStream getAudioInputStream(URL url) + throws UnsupportedAudioFileException, IOException { + + for (Iterator providers = ProviderService.getProviders( + audioFileReaderPath).iterator(); providers.hasNext();) { + try { + return ((AudioFileReader) (providers.next())) + .getAudioInputStream(url); + } catch (ClassCastException e) { + } catch (UnsupportedAudioFileException e) { + } + } + // sound.16=Could not get audio input stream from input URL + throw new UnsupportedAudioFileException( + Messages.getString("sound.16")); //$NON-NLS-1$ + } + + public static AudioInputStream getAudioInputStream(File file) + throws UnsupportedAudioFileException, IOException { + + for (Iterator providers = ProviderService.getProviders( + audioFileReaderPath).iterator(); providers.hasNext();) { + try { + return ((AudioFileReader) (providers.next())) + .getAudioInputStream(file); + } catch (ClassCastException e) { + } catch (UnsupportedAudioFileException e) { + } + } + // sound.17=Could not get audio input stream from input file + throw new UnsupportedAudioFileException( + Messages.getString("sound.17")); //$NON-NLS-1$ + } + + public static AudioFileFormat.Type[] getAudioFileTypes() { + List result = new ArrayList(); + for (Iterator providers = ProviderService.getProviders( + audioFileWriterPath).iterator(); providers.hasNext();) { + try { + AudioFileFormat.Type[] types = + ((AudioFileWriter) (providers.next())).getAudioFileTypes(); + for (AudioFileFormat.Type type : types) { + result.add(type); + } + } catch (ClassCastException e) { + } + } + AudioFileFormat.Type[] temp = new AudioFileFormat.Type[result.size()]; + return result.toArray(temp); + } + + public static boolean isFileTypeSupported(AudioFileFormat.Type fileType) { + + for (Iterator providers = ProviderService.getProviders( + audioFileWriterPath).iterator(); providers.hasNext();) { + if (((AudioFileWriter) (providers.next())) + .isFileTypeSupported(fileType)) { + return true; + } + } + return false; + } + + public static AudioFileFormat.Type[] getAudioFileTypes(AudioInputStream stream) { + List result = new ArrayList(); + for (Iterator providers = ProviderService.getProviders( + audioFileWriterPath).iterator(); providers.hasNext();) { + try { + AudioFileFormat.Type[] types = + ((AudioFileWriter) (providers.next())).getAudioFileTypes(stream); + for (AudioFileFormat.Type type : types) { + result.add(type); + } + } catch (ClassCastException e) { + } + } + AudioFileFormat.Type[] temp = new AudioFileFormat.Type[result.size()]; + return result.toArray(temp); + } + + public static boolean isFileTypeSupported(AudioFileFormat.Type fileType, + AudioInputStream stream) { + + for (Iterator providers = ProviderService.getProviders( + audioFileWriterPath).iterator(); providers.hasNext();) { + if (((AudioFileWriter) (providers.next())).isFileTypeSupported( + fileType, stream)) { + return true; + } + } + return false; + } + + public static int write(AudioInputStream stream, + AudioFileFormat.Type fileType, OutputStream out) throws IOException { + AudioFileWriter writer; + for (Iterator providers = ProviderService.getProviders( + audioFileWriterPath).iterator(); providers.hasNext();) { + writer = (AudioFileWriter) (providers.next()); + if (writer.isFileTypeSupported(fileType, stream)) { + return writer.write(stream, fileType, out); + } + } + // sound.18=Type is not supported + throw new IllegalArgumentException(Messages.getString("sound.18")); //$NON-NLS-1$ + } + + public static int write(AudioInputStream stream, + AudioFileFormat.Type fileType, File out) throws IOException { + AudioFileWriter writer; + for (Iterator providers = ProviderService.getProviders( + audioFileWriterPath).iterator(); providers.hasNext();) { + writer = (AudioFileWriter) (providers.next()); + if (writer.isFileTypeSupported(fileType, stream)) { + return writer.write(stream, fileType, out); + } + } + // sound.18=Type is not supported + throw new IllegalArgumentException(Messages.getString("sound.18")); //$NON-NLS-1$ + } +} \ No newline at end of file Index: modules/sound/build.xml =================================================================== --- modules/sound/build.xml (revision 504056) +++ modules/sound/build.xml (working copy) @@ -37,6 +37,8 @@ + + @@ -53,8 +55,11 @@ - + + + + @@ -116,6 +121,13 @@ + + + + + + + @@ -137,6 +149,7 @@ + @@ -166,7 +179,7 @@ - +