diff -r 2a9601315dfc -r 98ccebc37403 javauis/mmapi_qt/baseline/javasrc.mmf/com/nokia/microedition/media/ManagerImpl.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javauis/mmapi_qt/baseline/javasrc.mmf/com/nokia/microedition/media/ManagerImpl.java Fri May 14 15:47:24 2010 +0300 @@ -0,0 +1,675 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +package com.nokia.microedition.media; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Vector; +import java.util.Enumeration; +import javax.microedition.media.protocol.DataSource; +import javax.microedition.media.TimeBase; +import javax.microedition.media.Player; +import javax.microedition.media.MediaException; + +//import com.symbian.lcdjava.lang.ObjectExtensions; +//import com.symbian.epoc.events.MIDEventServer; +//import com.symbian.midp.runtime.ToolkitInvoker; +//import com.symbian.midp.runtime.ToolkitObserver; + +import com.nokia.microedition.media.protocol.ProtocolFactory; +import com.nokia.microedition.media.tone.PlayToneImpl; +import com.nokia.microedition.volumekeys.ForegroundListener; +import com.nokia.mj.impl.rt.support.Finalizer; + +//To get the shutdown event from the midlet +import com.nokia.mj.impl.rt.support.ApplicationUtils; +import com.nokia.mj.impl.rt.support.ApplicationInfo; +import com.nokia.mj.impl.rt.support.ShutdownListener; + +/** + * ManagerImpl implements the functionality specified in + * javax.microedition.media.Manager class. + * This class is a singleton and instance can be got with getInstance method. + */ +public class ManagerImpl implements PlugIn +{ + // ManagerImpl native instance + private static int sManagerHandle; + + // CMMAEventSource + private static int iFunctionSourceHandle; + + // Static instance, can be got with getInstace method + private static ManagerImpl sManager; + + private final TimeBase iSystemTimeBase = new SystemTimeBase(); + + private final Vector iPlugIns = new Vector(); + private final ProtocolFactory iProtocolFactory = new ProtocolFactory(); + private final ForegroundListener iForegroundListener; + private Finalizer iFinalizer; + + Finalizer registerForFinalization() + { + return new Finalizer() + { + public void finalizeImpl() + { + doFinalize(); + } + }; + } + + // Play tone implementation + private PlayToneImpl iPlayToneImpl = new PlayToneImpl(); + + static + { + + try{ + com.nokia.mj.impl.rt.support.Jvm.loadSystemLibrary("javalegacyutils"); + } + catch(Exception e) + { + System.out.println("loading javalegacyutils failed....."); + } + System.out.println("inside static block of ManagerImpl.java"); + // This is called when class is loaded for the first time + sManager = new ManagerImpl(); + try + { + // Invoke external components + Setup.setup(iFunctionSourceHandle); + } + catch (OutOfMemoryError oome) + { + // External setup failed clean MMA native resources and throw oome + sManager.doFinalize(); + throw oome; + } + } + + /** + * This private constructor can be called only from staic block. + */ + private ManagerImpl() + { + // Will cause registeredFinalize() to be called when ObjectExtensions + // is finalized. + + + com.nokia.mj.impl.rt.support.Jvm.loadSystemLibrary("javamobilemedia"); + //ObjectExtensions.registerForFinalization(this); + iFinalizer = registerForFinalization(); + + // Event server contructor needs new String object, + // otherwise it don't work.. + + iFunctionSourceHandle = _createEventSource(); + if (iFunctionSourceHandle < NativeError.KErrNone) + { + throw new OutOfMemoryError("Symbian OS error: " + sEventSourceHandle); + } + + sManagerHandle = _createManager(iFunctionSourceHandle, + ApplicationInfo.getInstance().getSuiteUid().hashCode()); + if (sManagerHandle < NativeError.KErrNone) + { + throw new OutOfMemoryError(); + } + //Use ShutdownListener to get notification of exit and release the resource + //MMAPI UI 3.x work + + setShutdownListener(); + + // ManagerImpl is also a PlugIn that getAllSupportedContentTypes, + // getAllSupportedProtocols and createPlayer methods can be used + // through PlugIn interface. + iPlugIns.addElement(this); + + // support for device://tone and jts + iPlugIns.addElement( + new com.nokia.microedition.media.protocol.device.tone.Protocol()); + + // Create foreground listener which listens the state of the midlet + // This feature is a part of the media keys feature so it is flagged + System.out.println("before constructing ForegroundListener...."); + iForegroundListener = new ForegroundListener(iFunctionSourceHandle); + iForegroundListener.init(); + } + + /** + * Returns MMA event source handle + */ + public static int getEventSource() + { + return iFunctionSourceHandle; + } + /** + * Returns native handle to Manager + */ + public static int getHandle() + { + return sManagerHandle; + } + + /** + * Return ManagerImpl instance + */ + public static ManagerImpl getInstance() + { + return sManager; + } + + /** + * Adds new PlugIn to PlugIns array. + * @param aPlugIn New PlugIn. + */ + public void addPlugIn(PlugIn aPlugIn) + { + iPlugIns.addElement(aPlugIn); + } + + + + + /** + * This will be called when ObjectExtensions is finalized. + */ + synchronized final void doFinalize() + { + _dispose(iFunctionSourceHandle); + iFunctionSourceHandle = 0; + } + + /** + * This method is called in Toolkit's destroyNotify call. + * This will release convenient native resources. All native resource + * will be deleted in registeredFinalize() method. + */ + synchronized final void release() + { + _release(iFunctionSourceHandle); + } + + /** + * Create String array from Vector and remove String duplicates. + * @param aVector Vector containing String objects. + */ + private String[] createStringArray(Vector aVector) + { + // remove all duplicates from the vector + for (int i = 0; i < aVector.size(); i++) + { + String element = (String)aVector.elementAt(i); + for (int j = i + 1; j < aVector.size();) + { + if (element.equals((String)aVector.elementAt(j))) + { + aVector.removeElementAt(j); + } + else + { + j++; + } + } + } + + // Create new array for vector elements and copy elements + String[] s = new String[ aVector.size()]; + aVector.copyInto(s); + return s; + } + + /** + * Return the list of supported content types for the given protocol. + *
+ * See content types for the syntax + * of the content types returned. + * See protocol name for the syntax + * of the protocol used. + *
+ * For example, if the given protocol
+ * is "http"
,
+ * then the supported content types that can be played back
+ * with the http
protocol will be returned.
+ *
+ * If null
is passed in as the protocol
,
+ * all the supported content types for this implementation
+ * will be returned. The returned array must be non-empty.
+ *
+ * If the given protocol
is an invalid or
+ * unsupported protocol, then an empty array will be returned.
+ *
+ * @param aProtocol The input protocol for the supported content types.
+ * @return The list of supported content types for the given protocol.
+ */
+ public String[] getAllSupportedContentTypes(String aProtocol)
+ {
+ if ((aProtocol != null) && (aProtocol.length() == 0))
+ {
+ // No supported types for 0 length string.
+ return new String[ 0 ];
+ }
+ Vector contentTypes = new Vector();
+
+ Enumeration plugIns = iPlugIns.elements();
+
+ // go through all plugins and get content types
+ while (plugIns.hasMoreElements())
+ {
+ PlugIn plugIn = (PlugIn)plugIns.nextElement();
+ String[] types = plugIn.getSupportedContentTypes(aProtocol);
+
+ // Add all types to vector
+ for (int i = 0; i < types.length; i++)
+ {
+ contentTypes.addElement(types[ i ]);
+ }
+ }
+ return createStringArray(contentTypes);
+ }
+
+ /**
+ * Return the list of supported protocols given the content
+ * type. The protocols are returned
+ * as strings which identify what locators can be used for creating
+ * Player
's.
+ *
+ * See protocol name for the syntax + * of the protocols returned. + * See content types for the syntax + * of the content type used. + *
+ * For example, if the given content_type
+ * is "audio/x-wav"
, then the supported protocols
+ * that can be used to play back audio/x-wav
+ * will be returned.
+ *
+ * If null
is passed in as the
+ * content_type
,
+ * all the supported protocols for this implementation
+ * will be returned. The returned array must be non-empty.
+ *
+ * If the given content_type
is an invalid or
+ * unsupported content type, then an empty array will be returned.
+ *
+ * @param aContentType The content type for the supported protocols.
+ * @return The list of supported protocols for the given content type.
+ */
+ public String[] getAllSupportedProtocols(String aContentType)
+ {
+ String contentType = aContentType;
+ if ((contentType != null) && contentType.equals(""))
+ {
+ return new String[ 0 ];
+ }
+
+ Vector protocols = new Vector();
+ Enumeration plugIns = iPlugIns.elements();
+ while (plugIns.hasMoreElements())
+ {
+ PlugIn plugIn = (PlugIn)plugIns.nextElement();
+ String[] types = plugIn.getSupportedProtocols(aContentType);
+ for (int i = 0; i < types.length; i++)
+ {
+ protocols.addElement(types[ i ]);
+ }
+ }
+ return createStringArray(protocols);
+ }
+
+ /**
+ * From PlugIn. Get MMA supported protocols.
+ */
+ public String[] getSupportedProtocols(String aContentType)
+ {
+ String[] protocols = _getSupportedProtocols(iFunctionSourceHandle,
+ sManagerHandle,
+ aContentType);
+ NativeError.checkOOM(protocols);
+ return protocols;
+ }
+
+ /**
+ * From PlugIn. Get MMA supported types.
+ */
+ public String[] getSupportedContentTypes(String aProtocol)
+ {
+ String[] types = _getSupportedContentTypes(iFunctionSourceHandle,
+ sManagerHandle,
+ aProtocol);
+ NativeError.checkOOM(types);
+ return types;
+ }
+
+ /**
+ * From PlugIn.
+ */
+ public InternalPlayer createPlayer(DataSource aSource)
+ throws MediaException, IOException
+ {
+ InternalPlayer player = null;
+ if (aSource.getContentType() != null)
+ {
+ // Create player from content type
+ if (isValidContentType(aSource.getContentType()))
+ {
+ player = NativePlayerFactory.createPlayer(aSource.getContentType(),
+ aSource);
+ }
+ else
+ {
+ throw new MediaException(
+ "Content type not supported: " + aSource.getContentType());
+ }
+ }
+
+ if ((player == null) &&
+ (aSource.getLocator() != null))
+ {
+ // Create player from locator
+ player = NativePlayerFactory.createPlayer(
+ new Locator(aSource.getLocator()),
+ aSource);
+ }
+
+ if (player == null)
+ {
+ // Could not create player from content-type or locator,
+ // try to create player from header data
+ player = NativePlayerFactory.createPlayer(
+ ((BufferDataSource)aSource).getHeader(),
+ aSource);
+ }
+
+ return player;
+ }
+
+ /**
+ * From PlugIn. Empty implemation.
+ */
+ public void preparePlayer(InternalPlayer aPlayer) throws MediaException
+ {
+
+ }
+
+ /**
+ * This method calls preparePlayer to all PlugIns.
+ */
+ private void pluginsPreparePlayer(InternalPlayer aPlayer)
+ throws MediaException
+ {
+ // Call preparePlayer to all plugins
+ Enumeration plugins = iPlugIns.elements();
+ while (plugins.hasMoreElements())
+ {
+ ((PlugIn)plugins.nextElement()).preparePlayer(aPlayer);
+ }
+ }
+
+ /**
+ * Create a Player
from an input locator.
+ *
+ * @param aLocator A locator string in URI syntax that describes
+ * the media content.
+ * @return A new Player
.
+ * @exception IllegalArgumentException Thrown if locator
+ * is null
.
+ * @exception MediaException Thrown if a Player
cannot
+ * be created for the given locator.
+ * @exception IOException Thrown if there was a problem connecting
+ * with the source pointed to by the locator
.
+ * @exception SecurityException Thrown if the caller does not
+ * have security permission to create the Player
.
+ */
+ public Player createPlayer(String aLocator)
+ throws IOException, MediaException
+ {
+ if (aLocator == null)
+ {
+ throw new IllegalArgumentException("Locator is null.");
+ }
+ InternalPlayer player = iProtocolFactory.createPlayer(
+ new Locator(aLocator));
+ if (player == null)
+ {
+ throw new MediaException("Locator not supported: " +
+ aLocator);
+ }
+ pluginsPreparePlayer(player);
+ return player;
+ }
+
+ /**
+ * Create a InternalPlayer
for a DataSource
.
+ */
+ public InternalPlayer createInternalPlayer(DataSource aSource)
+ throws IOException, MediaException
+ {
+ // Throw IllegalArgumentException if source is null.
+ if (aSource == null)
+ {
+ throw new IllegalArgumentException("DataSource is null.");
+ }
+ aSource.connect(); // Ensure that external source is connected.
+ if (aSource.getStreams() == null ||
+ aSource.getStreams().length == 0)
+ {
+ // There must be atleast one stream in the DataSource
+ throw new MediaException(
+ "There must be at least one stream in datasource");
+ }
+
+ BufferDataSource bdc = new BufferDataSource(aSource);
+
+ InternalPlayer player = null;
+ Enumeration plugins = iPlugIns.elements();
+ // Loop through all plugins, stop if player was created
+ while (plugins.hasMoreElements() &&
+ (player == null))
+ {
+ PlugIn tmp = (PlugIn)plugins.nextElement();
+ player = tmp.createPlayer(bdc);
+ }
+
+ if (player == null)
+ {
+ // MMA or plugins could not create player
+ bdc.disconnect();
+
+ throw new MediaException("Could not create player.");
+ }
+
+ return player;
+ }
+
+ /**
+ * Create a Player
to play back media from an
+ * InputStream
.
+ *
+ * The type
argument
+ * specifies the content-type of the input media. If
+ * null
is given, Manager
will
+ * attempt to determine the type. However, since determining
+ * the media type is non-trivial for some media types, it
+ * may not be feasible in some cases. The
+ * Manager
may throw a MediaException
+ * to indicate that.
+ *
+ * @param aStream The InputStream
that delivers the
+ * input media.
+ * @param aType The ContentType
of the media.
+ * @return A new Player
.
+ * @exception IllegalArgumentException Thrown if stream
+ * is null
.
+ * @exception MediaException Thrown if a Player
cannot
+ * be created for the given stream and type.
+ * @exception IOException Thrown if there was a problem reading data
+ * from the InputStream
.
+ * @exception SecurityException Thrown if the caller does not
+ * have security permission to create the Player
.
+ */
+ public Player createPlayer(InputStream aStream, String aType)
+ throws IOException, MediaException
+ {
+ if (aStream == null)
+ {
+ throw new IllegalArgumentException("InputStream is null.");
+ }
+
+ InputStreamSourceStream sourceStream =
+ new InputStreamSourceStream(aStream);
+
+ // Create data source without locator.
+ DataSource dataSource = new InputStreamDataSource(sourceStream,
+ aType);
+ InternalPlayer player = createInternalPlayer(dataSource);
+
+ if (player != null)
+ {
+ // Call preparePlayer to all plugins
+ pluginsPreparePlayer(player);
+ }
+
+ return player;
+ }
+
+ /**
+ * Play back a tone as specified by a note and its duration.
+ * A note is given in the range of 0 to 127 inclusive. The frequency
+ * of the note can be calculated from the following formula:
+ *
+ * SEMITONE_CONST = 17.31234049066755 = 1/(ln(2^(1/12))) + * note = ln(freq/8.176)*SEMITONE_CONST + * The musical note A = MIDI note 69 (0x45) = 440 Hz. + *+ * This call is a non-blocking call. Notice that this method may + * utilize CPU resources significantly on devices that don't + * have hardware support for tone generation. + * + * @param aNote Defines the tone of the note as specified by the + * above formula. + * @param aDuration The duration of the tone in milli-seconds. + * Duration must be positive. + * @param aVolume Audio volume range from 0 to 100. 100 represents + * the maximum + * volume at the current hardware level. Setting the volume to a + * value less + * than 0 will set the volume to 0. Setting the volume to greater than + * 100 will set the volume to 100. + * + * @exception IllegalArgumentException Thrown if the given note or + * duration is out of range. + * @exception MediaException Thrown if the tone cannot be played + * due to a device-related problem. + */ + public void playTone(int aNote, int aDuration, int aVolume) + throws MediaException + { + iPlayToneImpl.playTone(aNote, aDuration, aVolume); + } + + /** + * Get the time-base object for the system. + * @return The system time base. + */ + public TimeBase getSystemTimeBase() + { + return iSystemTimeBase; + } + + public boolean isValidContentType(String contentType) + { + for (int i=0; i < contentType.length(); i++) + { + if ((contentType.charAt(i) >= 0 && contentType.charAt(i) <= 31) || contentType.charAt(i) == 127) + return false; + } + return true; + } + + + +/** + * Registers for shutdown listener + */ + private void setShutdownListener() + { + // Get the instance of ApplicationUtils. + ApplicationUtils appUtils = ApplicationUtils.getInstance(); + + // add the listener + appUtils.addShutdownListener(new ShutdownListener() + { + public void shuttingDown() + { + try + { + System.out.println("Shutting down.........."); + // Do cleaning... + release(); + } + catch (Exception ex) + { + // catch the exception and call dispose + } + + if (iFunctionSourceHandle != 0) + { + _dispose(iFunctionSourceHandle); + iFunctionSourceHandle = 0; + } + } + + }); + } // end setShutdownListener() + + +// MMAPI UI 3.x req +/** + * get midlet state + */ + + public boolean isForground() + { + return iForegroundListener.isForeground(); + } + + + private native int _createManager(int aEventSourceHandle, + int aMIDletSuiteID); + private native int _createEventSource(); + private native void _dispose(int aEventSourceHandle); + + /** + * Releases native resources. + * @param aEventSourceHandle Handle to native CMMAEventSource instance. + */ + private native void _release(int aFunctionSourceHandle); + + private static native String[] _getSupportedContentTypes(int aFunctionSourceHandle, + int aManagerHandle, + String aContentType); + + private static native String[] _getSupportedProtocols(int aFunctionSourceHandle, + int aManagerHandle, + String aProtocol); +} + +// End of File