提交 cfc7f025 编写于 作者: S serb

8026163: Enhance media provisioning

Reviewed-by: art, skoivu
上级 83ec931c
...@@ -25,27 +25,33 @@ ...@@ -25,27 +25,33 @@
package com.sun.media.sound; package com.sun.media.sound;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import javax.sound.midi.Receiver; import javax.sound.midi.Receiver;
import javax.sound.midi.Sequencer; import javax.sound.midi.Sequencer;
import javax.sound.midi.Synthesizer; import javax.sound.midi.Synthesizer;
import javax.sound.midi.Transmitter; import javax.sound.midi.Transmitter;
import javax.sound.midi.spi.MidiDeviceProvider;
import javax.sound.midi.spi.MidiFileReader;
import javax.sound.midi.spi.MidiFileWriter;
import javax.sound.midi.spi.SoundbankReader;
import javax.sound.sampled.Clip; import javax.sound.sampled.Clip;
import javax.sound.sampled.Port; import javax.sound.sampled.Port;
import javax.sound.sampled.SourceDataLine; import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine; import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.spi.AudioFileReader;
import javax.sound.sampled.spi.AudioFileWriter;
import javax.sound.sampled.spi.FormatConversionProvider;
import javax.sound.sampled.spi.MixerProvider;
/** /**
* JDK13Services uses the Service class in JDK 1.3 * JDK13Services uses the Service class in JDK 1.3 to discover a list of service
* to discover a list of service providers installed * providers installed in the system.
* in the system. * <p>
*
* This class is public because it is called from javax.sound.midi.MidiSystem * This class is public because it is called from javax.sound.midi.MidiSystem
* and javax.sound.sampled.AudioSystem. The alternative would be to make * and javax.sound.sampled.AudioSystem. The alternative would be to make
* JSSecurityManager public, which is considered worse. * JSSecurityManager public, which is considered worse.
...@@ -54,80 +60,55 @@ import javax.sound.sampled.TargetDataLine; ...@@ -54,80 +60,55 @@ import javax.sound.sampled.TargetDataLine;
*/ */
public final class JDK13Services { public final class JDK13Services {
/** The default for the length of the period to hold the cache. /**
This value is given in milliseconds. It is equivalent to * Filename of the properties file for default provider properties. This
1 minute. * file is searched in the subdirectory "lib" of the JRE directory (this
*/ * behaviour is hardcoded).
private static final long DEFAULT_CACHING_PERIOD = 60000; */
/** Filename of the properties file for default provider properties.
This file is searched in the subdirectory "lib" of the JRE directory
(this behaviour is hardcoded).
*/
private static final String PROPERTIES_FILENAME = "sound.properties"; private static final String PROPERTIES_FILENAME = "sound.properties";
/** Cache for the providers. /**
Class objects of the provider type (MixerProvider, MidiDeviceProvider * Properties loaded from the properties file for default provider
...) are used as keys. The values are instances of ProviderCache. * properties.
*/ */
private static final Map providersCacheMap = new HashMap();
/** The length of the period to hold the cache.
This value is given in milliseconds.
*/
private static long cachingPeriod = DEFAULT_CACHING_PERIOD;
/** Properties loaded from the properties file for default provider
properties.
*/
private static Properties properties; private static Properties properties;
/**
/** Private, no-args constructor to ensure against instantiation. * Private, no-args constructor to ensure against instantiation.
*/ */
private JDK13Services() { private JDK13Services() {
} }
/**
/** Set the period provider lists are cached. * Obtains a List containing installed instances of the providers for the
This method is only intended for testing. * requested service. The returned List is immutable.
*/ *
public static void setCachingPeriod(int seconds) { * @param serviceClass The type of providers requested. This should be one
cachingPeriod = seconds * 1000L; * of AudioFileReader.class, AudioFileWriter.class,
} * FormatConversionProvider.class, MixerProvider.class,
* MidiDeviceProvider.class, MidiFileReader.class,
* MidiFileWriter.class or SoundbankReader.class.
/** Obtains a List containing installed instances of the *
providers for the requested service. * @return A List of providers of the requested type. This List is
The List of providers is cached for the period of time given by * immutable.
{@link #cachingPeriod cachingPeriod}. During this period, the same
List instance is returned for the same type of provider. After this
period, a new instance is constructed and returned. The returned
List is immutable.
@param serviceClass The type of providers requested. This should be one
of AudioFileReader.class, AudioFileWriter.class,
FormatConversionProvider.class, MixerProvider.class,
MidiDeviceProvider.class, MidiFileReader.class, MidiFileWriter.class or
SoundbankReader.class.
@return A List of providers of the requested type. This List is
immutable.
*/ */
public static synchronized List getProviders(Class serviceClass) { public static List<?> getProviders(final Class<?> serviceClass) {
ProviderCache cache = (ProviderCache) providersCacheMap.get(serviceClass); final List<?> providers;
if (cache == null) { if (!MixerProvider.class.equals(serviceClass)
cache = new ProviderCache(); && !FormatConversionProvider.class.equals(serviceClass)
providersCacheMap.put(serviceClass, cache); && !AudioFileReader.class.equals(serviceClass)
&& !AudioFileWriter.class.equals(serviceClass)
&& !MidiDeviceProvider.class.equals(serviceClass)
&& !SoundbankReader.class.equals(serviceClass)
&& !MidiFileWriter.class.equals(serviceClass)
&& !MidiFileReader.class.equals(serviceClass)) {
providers = new ArrayList<>(0);
} else {
providers = JSSecurityManager.getProviders(serviceClass);
} }
if (cache.providers == null || return Collections.unmodifiableList(providers);
System.currentTimeMillis() > cache.lastUpdate + cachingPeriod) {
cache.providers = Collections.unmodifiableList(JSSecurityManager.getProviders(serviceClass));
cache.lastUpdate = System.currentTimeMillis();
}
return cache.providers;
} }
/** Obtain the provider class name part of a default provider property. /** Obtain the provider class name part of a default provider property.
@param typeClass The type of the default provider property. This @param typeClass The type of the default provider property. This
should be one of Receiver.class, Transmitter.class, Sequencer.class, should be one of Receiver.class, Transmitter.class, Sequencer.class,
...@@ -219,14 +200,4 @@ public final class JDK13Services { ...@@ -219,14 +200,4 @@ public final class JDK13Services {
} }
return properties; return properties;
} }
// INNER CLASSES
private static class ProviderCache {
// System time of the last update in milliseconds.
public long lastUpdate;
// The providers.
public List providers;
}
} }
...@@ -185,8 +185,8 @@ final class JSSecurityManager { ...@@ -185,8 +185,8 @@ final class JSSecurityManager {
return thread; return thread;
} }
static <T> List<T> getProviders(final Class<T> providerClass) { static synchronized <T> List<T> getProviders(final Class<T> providerClass) {
List<T> p = new ArrayList<>(); List<T> p = new ArrayList<>(7);
// ServiceLoader creates "lazy" iterator instance, but it ensures that // ServiceLoader creates "lazy" iterator instance, but it ensures that
// next/hasNext run with permissions that are restricted by whatever // next/hasNext run with permissions that are restricted by whatever
// creates the ServiceLoader instance, so it requires to be called from // creates the ServiceLoader instance, so it requires to be called from
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册