summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
Diffstat (limited to 'media')
-rw-r--r--media/java/android/media/AudioFormat.java4
-rw-r--r--media/java/android/media/AudioManager.java242
-rw-r--r--media/java/android/media/AudioRecord.java134
-rw-r--r--media/java/android/media/AudioService.java414
-rw-r--r--media/java/android/media/AudioSystem.java20
-rw-r--r--media/java/android/media/AudioTrack.java476
-rw-r--r--media/java/android/media/JetPlayer.java134
-rw-r--r--media/java/android/media/MediaFile.java6
-rw-r--r--media/java/android/media/MediaPlayer.java6
-rw-r--r--media/java/android/media/MediaRecorder.java6
-rw-r--r--media/java/android/media/MediaScanner.java10
-rw-r--r--media/jni/android_media_MediaRecorder.cpp11
-rw-r--r--media/jni/soundpool/SoundPool.cpp46
-rw-r--r--media/jni/soundpool/SoundPool.h5
-rw-r--r--media/libmedia/Android.mk1
-rw-r--r--media/libmedia/AudioRecord.cpp18
-rw-r--r--media/libmedia/AudioSystem.cpp55
-rw-r--r--media/libmedia/AudioTrack.cpp14
-rw-r--r--media/libmedia/IAudioFlinger.cpp50
-rw-r--r--media/libmedia/IAudioFlingerClient.cpp81
-rw-r--r--media/libmedia/JetPlayer.cpp70
-rw-r--r--media/libmedia/ToneGenerator.cpp8
-rw-r--r--media/libmedia/mediaplayer.cpp10
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp147
-rw-r--r--media/libmediaplayerservice/MidiFile.cpp20
-rw-r--r--media/libmediaplayerservice/MidiFile.h2
-rw-r--r--media/libmediaplayerservice/VorbisPlayer.cpp4
-rw-r--r--media/sdutils/sdutil.cpp14
-rw-r--r--media/tests/MediaFrameworkTest/AndroidManifest.xml5
-rwxr-xr-xmedia/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java2
-rwxr-xr-xmedia/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java554
-rwxr-xr-xmedia/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java38
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaAudioTrackTest.java59
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java3
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java111
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java198
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java3
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java3
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java3
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java3
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java3
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java3
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java3
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java3
44 files changed, 1901 insertions, 1101 deletions
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index c857e17..0732b61 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -18,9 +18,9 @@ package android.media;
/**
* The AudioFormat class is used to access a number of audio format and
- * channel configuration constants.
+ * channel configuration constants. They are for instance used
+ * in __link AudioTrack} and __link AudioRecord}.
*
- * {@hide Pending API council review}
*/
public class AudioFormat {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 52cf69f..2978774 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -49,37 +49,60 @@ public class AudioManager {
private static boolean localLOGV = DEBUG || android.util.Config.LOGV;
/**
+ * Broadcast intent, a hint for applications that audio is about to become
+ * 'noisy' due to a change in audio outputs. For example, this intent may
+ * be sent when a wired headset is unplugged, or when an A2DP audio
+ * sink is disconnected, and the audio system is about to automatically
+ * switch audio route to the speaker. Applications that are controlling
+ * audio streams may consider pausing, reducing volume or some other action
+ * on receipt of this intent so as not to surprise the user with audio
+ * from the speaker.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_AUDIO_BECOMING_NOISY = "android.media.AUDIO_BECOMING_NOISY";
+
+ /**
* Sticky broadcast intent action indicating that the ringer mode has
* changed. Includes the new ringer mode.
- *
+ *
* @see #EXTRA_RINGER_MODE
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED";
-
+
/**
* The new ringer mode.
- *
+ *
* @see #RINGER_MODE_CHANGED_ACTION
* @see #RINGER_MODE_NORMAL
* @see #RINGER_MODE_SILENT
* @see #RINGER_MODE_VIBRATE
*/
public static final String EXTRA_RINGER_MODE = "android.media.EXTRA_RINGER_MODE";
-
+
/**
* Broadcast intent action indicating that the vibrate setting has
* changed. Includes the vibrate type and its new setting.
- *
+ *
* @see #EXTRA_VIBRATE_TYPE
* @see #EXTRA_VIBRATE_SETTING
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String VIBRATE_SETTING_CHANGED_ACTION = "android.media.VIBRATE_SETTING_CHANGED";
-
+
+ /**
+ * @hide Broadcast intent when the volume for a particular stream type changes.
+ * Includes the stream and the new volume
+ *
+ * @see #EXTRA_VOLUME_STREAM_TYPE
+ * @see #EXTRA_VOLUME_STREAM_VALUE
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION";
+
/**
* The new vibrate setting for a particular type.
- *
+ *
* @see #VIBRATE_SETTING_CHANGED_ACTION
* @see #EXTRA_VIBRATE_TYPE
* @see #VIBRATE_SETTING_ON
@@ -87,16 +110,27 @@ public class AudioManager {
* @see #VIBRATE_SETTING_ONLY_SILENT
*/
public static final String EXTRA_VIBRATE_SETTING = "android.media.EXTRA_VIBRATE_SETTING";
-
+
/**
* The vibrate type whose setting has changed.
- *
+ *
* @see #VIBRATE_SETTING_CHANGED_ACTION
* @see #VIBRATE_TYPE_NOTIFICATION
* @see #VIBRATE_TYPE_RINGER
*/
public static final String EXTRA_VIBRATE_TYPE = "android.media.EXTRA_VIBRATE_TYPE";
-
+
+ /**
+ * @hide The stream type for the volume changed intent.
+ */
+ public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";
+
+ /**
+ * @hide The volume associated with the stream for the volume changed intent.
+ */
+ public static final String EXTRA_VOLUME_STREAM_VALUE =
+ "android.media.EXTRA_VOLUME_STREAM_VALUE";
+
/** The audio stream for phone calls */
public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL;
/** The audio stream for system sounds */
@@ -109,6 +143,8 @@ public class AudioManager {
public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM;
/** The audio stream for notifications */
public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION;
+ /** @hide The audio stream for phone calls when connected to bluetooth */
+ public static final int STREAM_BLUETOOTH_SCO = AudioSystem.STREAM_BLUETOOTH_SCO;
/** Number of audio streams */
/**
* @deprecated Use AudioSystem.getNumStreamTypes() instead
@@ -123,9 +159,10 @@ public class AudioManager {
8, // STREAM_RING
16, // STREAM_MUSIC
8, // STREAM_ALARM
- 8 // STREAM_NOTIFICATION
- };
-
+ 8, // STREAM_NOTIFICATION
+ 15, // STREAM_BLUETOOTH_SCO
+ };
+
/** @hide Default volume index values for audio streams */
public static final int[] DEFAULT_STREAM_VOLUME = new int[] {
4, // STREAM_VOICE_CALL
@@ -133,12 +170,13 @@ public class AudioManager {
5, // STREAM_RING
11, // STREAM_MUSIC
6, // STREAM_ALARM
- 5 // STREAM_NOTIFICATION
- };
-
+ 5, // STREAM_NOTIFICATION
+ 7 // STREAM_BLUETOOTH_SCO
+ };
+
/**
* Increase the ringer volume.
- *
+ *
* @see #adjustVolume(int, int)
* @see #adjustStreamVolume(int, int, int)
*/
@@ -146,7 +184,7 @@ public class AudioManager {
/**
* Decrease the ringer volume.
- *
+ *
* @see #adjustVolume(int, int)
* @see #adjustStreamVolume(int, int, int)
*/
@@ -155,17 +193,17 @@ public class AudioManager {
/**
* Maintain the previous ringer volume. This may be useful when needing to
* show the volume toast without actually modifying the volume.
- *
+ *
* @see #adjustVolume(int, int)
* @see #adjustStreamVolume(int, int, int)
*/
public static final int ADJUST_SAME = 0;
// Flags should be powers of 2!
-
+
/**
* Show a toast containing the current volume.
- *
+ *
* @see #adjustStreamVolume(int, int, int)
* @see #adjustVolume(int, int)
* @see #setStreamVolume(int, int, int)
@@ -183,12 +221,12 @@ public class AudioManager {
* mode (for example, the ring stream type). If this flag is included, this
* behavior will be present regardless of the stream type being affected by
* the ringer mode.
- *
+ *
* @see #adjustVolume(int, int)
* @see #adjustStreamVolume(int, int, int)
*/
public static final int FLAG_ALLOW_RINGER_MODES = 1 << 1;
-
+
/**
* Whether to play a sound when changing the volume.
* <p>
@@ -197,28 +235,28 @@ public class AudioManager {
* in some cases (for example, the decided stream type is not
* {@link AudioManager#STREAM_RING}, or the volume is being adjusted
* downward).
- *
+ *
* @see #adjustStreamVolume(int, int, int)
* @see #adjustVolume(int, int)
* @see #setStreamVolume(int, int, int)
*/
public static final int FLAG_PLAY_SOUND = 1 << 2;
-
+
/**
* Removes any sounds/vibrate that may be in the queue, or are playing (related to
* changing volume).
*/
public static final int FLAG_REMOVE_SOUND_AND_VIBRATE = 1 << 3;
-
+
/**
* Whether to vibrate if going into the vibrate ringer mode.
*/
public static final int FLAG_VIBRATE = 1 << 4;
-
+
/**
* Ringer mode that will be silent and will not vibrate. (This overrides the
* vibrate setting.)
- *
+ *
* @see #setRingerMode(int)
* @see #getRingerMode()
*/
@@ -228,7 +266,7 @@ public class AudioManager {
* Ringer mode that will be silent and will vibrate. (This will cause the
* phone ringer to always vibrate, but the notification vibrate to only
* vibrate if set.)
- *
+ *
* @see #setRingerMode(int)
* @see #getRingerMode()
*/
@@ -238,7 +276,7 @@ public class AudioManager {
* Ringer mode that may be audible and may vibrate. It will be audible if
* the volume before changing out of this mode was audible. It will vibrate
* if the vibrate setting is on.
- *
+ *
* @see #setRingerMode(int)
* @see #getRingerMode()
*/
@@ -246,53 +284,53 @@ public class AudioManager {
/**
* Vibrate type that corresponds to the ringer.
- *
+ *
* @see #setVibrateSetting(int, int)
* @see #getVibrateSetting(int)
* @see #shouldVibrate(int)
*/
public static final int VIBRATE_TYPE_RINGER = 0;
-
+
/**
* Vibrate type that corresponds to notifications.
- *
+ *
* @see #setVibrateSetting(int, int)
* @see #getVibrateSetting(int)
* @see #shouldVibrate(int)
*/
public static final int VIBRATE_TYPE_NOTIFICATION = 1;
-
+
/**
* Vibrate setting that suggests to never vibrate.
- *
+ *
* @see #setVibrateSetting(int, int)
* @see #getVibrateSetting(int)
*/
public static final int VIBRATE_SETTING_OFF = 0;
-
+
/**
* Vibrate setting that suggests to vibrate when possible.
- *
+ *
* @see #setVibrateSetting(int, int)
* @see #getVibrateSetting(int)
*/
public static final int VIBRATE_SETTING_ON = 1;
-
+
/**
* Vibrate setting that suggests to only vibrate when in the vibrate ringer
* mode.
- *
+ *
* @see #setVibrateSetting(int, int)
* @see #getVibrateSetting(int)
*/
public static final int VIBRATE_SETTING_ONLY_SILENT = 2;
-
+
/**
* Suggests using the default stream type. This may not be used in all
* places a stream type is needed.
*/
public static final int USE_DEFAULT_STREAM_TYPE = Integer.MIN_VALUE;
-
+
private static IAudioService sService;
/**
@@ -315,8 +353,8 @@ public class AudioManager {
/**
* Adjusts the volume of a particular stream by one step in a direction.
- *
- * @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL},
+ *
+ * @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL},
* {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC} or
* {@link #STREAM_ALARM}
* @param direction The direction to adjust the volume. One of
@@ -340,7 +378,7 @@ public class AudioManager {
* active, it will have the highest priority regardless of if the in-call
* screen is showing. Another example, if music is playing in the background
* and a call is not active, the music stream will be adjusted.
- *
+ *
* @param direction The direction to adjust the volume. One of
* {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
* {@link #ADJUST_SAME}.
@@ -361,7 +399,7 @@ public class AudioManager {
/**
* Adjusts the volume of the most relevant stream, or the given fallback
* stream.
- *
+ *
* @param direction The direction to adjust the volume. One of
* {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
* {@link #ADJUST_SAME}.
@@ -380,10 +418,10 @@ public class AudioManager {
Log.e(TAG, "Dead object in adjustVolume", e);
}
}
-
+
/**
* Returns the current ringtone mode.
- *
+ *
* @return The current ringtone mode, one of {@link #RINGER_MODE_NORMAL},
* {@link #RINGER_MODE_SILENT}, or {@link #RINGER_MODE_VIBRATE}.
* @see #setRingerMode(int)
@@ -400,7 +438,7 @@ public class AudioManager {
/**
* Returns the maximum volume index for a particular stream.
- *
+ *
* @param streamType The stream type whose maximum volume index is returned.
* @return The maximum valid volume index for the stream.
* @see #getStreamVolume(int)
@@ -417,7 +455,7 @@ public class AudioManager {
/**
* Returns the current volume index for a particular stream.
- *
+ *
* @param streamType The stream type whose volume index is returned.
* @return The current volume index for the stream.
* @see #getStreamMaxVolume(int)
@@ -439,7 +477,7 @@ public class AudioManager {
* Silent mode will mute the volume and will not vibrate. Vibrate mode will
* mute the volume and vibrate. Normal mode will be audible and may vibrate
* according to user settings.
- *
+ *
* @param ringerMode The ringer mode, one of {@link #RINGER_MODE_NORMAL},
* {@link #RINGER_MODE_SILENT}, or {@link #RINGER_MODE_VIBRATE}.
* @see #getRingerMode()
@@ -455,7 +493,7 @@ public class AudioManager {
/**
* Sets the volume index for a particular stream.
- *
+ *
* @param streamType The stream whose volume index should be set.
* @param index The volume index to set. See
* {@link #getStreamMaxVolume(int)} for the largest valid value.
@@ -471,7 +509,7 @@ public class AudioManager {
Log.e(TAG, "Dead object in setStreamVolume", e);
}
}
-
+
/**
* Solo or unsolo a particular stream. All other streams are muted.
* <p>
@@ -479,13 +517,13 @@ public class AudioManager {
* with an active solo request on a stream dies, all streams that were muted
* because of this request will be unmuted automatically.
* <p>
- * The solo requests for a given stream are cumulative: the AudioManager
+ * The solo requests for a given stream are cumulative: the AudioManager
* can receive several solo requests from one or more clients and the stream
* will be unsoloed only when the same number of unsolo requests are received.
* <p>
- * For a better user experience, applications MUST unsolo a soloed stream
+ * For a better user experience, applications MUST unsolo a soloed stream
* in onPause() and solo is again in onResume() if appropriate.
- *
+ *
* @param streamType The stream to be soloed/unsoloed.
* @param state The required solo state: true for solo ON, false for solo OFF
*/
@@ -497,7 +535,7 @@ public class AudioManager {
Log.e(TAG, "Dead object in setStreamSolo", e);
}
}
-
+
/**
* Mute or unmute an audio stream.
* <p>
@@ -505,13 +543,13 @@ public class AudioManager {
* with an active mute request on a stream dies, this stream will be unmuted
* automatically.
* <p>
- * The mute requests for a given stream are cumulative: the AudioManager
+ * The mute requests for a given stream are cumulative: the AudioManager
* can receive several mute requests from one or more clients and the stream
* will be unmuted only when the same number of unmute requests are received.
* <p>
- * For a better user experience, applications MUST unmute a muted stream
+ * For a better user experience, applications MUST unmute a muted stream
* in onPause() and mute is again in onResume() if appropriate.
- *
+ *
* @param streamType The stream to be muted/unmuted.
* @param state The required mute state: true for mute ON, false for mute OFF
*/
@@ -532,7 +570,7 @@ public class AudioManager {
* vibrate. The notification manager will not vibrate if the policy doesn't
* allow it, so the client should always set a vibrate pattern and let the
* notification manager control whether or not to actually vibrate.
- *
+ *
* @param vibrateType The type of vibrate. One of
* {@link #VIBRATE_TYPE_NOTIFICATION} or
* {@link #VIBRATE_TYPE_RINGER}.
@@ -550,13 +588,13 @@ public class AudioManager {
return false;
}
}
-
+
/**
* Returns whether the user's vibrate setting for a vibrate type.
* <p>
* This shouldn't be needed by most clients that want to vibrate, instead
* see {@link #shouldVibrate(int)}.
- *
+ *
* @param vibrateType The type of vibrate. One of
* {@link #VIBRATE_TYPE_NOTIFICATION} or
* {@link #VIBRATE_TYPE_RINGER}.
@@ -578,7 +616,7 @@ public class AudioManager {
/**
* Sets the setting for when the vibrate type should vibrate.
- *
+ *
* @param vibrateType The type of vibrate. One of
* {@link #VIBRATE_TYPE_NOTIFICATION} or
* {@link #VIBRATE_TYPE_RINGER}.
@@ -597,11 +635,11 @@ public class AudioManager {
Log.e(TAG, "Dead object in setVibrateSetting", e);
}
}
-
+
/**
* Sets the speakerphone on or off.
*
- * @param on set <var>true</var> to turn on speakerphone;
+ * @param on set <var>true</var> to turn on speakerphone;
* <var>false</var> to turn it off
*/
public void setSpeakerphoneOn(boolean on){
@@ -620,17 +658,17 @@ public class AudioManager {
/**
* Sets audio routing to the Bluetooth headset on or off.
*
- * @param on set <var>true</var> to route SCO (voice) audio to/from Bluetooth
+ * @param on set <var>true</var> to route SCO (voice) audio to/from Bluetooth
* headset; <var>false</var> to route audio to/from phone earpiece
*/
public void setBluetoothScoOn(boolean on){
// Don't disable A2DP when turning off SCO.
// A2DP does not affect in-call routing.
- setRouting(MODE_RINGTONE,
+ setRouting(MODE_RINGTONE,
on ? ROUTE_BLUETOOTH_SCO: ROUTE_SPEAKER, ROUTE_ALL & ~ROUTE_BLUETOOTH_A2DP);
- setRouting(MODE_NORMAL,
+ setRouting(MODE_NORMAL,
on ? ROUTE_BLUETOOTH_SCO: ROUTE_SPEAKER, ROUTE_ALL & ~ROUTE_BLUETOOTH_A2DP);
- setRouting(MODE_IN_CALL,
+ setRouting(MODE_IN_CALL,
on ? ROUTE_BLUETOOTH_SCO: ROUTE_EARPIECE, ROUTE_ALL);
}
@@ -647,15 +685,15 @@ public class AudioManager {
/**
* Sets A2DP audio routing to the Bluetooth headset on or off.
*
- * @param on set <var>true</var> to route A2DP audio to/from Bluetooth
+ * @param on set <var>true</var> to route A2DP audio to/from Bluetooth
* headset; <var>false</var> disable A2DP audio
*/
public void setBluetoothA2dpOn(boolean on){
// the audio flinger chooses A2DP as a higher priority,
// so there is no need to disable other routes.
- setRouting(MODE_RINGTONE,
+ setRouting(MODE_RINGTONE,
on ? ROUTE_BLUETOOTH_A2DP: 0, ROUTE_BLUETOOTH_A2DP);
- setRouting(MODE_NORMAL,
+ setRouting(MODE_NORMAL,
on ? ROUTE_BLUETOOTH_A2DP: 0, ROUTE_BLUETOOTH_A2DP);
}
@@ -672,7 +710,7 @@ public class AudioManager {
/**
* Sets audio routing to the wired headset on or off.
*
- * @param on set <var>true</var> to route audio to/from wired
+ * @param on set <var>true</var> to route audio to/from wired
* headset; <var>false</var> disable wired headset audio
* @hide
*/
@@ -701,7 +739,7 @@ public class AudioManager {
/**
* Sets the microphone mute on or off.
*
- * @param on set <var>true</var> to mute the microphone;
+ * @param on set <var>true</var> to mute the microphone;
* <var>false</var> to turn mute off
*/
public void setMicrophoneMute(boolean on){
@@ -762,57 +800,57 @@ public class AudioManager {
/* modes for setMode/getMode/setRoute/getRoute */
/**
- * Audio harware modes.
- */
+ * Audio harware modes.
+ */
/**
- * Invalid audio mode.
- */
+ * Invalid audio mode.
+ */
public static final int MODE_INVALID = AudioSystem.MODE_INVALID;
/**
* Current audio mode. Used to apply audio routing to current mode.
- */
+ */
public static final int MODE_CURRENT = AudioSystem.MODE_CURRENT;
/**
* Normal audio mode: not ringing and no call established.
- */
+ */
public static final int MODE_NORMAL = AudioSystem.MODE_NORMAL;
/**
* Ringing audio mode. An incoming is being signaled.
- */
+ */
public static final int MODE_RINGTONE = AudioSystem.MODE_RINGTONE;
/**
* In call audio mode. A call is established.
- */
+ */
public static final int MODE_IN_CALL = AudioSystem.MODE_IN_CALL;
/* Routing bits for setRouting/getRouting API */
/**
* Routing audio output to earpiece
- */
+ */
public static final int ROUTE_EARPIECE = AudioSystem.ROUTE_EARPIECE;
/**
* Routing audio output to spaker
- */
+ */
public static final int ROUTE_SPEAKER = AudioSystem.ROUTE_SPEAKER;
/**
* @deprecated use {@link #ROUTE_BLUETOOTH_SCO}
- */
+ */
@Deprecated public static final int ROUTE_BLUETOOTH = AudioSystem.ROUTE_BLUETOOTH_SCO;
/**
* Routing audio output to bluetooth SCO
- */
+ */
public static final int ROUTE_BLUETOOTH_SCO = AudioSystem.ROUTE_BLUETOOTH_SCO;
/**
* Routing audio output to headset
- */
+ */
public static final int ROUTE_HEADSET = AudioSystem.ROUTE_HEADSET;
/**
* Routing audio output to bluetooth A2DP
- */
+ */
public static final int ROUTE_BLUETOOTH_A2DP = AudioSystem.ROUTE_BLUETOOTH_A2DP;
/**
* Used for mask parameter of {@link #setRouting(int,int,int)}.
- */
+ */
public static final int ROUTE_ALL = AudioSystem.ROUTE_ALL;
/**
@@ -892,33 +930,33 @@ public class AudioManager {
/**
* Keyboard and direction pad click sound
* @see #playSoundEffect(int)
- */
+ */
public static final int FX_KEY_CLICK = 0;
/**
* Focuse has moved up
* @see #playSoundEffect(int)
- */
+ */
public static final int FX_FOCUS_NAVIGATION_UP = 1;
/**
* Focuse has moved down
* @see #playSoundEffect(int)
- */
+ */
public static final int FX_FOCUS_NAVIGATION_DOWN = 2;
/**
* Focuse has moved left
* @see #playSoundEffect(int)
- */
+ */
public static final int FX_FOCUS_NAVIGATION_LEFT = 3;
/**
* Focuse has moved right
* @see #playSoundEffect(int)
- */
+ */
public static final int FX_FOCUS_NAVIGATION_RIGHT = 4;
/**
- * @hide Number of sound effects
- */
+ * @hide Number of sound effects
+ */
public static final int NUM_SOUND_EFFECTS = 5;
-
+
/**
* Plays a sound effect (Key clicks, lid open/close...)
* @param effectType The type of sound effect. One of
@@ -951,10 +989,10 @@ public class AudioManager {
private boolean querySoundEffectsEnabled() {
return Settings.System.getInt(mContext.getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED, 0) != 0;
}
-
-
+
+
/**
- * Load Sound effects.
+ * Load Sound effects.
* This method must be called when sound effects are enabled.
*/
public void loadSoundEffects() {
@@ -965,9 +1003,9 @@ public class AudioManager {
Log.e(TAG, "Dead object in loadSoundEffects"+e);
}
}
-
+
/**
- * Unload Sound effects.
+ * Unload Sound effects.
* This method can be called to free some memory when
* sound effects are disabled.
*/
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 7912003b..1314ba1 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -34,11 +34,14 @@ import android.util.Log;
* to record audio from the audio input hardware of the platform. This is
* achieved by "pulling" (reading) the data from the AudioRecord object. The
* application is responsible for polling the AudioRecord object in time using one of
- * the following three methods: {@link #read(byte[], int)}, {@link #read(short[], int)}
+ * the following three methods: {@link #read(byte[],int, int)}, {@link #read(short[], int, int)}
* or {@link #read(ByteBuffer, int)}. The choice of which method to use will be based
* on the audio data storage format that is the most convenient for the user of AudioRecord.
- *
- * {@hide Pending API council review}
+ * <p>Upon creation, an AudioRecord object initializes its associated audio buffer that it will
+ * fill with the new audio data. The size of this buffer, specified during the construction,
+ * determines how long an AudioRecord can record before "over-running" data that has not
+ * been read yet. Data should be from the audio hardware in chunks of sizes inferior to
+ * the total recording buffer size.
*/
public class AudioRecord
{
@@ -82,22 +85,22 @@ public class AudioRecord
*/
public static final int ERROR_INVALID_OPERATION = -3;
- private static final int AUDIORECORD_ERROR_SETUP_ZEROFRAMECOUNT = -4;
- private static final int AUDIORECORD_ERROR_SETUP_INVALIDCHANNELCOUNT = -5;
- private static final int AUDIORECORD_ERROR_SETUP_INVALIDFORMAT = -6;
- private static final int AUDIORECORD_ERROR_SETUP_INVALIDSTREAMTYPE = -7;
- private static final int AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED = -8;
+ private static final int AUDIORECORD_ERROR_SETUP_ZEROFRAMECOUNT = -16;
+ private static final int AUDIORECORD_ERROR_SETUP_INVALIDCHANNELCOUNT = -17;
+ private static final int AUDIORECORD_ERROR_SETUP_INVALIDFORMAT = -18;
+ private static final int AUDIORECORD_ERROR_SETUP_INVALIDSTREAMTYPE = -19;
+ private static final int AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED = -20;
// Events:
// to keep in sync with frameworks/base/include/media/AudioRecord.h
/**
* Event id for when the recording head has reached a previously set marker.
*/
- protected static final int EVENT_MARKER = 2;
+ private static final int NATIVE_EVENT_MARKER = 2;
/**
* Event id for when the previously set update period has passed during recording.
*/
- protected static final int EVENT_NEW_POS = 3;
+ private static final int NATIVE_EVENT_NEW_POS = 3;
private final static String TAG = "AudioRecord-Java";
@@ -130,63 +133,63 @@ public class AudioRecord
/**
* The audio data sampling rate in Hz.
*/
- protected int mSampleRate = 22050;
+ private int mSampleRate = 22050;
/**
* The number of input audio channels (1 is mono, 2 is stereo)
*/
- protected int mChannelCount = 1;
+ private int mChannelCount = 1;
/**
* The current audio channel configuration
*/
- protected int mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
+ private int mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
/**
* The encoding of the audio samples.
- * @see #AudioFormat.ENCODING_PCM_8BIT
- * @see #AudioFormat.ENCODING_PCM_16BIT
+ * @see AudioFormat#ENCODING_PCM_8BIT
+ * @see AudioFormat#ENCODING_PCM_16BIT
*/
- protected int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+ private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
/**
* Where the audio data is recorded from.
*/
- protected int mRecordSource = MediaRecorder.AudioSource.DEFAULT;
+ private int mRecordSource = MediaRecorder.AudioSource.DEFAULT;
/**
* Indicates the state of the AudioRecord instance.
*/
- protected int mState = STATE_UNINITIALIZED;
+ private int mState = STATE_UNINITIALIZED;
/**
* Indicates the recording state of the AudioRecord instance.
*/
- protected int mRecordingState = RECORDSTATE_STOPPED;
+ private int mRecordingState = RECORDSTATE_STOPPED;
/**
* Lock to make sure mRecordingState updates are reflecting the actual state of the object.
*/
- protected Object mRecordingStateLock = new Object();
+ private Object mRecordingStateLock = new Object();
/**
* The listener the AudioRecord notifies when a previously set marker is reached.
* @see #setMarkerReachedListener(OnMarkerReachedListener)
*/
- protected OnMarkerReachedListener mMarkerListener = null;
+ private OnMarkerReachedListener mMarkerListener = null;
/**
* Lock to protect marker listener updates against event notifications
*/
- protected final Object mMarkerListenerLock = new Object();
+ private final Object mMarkerListenerLock = new Object();
/**
* The listener the AudioRecord notifies periodically during recording.
* @see #setPeriodicNotificationListener(OnPeriodicNotificationListener)
*/
- protected OnPeriodicNotificationListener mPeriodicListener = null;
+ private OnPeriodicNotificationListener mPeriodicListener = null;
/**
* Lock to protect periodic listener updates against event notifications
*/
- protected final Object mPeriodicListenerLock = new Object();
+ private final Object mPeriodicListenerLock = new Object();
/**
* Handler for events coming from the native code
*/
- protected NativeEventHandler mNativeEventHandler = null;
+ private NativeEventHandler mNativeEventHandler = null;
/**
* Size of the native audio buffer.
*/
- protected int mNativeBufferSizeInBytes = 0;
+ private int mNativeBufferSizeInBytes = 0;
//---------------------------------------------------------
@@ -194,30 +197,30 @@ public class AudioRecord
//--------------------
/**
* Class constructor.
- * @param audioSource the recording source. See {@link MediaRecorder.AudioSource.DEFAULT}
- * and {@link MediaRecorder.AudioSource.MIC}.
+ * @param audioSource the recording source. See {@link MediaRecorder.AudioSource} for
+ * recording source definitions.
* @param sampleRateInHz the sample rate expressed in Hertz. Examples of rates are (but
* not limited to) 44100, 22050 and 11025.
* @param channelConfig describes the configuration of the audio channels.
- * See {@link AudioFormat.CHANNEL_CONFIGURATION_MONO} and
- * {@link AudioFormat.CHANNEL_CONFIGURATION_STEREO}
+ * See {@link AudioFormat#CHANNEL_CONFIGURATION_MONO} and
+ * {@link AudioFormat#CHANNEL_CONFIGURATION_STEREO}
* @param audioFormat the format in which the audio data is represented.
- * See {@link AudioFormat.ENCODING_PCM_16BIT} and
- * {@link AudioFormat.ENCODING_PCM_8BIT}
+ * See {@link AudioFormat#ENCODING_PCM_16BIT} and
+ * {@link AudioFormat#ENCODING_PCM_8BIT}
* @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is written
* to during the recording. New audio data can be read from this buffer in smaller chunks
* than this size.
* @throws java.lang.IllegalArgumentException
*/
public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat,
- int blockSizeInBytes)
+ int bufferSizeInBytes)
throws IllegalArgumentException {
mState = STATE_UNINITIALIZED;
mRecordingState = RECORDSTATE_STOPPED;
audioParamCheck(audioSource, sampleRateInHz, channelConfig, audioFormat);
- audioBuffSizeCheck(blockSizeInBytes);
+ audioBuffSizeCheck(bufferSizeInBytes);
// native initialization
//TODO: update native initialization when information about hardware init failure
@@ -367,8 +370,8 @@ public class AudioRecord
}
/**
- * Returns the configured audio data format. See {@link #AudioFormat.ENCODING_PCM_16BIT}
- * and {@link #AudioFormat.ENCODING_PCM_8BIT}.
+ * Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_16BIT}
+ * and {@link AudioFormat#ENCODING_PCM_8BIT}.
*/
public int getAudioFormat() {
return mAudioFormat;
@@ -376,8 +379,8 @@ public class AudioRecord
/**
* Returns the configured channel configuration.
- * See {@link #AudioFormat.CHANNEL_CONFIGURATION_MONO}
- * and {@link #AudioFormat.CHANNEL_CONFIGURATION_STEREO}.
+ * See {@link AudioFormat#CHANNEL_CONFIGURATION_MONO}
+ * and {@link AudioFormat#CHANNEL_CONFIGURATION_STEREO}.
*/
public int getChannelConfiguration() {
return mChannelConfiguration;
@@ -395,8 +398,8 @@ public class AudioRecord
* AudioRecord instance has been created to check if it was initialized
* properly. This ensures that the appropriate hardware resources have been
* acquired.
- * @see AudioRecord.STATE_INITIALIZED
- * @see AudioRecord.STATE_UNINITIALIZED
+ * @see AudioRecord#STATE_INITIALIZED
+ * @see AudioRecord#STATE_UNINITIALIZED
*/
public int getState() {
return mState;
@@ -404,8 +407,8 @@ public class AudioRecord
/**
* Returns the recording state of the AudioRecord instance.
- * @see AudioRecord.RECORDSTATE_STOPPED
- * @see AudioRecord.RECORDSTATE_RECORDING
+ * @see AudioRecord#RECORDSTATE_STOPPED
+ * @see AudioRecord#RECORDSTATE_RECORDING
*/
public int getRecordingState() {
return mRecordingState;
@@ -472,16 +475,15 @@ public class AudioRecord
//--------------------
/**
* Reads audio data from the audio hardware for recording into a buffer.
- * @throws IllegalStateException
* @param audioData the array to which the recorded audio data is written.
* @param offsetInBytes index in audioData from which the data is written.
* @param sizeInBytes the number of requested bytes.
- * @return the number of bytes that were read. This will not exceed sizeInBytes
+ * @return the number of bytes that were read or -1 if the object wasn't properly
+ * initialized. The number of bytes will not exceed sizeInBytes.
*/
- public int read(byte[] audioData, int offsetInBytes, int sizeInBytes)
- throws IllegalStateException {
+ public int read(byte[] audioData, int offsetInBytes, int sizeInBytes) {
if (mState != STATE_INITIALIZED) {
- throw(new IllegalStateException("read() called on uninitialized AudioRecord."));
+ return -1;
}
return native_read_in_byte_array(audioData, offsetInBytes, sizeInBytes);
@@ -490,16 +492,15 @@ public class AudioRecord
/**
* Reads audio data from the audio hardware for recording into a buffer.
- * @throws IllegalStateException
* @param audioData the array to which the recorded audio data is written.
* @param offsetInShorts index in audioData from which the data is written.
* @param sizeInShorts the number of requested shorts.
- * @return the number of shorts that were read. This will not exceed sizeInShorts
+ * @return the number of shorts that were read. or -1 if the object wasn't properly
+ * initialized. The number of shorts will not exceed sizeInShorts
*/
- public int read(short[] audioData, int offsetInShorts, int sizeInShorts)
- throws IllegalStateException {
+ public int read(short[] audioData, int offsetInShorts, int sizeInShorts) {
if (mState != STATE_INITIALIZED) {
- throw(new IllegalStateException("read() called on uninitialized AudioRecord."));
+ return -1;
}
return native_read_in_short_array(audioData, offsetInShorts, sizeInShorts);
@@ -509,15 +510,14 @@ public class AudioRecord
/**
* Reads audio data from the audio hardware for recording into a direct buffer. If this buffer
* is not a direct buffer, this method will always return 0.
- * @throws IllegalStateException
* @param audioBuffer the direct buffer to which the recorded audio data is written.
* @param sizeInBytes the number of requested bytes.
- * @return the number of bytes that were read. This will not exceed sizeInBytes.
+ * @return the number of bytes that were read or -1 if the object wasn't properly
+ * initialized. The number of bytes will not exceed sizeInBytes.
*/
- public int read(ByteBuffer audioBuffer, int sizeInBytes)
- throws IllegalStateException {
+ public int read(ByteBuffer audioBuffer, int sizeInBytes) {
if (mState != STATE_INITIALIZED) {
- throw(new IllegalStateException("read() called on uninitialized AudioRecord."));
+ return -1;
}
return native_read_in_direct_buffer(audioBuffer, sizeInBytes);
@@ -590,7 +590,7 @@ public class AudioRecord
* Called on the listener to notify it that the previously set marker has been reached
* by the recording head.
*/
- void onMarkerReached(AudioRecord track);
+ void onMarkerReached(AudioRecord recorder);
}
@@ -603,7 +603,7 @@ public class AudioRecord
* Called on the listener to periodically notify it that the recording head has reached
* a multiple of the notification period.
*/
- void onPeriodicNotification(AudioRecord track);
+ void onPeriodicNotification(AudioRecord recorder);
}
@@ -628,14 +628,14 @@ public class AudioRecord
return;
}
switch(msg.what) {
- case EVENT_MARKER:
+ case NATIVE_EVENT_MARKER:
synchronized (mMarkerListenerLock) {
if (mAudioRecord.mMarkerListener != null) {
mAudioRecord.mMarkerListener.onMarkerReached(mAudioRecord);
}
}
break;
- case EVENT_NEW_POS:
+ case NATIVE_EVENT_NEW_POS:
synchronized (mPeriodicListenerLock) {
if (mAudioRecord.mPeriodicListener != null) {
mAudioRecord.mPeriodicListener.onPeriodicNotification(mAudioRecord);
@@ -643,7 +643,7 @@ public class AudioRecord
}
break;
default:
- Log.e(TAG, "[ android.media.AudioTrack.NativeEventHandler ] " +
+ Log.e(TAG, "[ android.media.AudioRecord.NativeEventHandler ] " +
"Unknown event type: " + msg.what);
break;
}
@@ -658,14 +658,14 @@ public class AudioRecord
private static void postEventFromNative(Object audiorecord_ref,
int what, int arg1, int arg2, Object obj) {
//logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2);
- AudioRecord track = (AudioRecord)((WeakReference)audiorecord_ref).get();
- if (track == null) {
+ AudioRecord recorder = (AudioRecord)((WeakReference)audiorecord_ref).get();
+ if (recorder == null) {
return;
}
- if (track.mNativeEventHandler != null) {
- Message m = track.mNativeEventHandler.obtainMessage(what, arg1, arg2, obj);
- track.mNativeEventHandler.sendMessage(m);
+ if (recorder.mNativeEventHandler != null) {
+ Message m = recorder.mNativeEventHandler.obtainMessage(what, arg1, arg2, obj);
+ recorder.mNativeEventHandler.sendMessage(m);
}
}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index b39e7bb..f3d8957 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -16,8 +16,7 @@
package android.media;
-import com.android.internal.telephony.ITelephony;
-
+import android.app.ActivityManagerNative;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@@ -32,11 +31,13 @@ import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.provider.Settings.System;
import android.provider.Settings;
+import android.provider.Settings.System;
import android.util.Log;
import android.view.VolumePanel;
+import com.android.internal.telephony.ITelephony;
+
import java.io.IOException;
import java.util.ArrayList;
@@ -50,19 +51,19 @@ import java.util.ArrayList;
* volume and later persist to the database. Similarly, setting the ringer mode
* will update the state and broadcast a change and in a separate thread later
* persist the ringer mode.
- *
+ *
* @hide
*/
public class AudioService extends IAudioService.Stub {
-
+
private static final String TAG = "AudioService";
/** How long to delay before persisting a change in volume/ringer mode. */
private static final int PERSIST_DELAY = 3000;
-
+
private Context mContext;
private ContentResolver mContentResolver;
-
+
/** The UI */
private VolumePanel mVolumePanel;
@@ -75,7 +76,7 @@ public class AudioService extends IAudioService.Stub {
private static final int SENDMSG_NOOP = 1;
/** If the msg is already queued, queue this one and leave the old. */
private static final int SENDMSG_QUEUE = 2;
-
+
// AudioHandler message.whats
private static final int MSG_SET_SYSTEM_VOLUME = 0;
private static final int MSG_PERSIST_VOLUME = 1;
@@ -91,18 +92,18 @@ public class AudioService extends IAudioService.Stub {
private AudioHandler mAudioHandler;
/** @see VolumeStreamState */
private VolumeStreamState[] mStreamStates;
-
+
private boolean mMicMute;
private int mMode;
private int[] mRoutes = new int[AudioSystem.NUM_MODES];
private Object mSettingsLock = new Object();
private boolean mMediaServerOk;
-
+
private SoundPool mSoundPool;
private Object mSoundEffectsLock = new Object();
private static final int NUM_SOUNDPOOL_CHANNELS = 4;
private static final float SOUND_EFFECT_VOLUME = 1.0f;
-
+
/* Sound effect file names */
private static final String SOUND_EFFECTS_PATH = "/media/audio/ui/";
private static final String[] SOUND_EFFECT_FILES = new String[] {
@@ -119,7 +120,7 @@ public class AudioService extends IAudioService.Stub {
{0, -1}, // FX_FOCUS_NAVIGATION_LEFT
{0, -1} // FX_FOCUS_NAVIGATION_RIGHT
};
-
+
private AudioSystem.ErrorCallback mAudioSystemCallback = new AudioSystem.ErrorCallback() {
public void onError(int error) {
switch (error) {
@@ -145,7 +146,7 @@ public class AudioService extends IAudioService.Stub {
* Current ringer mode from one of {@link AudioManager#RINGER_MODE_NORMAL},
* {@link AudioManager#RINGER_MODE_SILENT}, or
* {@link AudioManager#RINGER_MODE_VIBRATE}.
- */
+ */
private int mRingerMode;
/** @see System#MODE_RINGER_STREAMS_AFFECTED */
@@ -153,7 +154,7 @@ public class AudioService extends IAudioService.Stub {
/** @see System#MUTE_STREAMS_AFFECTED */
private int mMuteAffectedStreams;
-
+
/**
* Has multiple bits per vibrate type to indicate the type's vibrate
* setting. See {@link #setVibrateSetting(int, int)}.
@@ -162,23 +163,23 @@ public class AudioService extends IAudioService.Stub {
* type since it depends on the ringer mode. See {@link #shouldVibrate(int)}.
*/
private int mVibrateSetting;
-
+
///////////////////////////////////////////////////////////////////////////
// Construction
///////////////////////////////////////////////////////////////////////////
-
+
/** @hide */
public AudioService(Context context) {
mContext = context;
mContentResolver = context.getContentResolver();
mVolumePanel = new VolumePanel(context, this);
-
+
createAudioSystemThread();
createStreamStates();
readPersistedSettings();
readAudioSettings();
mMediaServerOk = true;
- AudioSystem.setErrorCallback(mAudioSystemCallback);
+ AudioSystem.setErrorCallback(mAudioSystemCallback);
if (Settings.System.getInt(mContentResolver, Settings.System.SOUND_EFFECTS_ENABLED, 0) == 1) {
loadSoundEffects();
}
@@ -189,8 +190,8 @@ public class AudioService extends IAudioService.Stub {
mAudioSystemThread.start();
waitForAudioHandlerCreation();
}
-
- /** Waits for the volume handler to be created by the other thread. */
+
+ /** Waits for the volume handler to be created by the other thread. */
private void waitForAudioHandlerCreation() {
synchronized(this) {
while (mAudioHandler == null) {
@@ -203,37 +204,51 @@ public class AudioService extends IAudioService.Stub {
}
}
}
-
+
private void createStreamStates() {
- final int[] volumeLevelsPhone = createVolumeLevels(0, AudioManager.MAX_STREAM_VOLUME[AudioManager.STREAM_VOICE_CALL]);
- final int[] volumeLevelsCoarse = createVolumeLevels(0, AudioManager.MAX_STREAM_VOLUME[AudioManager.STREAM_SYSTEM]);
- final int[] volumeLevelsFine = createVolumeLevels(0, AudioManager.MAX_STREAM_VOLUME[AudioManager.STREAM_MUSIC]);
-
+ final int[] volumeLevelsPhone =
+ createVolumeLevels(0, AudioManager.MAX_STREAM_VOLUME[AudioManager.STREAM_VOICE_CALL]);
+ final int[] volumeLevelsCoarse =
+ createVolumeLevels(0, AudioManager.MAX_STREAM_VOLUME[AudioManager.STREAM_SYSTEM]);
+ final int[] volumeLevelsFine =
+ createVolumeLevels(0, AudioManager.MAX_STREAM_VOLUME[AudioManager.STREAM_MUSIC]);
+ final int[] volumeLevelsBtPhone =
+ createVolumeLevels(0,
+ AudioManager.MAX_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]);
+
int numStreamTypes = AudioSystem.getNumStreamTypes();
VolumeStreamState[] streams = mStreamStates = new VolumeStreamState[numStreamTypes];
-
+
for (int i = 0; i < numStreamTypes; i++) {
final int[] levels;
-
+
switch (i) {
-
+
case AudioSystem.STREAM_MUSIC:
levels = volumeLevelsFine;
break;
-
+
case AudioSystem.STREAM_VOICE_CALL:
levels = volumeLevelsPhone;
break;
-
+
+ case AudioSystem.STREAM_BLUETOOTH_SCO:
+ levels = volumeLevelsBtPhone;
+ break;
+
default:
levels = volumeLevelsCoarse;
break;
}
-
- streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS[i], i, levels);
+
+ if (i == AudioSystem.STREAM_BLUETOOTH_SCO) {
+ streams[i] = new VolumeStreamState(AudioManager.DEFAULT_STREAM_VOLUME[i], i,levels);
+ } else {
+ streams[i] = new VolumeStreamState(System.VOLUME_SETTINGS[i], i, levels);
+ }
}
}
-
+
private static int[] createVolumeLevels(int offset, int numlevels) {
double curve = 1.0f; // 1.4f
int [] volumes = new int[numlevels + offset];
@@ -249,7 +264,7 @@ public class AudioService extends IAudioService.Stub {
}
return volumes;
}
-
+
private void readPersistedSettings() {
final ContentResolver cr = mContentResolver;
@@ -260,19 +275,19 @@ public class AudioService extends IAudioService.Stub {
mVibrateSetting = System.getInt(cr, System.VIBRATE_ON, 0);
mMuteAffectedStreams = System.getInt(cr,
- System.MUTE_STREAMS_AFFECTED,
+ System.MUTE_STREAMS_AFFECTED,
((1 << AudioSystem.STREAM_MUSIC)|(1 << AudioSystem.STREAM_RING)|(1 << AudioSystem.STREAM_SYSTEM)));
-
+
// Each stream will read its own persisted settings
-
+
// Broadcast the sticky intent
broadcastRingerMode();
-
+
// Broadcast vibrate settings
broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER);
broadcastVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION);
}
-
+
private void readAudioSettings() {
synchronized (mSettingsLock) {
mMicMute = AudioSystem.isMicrophoneMuted();
@@ -282,7 +297,7 @@ public class AudioService extends IAudioService.Stub {
}
}
}
-
+
private void applyAudioSettings() {
synchronized (mSettingsLock) {
AudioSystem.muteMicrophone(mMicMute);
@@ -291,46 +306,46 @@ public class AudioService extends IAudioService.Stub {
AudioSystem.setRouting(mode, mRoutes[mode], AudioSystem.ROUTE_ALL);
}
}
- }
-
+ }
+
///////////////////////////////////////////////////////////////////////////
// IPC methods
///////////////////////////////////////////////////////////////////////////
-
+
/** @see AudioManager#adjustVolume(int, int) */
public void adjustVolume(int direction, int flags) {
adjustSuggestedStreamVolume(direction, AudioManager.USE_DEFAULT_STREAM_TYPE, flags);
}
-
+
/** @see AudioManager#adjustVolume(int, int, int) */
public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) {
int streamType = getActiveStreamType(suggestedStreamType);
-
+
// Don't play sound on other streams
if (streamType != AudioSystem.STREAM_RING && (flags & AudioManager.FLAG_PLAY_SOUND) != 0) {
flags &= ~AudioManager.FLAG_PLAY_SOUND;
}
-
+
adjustStreamVolume(streamType, direction, flags);
}
-
+
/** @see AudioManager#adjustStreamVolume(int, int, int) */
public void adjustStreamVolume(int streamType, int direction, int flags) {
ensureValidDirection(direction);
ensureValidStreamType(streamType);
-
+
boolean notificationsUseRingVolume = Settings.System.getInt(mContentResolver,
Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1) == 1;
if (notificationsUseRingVolume && streamType == AudioManager.STREAM_NOTIFICATION) {
// Redirect the volume change to the ring stream
streamType = AudioManager.STREAM_RING;
}
-
+
VolumeStreamState streamState = mStreamStates[streamType];
- final int oldIndex = streamState.mIndex;
+ final int oldIndex = streamState.mIndex;
boolean adjustVolume = true;
-
+
// If either the client forces allowing ringer modes for this adjustment,
// or the stream type is one that is affected by ringer modes
if ((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0
@@ -339,21 +354,21 @@ public class AudioService extends IAudioService.Stub {
// it does, it will handle adjusting the volome, so we won't below
adjustVolume = checkForRingerModeChange(oldIndex, direction);
}
-
+
if (adjustVolume && streamState.adjustIndex(direction)) {
-
+
boolean alsoUpdateNotificationVolume = notificationsUseRingVolume &&
streamType == AudioManager.STREAM_RING;
if (alsoUpdateNotificationVolume) {
mStreamStates[AudioManager.STREAM_NOTIFICATION].adjustIndex(direction);
}
-
+
// Post message to set system volume (it in turn will post a message
// to persist). Do not change volume if stream is muted.
if (streamState.muteCount() == 0) {
sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, streamType, SENDMSG_NOOP, 0, 0,
streamState, 0);
-
+
if (alsoUpdateNotificationVolume) {
sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, AudioManager.STREAM_NOTIFICATION,
SENDMSG_NOOP, 0, 0, mStreamStates[AudioManager.STREAM_NOTIFICATION], 0);
@@ -363,12 +378,44 @@ public class AudioService extends IAudioService.Stub {
// UI
mVolumePanel.postVolumeChanged(streamType, flags);
+ // Broadcast Intent
+ sendVolumeUpdate(streamType);
}
/** @see AudioManager#setStreamVolume(int, int, int) */
public void setStreamVolume(int streamType, int index, int flags) {
ensureValidStreamType(streamType);
-
+ syncRingerAndNotificationStreamVolume(streamType, index, false);
+
+ setStreamVolumeInt(streamType, index, false);
+
+ // UI, etc.
+ mVolumePanel.postVolumeChanged(streamType, flags);
+ // Broadcast Intent
+ sendVolumeUpdate(streamType);
+ }
+
+ private void sendVolumeUpdate(int streamType) {
+ Intent intent = new Intent(AudioManager.VOLUME_CHANGED_ACTION);
+ intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType);
+ intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, getStreamVolume(streamType));
+
+ // Currently, sending the intent only when the stream is BLUETOOTH_SCO
+ if (streamType == AudioManager.STREAM_BLUETOOTH_SCO) {
+ mContext.sendBroadcast(intent);
+ }
+ }
+
+ /**
+ * Sync the STREAM_RING and STREAM_NOTIFICATION volumes if mandated by the
+ * value in Settings.
+ *
+ * @param streamType Type of the stream
+ * @param index Volume index for the stream
+ * @param force If true, set the volume even if the current and desired
+ * volume as same
+ */
+ private void syncRingerAndNotificationStreamVolume(int streamType, int index, boolean force) {
boolean notificationsUseRingVolume = Settings.System.getInt(mContentResolver,
Settings.System.NOTIFICATIONS_USE_RING_VOLUME, 1) == 1;
if (notificationsUseRingVolume) {
@@ -378,23 +425,24 @@ public class AudioService extends IAudioService.Stub {
}
if (streamType == AudioManager.STREAM_RING) {
// One-off to sync notification volume to ringer volume
- setStreamVolumeInt(AudioManager.STREAM_NOTIFICATION, index);
+ setStreamVolumeInt(AudioManager.STREAM_NOTIFICATION, index, force);
}
}
-
- setStreamVolumeInt(streamType, index);
-
- // UI, etc.
- mVolumePanel.postVolumeChanged(streamType, flags);
}
+
/**
* Sets the stream state's index, and posts a message to set system volume.
* This will not call out to the UI. Assumes a valid stream type.
+ *
+ * @param streamType Type of the stream
+ * @param index Desired volume index of the stream
+ * @param force If true, set the volume even if the desired volume is same
+ * as the current volume.
*/
- private void setStreamVolumeInt(int streamType, int index) {
+ private void setStreamVolumeInt(int streamType, int index, boolean force) {
VolumeStreamState streamState = mStreamStates[streamType];
- if (streamState.setIndex(index)) {
+ if (streamState.setIndex(index) || force) {
// Post message to set system volume (it in turn will post a message
// to persist). Do not change volume if stream is muted.
if (streamState.muteCount() == 0) {
@@ -403,7 +451,7 @@ public class AudioService extends IAudioService.Stub {
}
}
}
-
+
/** @see AudioManager#setStreamSolo(int, boolean) */
public void setStreamSolo(int streamType, boolean state, IBinder cb) {
for (int stream = 0; stream < mStreamStates.length; stream++) {
@@ -412,7 +460,7 @@ public class AudioService extends IAudioService.Stub {
mStreamStates[stream].mute(cb, state);
}
}
-
+
/** @see AudioManager#setStreamMute(int, boolean) */
public void setStreamMute(int streamType, boolean state, IBinder cb) {
if (isStreamAffectedByMute(streamType)) {
@@ -441,32 +489,33 @@ public class AudioService extends IAudioService.Stub {
public void setRingerMode(int ringerMode) {
if (ringerMode != mRingerMode) {
mRingerMode = ringerMode;
-
+
// Adjust volumes via posting message
int numStreamTypes = AudioSystem.getNumStreamTypes();
if (mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
if (!isStreamAffectedByRingerMode(streamType)) continue;
// Bring back last audible volume
- setStreamVolumeInt(streamType, mStreamStates[streamType].mLastAudibleIndex);
+ setStreamVolumeInt(streamType, mStreamStates[streamType].mLastAudibleIndex,
+ false);
}
} else {
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
if (!isStreamAffectedByRingerMode(streamType)) continue;
// Either silent or vibrate, either way volume is 0
- setStreamVolumeInt(streamType, 0);
+ setStreamVolumeInt(streamType, 0, false);
}
}
-
+
// Send sticky broadcast
broadcastRingerMode();
-
+
// Post a persist ringer mode msg
sendMsg(mAudioHandler, MSG_PERSIST_RINGER_MODE, SHARED_MSG,
SENDMSG_REPLACE, 0, 0, null, PERSIST_DELAY);
}
}
-
+
/** @see AudioManager#shouldVibrate(int) */
public boolean shouldVibrate(int vibrateType) {
@@ -474,21 +523,21 @@ public class AudioService extends IAudioService.Stub {
case AudioManager.VIBRATE_SETTING_ON:
return mRingerMode != AudioManager.RINGER_MODE_SILENT;
-
+
case AudioManager.VIBRATE_SETTING_ONLY_SILENT:
return mRingerMode == AudioManager.RINGER_MODE_VIBRATE;
-
+
case AudioManager.VIBRATE_SETTING_OFF:
- // Phone ringer should always vibrate in vibrate mode
+ // Phone ringer should always vibrate in vibrate mode
if (vibrateType == AudioManager.VIBRATE_TYPE_RINGER) {
return mRingerMode == AudioManager.RINGER_MODE_VIBRATE;
}
-
+
default:
return false;
}
}
-
+
/** @see AudioManager#getVibrateSetting(int) */
public int getVibrateSetting(int vibrateType) {
return (mVibrateSetting >> (vibrateType * 2)) & 3;
@@ -498,10 +547,10 @@ public class AudioService extends IAudioService.Stub {
public void setVibrateSetting(int vibrateType, int vibrateSetting) {
mVibrateSetting = getValueForVibrateSetting(mVibrateSetting, vibrateType, vibrateSetting);
-
+
// Broadcast change
broadcastVibrateSetting(vibrateType);
-
+
// Post message to set ringer mode (it in turn will post a message
// to persist)
sendMsg(mAudioHandler, MSG_PERSIST_VIBRATE_SETTING, SHARED_MSG, SENDMSG_NOOP, 0, 0,
@@ -518,13 +567,13 @@ public class AudioService extends IAudioService.Stub {
// First clear the existing setting. Each vibrate type has two bits in
// the value. Note '3' is '11' in binary.
existingValue &= ~(3 << (vibrateType * 2));
-
+
// Set into the old value
existingValue |= (vibrateSetting & 3) << (vibrateType * 2);
-
+
return existingValue;
}
-
+
/** @see AudioManager#setMicrophoneMute(boolean) */
public void setMicrophoneMute(boolean on) {
if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
@@ -534,15 +583,15 @@ public class AudioService extends IAudioService.Stub {
if (on != mMicMute) {
AudioSystem.muteMicrophone(on);
mMicMute = on;
- }
+ }
}
}
-
+
/** @see AudioManager#isMicrophoneMute() */
public boolean isMicrophoneMute() {
return mMicMute;
}
-
+
/** @see AudioManager#setMode(int) */
public void setMode(int mode) {
if (!checkAudioSettingsPermission("setMode()")) {
@@ -552,15 +601,19 @@ public class AudioService extends IAudioService.Stub {
if (mode != mMode) {
AudioSystem.setMode(mode);
mMode = mode;
- }
+ }
+ int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
+ int index = mStreamStates[streamType].mIndex;
+ syncRingerAndNotificationStreamVolume(streamType, index, true);
+ setStreamVolumeInt(streamType, index, true);
}
}
-
+
/** @see AudioManager#getMode() */
public int getMode() {
return mMode;
}
-
+
/** @see AudioManager#setRouting(int, int, int) */
public void setRouting(int mode, int routes, int mask) {
if (!checkAudioSettingsPermission("setRouting()")) {
@@ -570,10 +623,14 @@ public class AudioService extends IAudioService.Stub {
if ((mRoutes[mode] & mask) != (routes & mask)) {
AudioSystem.setRouting(mode, routes, mask);
mRoutes[mode] = (mRoutes[mode] & ~mask) | (routes & mask);
- }
+ }
+ int streamType = getActiveStreamType(AudioManager.USE_DEFAULT_STREAM_TYPE);
+ int index = mStreamStates[streamType].mIndex;
+ syncRingerAndNotificationStreamVolume(streamType, index, true);
+ setStreamVolumeInt(streamType, index, true);
}
}
-
+
/** @see AudioManager#getRouting(int) */
public int getRouting(int mode) {
return mRoutes[mode];
@@ -583,7 +640,7 @@ public class AudioService extends IAudioService.Stub {
public boolean isMusicActive() {
return AudioSystem.isMusicActive();
}
-
+
/** @see AudioManager#setParameter(String, String) */
public void setParameter(String key, String value) {
AudioSystem.setParameter(key, value);
@@ -596,8 +653,8 @@ public class AudioService extends IAudioService.Stub {
}
/**
- * Loads samples into the soundpool.
- * This method must be called at when sound effects are enabled
+ * Loads samples into the soundpool.
+ * This method must be called at when sound effects are enabled
*/
public boolean loadSoundEffects() {
synchronized (mSoundEffectsLock) {
@@ -605,17 +662,17 @@ public class AudioService extends IAudioService.Stub {
if (mSoundPool == null) {
return false;
}
- /*
- * poolId table: The value -1 in this table indicates that corresponding
- * file (same index in SOUND_EFFECT_FILES[] has not been loaded.
- * Once loaded, the value in poolId is the sample ID and the same
+ /*
+ * poolId table: The value -1 in this table indicates that corresponding
+ * file (same index in SOUND_EFFECT_FILES[] has not been loaded.
+ * Once loaded, the value in poolId is the sample ID and the same
* sample can be reused for another effect using the same file.
- */
+ */
int[] poolId = new int[SOUND_EFFECT_FILES.length];
for (int fileIdx = 0; fileIdx < SOUND_EFFECT_FILES.length; fileIdx++) {
poolId[fileIdx] = -1;
}
- /*
+ /*
* Effects whose value in SOUND_EFFECT_FILES_MAP[effect][1] is -1 must be loaded.
* If load succeeds, value in SOUND_EFFECT_FILES_MAP[effect][1] is > 0:
* this indicates we have a valid sample loaded for this effect.
@@ -638,12 +695,12 @@ public class AudioService extends IAudioService.Stub {
}
}
}
-
+
return true;
}
/**
- * Unloads samples from the sound pool.
+ * Unloads samples from the sound pool.
* This method can be called to free some memory when
* sound effects are disabled.
*/
@@ -665,12 +722,12 @@ public class AudioService extends IAudioService.Stub {
mSoundPool.unload(SOUND_EFFECT_FILES_MAP[effect][1]);
SOUND_EFFECT_FILES_MAP[effect][1] = -1;
poolId[SOUND_EFFECT_FILES_MAP[effect][0]] = -1;
- }
+ }
}
mSoundPool = null;
}
}
-
+
///////////////////////////////////////////////////////////////////////////
// Internal methods
///////////////////////////////////////////////////////////////////////////
@@ -683,7 +740,7 @@ public class AudioService extends IAudioService.Stub {
private boolean checkForRingerModeChange(int oldIndex, int direction) {
boolean adjustVolumeIndex = true;
int newRingerMode = mRingerMode;
-
+
if (mRingerMode == AudioManager.RINGER_MODE_NORMAL && oldIndex == 1
&& direction == AudioManager.ADJUST_LOWER) {
newRingerMode = AudioManager.RINGER_MODE_VIBRATE;
@@ -697,7 +754,7 @@ public class AudioService extends IAudioService.Stub {
&& mRingerMode == AudioManager.RINGER_MODE_SILENT) {
newRingerMode = AudioManager.RINGER_MODE_VIBRATE;
}
-
+
if (newRingerMode != mRingerMode) {
setRingerMode(newRingerMode);
@@ -708,18 +765,18 @@ public class AudioService extends IAudioService.Stub {
*/
adjustVolumeIndex = false;
}
-
+
return adjustVolumeIndex;
}
-
+
public boolean isStreamAffectedByRingerMode(int streamType) {
- return (mRingerModeAffectedStreams & (1 << streamType)) != 0;
+ return (mRingerModeAffectedStreams & (1 << streamType)) != 0;
}
-
+
public boolean isStreamAffectedByMute(int streamType) {
return (mMuteAffectedStreams & (1 << streamType)) != 0;
}
-
+
private void ensureValidDirection(int direction) {
if (direction < AudioManager.ADJUST_LOWER || direction > AudioManager.ADJUST_RAISE) {
throw new IllegalArgumentException("Bad direction " + direction);
@@ -736,13 +793,15 @@ public class AudioService extends IAudioService.Stub {
boolean isOffhook = false;
try {
ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
- isOffhook = phone.isOffhook();
+ if (phone != null) isOffhook = phone.isOffhook();
} catch (RemoteException e) {
Log.w(TAG, "Couldn't connect to phone service", e);
}
- // TODO: applications can influence this
- if (isOffhook) {
+ if ((getRouting(AudioSystem.MODE_IN_CALL) & AudioSystem.ROUTE_BLUETOOTH_SCO) != 0) {
+ // Log.v(TAG, "getActiveStreamType: Forcing STREAM_BLUETOOTH_SCO...");
+ return AudioSystem.STREAM_BLUETOOTH_SCO;
+ } else if (isOffhook) {
// Log.v(TAG, "getActiveStreamType: Forcing STREAM_VOICE_CALL...");
return AudioSystem.STREAM_VOICE_CALL;
} else if (AudioSystem.isMusicActive()) {
@@ -756,29 +815,33 @@ public class AudioService extends IAudioService.Stub {
return suggestedStreamType;
}
}
-
+
private void broadcastRingerMode() {
// Send sticky broadcast
- Intent broadcast = new Intent(AudioManager.RINGER_MODE_CHANGED_ACTION);
- broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, mRingerMode);
- long origCallerIdentityToken = Binder.clearCallingIdentity();
- mContext.sendStickyBroadcast(broadcast);
- Binder.restoreCallingIdentity(origCallerIdentityToken);
+ if (ActivityManagerNative.isSystemReady()) {
+ Intent broadcast = new Intent(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ broadcast.putExtra(AudioManager.EXTRA_RINGER_MODE, mRingerMode);
+ long origCallerIdentityToken = Binder.clearCallingIdentity();
+ mContext.sendStickyBroadcast(broadcast);
+ Binder.restoreCallingIdentity(origCallerIdentityToken);
+ }
}
-
+
private void broadcastVibrateSetting(int vibrateType) {
// Send broadcast
- Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
- broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType);
- broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType));
- mContext.sendBroadcast(broadcast);
+ if (ActivityManagerNative.isSystemReady()) {
+ Intent broadcast = new Intent(AudioManager.VIBRATE_SETTING_CHANGED_ACTION);
+ broadcast.putExtra(AudioManager.EXTRA_VIBRATE_TYPE, vibrateType);
+ broadcast.putExtra(AudioManager.EXTRA_VIBRATE_SETTING, getVibrateSetting(vibrateType));
+ mContext.sendBroadcast(broadcast);
+ }
}
-
+
// Message helper methods
private static int getMsg(int baseMsg, int streamType) {
- return (baseMsg & 0xffff) | streamType << 16;
+ return (baseMsg & 0xffff) | streamType << 16;
}
-
+
private static int getMsgBase(int msg) {
return msg & 0xffff;
}
@@ -792,11 +855,11 @@ public class AudioService extends IAudioService.Stub {
} else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
return;
}
-
+
handler
.sendMessageDelayed(handler.obtainMessage(msg, arg1, arg2, obj), delay);
}
-
+
boolean checkAudioSettingsPermission(String method) {
if (mContext.checkCallingOrSelfPermission("android.permission.MODIFY_AUDIO_SETTINGS")
== PackageManager.PERMISSION_GRANTED) {
@@ -809,29 +872,29 @@ public class AudioService extends IAudioService.Stub {
return false;
}
-
+
///////////////////////////////////////////////////////////////////////////
// Inner classes
///////////////////////////////////////////////////////////////////////////
-
+
public class VolumeStreamState {
private final String mVolumeIndexSettingName;
- private final String mLastAudibleVolumeIndexSettingName;
+ private final String mLastAudibleVolumeIndexSettingName;
private final int mStreamType;
-
+
private final int[] mVolumes;
private int mIndex;
private int mLastAudibleIndex;
private ArrayList<VolumeDeathHandler> mDeathHandlers; //handles mute/solo requests client death
-
+
private VolumeStreamState(String settingName, int streamType, int[] volumes) {
-
+
mVolumeIndexSettingName = settingName;
mLastAudibleVolumeIndexSettingName = settingName + System.APPEND_FOR_LAST_AUDIBLE;
-
+
mStreamType = streamType;
mVolumes = volumes;
-
+
final ContentResolver cr = mContentResolver;
mIndex = getValidIndex(Settings.System.getInt(cr, mVolumeIndexSettingName, AudioManager.DEFAULT_STREAM_VOLUME[streamType]));
mLastAudibleIndex = getValidIndex(Settings.System.getInt(cr,
@@ -841,14 +904,31 @@ public class AudioService extends IAudioService.Stub {
mDeathHandlers = new ArrayList<VolumeDeathHandler>();
}
+ /**
+ * Constructor to be used when there is no setting associated with the VolumeStreamState.
+ *
+ * @param defaultVolume Default volume of the stream to use.
+ * @param streamType Type of the stream.
+ * @param volumes Volumes levels associated with this stream.
+ */
+ private VolumeStreamState(int defaultVolume, int streamType, int[] volumes) {
+ mVolumeIndexSettingName = null;
+ mLastAudibleVolumeIndexSettingName = null;
+ mIndex = mLastAudibleIndex = defaultVolume;
+ mStreamType = streamType;
+ mVolumes = volumes;
+ AudioSystem.setVolume(mStreamType, defaultVolume);
+ mDeathHandlers = new ArrayList<VolumeDeathHandler>();
+ }
+
public boolean adjustIndex(int deltaIndex) {
return setIndex(mIndex + deltaIndex);
}
-
+
public boolean setIndex(int index) {
int oldIndex = mIndex;
mIndex = getValidIndex(index);
-
+
if (oldIndex != mIndex) {
if (mIndex > 0) {
mLastAudibleIndex = mIndex;
@@ -858,11 +938,11 @@ public class AudioService extends IAudioService.Stub {
return false;
}
}
-
+
public int getMaxIndex() {
return mVolumes.length - 1;
}
-
+
public void mute(IBinder cb, boolean state) {
VolumeDeathHandler handler = getDeathHandler(cb, state);
if (handler == null) {
@@ -871,17 +951,17 @@ public class AudioService extends IAudioService.Stub {
}
handler.mute(state);
}
-
+
private int getValidIndex(int index) {
if (index < 0) {
return 0;
} else if (index >= mVolumes.length) {
return mVolumes.length - 1;
}
-
+
return index;
}
-
+
private class VolumeDeathHandler implements IBinder.DeathRecipient {
private IBinder mICallback; // To be notified of client's death
private int mMuteCount; // Number of active mutes for this client
@@ -924,7 +1004,7 @@ public class AudioService extends IAudioService.Stub {
mDeathHandlers.remove(this);
mICallback.unlinkToDeath(this, 0);
if (muteCount() == 0) {
- // If the stream is not mut any more, restore it's volume if
+ // If the stream is not mut any more, restore it's volume if
// ringer mode allows it
if (!isStreamAffectedByRingerMode(mStreamType) || mRingerMode == AudioManager.RINGER_MODE_NORMAL) {
setIndex(mLastAudibleIndex);
@@ -980,59 +1060,59 @@ public class AudioService extends IAudioService.Stub {
}
}
}
-
+
/** Thread that handles native AudioSystem control. */
private class AudioSystemThread extends Thread {
AudioSystemThread() {
super("AudioService");
}
-
+
@Override
public void run() {
// Set this thread up so the handler will work on it
Looper.prepare();
-
+
synchronized(AudioService.this) {
mAudioHandler = new AudioHandler();
// Notify that the handler has been created
AudioService.this.notify();
}
-
+
// Listen for volume change requests that are set by VolumePanel
Looper.loop();
}
}
-
+
/** Handles internal volume messages in separate volume thread. */
private class AudioHandler extends Handler {
-
+
private void setSystemVolume(VolumeStreamState streamState) {
-
+
// Adjust volume
AudioSystem
.setVolume(streamState.mStreamType, streamState.mVolumes[streamState.mIndex]);
-
+
// Post a persist volume msg
sendMsg(mAudioHandler, MSG_PERSIST_VOLUME, streamState.mStreamType,
SENDMSG_REPLACE, 0, 0, streamState, PERSIST_DELAY);
}
-
+
private void persistVolume(VolumeStreamState streamState) {
System.putInt(mContentResolver, streamState.mVolumeIndexSettingName,
streamState.mIndex);
System.putInt(mContentResolver, streamState.mLastAudibleVolumeIndexSettingName,
streamState.mLastAudibleIndex);
}
-
+
private void persistRingerMode() {
System.putInt(mContentResolver, System.MODE_RINGER, mRingerMode);
}
-
+
private void persistVibrateSetting() {
System.putInt(mContentResolver, System.VIBRATE_ON, mVibrateSetting);
}
-
+
private void playSoundEffect(int effectType) {
synchronized (mSoundEffectsLock) {
if (mSoundPool == null) {
@@ -1084,36 +1164,36 @@ public class AudioService extends IAudioService.Stub {
}
}
}
-
+
@Override
public void handleMessage(Message msg) {
int baseMsgWhat = getMsgBase(msg.what);
-
+
switch (baseMsgWhat) {
-
+
case MSG_SET_SYSTEM_VOLUME:
setSystemVolume((VolumeStreamState) msg.obj);
break;
-
+
case MSG_PERSIST_VOLUME:
persistVolume((VolumeStreamState) msg.obj);
break;
-
+
case MSG_PERSIST_RINGER_MODE:
persistRingerMode();
break;
-
+
case MSG_PERSIST_VIBRATE_SETTING:
persistVibrateSetting();
break;
-
+
case MSG_MEDIA_SERVER_DIED:
Log.e(TAG, "Media server died.");
- // Force creation of new IAudioflinger interface
+ // Force creation of new IAudioflinger interface
mMediaServerOk = false;
AudioSystem.getMode();
break;
-
+
case MSG_MEDIA_SERVER_STARTED:
Log.e(TAG, "Media server started.");
// Restore audio routing and stream volumes
@@ -1139,5 +1219,5 @@ public class AudioService extends IAudioService.Stub {
}
}
}
-
+
}
diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java
index 37100677..d0fa795 100644
--- a/media/java/android/media/AudioSystem.java
+++ b/media/java/android/media/AudioSystem.java
@@ -43,15 +43,17 @@ public class AudioSystem
public static final int STREAM_ALARM = 4;
/* The audio stream for notifications */
public static final int STREAM_NOTIFICATION = 5;
+ /* @hide The audio stream for phone calls when connected on bluetooth */
+ public static final int STREAM_BLUETOOTH_SCO = 6;
/**
* @deprecated Use {@link #numStreamTypes() instead}
*/
public static final int NUM_STREAMS = 5;
// Expose only the getter method publicly so we can change it in the future
- private static final int NUM_STREAM_TYPES = 6;
+ private static final int NUM_STREAM_TYPES = 7;
public static final int getNumStreamTypes() { return NUM_STREAM_TYPES; }
-
+
/* max and min volume levels */
/* Maximum volume setting, for use with setVolume(int,int) */
public static final int MAX_VOLUME = 100;
@@ -78,7 +80,7 @@ public class AudioSystem
/*
* Sets the microphone mute on or off.
*
- * param on set <var>true</var> to mute the microphone;
+ * param on set <var>true</var> to mute the microphone;
* <var>false</var> to turn mute off
* return command completion status see AUDIO_STATUS_OK, see AUDIO_STATUS_ERROR
*/
@@ -116,18 +118,18 @@ public class AudioSystem
public static final int MODE_RINGTONE = 1;
public static final int MODE_IN_CALL = 2;
public static final int NUM_MODES = 3;
-
+
/* Routing bits for setRouting/getRouting API */
public static final int ROUTE_EARPIECE = (1 << 0);
public static final int ROUTE_SPEAKER = (1 << 1);
-
- /** @deprecated use {@link #ROUTE_BLUETOOTH_SCO} */
+
+ /** @deprecated use {@link #ROUTE_BLUETOOTH_SCO} */
@Deprecated public static final int ROUTE_BLUETOOTH = (1 << 2);
public static final int ROUTE_BLUETOOTH_SCO = (1 << 2);
public static final int ROUTE_HEADSET = (1 << 3);
public static final int ROUTE_BLUETOOTH_A2DP = (1 << 4);
- public static final int ROUTE_ALL = 0xFFFFFFFF;
+ public static final int ROUTE_ALL = 0xFFFFFFFF;
/*
* Sets the audio routing for a specified mode
@@ -185,7 +187,7 @@ public class AudioSystem
public static final int AUDIO_STATUS_ERROR = 1;
/* Media server died. see ErrorCallback */
public static final int AUDIO_STATUS_SERVER_DIED = 100;
-
+
private static ErrorCallback mErrorCallback;
/*
@@ -211,7 +213,7 @@ public class AudioSystem
{
mErrorCallback = cb;
}
-
+
private static void errorCallbackFromNative(int error)
{
if (mErrorCallback != null) {
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 2b7656f..9bb1df9 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -30,12 +30,31 @@ import android.util.Log;
/**
* The AudioTrack class manages and plays a single audio resource for Java applications.
* It allows to stream PCM audio buffers to the audio hardware for playback. This is
- * be achieved by "pushing" the data to the AudioTrack object using the
- * {@link #write(byte[], int, int)} or {@link #write(short[], int, int)} method.
- * During construction, an AudioTrack object can be initialized with a given buffer.
- * This size determines how long an AudioTrack can play before running out of data.
- *
- * {@hide Pending API council review}
+ * achieved by "pushing" the data to the AudioTrack object using one of the
+ * {@link #write(byte[], int, int)} and {@link #write(short[], int, int)} methods.
+ * <p>An AudioTrack instance can operate under two modes: static of streaming.<br>
+ * The Streaming mode consists in continuously writing data to the AudioTrack, using one
+ * of the write() methods. These are blocking and return when the data has been transferred
+ * from the Java layer to the native layer, and is queued for playback. The streaming mode
+ * is most useful when playing blocks of audio data that for instance are:
+ * <ul>
+ * <li>too big to fit in memory because of the duration of the sound to play,</li>
+ * <li>too big to fit in memory because of the characteristics of the audio data
+ * (high sampling rate, bits per sample ...)</li>
+ * <li>chosen, received or generated as the audio keeps playing.</li>
+ * </ul>
+ * The static mode is to be chosen when dealing with short sounds that fit in memory and
+ * that need to be played with the smallest latency possible. Static mode AudioTrack instances can
+ * play the sound without the need to transfer the audio data from Java to the audio hardware
+ * each time the sound is to be played. The static mode will therefore be preferred for UI and
+ * game sounds that are played often, and with the smallest overhead possible.
+ * <p>Upon creation, an AudioTrack object initializes its associated audio buffer.
+ * The size of this buffer, specified during the construction, determines how long an AudioTrack
+ * can play before running out of data.<br>
+ * For an AudioTrack using the static mode, this size is the maximum size of the sound that can
+ * be played from it.<br>
+ * For the streaming mode, data will be written to the hardware in chunks of
+ * sizes inferior to the total buffer size.
*/
public class AudioTrack
{
@@ -46,42 +65,41 @@ public class AudioTrack
private static final float VOLUME_MIN = 0.0f;
/** Maximum value for a channel volume */
private static final float VOLUME_MAX = 1.0f;
-
+
/** state of an AudioTrack this is stopped */
public static final int PLAYSTATE_STOPPED = 1; // matches SL_PLAYSTATE_STOPPED
/** state of an AudioTrack this is paused */
public static final int PLAYSTATE_PAUSED = 2; // matches SL_PLAYSTATE_PAUSED
/** state of an AudioTrack this is playing */
public static final int PLAYSTATE_PLAYING = 3; // matches SL_PLAYSTATE_PLAYING
-
- /**
- * Creation mode where audio data is transferred from Java to the native layer
+
+ /**
+ * Creation mode where audio data is transferred from Java to the native layer
* only once before the audio starts playing.
*/
public static final int MODE_STATIC = 0;
- /**
- * Creation mode where audio data is streamed from Java to the native layer
+ /**
+ * Creation mode where audio data is streamed from Java to the native layer
* as the audio is playing.
*/
public static final int MODE_STREAM = 1;
-
- /**
- * State of an AudioTrack that was not successfully initialized upon creation
+
+ /**
+ * State of an AudioTrack that was not successfully initialized upon creation
*/
public static final int STATE_UNINITIALIZED = 0;
- /**
+ /**
* State of an AudioTrack that is ready to be used.
*/
public static final int STATE_INITIALIZED = 1;
/**
- * State of a successfully initialized AudioTrack that uses static data,
+ * State of a successfully initialized AudioTrack that uses static data,
* but that hasn't received that data yet.
*/
public static final int STATE_NO_STATIC_DATA = 2;
-
- // to keep in sync with libs/android_runtime/android_media_AudioTrack.cpp
- // error codes
+ // Error codes:
+ // to keep in sync with frameworks/base/core/jni/android_media_AudioTrack.cpp
/**
* Denotes a successful operation.
*/
@@ -90,139 +108,145 @@ public class AudioTrack
* Denotes a generic operation failure.
*/
public static final int ERROR = -1;
- private static final int ERROR_NATIVESETUP_AUDIOSYSTEM = -2;
- private static final int ERROR_NATIVESETUP_INVALIDCHANNELCOUNT = -3;
- private static final int ERROR_NATIVESETUP_INVALIDFORMAT = -4;
- private static final int ERROR_NATIVESETUP_INVALIDSTREAMTYPE = -5;
- private static final int ERROR_NATIVESETUP_NATIVEINITFAILED = -6;
/**
* Denotes a failure due to the use of an invalid value.
*/
- public static final int ERROR_BAD_VALUE = -7;
+ public static final int ERROR_BAD_VALUE = -2;
/**
* Denotes a failure due to the improper use of a method.
*/
- public static final int ERROR_INVALID_OPERATION = -8;
- // events
+ public static final int ERROR_INVALID_OPERATION = -3;
+
+ private static final int ERROR_NATIVESETUP_AUDIOSYSTEM = -16;
+ private static final int ERROR_NATIVESETUP_INVALIDCHANNELCOUNT = -17;
+ private static final int ERROR_NATIVESETUP_INVALIDFORMAT = -18;
+ private static final int ERROR_NATIVESETUP_INVALIDSTREAMTYPE = -19;
+ private static final int ERROR_NATIVESETUP_NATIVEINITFAILED = -20;
+
+ // Events:
+ // to keep in sync with frameworks/base/include/media/AudioTrack.h
/**
* Event id for when the playback head has reached a previously set marker.
*/
- protected static final int NATIVE_EVENT_MARKER = 3;
+ private static final int NATIVE_EVENT_MARKER = 3;
/**
* Event id for when the previously set update period has passed during playback.
*/
- protected static final int NATIVE_EVENT_NEW_POS = 4;
-
+ private static final int NATIVE_EVENT_NEW_POS = 4;
+
private final static String TAG = "AudioTrack-Java";
-
+
//--------------------------------------------------------------------------
// Member variables
//--------------------
/**
* Indicates the state of the AudioTrack instance
*/
- protected int mState = STATE_UNINITIALIZED;
+ private int mState = STATE_UNINITIALIZED;
/**
* Indicates the play state of the AudioTrack instance
*/
- protected int mPlayState = PLAYSTATE_STOPPED;
+ private int mPlayState = PLAYSTATE_STOPPED;
/**
* Lock to make sure mPlayState updates are reflecting the actual state of the object.
*/
- protected final Object mPlayStateLock = new Object();
+ private final Object mPlayStateLock = new Object();
/**
* The listener the AudioTrack notifies previously set marker is reached.
* @see #setMarkerReachedListener(OnMarkerReachedListener)
*/
- protected OnMarkerReachedListener mMarkerListener = null;
+ private OnMarkerReachedListener mMarkerListener = null;
/**
* Lock to protect marker listener updates against event notifications
*/
- protected final Object mMarkerListenerLock = new Object();
+ private final Object mMarkerListenerLock = new Object();
/**
* The listener the AudioTrack notifies periodically during playback.
* @see #setPeriodicNotificationListener(OnPeriodicNotificationListener)
*/
- protected OnPeriodicNotificationListener mPeriodicListener = null;
+ private OnPeriodicNotificationListener mPeriodicListener = null;
/**
* Lock to protect periodic listener updates against event notifications
*/
- protected final Object mPeriodicListenerLock = new Object();
+ private final Object mPeriodicListenerLock = new Object();
/**
* Size of the native audio buffer.
*/
- protected int mNativeBufferSizeInBytes = 0;
+ private int mNativeBufferSizeInBytes = 0;
/**
* Handler for events coming from the native code
*/
- protected NativeEventHandler mNativeEventHandler = null;
+ private NativeEventHandler mNativeEventHandler = null;
/**
* The audio data sampling rate in Hz.
*/
- protected int mSampleRate = 22050;
+ private int mSampleRate = 22050;
/**
* The number of input audio channels (1 is mono, 2 is stereo)
*/
- protected int mChannelCount = 1;
+ private int mChannelCount = 1;
/**
* The type of the audio stream to play. See
- * {@link AudioManager.STREAM_VOICE_CALL}, {@link AudioManager.STREAM_SYSTEM},
- * {@link AudioManager.STREAM_RING}, {@link AudioManager.STREAM_MUSIC} and
- * {@link AudioManager.STREAM_ALARM}
+ * {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
+ * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC} and
+ * {@link AudioManager#STREAM_ALARM}
*/
- protected int mStreamType = AudioManager.STREAM_MUSIC;
+ private int mStreamType = AudioManager.STREAM_MUSIC;
/**
* The way audio is consumed by the hardware, streaming or static.
*/
- protected int mDataLoadMode = MODE_STREAM;
+ private int mDataLoadMode = MODE_STREAM;
/**
* The current audio channel configuration
*/
- protected int mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
+ private int mChannelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
/**
* The encoding of the audio samples.
- * @see #AudioFormat.ENCODING_PCM_8BIT
- * @see #AudioFormat.ENCODING_PCM_16BIT
+ * @see AudioFormat#ENCODING_PCM_8BIT
+ * @see AudioFormat#ENCODING_PCM_16BIT
*/
- protected int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+ private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
//--------------------------------
// Used exclusively by native code
//--------------------
- /**
- * Accessed by native methods: provides access to C++ AudioTrack object
+ /**
+ * Accessed by native methods: provides access to C++ AudioTrack object
*/
@SuppressWarnings("unused")
private int mNativeTrackInJavaObj;
- /**
+ /**
* Accessed by native methods: provides access to the JNI data (i.e. resources used by
* the native AudioTrack object, but not stored in it).
*/
@SuppressWarnings("unused")
private int mJniData;
-
-
+
+
//--------------------------------------------------------------------------
// Constructor, Finalize
//--------------------
/**
* Class constructor.
- * @param streamType the type of the audio stream. See
- * {@link AudioSystem.STREAM_VOICE_CALL}, {@link AudioSystem.STREAM_SYSTEM},
- * {@link AudioSystem.STREAM_RING}, {@link AudioSystem.STREAM_MUSIC} and
- * {@link AudioSystem.STREAM_ALARM}
+ * @param streamType the type of the audio stream. See
+
+ * {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
+ * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC} and
+ * {@link AudioManager#STREAM_ALARM}
* @param sampleRateInHz the sample rate expressed in Hertz. Examples of rates are (but
* not limited to) 44100, 22050 and 11025.
- * @param channelConfig describes the configuration of the audio channels.
- * See {@link AudioFormat.CHANNEL_CONFIGURATION_MONO} and
- * {@link AudioFormat.CHANNEL_CONFIGURATION_STEREO}
- * @param audioFormat the format in which the audio data is represented.
- * See {@link AudioFormat.ENCODING_PCM_16BIT} and
- * {@link AudioFormat.ENCODING_PCM_8BIT}
+ * @param channelConfig describes the configuration of the audio channels.
+
+ * See {@link AudioFormat#CHANNEL_CONFIGURATION_MONO} and
+ * {@link AudioFormat#CHANNEL_CONFIGURATION_STEREO}
+
+ * @param audioFormat the format in which the audio data is represented.
+ * See {@link AudioFormat#ENCODING_PCM_16BIT} and
+ * {@link AudioFormat#ENCODING_PCM_8BIT}
* @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read
- * from for playback. If using the AudioTrack in streaming mode, you can write data into
+ * from for playback. If using the AudioTrack in streaming mode, you can write data into
* this buffer in smaller chunks than this size. If using the AudioTrack in static mode,
* this is the maximum size of the sound that will be played for this instance.
* @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
@@ -230,7 +254,7 @@ public class AudioTrack
*/
public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
int bufferSizeInBytes, int mode)
- throws IllegalArgumentException {
+ throws IllegalArgumentException {
mState = STATE_UNINITIALIZED;
audioParamCheck(streamType, sampleRateInHz, channelConfig, audioFormat, mode);
@@ -238,8 +262,8 @@ public class AudioTrack
audioBuffSizeCheck(bufferSizeInBytes);
// native initialization
- int initResult = native_setup(new WeakReference<AudioTrack>(this),
- mStreamType, mSampleRate, mChannelCount, mAudioFormat,
+ int initResult = native_setup(new WeakReference<AudioTrack>(this),
+ mStreamType, mSampleRate, mChannelCount, mAudioFormat,
mNativeBufferSizeInBytes, mDataLoadMode);
if (initResult != SUCCESS) {
loge("Error code "+initResult+" when initializing AudioTrack.");
@@ -252,8 +276,8 @@ public class AudioTrack
mState = STATE_INITIALIZED;
}
}
-
-
+
+
// Convenience method for the constructor's parameter checks.
// This is where constructor IllegalArgumentException-s are thrown
// postconditions:
@@ -262,25 +286,27 @@ public class AudioTrack
// mAudioFormat is valid
// mSampleRate is valid
// mDataLoadMode is valid
- private void audioParamCheck(int streamType, int sampleRateInHz,
+ private void audioParamCheck(int streamType, int sampleRateInHz,
int channelConfig, int audioFormat, int mode) {
-
+
//--------------
// stream type
if( (streamType != AudioManager.STREAM_ALARM) && (streamType != AudioManager.STREAM_MUSIC)
&& (streamType != AudioManager.STREAM_RING) && (streamType != AudioManager.STREAM_SYSTEM)
- && (streamType != AudioManager.STREAM_VOICE_CALL) && (streamType != AudioManager.STREAM_NOTIFICATION) ) {
+ && (streamType != AudioManager.STREAM_VOICE_CALL)
+ && (streamType != AudioManager.STREAM_NOTIFICATION)
+ && (streamType != AudioManager.STREAM_BLUETOOTH_SCO)) {
throw (new IllegalArgumentException("Invalid stream type."));
} else {
mStreamType = streamType;
}
-
+
//--------------
// sample rate
if ( (sampleRateInHz < 4000) || (sampleRateInHz > 48000) ) {
throw (new IllegalArgumentException(sampleRateInHz
+ "Hz is not a supported sample rate."));
- } else {
+ } else {
mSampleRate = sampleRateInHz;
}
@@ -314,10 +340,10 @@ public class AudioTrack
break;
default:
mAudioFormat = AudioFormat.ENCODING_INVALID;
- throw(new IllegalArgumentException("Unsupported sample encoding."
+ throw(new IllegalArgumentException("Unsupported sample encoding."
+ " Should be ENCODING_PCM_8BIT or ENCODING_PCM_16BIT."));
}
-
+
//--------------
// audio load mode
if ( (mode != MODE_STREAM) && (mode != MODE_STATIC) ) {
@@ -326,8 +352,8 @@ public class AudioTrack
mDataLoadMode = mode;
}
}
-
-
+
+
// Convenience method for the contructor's audio buffer size check.
// preconditions:
// mChannelCount is valid
@@ -335,18 +361,18 @@ public class AudioTrack
// postcondition:
// mNativeBufferSizeInBytes is valid (multiple of frame size, positive)
private void audioBuffSizeCheck(int audioBufferSize) {
- // NB: this section is only valid with PCM data.
+ // NB: this section is only valid with PCM data.
// To update when supporting compressed formats
- int frameSizeInBytes = mChannelCount
+ int frameSizeInBytes = mChannelCount
* (mAudioFormat == AudioFormat.ENCODING_PCM_8BIT ? 1 : 2);
if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) {
throw (new IllegalArgumentException("Invalid audio buffer size."));
}
-
+
mNativeBufferSizeInBytes = audioBufferSize;
}
-
-
+
+
// Convenience method for the creation of the native event handler
// It is called only when a non-null event listener is set.
// precondition:
@@ -361,8 +387,8 @@ public class AudioTrack
mNativeEventHandler = null;
}
}
-
-
+
+
/**
* Releases the native AudioTrack resources.
*/
@@ -377,7 +403,7 @@ public class AudioTrack
@Override
protected void finalize() {
native_finalize();
- }
+ }
//--------------------------------------------------------------------------
// Getters
@@ -390,7 +416,7 @@ public class AudioTrack
static public float getMinVolume() {
return AudioTrack.VOLUME_MIN;
}
-
+
/**
* Returns the maximum valid volume value. Volume values set above this one will
* be clamped at this value.
@@ -398,8 +424,8 @@ public class AudioTrack
*/
static public float getMaxVolume() {
return AudioTrack.VOLUME_MAX;
- }
-
+ }
+
/**
* Returns the configured audio data sample rate in Hz
*/
@@ -408,27 +434,28 @@ public class AudioTrack
}
/**
- * Returns the configured audio data format. See {@link #AudioFormat.ENCODING_PCM_16BIT}
- * and {@link #AudioFormat.ENCODING_PCM_8BIT}.
+ * Returns the configured audio data format. See {@link AudioFormat#ENCODING_PCM_16BIT}
+ * and {@link AudioFormat#ENCODING_PCM_8BIT}.
*/
public int getAudioFormat() {
return mAudioFormat;
}
-
+
/**
* Returns the type of audio stream this AudioTrack is configured for.
- * Compare the result against {@link AudioManager.STREAM_VOICE_CALL},
- * {@link AudioManager.STREAM_SYSTEM}, {@link AudioManager.STREAM_RING},
- * {@link AudioManager.STREAM_MUSIC} or {@link AudioManager.STREAM_ALARM}
+ * Compare the result against {@link AudioManager#STREAM_VOICE_CALL},
+ * {@link AudioManager#STREAM_SYSTEM}, {@link AudioManager#STREAM_RING},
+ * {@link AudioManager#STREAM_MUSIC} or {@link AudioManager#STREAM_ALARM}
*/
public int getStreamType() {
return mStreamType;
}
/**
- * Returns the configured channel configuration.
- * See {@link #AudioFormat.CHANNEL_CONFIGURATION_MONO}
- * and {@link #AudioFormat.CHANNEL_CONFIGURATION_STEREO}.
+ * Returns the configured channel configuration.
+
+ * See {@link AudioFormat#CHANNEL_CONFIGURATION_MONO}
+ * and {@link AudioFormat#CHANNEL_CONFIGURATION_STEREO}.
*/
public int getChannelConfiguration() {
return mChannelConfiguration;
@@ -443,19 +470,19 @@ public class AudioTrack
/**
* Returns the state of the AudioTrack instance. This is useful after the
- * AudioTrack instance has been created to check if it was initialized
+ * AudioTrack instance has been created to check if it was initialized
* properly. This ensures that the appropriate hardware resources have been
* acquired.
*/
public int getState() {
return mState;
}
-
+
/**
* Returns the playback state of the AudioTrack instance.
- * @see AudioTrack.PLAYSTATE_STOPPED
- * @see AudioTrack.PLAYSTATE_PAUSED
- * @see AudioTrack.PLAYSTATE_PLAYING
+ * @see #PLAYSTATE_STOPPED
+ * @see #PLAYSTATE_PAUSED
+ * @see #PLAYSTATE_PLAYING
*/
public int getPlayState() {
return mPlayState;
@@ -495,11 +522,49 @@ public class AudioTrack
static public int getNativeOutputSampleRate() {
return native_get_output_sample_rate();
}
-
+ /**
+ * {@hide}
+ * Returns the minimum buffer size required for the successful creation of an AudioTrack
+ * object to be created in the {@link #MODE_STREAM} mode.
+ * @param sampleRateInHz the sample rate expressed in Hertz.
+ * @param channelConfig describes the configuration of the audio channels.
+ * See {@link AudioFormat#CHANNEL_CONFIGURATION_MONO} and
+ * {@link AudioFormat#CHANNEL_CONFIGURATION_STEREO}
+ * @param audioFormat the format in which the audio data is represented.
+ * See {@link AudioFormat#ENCODING_PCM_16BIT} and
+ * {@link AudioFormat#ENCODING_PCM_8BIT}
+ * @return -1 if an invalid parameter was passed or if the implementation was unable to
+ * query the hardware for its output properties, or the minimum buffer size expressed
+ * in number of bytes.
+ */
+ static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
+ int channelCount = 0;
+ switch(channelConfig) {
+ case AudioFormat.CHANNEL_CONFIGURATION_MONO:
+ channelCount = 1;
+ break;
+ case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
+ channelCount = 2;
+ break;
+ default:
+ loge("getMinBufferSize(): Invalid channel configuration.");
+ return -1;
+ }
+
+ if ((audioFormat != AudioFormat.ENCODING_PCM_16BIT)
+ && (audioFormat != AudioFormat.ENCODING_PCM_8BIT)) {
+ loge("getMinBufferSize(): Invalid audio format.");
+ return -1;
+ }
+
+ return native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);
+ }
+
+
//--------------------------------------------------------------------------
// Initialization / configuration
- //--------------------
+ //--------------------
/**
* Sets the listener the AudioTrack notifies when a previously set marker is reached.
* @param listener
@@ -512,8 +577,8 @@ public class AudioTrack
createNativeEventHandler();
}
}
-
-
+
+
/**
* Sets the listener the AudioTrack notifies periodically during playback.
* @param listener
@@ -526,22 +591,20 @@ public class AudioTrack
createNativeEventHandler();
}
}
-
-
- /**
- * Sets the specified left/right output volume values on the AudioTrack. Values are clamped
+
+
+ /**
+ * Sets the specified left/right output volume values on the AudioTrack. Values are clamped
* to the ({@link #getMinVolume()}, {@link #getMaxVolume()}) interval if outside this range.
- * @param leftVolume output attenuation for the left channel. A value of 0.0f is silence,
+ * @param leftVolume output attenuation for the left channel. A value of 0.0f is silence,
* a value of 1.0f is no attenuation.
* @param rightVolume output attenuation for the right channel
- * @return {@link #SUCCESS}
- * @throws IllegalStateException
+ * @return error code or success, see {@link #SUCCESS},
+ * {@link #ERROR_INVALID_OPERATION}
*/
- public int setStereoVolume(float leftVolume, float rightVolume)
- throws IllegalStateException {
+ public int setStereoVolume(float leftVolume, float rightVolume) {
if (mState != STATE_INITIALIZED) {
- throw(new IllegalStateException("setStereoVolume() called on an "+
- "uninitialized AudioTrack."));
+ return ERROR_INVALID_OPERATION;
}
// clamp the volumes
@@ -559,11 +622,11 @@ public class AudioTrack
}
native_setVolume(leftVolume, rightVolume);
-
+
return SUCCESS;
}
-
-
+
+
/**
* Sets the playback sample rate for this track. This sets the sampling rate at which
* the audio data will be consumed and played back, not the original sampling rate of the
@@ -573,70 +636,88 @@ public class AudioTrack
* sample rate (see {@link #getNativeOutputSampleRate()}). Use {@link #getSampleRate()} to
* check the rate actually used in hardware after potential clamping.
* @param sampleRateInHz
- * @return {@link #SUCCESS}
+ * @return error code or success, see {@link #SUCCESS},
+ * {@link #ERROR_INVALID_OPERATION}
*/
public int setPlaybackRate(int sampleRateInHz) {
+ if (mState != STATE_INITIALIZED) {
+ return ERROR_INVALID_OPERATION;
+ }
native_set_playback_rate(sampleRateInHz);
return SUCCESS;
}
-
-
+
+
/**
- *
+ *
* @param markerInFrames marker in frames
* @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
- * {@link #ERROR_INVALID_OPERATION}
+ * {@link #ERROR_INVALID_OPERATION}
*/
public int setNotificationMarkerPosition(int markerInFrames) {
+ if (mState != STATE_INITIALIZED) {
+ return ERROR_INVALID_OPERATION;
+ }
return native_set_marker_pos(markerInFrames);
}
-
-
+
+
/**
* @param periodInFrames update period in frames
* @return error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION}
*/
public int setPositionNotificationPeriod(int periodInFrames) {
+ if (mState != STATE_INITIALIZED) {
+ return ERROR_INVALID_OPERATION;
+ }
return native_set_pos_update_period(periodInFrames);
}
-
-
+
+
/**
* Sets the playback head position. The track must be stopped for the position to be changed.
* @param positionInFrames playback head position in frames
- * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}
- * @throws java.lang.IllegalStateException if the track is not in
- * the {@link #PLAYSTATE_STOPPED} state.
+ * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
+ * {@link #ERROR_INVALID_OPERATION}
*/
- public int setPlaybackHeadPosition(int positionInFrames)
- throws IllegalStateException {
+ public int setPlaybackHeadPosition(int positionInFrames) {
synchronized(mPlayStateLock) {
if(mPlayState == PLAYSTATE_STOPPED) {
return native_set_position(positionInFrames);
+ } else {
+ return ERROR_INVALID_OPERATION;
}
}
- throw(new IllegalStateException("setPlaybackHeadPosition() called on a track that is "+
- "not in the PLAYSTATE_STOPPED play state."));
}
-
+
/**
* Sets the loop points and the loop count. The loop can be infinite.
* @param startInFrames loop start marker in frames
* @param endInFrames loop end marker in frames
- * @param loopCount the number of times the loop is looped.
+ * @param loopCount the number of times the loop is looped.
* A value of -1 means infinite looping.
- * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE}
+ * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
+ * {@link #ERROR_INVALID_OPERATION}
*/
public int setLoopPoints(int startInFrames, int endInFrames, int loopCount) {
return native_set_loop(startInFrames, endInFrames, loopCount);
}
+ /**
+ * Sets the initialization state of the instance. To be used in an AudioTrack subclass
+ * constructor to set a subclass-specific post-initialization state.
+ * @param state the state of the AudioTrack instance
+ */
+ protected void setState(int state) {
+ mState = state;
+ }
+
//---------------------------------------------------------
// Transport control methods
//--------------------
/**
- * Starts playing an AudioTrack.
+ * Starts playing an AudioTrack.
* @throws IllegalStateException
*/
public void play()
@@ -644,7 +725,7 @@ public class AudioTrack
if (mState != STATE_INITIALIZED) {
throw(new IllegalStateException("play() called on uninitialized AudioTrack."));
}
-
+
synchronized(mPlayStateLock) {
native_start();
mPlayState = PLAYSTATE_PLAYING;
@@ -671,7 +752,7 @@ public class AudioTrack
/**
* Pauses the playback of the audio data.
* @throws IllegalStateException
- */
+ */
public void pause()
throws IllegalStateException {
if (mState != STATE_INITIALIZED) {
@@ -685,25 +766,21 @@ public class AudioTrack
mPlayState = PLAYSTATE_PAUSED;
}
}
-
-
+
+
//---------------------------------------------------------
// Audio data supply
//--------------------
/**
* Flushes the audio data currently queued for playback.
- * @throws IllegalStateException
- */
- public void flush()
- throws IllegalStateException {
- if (mState != STATE_INITIALIZED) {
- throw(new IllegalStateException("flush() called on uninitialized AudioTrack."));
- }
- //logd("flush()");
+ */
- // flush the data in native layer
- native_flush();
+ public void flush() {
+ if (mState == STATE_INITIALIZED) {
+ // flush the data in native layer
+ native_flush();
+ }
}
@@ -712,12 +789,12 @@ public class AudioTrack
* @param audioData the array that holds the data to play.
* @param offsetInBytes the offset in audioData where the data to play starts.
* @param sizeInBytes the number of bytes to read in audioData after the offset.
- * @return the number of bytes that were written.
- * @throws IllegalStateException
- */
- public int write(byte[] audioData,int offsetInBytes, int sizeInBytes)
- throws IllegalStateException {
- if ((mDataLoadMode == MODE_STATIC)
+ * @return the number of bytes that were written or -1 if the object wasn't properly
+ * initialized.
+ */
+
+ public int write(byte[] audioData,int offsetInBytes, int sizeInBytes) {
+ if ((mDataLoadMode == MODE_STATIC)
&& (mState == STATE_NO_STATIC_DATA)
&& (sizeInBytes > 0)) {
mState = STATE_INITIALIZED;
@@ -726,24 +803,24 @@ public class AudioTrack
// or: how to update data for static tracks?
if (mState != STATE_INITIALIZED) {
- throw(new IllegalStateException("write() called on uninitialized AudioTrack."));
+ return -1;
}
return native_write_byte(audioData, offsetInBytes, sizeInBytes);
}
-
-
+
+
/**
* Writes the audio data to the audio hardware for playback.
* @param audioData the array that holds the data to play.
* @param offsetInShorts the offset in audioData where the data to play starts.
* @param sizeInShorts the number of bytes to read in audioData after the offset.
- * @return the number of shorts that were written.
- * @throws IllegalStateException
- */
- public int write(short[] audioData, int offsetInShorts, int sizeInShorts)
- throws IllegalStateException {
- if ((mDataLoadMode == MODE_STATIC)
+ * @return the number of shorts that were written or -1 if the object wasn't properly
+ * initialized.
+ */
+
+ public int write(short[] audioData, int offsetInShorts, int sizeInShorts) {
+ if ((mDataLoadMode == MODE_STATIC)
&& (mState == STATE_NO_STATIC_DATA)
&& (sizeInShorts > 0)) {
mState = STATE_INITIALIZED;
@@ -752,13 +829,13 @@ public class AudioTrack
// or: how to update data for static tracks?
if (mState != STATE_INITIALIZED) {
- throw(new IllegalStateException("write() called on uninitialized AudioTrack."));
+ return -1;
}
return native_write_short(audioData, offsetInShorts, sizeInShorts);
}
-
-
+
+
/**
* Notifies the native resource to reuse the audio data already loaded in the native
* layer. This call is only valid with AudioTrack instances that don't use the streaming
@@ -791,7 +868,7 @@ public class AudioTrack
/**
- * Interface definition for a callback to be invoked for each periodic AudioTrack
+ * Interface definition for a callback to be invoked for each periodic AudioTrack
* update during playback. The update interval is set by setPositionNotificationPeriod().
*/
public interface OnPeriodicNotificationListener {
@@ -858,28 +935,28 @@ public class AudioTrack
if (track == null) {
return;
}
-
+
if (track.mNativeEventHandler != null) {
Message m = track.mNativeEventHandler.obtainMessage(what, arg1, arg2, obj);
track.mNativeEventHandler.sendMessage(m);
}
}
-
-
+
+
//---------------------------------------------------------
// Native methods called from the Java side
//--------------------
- private native final int native_setup(Object audiotrack_this,
- int streamType, int sampleRate, int nbChannels, int audioFormat,
+ private native final int native_setup(Object audiotrack_this,
+ int streamType, int sampleRate, int nbChannels, int audioFormat,
int buffSizeInBytes, int mode);
private native final void native_finalize();
-
+
private native final void native_release();
- private native final void native_start();
+ private native final void native_start();
private native final void native_stop();
@@ -887,34 +964,36 @@ public class AudioTrack
private native final void native_flush();
- private native final int native_write_byte(byte[] audioData,
+ private native final int native_write_byte(byte[] audioData,
int offsetInBytes, int sizeInBytes);
-
- private native final int native_write_short(short[] audioData,
+
+ private native final int native_write_short(short[] audioData,
int offsetInShorts, int sizeInShorts);
-
+
private native final int native_reload_static();
private native final int native_get_native_frame_count();
private native final void native_setVolume(float leftVolume, float rightVolume);
-
+
private native final void native_set_playback_rate(int sampleRateInHz);
private native final int native_get_playback_rate();
-
+
private native final int native_set_marker_pos(int marker);
private native final int native_get_marker_pos();
-
+
private native final int native_set_pos_update_period(int updatePeriod);
private native final int native_get_pos_update_period();
-
+
private native final int native_set_position(int position);
private native final int native_get_position();
-
+
private native final int native_set_loop(int start, int end, int loopCount);
-
+
static private native final int native_get_output_sample_rate();
-
+ static private native final int native_get_min_buff_size(
+ int sampleRateInHz, int channelConfig, int audioFormat);
+
//---------------------------------------------------------
// Utility methods
@@ -928,7 +1007,4 @@ public class AudioTrack
Log.e(TAG, "[ android.media.AudioTrack ] " + msg);
}
-}
-
-
-
+} \ No newline at end of file
diff --git a/media/java/android/media/JetPlayer.java b/media/java/android/media/JetPlayer.java
index b9268d5..bfa2f80 100644
--- a/media/java/android/media/JetPlayer.java
+++ b/media/java/android/media/JetPlayer.java
@@ -17,9 +17,11 @@
package android.media;
+import java.io.FileDescriptor;
import java.lang.ref.WeakReference;
import java.lang.CloneNotSupportedException;
+import android.content.res.AssetFileDescriptor;
import android.os.Looper;
import android.os.Handler;
import android.os.Message;
@@ -29,9 +31,7 @@ import android.util.Log;
* JetPlayer provides access to JET content playback and control.
* <p>
* Use <code>JetPlayer.getJetPlayer()</code> to get an instance of this class.
- * There can only be one instance of this class at any one time.
*
- * @hide
*/
public class JetPlayer
{
@@ -39,15 +39,29 @@ public class JetPlayer
// Constants
//------------------------
/**
- * The maximum number of simultaneous tracks. Use {@link #getMaxTracks()} to
+ * The maximum number of simultaneous tracks. Use __link #getMaxTracks()} to
* access this value.
*/
- protected static int MAXTRACKS = 32;
+ private static int MAXTRACKS = 32;
- // These constants are to be kept in sync with the ones in include/media/JetPlayer.h
- protected static final int JET_USERID_UPDATE = 1;
- protected static final int JET_NUMQUEUEDSEGMENT_UPDATE = 2;
- protected static final int JET_PAUSE_UPDATE = 3;
+ // to keep in sync with the JetPlayer class constants
+ // defined in frameworks/base/include/media/JetPlayer.h
+ private static final int JET_EVENT = 1;
+ private static final int JET_USERID_UPDATE = 2;
+ private static final int JET_NUMQUEUEDSEGMENT_UPDATE = 3;
+ private static final int JET_PAUSE_UPDATE = 4;
+
+ // to keep in sync with external/sonivox/arm-wt-22k/lib_src/jet_data.h
+ // Encoding of event information on 32 bits
+ private static final int JET_EVENT_VAL_MASK = 0x0000007f; // mask for value
+ private static final int JET_EVENT_CTRL_MASK = 0x00003f80; // mask for controller
+ private static final int JET_EVENT_CHAN_MASK = 0x0003c000; // mask for channel
+ private static final int JET_EVENT_TRACK_MASK = 0x00fc0000; // mask for track number
+ private static final int JET_EVENT_SEG_MASK = 0xff000000; // mask for segment ID
+ private static final int JET_EVENT_CTRL_SHIFT = 7; // shift to get controller number to bit 0
+ private static final int JET_EVENT_CHAN_SHIFT = 14; // shift to get MIDI channel to bit 0
+ private static final int JET_EVENT_TRACK_SHIFT = 18; // shift to get track ID to bit 0
+ private static final int JET_EVENT_SEG_SHIFT = 24; // shift to get segment ID to bit 0
//--------------------------------------------
@@ -56,13 +70,20 @@ public class JetPlayer
private EventHandler mNativeEventHandler = null;
/**
- * Lock to protect event listener updates against event notifications
+ * Lock to protect status listener updates against status change notifications
*/
- protected final Object mStatusListenerLock = new Object();
+ private final Object mStatusListenerLock = new Object();
- protected JetStatusUpdateListener mJetStatusUpdateListener = null;
+ /**
+ * Lock to protect the event listener updates against event notifications
+ */
+ private final Object mEventListenerLock = new Object();
+
+ private JetStatusUpdateListener mJetStatusUpdateListener = null;
- protected static JetPlayer singletonRef;
+ private JetEventListener mJetEventListener = null;
+
+ private static JetPlayer singletonRef;
//--------------------------------
@@ -136,8 +157,14 @@ public class JetPlayer
//--------------------------------------------
// Jet functionality
//------------------------
- public boolean openJetFile(String path) {
- return native_openJetFile(path);
+ public boolean loadJetFile(String path) {
+ return native_loadJetFromFile(path);
+ }
+
+
+ public boolean loadJetFile(AssetFileDescriptor afd) {
+ return native_loadJetFromFileD(
+ afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
}
@@ -195,6 +222,10 @@ public class JetPlayer
}
+ public boolean clearQueue() {
+ return native_clearQueue();
+ }
+
//---------------------------------------------------------
// Internal class to handle events posted from native code
@@ -211,28 +242,42 @@ public class JetPlayer
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
+ case JET_EVENT:
+ synchronized (mEventListenerLock) {
+ if (mJetEventListener != null) {
+ // call the appropriate listener after decoding the event parameters
+ // encoded in msg.arg1
+ mJetEventListener.onJetEvent(
+ mJet,
+ (short)((msg.arg1 & JET_EVENT_SEG_MASK) >> JET_EVENT_SEG_SHIFT),
+ (byte) ((msg.arg1 & JET_EVENT_TRACK_MASK) >> JET_EVENT_TRACK_SHIFT),
+ (byte) ((msg.arg1 & JET_EVENT_CHAN_MASK) >> JET_EVENT_CHAN_SHIFT),
+ (byte) ((msg.arg1 & JET_EVENT_CTRL_MASK) >> JET_EVENT_CTRL_SHIFT),
+ (byte) (msg.arg1 & JET_EVENT_VAL_MASK) );
+ }
+ }
+ return;
case JET_USERID_UPDATE:
synchronized (mStatusListenerLock) {
if (mJetStatusUpdateListener != null) {
- mJetStatusUpdateListener.onJetUserIdUpdate(msg.arg1, msg.arg2);
+ mJetStatusUpdateListener.onJetUserIdUpdate(mJet, msg.arg1, msg.arg2);
}
}
return;
case JET_NUMQUEUEDSEGMENT_UPDATE:
synchronized (mStatusListenerLock) {
if (mJetStatusUpdateListener != null) {
- mJetStatusUpdateListener.onJetNumQueuedSegmentUpdate(msg.arg1);
+ mJetStatusUpdateListener.onJetNumQueuedSegmentUpdate(mJet, msg.arg1);
}
}
return;
case JET_PAUSE_UPDATE:
synchronized (mStatusListenerLock) {
if (mJetStatusUpdateListener != null)
- mJetStatusUpdateListener.onJetPauseUpdate(msg.arg1);
+ mJetStatusUpdateListener.onJetPauseUpdate(mJet, msg.arg1);
}
return;
-
default:
loge("Unknown message type " + msg.what);
return;
@@ -242,7 +287,7 @@ public class JetPlayer
//--------------------------------------------
- // Jet event listener
+ // Jet status update listener
//------------------------
public void setStatusUpdateListener(JetStatusUpdateListener listener) {
synchronized(mStatusListenerLock) {
@@ -255,31 +300,66 @@ public class JetPlayer
}
/**
- * Handles the notification when the JET segment userID is updated.
+ * Handles the notification when the JET status is updated.
*/
public interface JetStatusUpdateListener {
/**
* Callback for when JET's currently playing segment userID is updated.
*
+ * @param player the JET player the status update is coming from
* @param userId the ID of the currently playing segment
* @param repeatCount the repetition count for the segment (0 means it plays once)
*/
- void onJetUserIdUpdate(int userId, int repeatCount);
+ void onJetUserIdUpdate(JetPlayer player, int userId, int repeatCount);
/**
* Callback for when JET's number of queued segments is updated.
*
+ * @param player the JET player the status update is coming from
* @param nbSegments the number of segments in the JET queue
*/
- void onJetNumQueuedSegmentUpdate(int nbSegments);
+ void onJetNumQueuedSegmentUpdate(JetPlayer player, int nbSegments);
/**
* Callback for when JET pause state is updated.
*
+ * @param player the JET player the status update is coming from
* @param paused indicates whether JET is paused or not
*/
- void onJetPauseUpdate(int paused);
- };
+ void onJetPauseUpdate(JetPlayer player, int paused);
+ }
+
+
+ //--------------------------------------------
+ // Jet event listener
+ //------------------------
+ public void setEventListener(JetEventListener listener) {
+ synchronized(mEventListenerLock) {
+ mJetEventListener = listener;
+ }
+
+ if ((listener != null) && (mNativeEventHandler == null)) {
+ createNativeEventHandler();
+ }
+ }
+
+ /**
+ * Handles the notification when the JET engine generates an event.
+ */
+ public interface JetEventListener {
+ /**
+ * Callback for when the JET engine generates a new event.
+ *
+ * @param player the JET player the event is coming from
+ * @param segment 8 bit unsigned value
+ * @param track 6 bit unsigned value
+ * @param channel 4 bit unsigned value
+ * @param controller 7 bit unsigned value
+ * @param value 7 bit unsigned value
+ */
+ void onJetEvent(JetPlayer player,
+ short segment, byte track, byte channel, byte controller, byte value);
+ }
//--------------------------------------------
@@ -289,7 +369,8 @@ public class JetPlayer
int maxTracks, int trackBufferSize);
private native final void native_finalize();
private native final void native_release();
- private native final boolean native_openJetFile(String pathToJetFile);
+ private native final boolean native_loadJetFromFile(String pathToJetFile);
+ private native final boolean native_loadJetFromFileD(FileDescriptor fd, long offset, long len);
private native final boolean native_closeJetFile();
private native final boolean native_playJet();
private native final boolean native_pauseJet();
@@ -300,7 +381,8 @@ public class JetPlayer
private native final boolean native_setMuteFlags(int muteFlags, boolean sync);
private native final boolean native_setMuteArray(boolean[]muteArray, boolean sync);
private native final boolean native_setMuteFlag(int trackId, boolean muteFlag, boolean sync);
- private native final boolean native_triggerClip(int clipId);
+ private native final boolean native_triggerClip(int clipId);
+ private native final boolean native_clearQueue();
//---------------------------------------------------------
// Called exclusively by native code
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 22361aa..f05842d 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -102,13 +102,17 @@ public class MediaFile {
addFileType("AMR", FILE_TYPE_AMR, "audio/amr");
addFileType("AWB", FILE_TYPE_AWB, "audio/amr-wb");
addFileType("WMA", FILE_TYPE_WMA, "audio/x-ms-wma");
- addFileType("OGG", FILE_TYPE_OGG, "application/ogg");
+ addFileType("OGG", FILE_TYPE_OGG, "application/ogg");
+ addFileType("OGA", FILE_TYPE_OGG, "application/ogg");
addFileType("MID", FILE_TYPE_MID, "audio/midi");
+ addFileType("MIDI", FILE_TYPE_MID, "audio/midi");
addFileType("XMF", FILE_TYPE_MID, "audio/midi");
addFileType("RTTTL", FILE_TYPE_MID, "audio/midi");
addFileType("SMF", FILE_TYPE_SMF, "audio/sp-midi");
addFileType("IMY", FILE_TYPE_IMY, "audio/imelody");
+ addFileType("RTX", FILE_TYPE_MID, "audio/midi");
+ addFileType("OTA", FILE_TYPE_MID, "audio/midi");
addFileType("MP4", FILE_TYPE_MP4, "video/mp4");
addFileType("M4V", FILE_TYPE_M4V, "video/mp4");
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 1a82654..601557d 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -39,11 +39,11 @@ import java.lang.ref.WeakReference;
/**
* MediaPlayer class can be used to control playback
* of audio/video files and streams. An example on how to use the methods in
- * this class can be found in <a href="../widget/VideoView.html">VideoView</a>.
- * Please see <a href="../../../toolbox/apis/media.html">Android Media APIs</a>
+ * this class can be found in {@link android.widget.VideoView}.
+ * Please see <a href="{@docRoot}guide/topics/media/index.html">Audio and Video</a>
* for additional help using MediaPlayer.
*
- * <p>Topics covered are:
+ * <p>Topics covered here are:
* <ol>
* <li><a href="#StateDiagram">State Diagram</a>
* <li><a href="#Valid_and_Invalid_States">Valid and Invalid States</a>
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 651cc41..4a30114 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -24,7 +24,7 @@ import java.io.IOException;
* Used to record audio and video. The recording control is based on a
* simple state machine (see below).
*
- * <p><img src="../../../images/mediarecorder_state_diagram.gif" border="0" />
+ * <p><img src="{@docRoot}images/mediarecorder_state_diagram.gif" border="0" />
* </p>
*
* <p>A common case of using MediaRecorder to record audio works as follows:
@@ -42,8 +42,8 @@ import java.io.IOException;
* recorder.release(); // Now the object cannot be reused
* </pre>
*
- * <p>See the <a href="../../../toolbox/apis/media.html">Android Media APIs</a>
- * page for additional help with using MediaRecorder.
+ * <p>See the <a href="{@docRoot}guide/topics/media/index.html">Audio and Video</a>
+ * documentation for additional help with using MediaRecorder.
*/
public class MediaRecorder
{
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 38203b6..fc8476d 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -118,6 +118,7 @@ public class MediaScanner
private static final String NOTIFICATIONS_DIR = "/notifications/";
private static final String ALARMS_DIR = "/alarms/";
private static final String MUSIC_DIR = "/music/";
+ private static final String PODCAST_DIR = "/podcasts/";
private static final String[] ID3_GENRES = {
// ID3v1 Genres
@@ -455,8 +456,9 @@ public class MediaScanner
boolean ringtones = (path.indexOf(RINGTONES_DIR) > 0);
boolean notifications = (path.indexOf(NOTIFICATIONS_DIR) > 0);
boolean alarms = (path.indexOf(ALARMS_DIR) > 0);
+ boolean podcasts = (path.indexOf(PODCAST_DIR) > 0);
boolean music = (path.indexOf(MUSIC_DIR) > 0) ||
- (!ringtones && !notifications && !alarms);
+ (!ringtones && !notifications && !alarms && !podcasts);
if (mFileType == MediaFile.FILE_TYPE_MP3 ||
mFileType == MediaFile.FILE_TYPE_MP4 ||
@@ -473,7 +475,7 @@ public class MediaScanner
// we used to compute the width and height but it's not worth it
}
- result = endFile(entry, ringtones, notifications, alarms, music);
+ result = endFile(entry, ringtones, notifications, alarms, music, podcasts);
}
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in MediaScanner.scanFile()", e);
@@ -586,7 +588,8 @@ public class MediaScanner
return map;
}
- public Uri endFile(FileCacheEntry entry, boolean ringtones, boolean notifications, boolean alarms, boolean music)
+ private Uri endFile(FileCacheEntry entry, boolean ringtones, boolean notifications,
+ boolean alarms, boolean music, boolean podcasts)
throws RemoteException {
// update database
Uri tableUri;
@@ -634,6 +637,7 @@ public class MediaScanner
values.put(Audio.Media.IS_NOTIFICATION, notifications);
values.put(Audio.Media.IS_ALARM, alarms);
values.put(Audio.Media.IS_MUSIC, music);
+ values.put(Audio.Media.IS_PODCAST, podcasts);
} else if (isImage) {
// nothing right now
}
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 2810a9c..8eb638e 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -60,15 +60,18 @@ static sp<Surface> get_surface(JNIEnv* env, jobject clazz)
return sp<Surface>(p);
}
-static void process_media_recorder_call(JNIEnv *env, status_t opStatus, const char* exception, const char* message)
+// Returns true if it throws an exception.
+static bool process_media_recorder_call(JNIEnv *env, status_t opStatus, const char* exception, const char* message)
{
LOGV("process_media_recorder_call");
if (opStatus == (status_t)INVALID_OPERATION) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return true;
} else if (opStatus != (status_t)OK) {
jniThrowException(env, exception, message);
+ return true;
}
- return;
+ return false;
}
static void android_media_MediaRecorder_setCamera(JNIEnv* env, jobject thiz, jobject camera)
@@ -196,7 +199,9 @@ android_media_MediaRecorder_prepare(JNIEnv *env, jobject thiz)
if (surface != NULL) {
const sp<Surface>& native_surface = get_surface(env, surface);
LOGI("prepare: surface=%p (id=%d)", native_surface.get(), native_surface->ID());
- process_media_recorder_call(env, mr->setPreviewSurface(native_surface), "java/lang/RuntimeException", "setPreviewSurface failed.");
+ if (process_media_recorder_call(env, mr->setPreviewSurface(native_surface), "java/lang/RuntimeException", "setPreviewSurface failed.")) {
+ return;
+ }
}
process_media_recorder_call(env, mr->prepare(), "java/io/IOException", "prepare failed.");
}
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index 7872a8d..559f9d5 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -64,13 +64,6 @@ SoundPool::SoundPool(jobject soundPoolRef, int maxChannels, int streamType, int
mChannels.push_back(&mChannelPool[i]);
}
- if (AudioSystem::getOutputFrameCount(&mFrameCount) != NO_ERROR) {
- mFrameCount = kDefaultFrameCount;
- }
- if (AudioSystem::getOutputSamplingRate(&mSampleRate) != NO_ERROR) {
- mSampleRate = kDefaultSampleRate;
- }
-
// start decode thread
startThreads();
}
@@ -481,8 +474,8 @@ void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftV
{
AudioTrack* oldTrack;
- LOGV("play: sampleID=%d, channelID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f",
- sample->sampleID(), nextChannelID, leftVolume, rightVolume, priority, loop, rate);
+ LOGV("play %p: sampleID=%d, channelID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f",
+ this, sample->sampleID(), nextChannelID, leftVolume, rightVolume, priority, loop, rate);
// if not idle, this voice is being stolen
if (mState != IDLE) {
@@ -496,9 +489,17 @@ void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftV
}
// initialize track
+ int afFrameCount;
+ int afSampleRate;
+ if (AudioSystem::getOutputFrameCount(&afFrameCount) != NO_ERROR) {
+ afFrameCount = kDefaultFrameCount;
+ }
+ if (AudioSystem::getOutputSamplingRate(&afSampleRate) != NO_ERROR) {
+ afSampleRate = kDefaultSampleRate;
+ }
int numChannels = sample->numChannels();
uint32_t sampleRate = uint32_t(float(sample->sampleRate()) * rate + 0.5);
- uint32_t bufferFrames = (mSoundPool->mFrameCount * sampleRate) / mSoundPool->mSampleRate;
+ uint32_t bufferFrames = (afFrameCount * sampleRate) / afSampleRate;
uint32_t frameCount = 0;
if (loop) {
@@ -511,12 +512,21 @@ void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftV
}
AudioTrack* newTrack;
+
+ // mToggle toggles each time a track is started on a given channel.
+ // The toggle is concatenated with the SoundChannel address and passed to AudioTrack
+ // as callback user data. This enables the detection of callbacks received from the old
+ // audio track while the new one is being started and avoids processing them with
+ // wrong audio audio buffer size (mAudioBufferSize)
+ unsigned long toggle = mToggle ^ 1;
+ void *userData = (void *)((unsigned long)this | toggle);
+
#ifdef USE_SHARED_MEM_BUFFER
newTrack = new AudioTrack(mSoundPool->streamType(), sampleRate, sample->format(),
- numChannels, sample->getIMemory(), 0, callback, this);
+ numChannels, sample->getIMemory(), 0, callback, userData);
#else
newTrack = new AudioTrack(mSoundPool->streamType(), sampleRate, sample->format(),
- numChannels, frameCount, 0, callback, this, bufferFrames);
+ numChannels, frameCount, 0, callback, userData, bufferFrames);
#endif
if (newTrack->initCheck() != NO_ERROR) {
LOGE("Error creating AudioTrack");
@@ -529,6 +539,8 @@ void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftV
{
Mutex::Autolock lock(&mLock);
+ // From now on, AudioTrack callbacks recevieved with previous toggle value will be ignored.
+ mToggle = toggle;
oldTrack = mAudioTrack;
mAudioTrack = newTrack;
mPos = 0;
@@ -583,7 +595,13 @@ void SoundChannel::nextEvent()
void SoundChannel::callback(int event, void* user, void *info)
{
- SoundChannel* channel = static_cast<SoundChannel*>(user);
+ unsigned long toggle = (unsigned long)user & 1;
+ SoundChannel* channel = static_cast<SoundChannel*>((void *)((unsigned long)user & ~1));
+
+ if (channel->mToggle != toggle) {
+ LOGV("callback with wrong toggle");
+ return;
+ }
channel->process(event, info);
}
@@ -592,7 +610,7 @@ void SoundChannel::process(int event, void *info)
//LOGV("process(%d)", mChannelID);
sp<Sample> sample = mSample;
- LOGV("SoundChannel::process event %d", event);
+// LOGV("SoundChannel::process event %d", event);
if (event == AudioTrack::EVENT_MORE_DATA) {
AudioTrack::Buffer* b = static_cast<AudioTrack::Buffer *>(info);
diff --git a/media/jni/soundpool/SoundPool.h b/media/jni/soundpool/SoundPool.h
index d02ae8b..7802781 100644
--- a/media/jni/soundpool/SoundPool.h
+++ b/media/jni/soundpool/SoundPool.h
@@ -118,7 +118,7 @@ protected:
class SoundChannel : public SoundEvent {
public:
enum state { IDLE, RESUMING, STOPPING, PAUSED, PLAYING };
- SoundChannel() : mAudioTrack(0), mState(IDLE), mNumChannels(1), mPos(0) {}
+ SoundChannel() : mAudioTrack(0), mState(IDLE), mNumChannels(1), mPos(0), mToggle(0) {}
~SoundChannel();
void init(SoundPool* soundPool);
void play(const sp<Sample>& sample, int channelID, float leftVolume, float rightVolume,
@@ -151,6 +151,7 @@ private:
int mNumChannels;
int mPos;
int mAudioBufferSize;
+ unsigned long mToggle;
};
// application object for managing a pool of sounds
@@ -215,8 +216,6 @@ private:
int mAllocated;
int mNextSampleID;
int mNextChannelID;
- int mFrameCount;
- int mSampleRate;
bool mQuit;
};
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 2a697b9..8020da2 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -4,6 +4,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
AudioTrack.cpp \
IAudioFlinger.cpp \
+ IAudioFlingerClient.cpp \
IAudioTrack.cpp \
IAudioRecord.cpp \
AudioRecord.cpp \
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 3d39181..a987b92 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -128,8 +128,22 @@ status_t AudioRecord::set(
return BAD_VALUE;
}
- // TODO: Get input frame count from hardware.
- int minFrameCount = 1024*2;
+ size_t inputBuffSizeInBytes = -1;
+ if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &inputBuffSizeInBytes)
+ != NO_ERROR) {
+ LOGE("AudioSystem could not query the input buffer size.");
+ return NO_INIT;
+ }
+ if (inputBuffSizeInBytes == 0) {
+ LOGE("Recording parameters are not supported: sampleRate %d, channelCount %d, format %d",
+ sampleRate, channelCount, format);
+ return BAD_VALUE;
+ }
+ int frameSizeInBytes = channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1);
+
+ // We use 2* size of input buffer for ping pong use of record buffer.
+ int minFrameCount = 2 * inputBuffSizeInBytes / frameSizeInBytes;
+ LOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
if (frameCount == 0) {
frameCount = minFrameCount;
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index a375b55..cf91105 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -15,6 +15,8 @@
*/
#define LOG_TAG "AudioSystem"
+//#define LOG_NDEBUG 0
+
#include <utils/Log.h>
#include <utils/IServiceManager.h>
#include <media/AudioSystem.h>
@@ -26,12 +28,17 @@ namespace android {
// client singleton for AudioFlinger binder interface
Mutex AudioSystem::gLock;
sp<IAudioFlinger> AudioSystem::gAudioFlinger;
-sp<AudioSystem::DeathNotifier> AudioSystem::gDeathNotifier;
+sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient;
audio_error_callback AudioSystem::gAudioErrorCallback = NULL;
// Cached values
int AudioSystem::gOutSamplingRate = 0;
int AudioSystem::gOutFrameCount = 0;
uint32_t AudioSystem::gOutLatency = 0;
+// Cached values for recording queries
+uint32_t AudioSystem::gPrevInSamplingRate = 16000;
+int AudioSystem::gPrevInFormat = AudioSystem::PCM_16_BIT;
+int AudioSystem::gPrevInChannelCount = 1;
+size_t AudioSystem::gInBuffSize = 0;
// establish binder interface to AudioFlinger service
@@ -48,15 +55,16 @@ const sp<IAudioFlinger>& AudioSystem::get_audio_flinger()
LOGW("AudioFlinger not published, waiting...");
usleep(500000); // 0.5 s
} while(true);
- if (gDeathNotifier == NULL) {
- gDeathNotifier = new DeathNotifier();
+ if (gAudioFlingerClient == NULL) {
+ gAudioFlingerClient = new AudioFlingerClient();
} else {
if (gAudioErrorCallback) {
gAudioErrorCallback(NO_ERROR);
}
}
- binder->linkToDeath(gDeathNotifier);
+ binder->linkToDeath(gAudioFlingerClient);
gAudioFlinger = interface_cast<IAudioFlinger>(binder);
+ gAudioFlinger->registerClient(gAudioFlingerClient);
// Cache frequently accessed parameters
gOutFrameCount = (int)gAudioFlinger->frameCount();
gOutSamplingRate = (int)gAudioFlinger->sampleRate();
@@ -250,7 +258,7 @@ status_t AudioSystem::getOutputSamplingRate(int* samplingRate)
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
// gOutSamplingRate is updated by get_audio_flinger()
- }
+ }
*samplingRate = gOutSamplingRate;
return NO_ERROR;
@@ -261,7 +269,7 @@ status_t AudioSystem::getOutputFrameCount(int* frameCount)
if (gOutFrameCount == 0) {
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
- // gOutSamplingRate is updated by get_audio_flinger()
+ // gOutFrameCount is updated by get_audio_flinger()
}
*frameCount = gOutFrameCount;
return NO_ERROR;
@@ -279,14 +287,38 @@ status_t AudioSystem::getOutputLatency(uint32_t* latency)
return NO_ERROR;
}
+status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, int format, int channelCount,
+ size_t* buffSize)
+{
+ // Do we have a stale gInBufferSize or are we requesting the input buffer size for new values
+ if ((gInBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat)
+ || (channelCount != gPrevInChannelCount)) {
+ // save the request params
+ gPrevInSamplingRate = sampleRate;
+ gPrevInFormat = format;
+ gPrevInChannelCount = channelCount;
+
+ gInBuffSize = 0;
+ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
+ if (af == 0) {
+ return PERMISSION_DENIED;
+ }
+ gInBuffSize = af->getInputBufferSize(sampleRate, format, channelCount);
+ }
+ *buffSize = gInBuffSize;
+
+ return NO_ERROR;
+}
+
// ---------------------------------------------------------------------------
-void AudioSystem::DeathNotifier::binderDied(const wp<IBinder>& who) {
+void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who) {
Mutex::Autolock _l(AudioSystem::gLock);
AudioSystem::gAudioFlinger.clear();
AudioSystem::gOutSamplingRate = 0;
AudioSystem::gOutFrameCount = 0;
AudioSystem::gOutLatency = 0;
+ AudioSystem::gInBuffSize = 0;
if (gAudioErrorCallback) {
gAudioErrorCallback(DEAD_OBJECT);
@@ -294,6 +326,15 @@ void AudioSystem::DeathNotifier::binderDied(const wp<IBinder>& who) {
LOGW("AudioFlinger server died!");
}
+void AudioSystem::AudioFlingerClient::audioOutputChanged(uint32_t frameCount, uint32_t samplingRate, uint32_t latency) {
+
+ AudioSystem::gOutFrameCount = frameCount;
+ AudioSystem::gOutSamplingRate = samplingRate;
+ AudioSystem::gOutLatency = latency;
+
+ LOGV("AudioFlinger output changed!");
+}
+
void AudioSystem::setErrorCallback(audio_error_callback cb) {
Mutex::Autolock _l(AudioSystem::gLock);
gAudioErrorCallback = cb;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index f9f8568..63b2012 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -603,13 +603,17 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
if (__builtin_expect(result!=NO_ERROR, false)) {
cblk->waitTimeMs += WAIT_PERIOD_MS;
if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) {
- LOGW( "obtainBuffer timed out (is the CPU pegged?) "
- "user=%08x, server=%08x", cblk->user, cblk->server);
- mAudioTrack->start(); // FIXME: Wake up audioflinger
- timeout = 1;
+ // timing out when a loop has been set and we have already written upto loop end
+ // is a normal condition: no need to wake AudioFlinger up.
+ if (cblk->user < cblk->loopEnd) {
+ LOGW( "obtainBuffer timed out (is the CPU pegged?) "
+ "user=%08x, server=%08x", cblk->user, cblk->server);
+ mAudioFlinger->wakeUp();
+ timeout = 1;
+ }
cblk->waitTimeMs = 0;
}
- ;
+
if (--waitCount == 0) {
return TIMED_OUT;
}
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 018ea6c..4215820 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -51,6 +51,9 @@ enum {
GET_MIC_MUTE,
IS_MUSIC_ACTIVE,
SET_PARAMETER,
+ REGISTER_CLIENT,
+ GET_INPUTBUFFERSIZE,
+ WAKE_UP
};
class BpAudioFlinger : public BpInterface<IAudioFlinger>
@@ -303,6 +306,33 @@ public:
remote()->transact(SET_PARAMETER, data, &reply);
return reply.readInt32();
}
+
+ virtual void registerClient(const sp<IAudioFlingerClient>& client)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ data.writeStrongBinder(client->asBinder());
+ remote()->transact(REGISTER_CLIENT, data, &reply);
+ }
+
+ virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ data.writeInt32(sampleRate);
+ data.writeInt32(format);
+ data.writeInt32(channelCount);
+ remote()->transact(GET_INPUTBUFFERSIZE, data, &reply);
+ return reply.readInt32();
+ }
+
+ virtual void wakeUp()
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
+ remote()->transact(WAKE_UP, data, &reply);
+ return;
+ }
};
IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
@@ -470,6 +500,26 @@ status_t BnAudioFlinger::onTransact(
reply->writeInt32( setParameter(key, value) );
return NO_ERROR;
} break;
+ case REGISTER_CLIENT: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient>(data.readStrongBinder());
+ registerClient(client);
+ return NO_ERROR;
+ } break;
+ case GET_INPUTBUFFERSIZE: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ uint32_t sampleRate = data.readInt32();
+ int format = data.readInt32();
+ int channelCount = data.readInt32();
+ reply->writeInt32( getInputBufferSize(sampleRate, format, channelCount) );
+ return NO_ERROR;
+ } break;
+ case WAKE_UP: {
+ CHECK_INTERFACE(IAudioFlinger, data, reply);
+ wakeUp();
+ return NO_ERROR;
+ } break;
+
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/IAudioFlingerClient.cpp b/media/libmedia/IAudioFlingerClient.cpp
new file mode 100644
index 0000000..d956266
--- /dev/null
+++ b/media/libmedia/IAudioFlingerClient.cpp
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed 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.
+ */
+
+#define LOG_TAG "IAudioFlingerClient"
+#include <utils/Log.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Parcel.h>
+
+#include <media/IAudioFlingerClient.h>
+
+namespace android {
+
+enum {
+ AUDIO_OUTPUT_CHANGED = IBinder::FIRST_CALL_TRANSACTION
+};
+
+class BpAudioFlingerClient : public BpInterface<IAudioFlingerClient>
+{
+public:
+ BpAudioFlingerClient(const sp<IBinder>& impl)
+ : BpInterface<IAudioFlingerClient>(impl)
+ {
+ }
+
+ void audioOutputChanged(uint32_t frameCount, uint32_t samplingRate, uint32_t latency)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioFlingerClient::getInterfaceDescriptor());
+ data.writeInt32(frameCount);
+ data.writeInt32(samplingRate);
+ data.writeInt32(latency);
+ remote()->transact(AUDIO_OUTPUT_CHANGED, data, &reply);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(AudioFlingerClient, "android.media.IAudioFlingerClient");
+
+// ----------------------------------------------------------------------
+
+#define CHECK_INTERFACE(interface, data, reply) \
+ do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
+ LOGW("Call incorrectly routed to " #interface); \
+ return PERMISSION_DENIED; \
+ } } while (0)
+
+status_t BnAudioFlingerClient::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ switch(code) {
+ case AUDIO_OUTPUT_CHANGED: {
+ CHECK_INTERFACE(IAudioFlingerClient, data, reply);
+ uint32_t frameCount = data.readInt32();
+ uint32_t samplingRate = data.readInt32();
+ uint32_t latency = data.readInt32();
+ audioOutputChanged(frameCount, samplingRate, latency);
+ return NO_ERROR;
+ } break;
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp
index f0edf88..ead24d4 100644
--- a/media/libmedia/JetPlayer.cpp
+++ b/media/libmedia/JetPlayer.cpp
@@ -214,12 +214,15 @@ int JetPlayer::render() {
}
p += count * pLibConfig->numChannels;
num_output += count * pLibConfig->numChannels * sizeof(EAS_PCM);
+
+ // send events that were generated (if any) to the event callback
+ fireEventsFromJetQueue();
}
// update playback state
//LOGV("JetPlayer::render(): updating state");
JET_Status(mEasData, &mJetStatus);
- fireEventOnStatusChange();
+ fireUpdateOnStatusChange();
mPaused = mJetStatus.paused;
mMutex.unlock(); // UNLOCK ]]]]]]]] -----------------------------------
@@ -261,9 +264,9 @@ threadExit:
//-------------------------------------------------------------------------------------------------
-// fire up an event if any of the status fields has changed
+// fire up an update if any of the status fields has changed
// precondition: mMutex locked
-void JetPlayer::fireEventOnStatusChange()
+void JetPlayer::fireUpdateOnStatusChange()
{
if( (mJetStatus.currentUserID != mPreviousJetStatus.currentUserID)
||(mJetStatus.segmentRepeatCount != mPreviousJetStatus.segmentRepeatCount) ) {
@@ -303,9 +306,31 @@ void JetPlayer::fireEventOnStatusChange()
//-------------------------------------------------------------------------------------------------
-int JetPlayer::openFile(const char* path)
+// fire up all the JET events in the JET engine queue (until the queue is empty)
+// precondition: mMutex locked
+void JetPlayer::fireEventsFromJetQueue()
+{
+ if(!mEventCallback) {
+ // no callback, just empty the event queue
+ while (JET_GetEvent(mEasData, NULL, NULL)) { }
+ return;
+ }
+
+ EAS_U32 rawEvent;
+ while (JET_GetEvent(mEasData, &rawEvent, NULL)) {
+ mEventCallback(
+ JetPlayer::JET_EVENT,
+ rawEvent,
+ -1,
+ mJavaJetPlayerRef);
+ }
+}
+
+
+//-------------------------------------------------------------------------------------------------
+int JetPlayer::loadFromFile(const char* path)
{
- LOGV("JetPlayer::openFile(): path=%s", path);
+ LOGV("JetPlayer::loadFromFile(): path=%s", path);
Mutex::Autolock lock(mMutex);
@@ -326,6 +351,29 @@ int JetPlayer::openFile(const char* path)
return( result );
}
+
+//-------------------------------------------------------------------------------------------------
+int JetPlayer::loadFromFD(const int fd, const long long offset, const long long length)
+{
+ LOGV("JetPlayer::loadFromFD(): fd=%d offset=%lld length=%lld", fd, offset, length);
+
+ Mutex::Autolock lock(mMutex);
+
+ mEasJetFileLoc = (EAS_FILE_LOCATOR) malloc(sizeof(EAS_FILE));
+ mEasJetFileLoc->fd = fd;
+ mEasJetFileLoc->offset = offset;
+ mEasJetFileLoc->length = length;
+ mEasJetFileLoc->path = NULL;
+
+ EAS_RESULT result = JET_OpenFile(mEasData, mEasJetFileLoc);
+ if(result != EAS_SUCCESS)
+ mState = EAS_STATE_ERROR;
+ else
+ mState = EAS_STATE_OPEN;
+ return( result );
+}
+
+
//-------------------------------------------------------------------------------------------------
int JetPlayer::closeFile()
{
@@ -348,7 +396,7 @@ int JetPlayer::play()
JET_Status(mEasData, &mJetStatus);
this->dumpJetStatus(&mJetStatus);
- fireEventOnStatusChange();
+ fireUpdateOnStatusChange();
// wake up render thread
LOGV("JetPlayer::play(): wakeup render thread");
@@ -368,7 +416,7 @@ int JetPlayer::pause()
JET_Status(mEasData, &mJetStatus);
this->dumpJetStatus(&mJetStatus);
- fireEventOnStatusChange();
+ fireUpdateOnStatusChange();
return result;
@@ -408,6 +456,14 @@ int JetPlayer::triggerClip(int clipId)
}
//-------------------------------------------------------------------------------------------------
+int JetPlayer::clearQueue()
+{
+ LOGV("JetPlayer::clearQueue");
+ Mutex::Autolock lock(mMutex);
+ return JET_Clear_Queue(mEasData);
+}
+
+//-------------------------------------------------------------------------------------------------
void JetPlayer::dump()
{
LOGE("JetPlayer dump: JET file=%s", mEasJetFileLoc->path);
diff --git a/media/libmedia/ToneGenerator.cpp b/media/libmedia/ToneGenerator.cpp
index 584d135..fa36460 100644
--- a/media/libmedia/ToneGenerator.cpp
+++ b/media/libmedia/ToneGenerator.cpp
@@ -97,10 +97,6 @@ ToneGenerator::ToneGenerator(int streamType, float volume) {
LOGE("Unable to marshal AudioFlinger");
return;
}
- if (AudioSystem::getOutputFrameCount(&mBufferSize) != NO_ERROR) {
- LOGE("Unable to marshal AudioFlinger");
- return;
- }
mStreamType = streamType;
mVolume = volume;
mpAudioTrack = 0;
@@ -275,9 +271,9 @@ bool ToneGenerator::initAudioTrack() {
mpAudioTrack = 0;
}
- // Open audio track in mono, PCM 16bit, default sampling rate, 2 buffers of
+ // Open audio track in mono, PCM 16bit, default sampling rate, default buffer size
mpAudioTrack
- = new AudioTrack(mStreamType, 0, AudioSystem::PCM_16_BIT, 1, NUM_PCM_BUFFERS*mBufferSize, 0, audioCallback, this, mBufferSize);
+ = new AudioTrack(mStreamType, 0, AudioSystem::PCM_16_BIT, 1, 0, 0, audioCallback, this, 0);
if (mpAudioTrack == 0) {
LOGE("AudioTrack allocation failed");
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index ebdbda8..31ff507 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -172,7 +172,7 @@ status_t MediaPlayer::setDataSource(const sp<IMediaPlayer>& player)
status_t MediaPlayer::setDataSource(const char *url)
{
LOGV("setDataSource(%s)", url);
- status_t err = UNKNOWN_ERROR;
+ status_t err = BAD_VALUE;
if (url != NULL) {
const sp<IMediaPlayerService>& service(getMediaPlayerService());
if (service != 0) {
@@ -199,7 +199,7 @@ status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface)
{
LOGV("setVideoSurface");
Mutex::Autolock _l(mLock);
- if (mPlayer == 0) return UNKNOWN_ERROR;
+ if (mPlayer == 0) return NO_INIT;
return mPlayer->setVideoSurface(surface->getISurface());
}
@@ -219,7 +219,7 @@ status_t MediaPlayer::prepare()
{
LOGV("prepare");
Mutex::Autolock _l(mLock);
- if (mPrepareSync) return UNKNOWN_ERROR;
+ if (mPrepareSync) return -EALREADY;
mPrepareSync = true;
status_t ret = prepareAsync_l();
if (ret != NO_ERROR) return ret;
@@ -253,7 +253,6 @@ status_t MediaPlayer::start()
status_t ret = mPlayer->start();
if (ret != NO_ERROR) {
mCurrentState = MEDIA_PLAYER_STATE_ERROR;
- ret = UNKNOWN_ERROR;
} else {
if (mCurrentState == MEDIA_PLAYER_PLAYBACK_COMPLETE) {
LOGV("playback completed immediately following start()");
@@ -275,7 +274,6 @@ status_t MediaPlayer::stop()
status_t ret = mPlayer->stop();
if (ret != NO_ERROR) {
mCurrentState = MEDIA_PLAYER_STATE_ERROR;
- ret = UNKNOWN_ERROR;
} else {
mCurrentState = MEDIA_PLAYER_STOPPED;
}
@@ -295,7 +293,6 @@ status_t MediaPlayer::pause()
status_t ret = mPlayer->pause();
if (ret != NO_ERROR) {
mCurrentState = MEDIA_PLAYER_STATE_ERROR;
- ret = UNKNOWN_ERROR;
} else {
mCurrentState = MEDIA_PLAYER_PAUSED;
}
@@ -422,7 +419,6 @@ status_t MediaPlayer::reset()
if (ret != NO_ERROR) {
LOGE("reset() failed with return code (%d)", ret);
mCurrentState = MEDIA_PLAYER_STATE_ERROR;
- ret = UNKNOWN_ERROR;
} else {
mCurrentState = MEDIA_PLAYER_IDLE;
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 53831717..9e366e2 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -61,113 +61,32 @@ pid_t gettid() { return syscall(__NR_gettid);}
#undef __KERNEL__
#endif
-/*
- When USE_SIGBUS_HANDLER is set to 1, a handler for SIGBUS will be
- installed, which allows us to recover when there is a read error
- when accessing an mmap'ed file. However, since the kernel folks
- don't seem to like it when non kernel folks install signal handlers
- in their own process, this is currently disabled.
- Without the handler, the process hosting this service will die and
- then be restarted. This is mostly OK right now because the process is
- not being shared with any other services, and clients of the service
- will be notified of its death in their MediaPlayer.onErrorListener
- callback, assuming they have installed one, and can then attempt to
- do their own recovery.
- It does open us up to a DOS attack against the media server, where
- a malicious application can trivially force the media server to
- restart continuously.
-*/
-#define USE_SIGBUS_HANDLER 0
+
+namespace android {
// TODO: Temp hack until we can register players
-static const char* MIDI_FILE_EXTS[] =
-{
- ".mid",
- ".smf",
- ".xmf",
- ".imy",
- ".rtttl",
- ".rtx",
- ".ota"
+typedef struct {
+ const char *extension;
+ const player_type playertype;
+} extmap;
+extmap FILE_EXTS [] = {
+ {".mid", SONIVOX_PLAYER},
+ {".midi", SONIVOX_PLAYER},
+ {".smf", SONIVOX_PLAYER},
+ {".xmf", SONIVOX_PLAYER},
+ {".imy", SONIVOX_PLAYER},
+ {".rtttl", SONIVOX_PLAYER},
+ {".rtx", SONIVOX_PLAYER},
+ {".ota", SONIVOX_PLAYER},
+ {".ogg", VORBIS_PLAYER},
+ {".oga", VORBIS_PLAYER},
};
-namespace android {
-
// TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround
/* static */ const uint32_t MediaPlayerService::AudioOutput::kAudioVideoDelayMs = 96;
/* static */ int MediaPlayerService::AudioOutput::mMinBufferCount = 4;
/* static */ bool MediaPlayerService::AudioOutput::mIsOnEmulator = false;
-static struct sigaction oldact;
-static pthread_key_t sigbuskey;
-
-static void sigbushandler(int signal, siginfo_t *info, void *context)
-{
- char *faultaddr = (char*) info->si_addr;
- LOGE("SIGBUS at %p\n", faultaddr);
-
- struct mediasigbushandler* h = (struct mediasigbushandler*) pthread_getspecific(sigbuskey);
-
- if (h) {
- if (h->len) {
- if (faultaddr < h->base || faultaddr >= h->base + h->len) {
- // outside specified range, call old handler
- if (oldact.sa_flags & SA_SIGINFO) {
- oldact.sa_sigaction(signal, info, context);
- } else {
- oldact.sa_handler(signal);
- }
- return;
- }
- }
-
- // no range specified or address was in range
-
- if (h->handlesigbus) {
- if (h->handlesigbus(info, h)) {
- // thread's handler didn't handle the signal
- if (oldact.sa_flags & SA_SIGINFO) {
- oldact.sa_sigaction(signal, info, context);
- } else {
- oldact.sa_handler(signal);
- }
- }
- return;
- }
-
- if (h->sigbusvar) {
- // map in a zeroed out page so the operation can succeed
- long pagesize = sysconf(_SC_PAGE_SIZE);
- long pagemask = ~(pagesize - 1);
- void * pageaddr = (void*) (((long)(faultaddr)) & pagemask);
-
- void * bar = mmap( pageaddr, pagesize, PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE|MAP_FIXED, -1, 0);
- if (bar == MAP_FAILED) {
- LOGE("couldn't map zero page at %p: %s", pageaddr, strerror(errno));
- if (oldact.sa_flags & SA_SIGINFO) {
- oldact.sa_sigaction(signal, info, context);
- } else {
- oldact.sa_handler(signal);
- }
- return;
- }
-
- LOGE("setting sigbusvar at %p", h->sigbusvar);
- *(h->sigbusvar) = 1;
- return;
- }
- }
-
- LOGE("SIGBUS: no handler, or improperly configured handler (%p)", h);
-
- if (oldact.sa_flags & SA_SIGINFO) {
- oldact.sa_sigaction(signal, info, context);
- } else {
- oldact.sa_handler(signal);
- }
- return;
-}
-
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
@@ -177,25 +96,10 @@ MediaPlayerService::MediaPlayerService()
{
LOGV("MediaPlayerService created");
mNextConnId = 1;
-
- pthread_key_create(&sigbuskey, NULL);
-
-
-#if USE_SIGBUS_HANDLER
- struct sigaction act;
- memset(&act,0, sizeof act);
- act.sa_sigaction = sigbushandler;
- act.sa_flags = SA_SIGINFO;
- sigaction(SIGBUS, &act, &oldact);
-#endif
}
MediaPlayerService::~MediaPlayerService()
{
-#if USE_SIGBUS_HANDLER
- sigaction(SIGBUS, &oldact, NULL);
-#endif
- pthread_key_delete(sigbuskey);
LOGV("MediaPlayerService destroyed");
}
@@ -481,7 +385,7 @@ static player_type getPlayerType(int fd, int64_t offset, int64_t length)
locator.offset = offset;
locator.length = length;
EAS_HANDLE eashandle;
- if (EAS_OpenFile(easdata, &locator, &eashandle, NULL) == EAS_SUCCESS) {
+ if (EAS_OpenFile(easdata, &locator, &eashandle) == EAS_SUCCESS) {
EAS_CloseFile(easdata, eashandle);
EAS_Shutdown(easdata);
return SONIVOX_PLAYER;
@@ -498,22 +402,16 @@ static player_type getPlayerType(const char* url)
// use MidiFile for MIDI extensions
int lenURL = strlen(url);
- for (int i = 0; i < NELEM(MIDI_FILE_EXTS); ++i) {
- int len = strlen(MIDI_FILE_EXTS[i]);
+ for (int i = 0; i < NELEM(FILE_EXTS); ++i) {
+ int len = strlen(FILE_EXTS[i].extension);
int start = lenURL - len;
if (start > 0) {
- if (!strncmp(url + start, MIDI_FILE_EXTS[i], len)) {
- LOGV("Type is MIDI");
- return SONIVOX_PLAYER;
+ if (!strncmp(url + start, FILE_EXTS[i].extension, len)) {
+ return FILE_EXTS[i].playertype;
}
}
}
- if (strcmp(url + strlen(url) - 4, ".ogg") == 0) {
- LOGV("Type is Vorbis");
- return VORBIS_PLAYER;
- }
-
// Fall through to PV
return PV_PLAYER;
}
@@ -539,7 +437,6 @@ static sp<MediaPlayerBase> createPlayer(player_type playerType, void* cookie,
if (p != NULL) {
if (p->initCheck() == NO_ERROR) {
p->setNotifyCallback(cookie, notifyFunc);
- p->setSigBusHandlerStructTLSKey(sigbuskey);
} else {
p.clear();
}
diff --git a/media/libmediaplayerservice/MidiFile.cpp b/media/libmediaplayerservice/MidiFile.cpp
index cfad66c..7ce2fab 100644
--- a/media/libmediaplayerservice/MidiFile.cpp
+++ b/media/libmediaplayerservice/MidiFile.cpp
@@ -40,8 +40,6 @@ static pid_t myTid() { return getpid(); }
// ----------------------------------------------------------------------------
-extern pthread_key_t EAS_sigbuskey;
-
namespace android {
// ----------------------------------------------------------------------------
@@ -132,7 +130,7 @@ status_t MidiFile::setDataSource(const char* path)
mFileLocator.fd = -1;
mFileLocator.offset = 0;
mFileLocator.length = 0;
- EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle, &mMemFailedVar);
+ EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle);
if (result == EAS_SUCCESS) {
updateState();
}
@@ -148,12 +146,6 @@ status_t MidiFile::setDataSource(const char* path)
return NO_ERROR;
}
-status_t MidiFile::setSigBusHandlerStructTLSKey(pthread_key_t key)
-{
- EAS_sigbuskey = key;
- return 0;
-}
-
status_t MidiFile::setDataSource(int fd, int64_t offset, int64_t length)
{
LOGV("MidiFile::setDataSource fd=%d", fd);
@@ -168,7 +160,7 @@ status_t MidiFile::setDataSource(int fd, int64_t offset, int64_t length)
mFileLocator.fd = dup(fd);
mFileLocator.offset = offset;
mFileLocator.length = length;
- EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle, &mMemFailedVar);
+ EAS_RESULT result = EAS_OpenFile(mEasData, &mFileLocator, &mEasHandle);
updateState();
if (result != EAS_SUCCESS) {
@@ -332,7 +324,7 @@ status_t MidiFile::getDuration(int* duration)
EAS_HANDLE easHandle = NULL;
EAS_RESULT result = EAS_Init(&easData);
if (result == EAS_SUCCESS) {
- result = EAS_OpenFile(easData, &mFileLocator, &easHandle, NULL);
+ result = EAS_OpenFile(easData, &mFileLocator, &easHandle);
}
if (result == EAS_SUCCESS) {
result = EAS_Prepare(easData, easHandle);
@@ -451,8 +443,6 @@ int MidiFile::render() {
LOGV("MidiFile::render");
- struct mediasigbushandler sigbushandler;
-
// allocate render buffer
mAudioBuffer = new EAS_PCM[pLibConfig->mixBufferSize * pLibConfig->numChannels * NUM_BUFFERS];
if (!mAudioBuffer) {
@@ -468,10 +458,6 @@ int MidiFile::render() {
mCondition.signal();
}
- sigbushandler.handlesigbus = NULL;
- sigbushandler.sigbusvar = mMemFailedVar;
- pthread_setspecific(EAS_sigbuskey, &sigbushandler);
-
while (1) {
mMutex.lock();
diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h
index 9d2dfdd..302f1cf 100644
--- a/media/libmediaplayerservice/MidiFile.h
+++ b/media/libmediaplayerservice/MidiFile.h
@@ -30,7 +30,6 @@ public:
~MidiFile();
virtual status_t initCheck();
- virtual status_t setSigBusHandlerStructTLSKey(pthread_key_t key);
virtual status_t setDataSource(const char* path);
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual status_t setVideoSurface(const sp<ISurface>& surface) { return UNKNOWN_ERROR; }
@@ -57,7 +56,6 @@ private:
Mutex mMutex;
Condition mCondition;
- int* mMemFailedVar;
EAS_DATA_HANDLE mEasData;
EAS_HANDLE mEasHandle;
EAS_PCM* mAudioBuffer;
diff --git a/media/libmediaplayerservice/VorbisPlayer.cpp b/media/libmediaplayerservice/VorbisPlayer.cpp
index 9a64403..009d628 100644
--- a/media/libmediaplayerservice/VorbisPlayer.cpp
+++ b/media/libmediaplayerservice/VorbisPlayer.cpp
@@ -455,13 +455,15 @@ int VorbisPlayer::render() {
current_section = 0;
numread = ov_read(&mVorbisFile, mAudioBuffer, AUDIOBUFFER_SIZE, &current_section);
} else {
- sendEvent(MEDIA_PLAYBACK_COMPLETE);
mAudioSink->stop();
audioStarted = false;
mRender = false;
mPaused = true;
int endpos = ov_time_tell(&mVorbisFile);
+ LOGV("send MEDIA_PLAYBACK_COMPLETE");
+ sendEvent(MEDIA_PLAYBACK_COMPLETE);
+
// wait until we're started again
LOGV("playback complete - wait for signal");
mCondition.wait(mMutex);
diff --git a/media/sdutils/sdutil.cpp b/media/sdutils/sdutil.cpp
index 0daa523..a9aabf0 100644
--- a/media/sdutils/sdutil.cpp
+++ b/media/sdutils/sdutil.cpp
@@ -114,6 +114,16 @@ static int unmount(const char* path) {
return -1;
}
+static int format(const char* path) {
+ String16 string(path);
+
+ if (isMounted(path))
+ return -EBUSY;
+ gMountService->formatMedia(string);
+
+ return 0;
+}
+
static int umsEnable(bool enable) {
gMountService->setMassStorageEnabled(enable);
return 0;
@@ -129,6 +139,9 @@ int main(int argc, char **argv)
if (strcmp(command, "mount") == 0) {
android::init();
return android::mount(argument);
+ } else if (strcmp(command, "format") == 0) {
+ android::init();
+ return android::format(argument);
} else if (strcmp(command, "unmount") == 0) {
android::init();
return android::unmount(argument);
@@ -145,6 +158,7 @@ int main(int argc, char **argv)
fprintf(stderr, "usage:\n"
" sdutil mount <mount path> - mounts the SD card at the given mount point\n"
" sdutil unmount <mount path> - unmounts the SD card at the given mount point\n"
+ " sdutil format <mount path> - formats the SD card at the given mount point\n"
" sdutil ums enable - enables USB mass storage\n"
" sdutil ums disable - disnables USB mass storage\n"
);
diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml
index 16e658a..a32f590 100644
--- a/media/tests/MediaFrameworkTest/AndroidManifest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml
@@ -42,5 +42,10 @@
android:targetPackage="com.android.mediaframeworktest"
android:label="MediaFramework unit tests InstrumentationRunner">
</instrumentation>
+
+ <instrumentation android:name=".MediaRecorderStressTestRunner"
+ android:targetPackage="com.android.mediaframeworktest"
+ android:label="MediaRecorder stress tests InstrumentationRunner">
+ </instrumentation>
</manifest>
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
index 3d3878e..1731940 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
@@ -21,6 +21,7 @@ import com.android.mediaframeworktest.functional.SimTonesTest;
import com.android.mediaframeworktest.functional.MediaMetadataTest;
import com.android.mediaframeworktest.functional.CameraTest;
import com.android.mediaframeworktest.functional.MediaRecorderTest;
+import com.android.mediaframeworktest.functional.MediaAudioTrackTest;
import junit.framework.TestSuite;
@@ -48,6 +49,7 @@ public class MediaFrameworkTestRunner extends InstrumentationTestRunner {
suite.addTestSuite(MediaMetadataTest.class);
suite.addTestSuite(CameraTest.class);
suite.addTestSuite(MediaRecorderTest.class);
+ suite.addTestSuite(MediaAudioTrackTest.class);
return suite;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
index 5843007..5e9c488 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaNames.java
@@ -25,16 +25,16 @@ package com.android.mediaframeworktest;
public class MediaNames {
//Audio files
- public static final String MP3CBR = "/sdcard/music/MP3CBR.mp3";
- public static final String MP3VBR = "/sdcard/music/MP3VBR.mp3";
- public static final String SHORTMP3 = "/sdcard/music/SHORTMP3.mp3";
- public static final String MIDI = "/sdcard/music/MIDI.mid";
- public static final String WMA9 = "/sdcard/music/WMA9.wma";
- public static final String WMA10 = "/sdcard/music/WMA10.wma";
- public static final String WAV = "/sdcard/music/complicated_wav.wav";
- public static final String AMR = "/sdcard/music/AMRNB.amr";
- public static final String OGG = "/sdcard/music/Mists_of_Time-4T.ogg";
- public static final String OGGSHORT = "/sdcard/music/Skippy.ogg";
+ public static final String MP3CBR = "/sdcard/media_api/music/MP3CBR.mp3";
+ public static final String MP3VBR = "/sdcard/media_api/music/MP3VBR.mp3";
+ public static final String SHORTMP3 = "/sdcard/media_api/music/SHORTMP3.mp3";
+ public static final String MIDI = "/sdcard/media_api/music/MIDI.mid";
+ public static final String WMA9 = "/sdcard/media_api/music/WMA9.wma";
+ public static final String WMA10 = "/sdcard/media_api/music/WMA10.wma";
+ public static final String WAV = "/sdcard/media_api/music/complicated_wav.wav";
+ public static final String AMR = "/sdcard/media_api/music/AMRNB.amr";
+ public static final String OGG = "/sdcard/media_api/music/Mists_of_Time-4T.ogg";
+ public static final String OGGSHORT = "/sdcard/media_api/music/Skippy.ogg";
public static final int MP3CBR_LENGTH = 231116;
public static final int MP3VBR_LENGTH = 126407;
@@ -60,20 +60,20 @@ public class MediaNames {
//public static final String VIDEO_RTSP3GP = "rtsp://193.159.241.21/sp/alizee05.3gp";
//local video
- public static final String VIDEO_MP4 = "/sdcard/video/gingerkids.MP4";
- public static final String VIDEO_LONG_3GP = "/sdcard/video/radiohead.3gp";
- public static final String VIDEO_SHORT_3GP = "/sdcard/video/short.3gp";
- public static final String VIDEO_LARGE_SIZE_3GP = "/sdcard/video/border_large.3gp";
- public static final String VIDEO_H263_AAC = "/sdcard/video/H263_AAC.3gp";
- public static final String VIDEO_H263_AMR = "/sdcard/video/H263_AMR.3gp";
- public static final String VIDEO_H264_AAC = "/sdcard/video/H264_AAC.3gp";
- public static final String VIDEO_H264_AMR = "/sdcard/video/H264_AMR.3gp";
- public static final String VIDEO_WMV = "/sdcard/video/bugs.wmv";
- public static final String VIDEO_HIGHRES_H263 = "/sdcard/video/h263_qcif_30fps.3gp";
- public static final String VIDEO_HIGHRES_MP4 = "/sdcard/video/mpeg4_qvga_24fps.3gp";
+ public static final String VIDEO_MP4 = "/sdcard/media_api/video/gingerkids.MP4";
+ public static final String VIDEO_LONG_3GP = "/sdcard/media_api/video/radiohead.3gp";
+ public static final String VIDEO_SHORT_3GP = "/sdcard/media_api/video/short.3gp";
+ public static final String VIDEO_LARGE_SIZE_3GP = "/sdcard/media_api/video/border_large.3gp";
+ public static final String VIDEO_H263_AAC = "/sdcard/media_api/video/H263_AAC.3gp";
+ public static final String VIDEO_H263_AMR = "/sdcard/media_api/video/H263_AMR.3gp";
+ public static final String VIDEO_H264_AAC = "/sdcard/media_api/video/H264_AAC.3gp";
+ public static final String VIDEO_H264_AMR = "/sdcard/media_api/video/H264_AMR.3gp";
+ public static final String VIDEO_WMV = "/sdcard/media_api/video/bugs.wmv";
+ public static final String VIDEO_HIGHRES_H263 = "/sdcard/media_api/video/h263_qcif_30fps.3gp";
+ public static final String VIDEO_HIGHRES_MP4 = "/sdcard/media_api/video/mpeg4_qvga_24fps.3gp";
//ringtone
- public static final String ringtone = "/sdcard/ringtones/F1_NewVoicemail.mp3";
+ public static final String ringtone = "/sdcard/media_api/ringtones/F1_NewVoicemail.mp3";
//streaming mp3
public static final String STREAM_LARGE_MP3 =
@@ -110,264 +110,266 @@ public class MediaNames {
"http://wms.pv.com:7070/MediaDownloadContent/UserUploads/beefcake.mp3";
//Sonivox
- public static String MIDIFILES[] = { "/sdcard/music/Leadsol.mxmf",
- "/sdcard/music/abba.imy", "/sdcard/music/ants.mid",
- "/sdcard/music/greensleeves.rtttl", "/sdcard/music/test.ota"};
+ public static String MIDIFILES[] = {
+ "/sdcard/media_api/music/Leadsol.mxmf",
+ "/sdcard/media_api/music/abba.imy", "/sdcard/media_api/music/ants.mid",
+ "/sdcard/media_api/music/greensleeves.rtttl", "/sdcard/media_api/music/test.ota"};
//Performance measurement
- public static String[] WAVFILES = { "/sdcard/music_perf/WAV/M1F1-AlawWE-AFsp.wav",
- "/sdcard/music_perf/WAV/M1F1-float64-AFsp.wav",
- "/sdcard/music_perf/WAV/song.wav",
- "/sdcard/music_perf/WAV/WAVEtest.wav",
- "/sdcard/music_perf/WAV/WAVEtest_out.wav",
- "/sdcard/music_perf/WAV/test_out.wav"};
-
+ public static String[] WAVFILES = {
+ "/sdcard/media_api/music_perf/WAV/M1F1-AlawWE-AFsp.wav",
+ "/sdcard/media_api/music_perf/WAV/M1F1-float64-AFsp.wav",
+ "/sdcard/media_api/music_perf/WAV/song.wav",
+ "/sdcard/media_api/music_perf/WAV/WAVEtest.wav",
+ "/sdcard/media_api/music_perf/WAV/WAVEtest_out.wav",
+ "/sdcard/media_api/music_perf/WAV/test_out.wav"};
+
public static String[] AMRNBFILES = {
- "/sdcard/music_perf/AMR/AI_AMR-NB_5.9kbps_6.24kbps_8khz_mono_NMC.amr",
- "/sdcard/music_perf/AMR/AI_AMR-NB_5.15kbps_5.46kbps_8khz_mono_NMC.amr",
- "/sdcard/music_perf/AMR/AI_AMR-NB_7.4kbps_7.80kbps_8khz_mono_NMC.amr",
- "/sdcard/music_perf/AMR/AI_AMR-NB_7.95kbps_9.6kbps_8khz_mono_NMC.amr",
- "/sdcard/music_perf/AMR/AI_AMR-NB_10.2kbps_10.48kbps_8khz_mono_NMC.amr"};
+ "/sdcard/media_api/music_perf/AMR/AI_AMR-NB_5.9kbps_6.24kbps_8khz_mono_NMC.amr",
+ "/sdcard/media_api/music_perf/AMR/AI_AMR-NB_5.15kbps_5.46kbps_8khz_mono_NMC.amr",
+ "/sdcard/media_api/music_perf/AMR/AI_AMR-NB_7.4kbps_7.80kbps_8khz_mono_NMC.amr",
+ "/sdcard/media_api/music_perf/AMR/AI_AMR-NB_7.95kbps_9.6kbps_8khz_mono_NMC.amr",
+ "/sdcard/media_api/music_perf/AMR/AI_AMR-NB_10.2kbps_10.48kbps_8khz_mono_NMC.amr"};
public static String[] AMRWBFILES = {
- "/sdcard/music_perf/AMRWB/NIN_AMR-WB_15.85kbps_16kbps.amr",
- "/sdcard/music_perf/AMRWB/NIN_AMR-WB_18.25kbps_18kbps.amr",
- "/sdcard/music_perf/AMRWB/NIN_AMR-WB_19.85kbps_20kbps.amr",
- "/sdcard/music_perf/AMRWB/NIN_AMR-WB_23.05kbps_23kbps.amr",
- "/sdcard/music_perf/AMRWB/NIN_AMR-WB_23.85kbps_24kbps.amr",
- "/sdcard/music_perf/AMRWB/PD_AMR-WB_19.85kbps_20kbps.amr",
- "/sdcard/music_perf/AMRWB/PD_AMR-WB_23.05kbps_23kbps.amr",
- "/sdcard/music_perf/AMRWB/PD_AMR-WB_23.85kbps_24kbps.amr",
- "/sdcard/music_perf/AMRWB/WC_AMR-WB_23.05kbps_23kbps.amr",
- "/sdcard/music_perf/AMRWB/WC_AMR-WB_23.85kbps_24kbps.amr", };
+ "/sdcard/media_api/music_perf/AMRWB/NIN_AMR-WB_15.85kbps_16kbps.amr",
+ "/sdcard/media_api/music_perf/AMRWB/NIN_AMR-WB_18.25kbps_18kbps.amr",
+ "/sdcard/media_api/music_perf/AMRWB/NIN_AMR-WB_19.85kbps_20kbps.amr",
+ "/sdcard/media_api/music_perf/AMRWB/NIN_AMR-WB_23.05kbps_23kbps.amr",
+ "/sdcard/media_api/music_perf/AMRWB/NIN_AMR-WB_23.85kbps_24kbps.amr",
+ "/sdcard/media_api/music_perf/AMRWB/PD_AMR-WB_19.85kbps_20kbps.amr",
+ "/sdcard/media_api/music_perf/AMRWB/PD_AMR-WB_23.05kbps_23kbps.amr",
+ "/sdcard/media_api/music_perf/AMRWB/PD_AMR-WB_23.85kbps_24kbps.amr",
+ "/sdcard/media_api/music_perf/AMRWB/WC_AMR-WB_23.05kbps_23kbps.amr",
+ "/sdcard/media_api/music_perf/AMRWB/WC_AMR-WB_23.85kbps_24kbps.amr", };
public static String[] MP3FILES = {
- "/sdcard/music_perf/MP3/NIN_56kbps_32khz_stereo_VBR_MCA.MP3",
- "/sdcard/music_perf/MP3/NIN_80kbps_32khz_stereo_VBR_MCA.mp3",
- "/sdcard/music_perf/MP3/NIN_80kbps_44.1khz_stereo_VBR_MCA.mp3",
- "/sdcard/music_perf/MP3/NIN_80kbps_48khz_stereo_VBR_MCA.mp3",
- "/sdcard/music_perf/MP3/NIN_112kbps_32khz_stereo_VBR_MCA.mp3",
- "/sdcard/music_perf/MP3/NIN_112kbps_44.1khz_stereo_VBR_MCA.mp3",
- "/sdcard/music_perf/MP3/NIN_112kbps_48khz_stereo_VBR_MCA.mp3",
- "/sdcard/music_perf/MP3/NIN_192kbps_32khz_mono_CBR_MCA.mp3",
- "/sdcard/music_perf/MP3/NIN_192kbps_44.1khz_mono_CBR_MCA.mp3",
- "/sdcard/music_perf/MP3/NIN_192kbps_48khz_mono_CBR_MCA.mp3",
- "/sdcard/music_perf/MP3/NIN_256kbps_44.1khz_mono_CBR_MCA.mp3",
- "/sdcard/music_perf/MP3/NIN_256kbps_48khz_mono_CBR_MCA.mp3",
- "/sdcard/music_perf/MP3/PD_112kbps_32khz_stereo_VBR_MCA.mp3",
- "/sdcard/music_perf/MP3/PD_112kbps_44.1khz_stereo_VBR_MCA.mp3",
- "/sdcard/music_perf/MP3/PD_112kbps_48khz_stereo_VBR_MCA.mp3",
- "/sdcard/music_perf/MP3/PD_192kbps_32khz_mono_CBR_DPA.mp3",
- "/sdcard/music_perf/MP3/PD_256kbps_44.1khz_mono_CBR_DPA.mp3",
- "/sdcard/music_perf/MP3/PD_256kbps_48khz_mono_CBR_MCA.mp3",
- "/sdcard/music_perf/MP3/WC_256kbps_44.1khz_mono_CBR_DPA.mp3",
- "/sdcard/music_perf/MP3/WC_256kbps_48khz_mono_CBR_DPA.mp3",
- "/sdcard/music_perf/regular_album_photo/Apologize.mp3",
- "/sdcard/music_perf/regular_album_photo/Because_Of_You.mp3",
- "/sdcard/music_perf/regular_album_photo/Complicated.mp3",
- "/sdcard/music_perf/regular_album_photo/Glamorous.mp3",
- "/sdcard/music_perf/regular_album_photo/Im_With_You.mp3",
- "/sdcard/music_perf/regular_album_photo/Smile.mp3",
- "/sdcard/music_perf/regular_album_photo/Suddenly_I_See.mp3",
- "/sdcard/music_perf/regular_album_photo/When You Say Nothing At All.mp3",
- "/sdcard/music_perf/regular_album_photo/my_happy_ending.mp3"};
+ "/sdcard/media_api/music_perf/MP3/NIN_56kbps_32khz_stereo_VBR_MCA.MP3",
+ "/sdcard/media_api/music_perf/MP3/NIN_80kbps_32khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/NIN_80kbps_44.1khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/NIN_80kbps_48khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/NIN_112kbps_32khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/NIN_112kbps_44.1khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/NIN_112kbps_48khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/NIN_192kbps_32khz_mono_CBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/NIN_192kbps_44.1khz_mono_CBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/NIN_192kbps_48khz_mono_CBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/NIN_256kbps_44.1khz_mono_CBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/NIN_256kbps_48khz_mono_CBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/PD_112kbps_32khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/PD_112kbps_44.1khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/PD_112kbps_48khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/PD_192kbps_32khz_mono_CBR_DPA.mp3",
+ "/sdcard/media_api/music_perf/MP3/PD_256kbps_44.1khz_mono_CBR_DPA.mp3",
+ "/sdcard/media_api/music_perf/MP3/PD_256kbps_48khz_mono_CBR_MCA.mp3",
+ "/sdcard/media_api/music_perf/MP3/WC_256kbps_44.1khz_mono_CBR_DPA.mp3",
+ "/sdcard/media_api/music_perf/MP3/WC_256kbps_48khz_mono_CBR_DPA.mp3",
+ "/sdcard/media_api/music_perf/regular_album_photo/Apologize.mp3",
+ "/sdcard/media_api/music_perf/regular_album_photo/Because_Of_You.mp3",
+ "/sdcard/media_api/music_perf/regular_album_photo/Complicated.mp3",
+ "/sdcard/media_api/music_perf/regular_album_photo/Glamorous.mp3",
+ "/sdcard/media_api/music_perf/regular_album_photo/Im_With_You.mp3",
+ "/sdcard/media_api/music_perf/regular_album_photo/Smile.mp3",
+ "/sdcard/media_api/music_perf/regular_album_photo/Suddenly_I_See.mp3",
+ "/sdcard/media_api/music_perf/regular_album_photo/When You Say Nothing At All.mp3",
+ "/sdcard/media_api/music_perf/regular_album_photo/my_happy_ending.mp3"};
public static String[] AACFILES = {
- "/sdcard/music_perf/AAC/AI_AAC_24kbps_12khz_Mono_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/AI_AAC_56kbps_22.05khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/AI_AAC_56kbps_32khz_Stereo_CBR_SSE.mp4",
- "/sdcard/music_perf/AAC/AI_AAC_56kbps_44.1khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/AI_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/AI_AAC_80kbps_32khz_Stereo_CBR_SSE.mp4",
- "/sdcard/music_perf/AAC/NIN_AAC_56kbps_22.05khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/NIN_AAC_56kbps_32khz_Stereo_CBR_SSE.mp4",
- "/sdcard/music_perf/AAC/NIN_AAC_56kbps_44.1khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/NIN_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/NIN_AAC_80kbps_32khz_Stereo_CBR_SSE.mp4",
- "/sdcard/music_perf/AAC/PD_AAC_56kbps_22.05khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/PD_AAC_56kbps_32khz_Stereo_CBR_SSE.mp4",
- "/sdcard/music_perf/AAC/PD_AAC_56kbps_44.1khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/PD_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/PD_AAC_80kbps_32khz_Stereo_CBR_SSE.mp4",
- "/sdcard/music_perf/AAC/PV_AAC_56kbps_22.05khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/PV_AAC_56kbps_32khz_Stereo_CBR_SSE.mp4",
- "/sdcard/music_perf/AAC/PV_AAC_56kbps_44.1khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/PV_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/PV_AAC_80kbps_32khz_Stereo_CBR_SSE.mp4",
- "/sdcard/music_perf/AAC/WC_AAC_56kbps_22.05khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/WC_AAC_56kbps_32khz_Stereo_CBR_SSE.mp4",
- "/sdcard/music_perf/AAC/WC_AAC_56kbps_44.1khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/WC_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4",
- "/sdcard/music_perf/AAC/WC_AAC_80kbps_32khz_Stereo_CBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/AI_AAC_24kbps_12khz_Mono_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/AI_AAC_56kbps_22.05khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/AI_AAC_56kbps_32khz_Stereo_CBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/AI_AAC_56kbps_44.1khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/AI_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/AI_AAC_80kbps_32khz_Stereo_CBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/NIN_AAC_56kbps_22.05khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/NIN_AAC_56kbps_32khz_Stereo_CBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/NIN_AAC_56kbps_44.1khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/NIN_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/NIN_AAC_80kbps_32khz_Stereo_CBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/PD_AAC_56kbps_22.05khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/PD_AAC_56kbps_32khz_Stereo_CBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/PD_AAC_56kbps_44.1khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/PD_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/PD_AAC_80kbps_32khz_Stereo_CBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/PV_AAC_56kbps_22.05khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/PV_AAC_56kbps_32khz_Stereo_CBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/PV_AAC_56kbps_44.1khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/PV_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/PV_AAC_80kbps_32khz_Stereo_CBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/WC_AAC_56kbps_22.05khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/WC_AAC_56kbps_32khz_Stereo_CBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/WC_AAC_56kbps_44.1khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/WC_AAC_80kbps_32khz_Stereo_1pCBR_SSE.mp4",
+ "/sdcard/media_api/music_perf/AAC/WC_AAC_80kbps_32khz_Stereo_CBR_SSE.mp4",
};
- public static String[] VIDEOFILES = { "/sdcard/video_perf/AI_CTO_Mpeg4_32kbps_10fps_SQCIF_128x96+AAC_8kbps_8khz_mono_QTE.mp4",
- "/sdcard/video_perf/AI_CTO_Mpeg4_32kbps_12fps_SQCIF_128x96+AAC_8kbps_8khz_mono_QTE.mp4",
- "/sdcard/video_perf/AI_CTO_Mpeg4_32kbps_15fps_SQCIF_128x96+AAC_8kbps_8khz_mono_QTE.mp4",
- "/sdcard/video_perf/AI_CTO_Mpeg4_32kbps_5fps_SQCIF_128x96+AAC_8kbps_8khz_mono_QTE.mp4",
- "/sdcard/video_perf/AI_CTO_Mpeg4_32kbps_5fps_SQCIF_128x96+AAC_8kbps_8khz_mono_SSE.mp4",
- "/sdcard/video_perf/AI_CTO_Mpeg4_32kbps_7.5fps_SQCIF_128x96+AAC_8kbps_8khz_mono_QTE.mp4",
- "/sdcard/video_perf/AI_WMV_1024kbps_20fps_QCIF_176x144_noaudio_SSE.wmv",
- "/sdcard/video_perf/AI_WMV_1024kbps_25fps_QCIF_176x144_noaudio_SSE.wmv",
- "/sdcard/video_perf/Chicken.wmv",
- "/sdcard/video_perf/MP_qcif_15fps_100kbps_48kHz_192kbps_30secs.wmv",
- "/sdcard/video_perf/NIN_CTO_H264_123kbps_5fps_QCIF_176x144+AMR_12.2kbps_8khz_mono_QTE.3gp",
- "/sdcard/video_perf/NIN_CTO_H264_96kbps_10.2fps_QCIF_176x144+AMR_12.2kbps_8khz_mono_QTE.3gp",
- "/sdcard/video_perf/NIN_CTO_H264_96kbps_12fps_QCIF_176x144+AMR_12.2kbps_8khz_mono_QTE.3gp",
- "/sdcard/video_perf/NIN_CTO_H264_96kbps_15fps_QCIF_176x144+AMR_12.2kbps_8khz_mono_QTE.3gp",
- "/sdcard/video_perf/NIN_CTO_Mpeg4_123kbps_15fps_QCIF_176x144+AAC_32kbps_22khz_mono_SSE.3gp",
- "/sdcard/video_perf/NIN_CTO_Mpeg4_123kbps_7.5fps_QCIF_176x144+AAC_32kbps_22khz_stereo_SSE.3gp",
- "/sdcard/video_perf/NIN_CTO_Mpeg4_128kbps_10fps_QCIF_176x144+AAC+_32kbps_48khz_stereo_SSE.3gp",
- "/sdcard/video_perf/NIN_CTO_Mpeg4_128kbps_12fps_QCIF_176x144+AAC+_32kbps_48khz_stereo_SSE.3gp",
- "/sdcard/video_perf/NIN_CTO_Mpeg4_128kbps_15fps_QCIF_176x144+AAC+_32kbps_48khz_stereo_SSE.3gp",
- "/sdcard/video_perf/NIN_CTO_Mpeg4_128kbps_5fps_QCIF_176x144+AAC+_32kbps_48khz_stereo_SSE.3gp",
- "/sdcard/video_perf/NIN_CTO_Mpeg4_128kbps_7.5fps_QCIF_176x144+AAC+_32kbps_48khz_stereo_SSE.3gp",
- "/sdcard/video_perf/NIN_H263_128kbps_10fps_QCIF_174x144_noaudio_SSE.mp4",
- "/sdcard/video_perf/NIN_H263_128kbps_15fps_QCIF_174x144_noaudio_SSE.mp4",
- "/sdcard/video_perf/NIN_H263_48kbps_10fps_QCIF_174x144_noaudio_SSE.3gp",
- "/sdcard/video_perf/NIN_H263_48kbps_12fps_QCIF_174x144_noaudio_SSE.3gp",
- "/sdcard/video_perf/NIN_H264_123kbps_15fps_QCIF_176x144+AAC_32kbps_22khz_stereo_SSE.3gp",
- "/sdcard/video_perf/NIN_H264_123kbps_7.5fps_QCIF_176x144+AAC_32kbps_22khz_stereo_SSE.3gp",
- "/sdcard/video_perf/PV_H264_2000kbps_20fps_CIF_352x288+AAC_96kbps_48khz_stereo_SSE.mp4",
- "/sdcard/video_perf/PV_H264_2000kbps_25fps_CIF_352x288+AAC_96kbps_48khz_stereo_SSE.mp4",
- "/sdcard/video_perf/PV_H264_2000kbps_30fps_CIF_352x288+AAC_128kbps_48khz_stereo_SSE.mp4",
- "/sdcard/video_perf/Stevie-1.wmv",
- "/sdcard/video_perf/WC_H264_1600kbps_20fps_QCIF_176x144+AAC_96kbps_48khz_mono_SSE.mp4",
- "/sdcard/video_perf/WC_H264_1600kbps_25fps_QCIF_176x144+AAC_96kbps_48khz_mono_SSE.mp4",
- "/sdcard/video_perf/WC_H264_1600kbps_30fps_QCIF_176x144+AAC_96kbps_48khz_mono_SSE.mp4",
- "/sdcard/video_perf/bugs.wmv",
- "/sdcard/video_perf/niceday.wmv",
- "/sdcard/video_perf/eaglesatopnflpe.wmv",
+ public static String[] VIDEOFILES = { "/sdcard/media_api/video_perf/AI_CTO_Mpeg4_32kbps_10fps_SQCIF_128x96+AAC_8kbps_8khz_mono_QTE.mp4",
+ "/sdcard/media_api/video_perf/AI_CTO_Mpeg4_32kbps_12fps_SQCIF_128x96+AAC_8kbps_8khz_mono_QTE.mp4",
+ "/sdcard/media_api/video_perf/AI_CTO_Mpeg4_32kbps_15fps_SQCIF_128x96+AAC_8kbps_8khz_mono_QTE.mp4",
+ "/sdcard/media_api/video_perf/AI_CTO_Mpeg4_32kbps_5fps_SQCIF_128x96+AAC_8kbps_8khz_mono_QTE.mp4",
+ "/sdcard/media_api/video_perf/AI_CTO_Mpeg4_32kbps_5fps_SQCIF_128x96+AAC_8kbps_8khz_mono_SSE.mp4",
+ "/sdcard/media_api/video_perf/AI_CTO_Mpeg4_32kbps_7.5fps_SQCIF_128x96+AAC_8kbps_8khz_mono_QTE.mp4",
+ "/sdcard/media_api/video_perf/AI_WMV_1024kbps_20fps_QCIF_176x144_noaudio_SSE.wmv",
+ "/sdcard/media_api/video_perf/AI_WMV_1024kbps_25fps_QCIF_176x144_noaudio_SSE.wmv",
+ "/sdcard/media_api/video_perf/Chicken.wmv",
+ "/sdcard/media_api/video_perf/MP_qcif_15fps_100kbps_48kHz_192kbps_30secs.wmv",
+ "/sdcard/media_api/video_perf/NIN_CTO_H264_123kbps_5fps_QCIF_176x144+AMR_12.2kbps_8khz_mono_QTE.3gp",
+ "/sdcard/media_api/video_perf/NIN_CTO_H264_96kbps_10.2fps_QCIF_176x144+AMR_12.2kbps_8khz_mono_QTE.3gp",
+ "/sdcard/media_api/video_perf/NIN_CTO_H264_96kbps_12fps_QCIF_176x144+AMR_12.2kbps_8khz_mono_QTE.3gp",
+ "/sdcard/media_api/video_perf/NIN_CTO_H264_96kbps_15fps_QCIF_176x144+AMR_12.2kbps_8khz_mono_QTE.3gp",
+ "/sdcard/media_api/video_perf/NIN_CTO_Mpeg4_123kbps_15fps_QCIF_176x144+AAC_32kbps_22khz_mono_SSE.3gp",
+ "/sdcard/media_api/video_perf/NIN_CTO_Mpeg4_123kbps_7.5fps_QCIF_176x144+AAC_32kbps_22khz_stereo_SSE.3gp",
+ "/sdcard/media_api/video_perf/NIN_CTO_Mpeg4_128kbps_10fps_QCIF_176x144+AAC+_32kbps_48khz_stereo_SSE.3gp",
+ "/sdcard/media_api/video_perf/NIN_CTO_Mpeg4_128kbps_12fps_QCIF_176x144+AAC+_32kbps_48khz_stereo_SSE.3gp",
+ "/sdcard/media_api/video_perf/NIN_CTO_Mpeg4_128kbps_15fps_QCIF_176x144+AAC+_32kbps_48khz_stereo_SSE.3gp",
+ "/sdcard/media_api/video_perf/NIN_CTO_Mpeg4_128kbps_5fps_QCIF_176x144+AAC+_32kbps_48khz_stereo_SSE.3gp",
+ "/sdcard/media_api/video_perf/NIN_CTO_Mpeg4_128kbps_7.5fps_QCIF_176x144+AAC+_32kbps_48khz_stereo_SSE.3gp",
+ "/sdcard/media_api/video_perf/NIN_H263_128kbps_10fps_QCIF_174x144_noaudio_SSE.mp4",
+ "/sdcard/media_api/video_perf/NIN_H263_128kbps_15fps_QCIF_174x144_noaudio_SSE.mp4",
+ "/sdcard/media_api/video_perf/NIN_H263_48kbps_10fps_QCIF_174x144_noaudio_SSE.3gp",
+ "/sdcard/media_api/video_perf/NIN_H263_48kbps_12fps_QCIF_174x144_noaudio_SSE.3gp",
+ "/sdcard/media_api/video_perf/NIN_H264_123kbps_15fps_QCIF_176x144+AAC_32kbps_22khz_stereo_SSE.3gp",
+ "/sdcard/media_api/video_perf/NIN_H264_123kbps_7.5fps_QCIF_176x144+AAC_32kbps_22khz_stereo_SSE.3gp",
+ "/sdcard/media_api/video_perf/PV_H264_2000kbps_20fps_CIF_352x288+AAC_96kbps_48khz_stereo_SSE.mp4",
+ "/sdcard/media_api/video_perf/PV_H264_2000kbps_25fps_CIF_352x288+AAC_96kbps_48khz_stereo_SSE.mp4",
+ "/sdcard/media_api/video_perf/PV_H264_2000kbps_30fps_CIF_352x288+AAC_128kbps_48khz_stereo_SSE.mp4",
+ "/sdcard/media_api/video_perf/Stevie-1.wmv",
+ "/sdcard/media_api/video_perf/WC_H264_1600kbps_20fps_QCIF_176x144+AAC_96kbps_48khz_mono_SSE.mp4",
+ "/sdcard/media_api/video_perf/WC_H264_1600kbps_25fps_QCIF_176x144+AAC_96kbps_48khz_mono_SSE.mp4",
+ "/sdcard/media_api/video_perf/WC_H264_1600kbps_30fps_QCIF_176x144+AAC_96kbps_48khz_mono_SSE.mp4",
+ "/sdcard/media_api/video_perf/bugs.wmv",
+ "/sdcard/media_api/video_perf/niceday.wmv",
+ "/sdcard/media_api/video_perf/eaglesatopnflpe.wmv",
};
//wma - only support up to wma 9
public static String[] WMASUPPORTED = {
- "/sdcard/music_perf/WMASUPPORTED/AI_WMA9.2_32kbps_44.1khz_mono_CBR_DPA.wma",
- "/sdcard/music_perf/WMASUPPORTED/AI_WMA9.2_48kbps_44.1khz_mono_CBR_DPA.wma",
- "/sdcard/music_perf/WMASUPPORTED/NIN_WMA9.2_32kbps_44.1khz_mono_CBR_DPA.wma",
- "/sdcard/music_perf/WMASUPPORTED/NIN_WMA9.2_48kbps_44.1khz_mono_CBR_DPA.wma",
- "/sdcard/music_perf/WMASUPPORTED/PD_WMA9.2_32kbps_44.1khz_mono_CBR_DPA.wma",
- "/sdcard/music_perf/WMASUPPORTED/PD_WMA9.2_48kbps_44.1khz_mono_CBR_DPA.wma",
- "/sdcard/music_perf/WMASUPPORTED/PV_WMA9.2_32kbps_44.1khz_mono_CBR_DPA.wma",
- "/sdcard/music_perf/WMASUPPORTED/PV_WMA9.2_48kbps_44.1khz_mono_CBR_DPA.wma",
- "/sdcard/music_perf/WMASUPPORTED/WC_WMA9.2_32kbps_44.1khz_mono_CBR_DPA.wma",
- "/sdcard/music_perf/WMASUPPORTED/WC_WMA9.2_48kbps_44.1khz_mono_CBR_DPA.wma"
+ "/sdcard/media_api/music_perf/WMASUPPORTED/AI_WMA9.2_32kbps_44.1khz_mono_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMASUPPORTED/AI_WMA9.2_48kbps_44.1khz_mono_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMASUPPORTED/NIN_WMA9.2_32kbps_44.1khz_mono_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMASUPPORTED/NIN_WMA9.2_48kbps_44.1khz_mono_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMASUPPORTED/PD_WMA9.2_32kbps_44.1khz_mono_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMASUPPORTED/PD_WMA9.2_48kbps_44.1khz_mono_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMASUPPORTED/PV_WMA9.2_32kbps_44.1khz_mono_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMASUPPORTED/PV_WMA9.2_48kbps_44.1khz_mono_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMASUPPORTED/WC_WMA9.2_32kbps_44.1khz_mono_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMASUPPORTED/WC_WMA9.2_48kbps_44.1khz_mono_CBR_DPA.wma"
};
public static String[] WMAUNSUPPORTED = {
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_127kbps_48khz_stereo_CBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_128kbps_44.1khz_stereo_2pVBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_128kbps_48khz_stereo_2pVBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_128kbps_88khz_stereo_CBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_128kbps_96khz_stereo_CBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_192kbps_44.1khz_stereo_2pVBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_192kbps_88khz_stereo_CBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_192kbps_96khz_stereo_CBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_256kbps_44khz_stereo_CBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_256kbps_48khz_stereo_CBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_256kbps_88khz_stereo_CBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_256kbps_96khz_stereo_CBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_384kbps_44khz_stereo_CBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_384kbps_48khz_stereo_CBR_DPA.wma",
- "/sdcard/music_perf/WMAUNSUPPORTED/AI_WMA10_384kbps_88khz_stereo_CBR_DPA.wma"
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_127kbps_48khz_stereo_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_128kbps_44.1khz_stereo_2pVBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_128kbps_48khz_stereo_2pVBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_128kbps_88khz_stereo_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_128kbps_96khz_stereo_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_192kbps_44.1khz_stereo_2pVBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_192kbps_88khz_stereo_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_192kbps_96khz_stereo_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_256kbps_44khz_stereo_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_256kbps_48khz_stereo_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_256kbps_88khz_stereo_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_256kbps_96khz_stereo_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_384kbps_44khz_stereo_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_384kbps_48khz_stereo_CBR_DPA.wma",
+ "/sdcard/media_api/music_perf/WMAUNSUPPORTED/AI_WMA10_384kbps_88khz_stereo_CBR_DPA.wma"
};
//Media Recorder
- public static final String RECORDER_OUTPUT = "/sdcard/recorderOutput.amr";
+ public static final String RECORDER_OUTPUT = "/sdcard/media_api/recorderOutput.amr";
//video thumbnail
- public static final String THUMBNAIL_OUTPUT = "/sdcard/videoThumbnail.png";
- public static final String GOLDEN_THUMBNAIL_OUTPUT = "/sdcard/goldenThumbnail.png";
+ public static final String THUMBNAIL_OUTPUT = "/sdcard/media_api/videoThumbnail.png";
+ public static final String GOLDEN_THUMBNAIL_OUTPUT = "/sdcard/media_api/goldenThumbnail.png";
//Metadata Utility
public static final String[] THUMBNAIL_CAPTURE_TEST_FILES = {
- "/sdcard/metadata/test.mp4",
- "/sdcard/metadata/test1.3gp",
- "/sdcard/metadata/test2.3gp",
- "/sdcard/metadata/test3.3gp",
- "/sdcard/metadata/test4.3gp",
- "/sdcard/metadata/test5.3gp",
- "/sdcard/metadata/test6.3gp",
- "/sdcard/metadata/test7.3gp",
- "/sdcard/metadata/test8.3gp",
- "/sdcard/metadata/test9.3gp",
- "/sdcard/metadata/test10.3gp",
- "/sdcard/metadata/test11.3gp",
- "/sdcard/metadata/test12.3gp",
- "/sdcard/metadata/test13.3gp",
- "/sdcard/metadata/test14.3gp",
- "/sdcard/metadata/test15.3gp",
- "/sdcard/metadata/test16.3gp",
- "/sdcard/metadata/test17.3gp",
- "/sdcard/metadata/test18.3gp",
- "/sdcard/metadata/test19.3gp",
- "/sdcard/metadata/test20.3gp",
- "/sdcard/metadata/test21.3gp",
- "/sdcard/metadata/test22.3gp",
- "/sdcard/metadata/test23.3gp",
- "/sdcard/metadata/test24.3gp",
- "/sdcard/metadata/test25.3gp",
- "/sdcard/metadata/test26.3gp",
- "/sdcard/metadata/test27.3gp",
- "/sdcard/metadata/test28.3gp",
- "/sdcard/metadata/test29.3gp",
- "/sdcard/metadata/test30.3gp",
- "/sdcard/metadata/test31.3gp",
- "/sdcard/metadata/test32.3gp",
- "/sdcard/metadata/test33.3gp",
- "/sdcard/metadata/test35.mp4",
- "/sdcard/metadata/test36.m4v",
- "/sdcard/metadata/test34.wmv",
- "/sdcard/metadata/test_metadata.mp4",
+ "/sdcard/media_api/metadata/test.mp4",
+ "/sdcard/media_api/metadata/test1.3gp",
+ "/sdcard/media_api/metadata/test2.3gp",
+ "/sdcard/media_api/metadata/test3.3gp",
+ "/sdcard/media_api/metadata/test4.3gp",
+ "/sdcard/media_api/metadata/test5.3gp",
+ "/sdcard/media_api/metadata/test6.3gp",
+ "/sdcard/media_api/metadata/test7.3gp",
+ "/sdcard/media_api/metadata/test8.3gp",
+ "/sdcard/media_api/metadata/test9.3gp",
+ "/sdcard/media_api/metadata/test10.3gp",
+ "/sdcard/media_api/metadata/test11.3gp",
+ "/sdcard/media_api/metadata/test12.3gp",
+ "/sdcard/media_api/metadata/test13.3gp",
+ "/sdcard/media_api/metadata/test14.3gp",
+ "/sdcard/media_api/metadata/test15.3gp",
+ "/sdcard/media_api/metadata/test16.3gp",
+ "/sdcard/media_api/metadata/test17.3gp",
+ "/sdcard/media_api/metadata/test18.3gp",
+ "/sdcard/media_api/metadata/test19.3gp",
+ "/sdcard/media_api/metadata/test20.3gp",
+ "/sdcard/media_api/metadata/test21.3gp",
+ "/sdcard/media_api/metadata/test22.3gp",
+ "/sdcard/media_api/metadata/test23.3gp",
+ "/sdcard/media_api/metadata/test24.3gp",
+ "/sdcard/media_api/metadata/test25.3gp",
+ "/sdcard/media_api/metadata/test26.3gp",
+ "/sdcard/media_api/metadata/test27.3gp",
+ "/sdcard/media_api/metadata/test28.3gp",
+ "/sdcard/media_api/metadata/test29.3gp",
+ "/sdcard/media_api/metadata/test30.3gp",
+ "/sdcard/media_api/metadata/test31.3gp",
+ "/sdcard/media_api/metadata/test32.3gp",
+ "/sdcard/media_api/metadata/test33.3gp",
+ "/sdcard/media_api/metadata/test35.mp4",
+ "/sdcard/media_api/metadata/test36.m4v",
+ "/sdcard/media_api/metadata/test34.wmv",
+ "/sdcard/media_api/metadata/test_metadata.mp4",
};
public static final String[] METADATA_RETRIEVAL_TEST_FILES = {
// Raw AAC is not supported
- // "/sdcard/test_raw.aac",
- // "/sdcard/test_adts.aac",
- // "/sdcard/test_adif.aac",
- "/sdcard/metadata/test_metadata.mp4",
- "/sdcard/metadata/WMA10.wma",
- "/sdcard/metadata/Leadsol_out.wav",
- "/sdcard/metadata/test_aac.mp4",
- "/sdcard/metadata/test_amr.mp4",
- "/sdcard/metadata/test_avc_amr.mp4",
- "/sdcard/metadata/test_metadata.mp4",
- "/sdcard/metadata/test_vbr.mp3",
- "/sdcard/metadata/test_cbr.mp3",
- "/sdcard/metadata/metadata_test1.mp3",
- "/sdcard/metadata/test33.3gp",
- "/sdcard/metadata/test35.mp4",
- "/sdcard/metadata/test36.m4v",
- "/sdcard/metadata/test_m4v_amr.mp4",
- "/sdcard/metadata/test_h263_amr.mp4",
- "/sdcard/metadata/test34.wmv",
+ // "/sdcard/media_api/test_raw.aac",
+ // "/sdcard/media_api/test_adts.aac",
+ // "/sdcard/media_api/test_adif.aac",
+ "/sdcard/media_api/metadata/test_metadata.mp4",
+ "/sdcard/media_api/metadata/WMA10.wma",
+ "/sdcard/media_api/metadata/Leadsol_out.wav",
+ "/sdcard/media_api/metadata/test_aac.mp4",
+ "/sdcard/media_api/metadata/test_amr.mp4",
+ "/sdcard/media_api/metadata/test_avc_amr.mp4",
+ "/sdcard/media_api/metadata/test_metadata.mp4",
+ "/sdcard/media_api/metadata/test_vbr.mp3",
+ "/sdcard/media_api/metadata/test_cbr.mp3",
+ "/sdcard/media_api/metadata/metadata_test1.mp3",
+ "/sdcard/media_api/metadata/test33.3gp",
+ "/sdcard/media_api/metadata/test35.mp4",
+ "/sdcard/media_api/metadata/test36.m4v",
+ "/sdcard/media_api/metadata/test_m4v_amr.mp4",
+ "/sdcard/media_api/metadata/test_h263_amr.mp4",
+ "/sdcard/media_api/metadata/test34.wmv",
};
public static final String[] ALBUMART_TEST_FILES = {
- "/sdcard/album_photo/test_22_16_mp3.mp3",
- "/sdcard/album_photo/PD_256kbps_48khz_mono_CBR_MCA.mp3",
- "/sdcard/album_photo/PD_256kbps_44.1khz_mono_CBR_DPA.mp3",
- "/sdcard/album_photo/PD_192kbps_32khz_mono_CBR_DPA.mp3",
- "/sdcard/album_photo/NIN_256kbps_48khz_mono_CBR_MCA.mp3",
- "/sdcard/album_photo/NIN_256kbps_44.1khz_mono_CBR_MCA.mp3",
- "/sdcard/album_photo/NIN_112kbps(96kbps)_48khz_stereo_VBR_MCA.mp3",
- "/sdcard/album_photo/NIN_112kbps(96kbps)_44.1khz_stereo_VBR_MCA.mp3",
- "/sdcard/album_photo/lightGreen1.mp3",
- "/sdcard/album_photo/babyBlue2 1.mp3",
- "/sdcard/album_photo/2-01 01 NIN_56kbps(64kbps)_32khz_stereo_VBR_MCA.mp3",
- "/sdcard/album_photo/02_NIN_112kbps(80kbps)_32khz_stereo_VBR_MCA.mp3",
- "/sdcard/album_photo/No_Woman_No_Cry_128K.wma",
- "/sdcard/album_photo/Beethoven_2.wma",
+ "/sdcard/media_api/album_photo/test_22_16_mp3.mp3",
+ "/sdcard/media_api/album_photo/PD_256kbps_48khz_mono_CBR_MCA.mp3",
+ "/sdcard/media_api/album_photo/PD_256kbps_44.1khz_mono_CBR_DPA.mp3",
+ "/sdcard/media_api/album_photo/PD_192kbps_32khz_mono_CBR_DPA.mp3",
+ "/sdcard/media_api/album_photo/NIN_256kbps_48khz_mono_CBR_MCA.mp3",
+ "/sdcard/media_api/album_photo/NIN_256kbps_44.1khz_mono_CBR_MCA.mp3",
+ "/sdcard/media_api/album_photo/NIN_112kbps(96kbps)_48khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/album_photo/NIN_112kbps(96kbps)_44.1khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/album_photo/lightGreen1.mp3",
+ "/sdcard/media_api/album_photo/babyBlue2 1.mp3",
+ "/sdcard/media_api/album_photo/2-01 01 NIN_56kbps(64kbps)_32khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/album_photo/02_NIN_112kbps(80kbps)_32khz_stereo_VBR_MCA.mp3",
+ "/sdcard/media_api/album_photo/No_Woman_No_Cry_128K.wma",
+ "/sdcard/media_api/album_photo/Beethoven_2.wma",
};
//TEST_PATH_1: is a video and contains metadata for key "num-tracks"
// TEST_PATH_2: any valid media file.
// TEST_PATH_3: invalid media file
- public static final String TEST_PATH_1 = "/sdcard/metadata/test.mp4";
- public static final String TEST_PATH_3 = "/sdcard/data.txt";
+ public static final String TEST_PATH_1 = "/sdcard/media_api/metadata/test.mp4";
+ public static final String TEST_PATH_3 = "/sdcard/media_api/data.txt";
public static final String TEST_PATH_4 = "somenonexistingpathname";
public static final String TEST_PATH_5 = "mem://012345";
@@ -376,81 +378,81 @@ public class MediaNames {
//cd_track_number, album, artist, author, composer, date, genre
//title, years, duration
public static final String META_DATA_MP3 [][] = {
- {"/sdcard/metaDataTestMedias/MP3/ID3V1_ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist",
+ {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V1_ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist",
"ID3V2.3 Lyricist", "ID3V2.3 Composer", null, "Blues",
"ID3V2.3 Title", "1234", "321", "1"},
- {"/sdcard/metaDataTestMedias/MP3/ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist",
+ {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V2.mp3", "1/10", "ID3V2.3 Album", "ID3V2.3 Artist",
"ID3V2.3 Lyricist", "ID3V2.3 Composer", null, "Blues",
"ID3V2.3 Title", "1234", "313", "1"},
- {"/sdcard/metaDataTestMedias/MP3/ID3V1.mp3", null, "test ID3V1 Album", "test ID3V1 Artist",
+ {"/sdcard/media_api/metaDataTestMedias/MP3/ID3V1.mp3", null, "test ID3V1 Album", "test ID3V1 Artist",
null, null, null, null, "test ID3V1 Title", "1234", "231332", "1"},
- {"/sdcard/metaDataTestMedias/MP3/Corrupted_ID3V1.mp3" , null, null, null,
+ {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V1.mp3" , null, null, null,
null, null, null, null, null, null, "231330", "1"},
//The corrupted TALB field in id3v2 would not switch to id3v1 tag automatically
- {"/sdcard/metaDataTestMedias/MP3/Corrupted_ID3V2_TALB.mp3", "01", null, "ID3V2.3 Artist",
+ {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TALB.mp3", "01", null, "ID3V2.3 Artist",
"ID3V2.3 Lyricist", "ID3V2.3 Composer", null,
"Blues", "ID3V2.3 Title", "1234", "321", "1"},
- {"/sdcard/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM.mp3", "01", "ID3V2.3 Album",
+ {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM.mp3", "01", "ID3V2.3 Album",
"ID3V2.3 Artist", "ID3V2.3 Lyricist", null, null,
"Blues", "ID3V2.3 Title", "1234", "321", "1"},
- {"/sdcard/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM_2.mp3", "01", "ID3V2.3 Album",
+ {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TCOM_2.mp3", "01", "ID3V2.3 Album",
"ID3V2.3 Artist", null, null, null, "Blues", "ID3V2.3 Title", "1234", "321", "1"},
- {"/sdcard/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK.mp3", "dd", "ID3V2.3 Album",
+ {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK.mp3", "dd", "ID3V2.3 Album",
"ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null,
"Blues", "ID3V2.3 Title", "1234", "321", "1"},
- {"/sdcard/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK_2.mp3", "01", "ID3V2.3 Album",
+ {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TRCK_2.mp3", "01", "ID3V2.3 Album",
"ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", null, "321", "1"},
- {"/sdcard/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER.mp3", "01", "ID3V2.3 Album",
+ {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER.mp3", "01", "ID3V2.3 Album",
"ID3V2.3 Artist", null, null, null, null, "ID3V2.3 Title", "9999", "321", "1"},
- {"/sdcard/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER_2.mp3", "01", "ID3V2.3 Album",
+ {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TYER_2.mp3", "01", "ID3V2.3 Album",
"ID3V2.3 Artist", "ID3V2.3 Lyricist", "ID3V2.3 Composer", null,
"Blues", "ID3V2.3 Title", null, "321", "1"},
- {"/sdcard/metaDataTestMedias/MP3/Corrupted_ID3V2_TIT.mp3", null, null, null,
+ {"/sdcard/media_api/metaDataTestMedias/MP3/Corrupted_ID3V2_TIT.mp3", null, null, null,
null, null, null, null, null, null, "577", "1"}
};
public static final String META_DATA_OTHERS [][] = {
- {"/sdcard/metaDataTestMedias/3GP/cat.3gp", null, null, null,
+ {"/sdcard/media_api/metaDataTestMedias/3GP/cat.3gp", null, null, null,
null, null, "20080309T002415.000Z", null,
null, null, "1404928", "2"},
- {"/sdcard/metaDataTestMedias/AMR/AMR_NB.amr", null, null, null,
+ {"/sdcard/media_api/metaDataTestMedias/AMR/AMR_NB.amr", null, null, null,
null, null, null, null,
null, null, "126540", "1"},
- {"/sdcard/metaDataTestMedias/AMRWB/AMR_WB.amr", null, null, null,
+ {"/sdcard/media_api/metaDataTestMedias/AMRWB/AMR_WB.amr", null, null, null,
null, null, null, null,
null, null, "231180", "1"},
- {"/sdcard/metaDataTestMedias/M4A/Jaws Of Life_ver1.m4a", null, "Suspended Animation",
+ {"/sdcard/media_api/metaDataTestMedias/M4A/Jaws Of Life_ver1.m4a", null, "Suspended Animation",
"John Petrucci", null, null, "20070510T125223.000Z",
null, null, "2005", "231180", "1"},
- {"/sdcard/metaDataTestMedias/M4V/sample_iPod.m4v", null, null,
+ {"/sdcard/media_api/metaDataTestMedias/M4V/sample_iPod.m4v", null, null,
null, null, null, "20051220T202015.000Z",
null, null, null, "3771392", "2"},
- {"/sdcard/metaDataTestMedias/MIDI/MIDI.mid", null, "Suspended Animation",
+ {"/sdcard/media_api/metaDataTestMedias/MIDI/MIDI.mid", null, "Suspended Animation",
"John Petrucci", null, null, "20070510T125223.000Z",
null, null, "2005", "231180", "1"},
- {"/sdcard/metaDataTestMedias/MP4/kung_fu_panda_h264.mp4", null, "mp4 album Kung Fu Panda",
+ {"/sdcard/media_api/metaDataTestMedias/MP4/kung_fu_panda_h264.mp4", null, "mp4 album Kung Fu Panda",
"mp4 artist Kung Fu Panda", null, null, "20080517T091451.000Z",
"Kung Fu Panda", "Kung Fu Panda", "2008", "5667840", "2"},
- {"/sdcard/metaDataTestMedias/OGG/Ring_Classic_02.ogg", null, "Suspended Animation",
+ {"/sdcard/media_api/metaDataTestMedias/OGG/Ring_Classic_02.ogg", null, "Suspended Animation",
"John Petrucci", null, null, "20070510T125223.000Z",
null, null, "2005", "231180", "1"},
- {"/sdcard/metaDataTestMedias/OGG/When You Say Nothing At All.ogg",
+ {"/sdcard/media_api/metaDataTestMedias/OGG/When You Say Nothing At All.ogg",
null, "Suspended Animation", "John Petrucci",
null, null, "20070510T125223.000Z", null, null, "2005", "231180", "1"},
- {"/sdcard/metaDataTestMedias/WAV/Im With You.wav", null, null,
+ {"/sdcard/media_api/metaDataTestMedias/WAV/Im With You.wav", null, null,
null, null, null, null,
null, null, null, "224000", "1"},
- {"/sdcard/metaDataTestMedias/WMA/WMA9.wma", "6", "Ten Songs in the Key of Betrayal",
+ {"/sdcard/media_api/metaDataTestMedias/WMA/WMA9.wma", "6", "Ten Songs in the Key of Betrayal",
"Alien Crime Syndicate", "Alien Crime Syndicate",
"wma 9 Composer", "20040521T175729.483Z",
"Rock", "Run for the Money", "2004", "134479", "1"},
- {"/sdcard/metaDataTestMedias/WMA/WMA10.wma", "09", "wma 10 Album",
+ {"/sdcard/media_api/metaDataTestMedias/WMA/WMA10.wma", "09", "wma 10 Album",
"wma 10 Album Artist", "wma 10 Artist", "wma 10 Composer", "20070705T063625.097Z",
"Acid Jazz", "wma 10 Title", "2010", "126574", "1"},
- {"/sdcard/metaDataTestMedias/WMV/bugs.wmv", "8", "wmv 9 Album",
+ {"/sdcard/media_api/metaDataTestMedias/WMV/bugs.wmv", "8", "wmv 9 Album",
null, "wmv 9 Artist ", null, "20051122T155247.540Z",
null, "Looney Tunes - Hare-Breadth Hurry", "2005", "193482", "2"},
- {"/sdcard/metaDataTestMedias/WMV/clips_ver7.wmv", "50", "wmv 7 Album",
+ {"/sdcard/media_api/metaDataTestMedias/WMV/clips_ver7.wmv", "50", "wmv 7 Album",
null, "Hallau Shoots & Company", null, "20020226T170045.891Z",
null, "CODEC Shootout", "1986", "43709", "2"}
};
@@ -471,9 +473,25 @@ public class MediaNames {
public static final String RECORDED_VIDEO_3GP = "/sdcard/temp.3gp";
+ public static final String INVALD_VIDEO_PATH = "/sdcard/media_api/filepathdoesnotexist" +
+ "/filepathdoesnotexist/temp.3gp";
+
- public static final long RECORDED_TIME = 3000;
+ public static final long RECORDED_TIME = 5000;
public static final long VALID_VIDEO_DURATION = 2000;
-
+ //Videos for the mediaplayer stress test
+ public static String[] H263_STRESS = {
+ "/sdcard/media_api/video_stress/h263/H263_CIF.3gp",
+ "/sdcard/media_api/video_stress/h263/H263_QCIF.3gp",
+ "/sdcard/media_api/video_stress/h263/H263_QVGA.3gp",
+ "/sdcard/media_api/video_stress/h263/H263_SQVGA.3gp"
+ };
+
+ public static String[] MPEG4_STRESS = {
+ "/sdcard/media_api/video_stress/h263/mpeg4_CIF.mp4",
+ "/sdcard/media_api/video_stress/h263/mpeg4_QCIF.3gp",
+ "/sdcard/media_api/video_stress/h263/mpeg4_QVGA.3gp",
+ "/sdcard/media_api/video_stress/h263/mpeg4_SQVGA.mp4"
+ };
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java
new file mode 100755
index 0000000..12eacd3
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaRecorderStressTestRunner.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed 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 com.android.mediaframeworktest;
+
+import android.test.InstrumentationTestRunner;
+import android.test.InstrumentationTestSuite;
+import com.android.mediaframeworktest.stress.MediaRecorderStressTest;
+
+import junit.framework.TestSuite;
+
+public class MediaRecorderStressTestRunner extends InstrumentationTestRunner {
+
+ @Override
+ public TestSuite getAllTests() {
+ TestSuite suite = new InstrumentationTestSuite(this);
+ suite.addTestSuite(MediaRecorderStressTest.class);
+ return suite;
+ }
+
+ @Override
+ public ClassLoader getLoader() {
+ return MediaRecorderStressTestRunner.class.getClassLoader();
+ }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaAudioTrackTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaAudioTrackTest.java
new file mode 100644
index 0000000..ae6a834
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaAudioTrackTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed 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 com.android.mediaframeworktest.functional;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import com.android.mediaframeworktest.MediaNames;
+
+import android.media.AudioTrack;
+import android.content.Context;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
+
+/**
+ * Junit / Instrumentation test case for the media AudioTrack api
+
+ */
+public class MediaAudioTrackTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+ private String TAG = "MediaAudioTrack";
+
+ public MediaAudioTrackTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ //Test case 1: Set the invalid volume
+ @MediumTest
+ public void testGetMinVolume() throws Exception {
+ //To Do: Create the test case for GetMinVolume
+ assertTrue("testGetMinVolume", true);
+ }
+
+}
+
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
index 20f213e..dd94164 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaPlayerApiTest.java
@@ -385,9 +385,6 @@ public class MediaPlayerApiTest extends ActivityInstrumentationTestCase<MediaFra
assertTrue("WMV SeekTo", isSeek);
}
- //TODO(elaurent)
- //reactivate the test until bug#1495237 fix
- @Suppress
@LargeTest
public void testSoundRecord() throws Exception {
boolean isRecordered = CodecTest.mediaRecorderRecord(MediaNames.RECORDER_OUTPUT);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
index d970f5e..65451c5 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
@@ -35,8 +35,7 @@ import android.test.suitebuilder.annotation.Suppress;
/**
- * Junit / Instrumentation test case for the media recorder api
-
+ * Junit / Instrumentation test case for the media recorder api
*/
public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFrameworkTest> {
private String TAG = "MediaRecorderTest";
@@ -60,12 +59,48 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
}
private void recordVideo(int frameRate, int width, int height,
- int videoFormat, int outFormat, String outFile, boolean videoOnly){
+ int videoFormat, int outFormat, String outFile, boolean videoOnly) {
Log.v(TAG,"startPreviewAndPrepareRecording");
- try{
- if (!videoOnly){
+ try {
+ if (!videoOnly) {
+ Log.v(TAG, "setAudioSource");
+ mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ }
+ mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+ mRecorder.setOutputFormat(outFormat);
+ Log.v(TAG, "output format " + outFormat);
+ mRecorder.setOutputFile(outFile);
+ mRecorder.setVideoFrameRate(frameRate);
+ mRecorder.setVideoSize(width, height);
+ Log.v(TAG, "setEncoder");
+ mRecorder.setVideoEncoder(videoFormat);
+ if (!videoOnly) {
+ mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ }
+ mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ Log.v(TAG, "setPreview");
+ mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+ Log.v(TAG, "prepare");
+ mRecorder.prepare();
+ Log.v(TAG, "start");
+ mRecorder.start();
+ Thread.sleep(MediaNames.RECORDED_TIME);
+ Log.v(TAG, "stop");
+ mRecorder.stop();
+ mRecorder.release();
+ } catch (Exception e) {
+ Log.v("record video failed ", e.toString());
+ mRecorder.release();
+ }
+ }
+
+
+ private boolean invalidRecordSetting(int frameRate, int width, int height,
+ int videoFormat, int outFormat, String outFile, boolean videoOnly) {
+ try {
+ if (!videoOnly) {
Log.v(TAG, "setAudioSource");
- //mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
}
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mRecorder.setOutputFormat(outFormat);
@@ -75,8 +110,8 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
mRecorder.setVideoSize(width, height);
Log.v(TAG, "setEncoder");
mRecorder.setVideoEncoder(videoFormat);
- if (!videoOnly){
- // mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ if (!videoOnly) {
+ mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
}
mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
Log.v(TAG, "setPreview");
@@ -88,16 +123,21 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
Thread.sleep(MediaNames.RECORDED_TIME);
Log.v(TAG, "stop");
mRecorder.stop();
- mRecorder.reset();
mRecorder.release();
- } catch (Exception e){
+ } catch (Exception e) {
Log.v("record video failed ", e.toString());
+ mRecorder.release();
+ Log.v(TAG, "reset and release");
+ return true;
}
+ return false;
}
- private void getOutputVideoProperty(String outputFilePath){
+
+
+ private void getOutputVideoProperty(String outputFilePath) {
MediaPlayer mediaPlayer = new MediaPlayer();
- try{
+ try {
mediaPlayer.setDataSource(outputFilePath);
Log.v(TAG, "file Path = " + outputFilePath);
mediaPlayer.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
@@ -111,19 +151,20 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
mediaPlayer.release();
} catch (Exception e) {
Log.v(TAG, e.toString());
+ mediaPlayer.release();
}
}
- private void removeFile(String filePath){
+ private void removeFile(String filePath) {
File fileRemove = new File(filePath);
fileRemove.delete();
}
- private boolean validateVideo(String filePath, int width, int height){
+ private boolean validateVideo(String filePath, int width, int height) {
boolean validVideo = false;
getOutputVideoProperty(filePath);
if (mOutputVideoWidth == width && mOutputVideoHeight == height &&
- mOutputDuration > MediaNames.VALID_VIDEO_DURATION ){
+ mOutputDuration > MediaNames.VALID_VIDEO_DURATION ) {
validVideo = true;
}
Log.v(TAG, "width = " + mOutputVideoWidth + " height = " + mOutputVideoHeight + " Duration = " + mOutputDuration);
@@ -143,7 +184,7 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
}
//Format: QVGA h263
- @Suppress
+ @LargeTest
public void testQVGAH263() throws Exception {
boolean videoRecordedResult = false;
recordVideo(15, 320, 240, MediaRecorder.VideoEncoder.H263,
@@ -153,7 +194,7 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
}
//Format: SQVGA h263
- @Suppress
+ @LargeTest
public void testSQVGAH263() throws Exception {
boolean videoRecordedResult = false;
recordVideo(15, 240, 160, MediaRecorder.VideoEncoder.H263,
@@ -184,14 +225,12 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
- @Suppress
+ @LargeTest
public void testVideoOnly() throws Exception {
boolean videoRecordedResult = false;
- for (int i=0; i< 10; i++){
recordVideo(15, 176, 144, MediaRecorder.VideoEncoder.H263,
MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, true);
videoRecordedResult = validateVideo(MediaNames.RECORDED_VIDEO_3GP, 176, 144);
- }
assertTrue("QCIFH263 Video Only", videoRecordedResult);
}
@@ -204,7 +243,7 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
assertTrue("PortraitH263", videoRecordedResult);
}
- @LargeTest
+ @Suppress
public void testHVGAMP4() throws Exception {
boolean videoRecordedResult = false;
recordVideo(15, 480, 320, MediaRecorder.VideoEncoder.MPEG_4_SP,
@@ -242,7 +281,7 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
}
- //Format: CIF h263
+ //Format: CIF MP4
@LargeTest
public void testCIFMP4() throws Exception {
boolean videoRecordedResult = false;
@@ -253,14 +292,14 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
}
- //Format: CIF h263 outputforma 3gpp
+ //Format: CIF MP4 output format 3gpp
@LargeTest
public void testCIFMP43GPP() throws Exception {
boolean videoRecordedResult = false;
recordVideo(15, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP,
MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false);
videoRecordedResult = validateVideo(MediaNames.RECORDED_VIDEO_3GP, 352, 288);
- assertTrue("CIFH263", videoRecordedResult);
+ assertTrue("CIFMP4 3GPP", videoRecordedResult);
}
@LargeTest
@@ -272,5 +311,29 @@ public class MediaRecorderTest extends ActivityInstrumentationTestCase<MediaFram
assertTrue("QCIFH263 3GPP", videoRecordedResult);
}
+ @LargeTest
+ public void testInvalidVideoPath() throws Exception {
+ boolean isTestInvalidVideoPathSuccessful = false;
+ isTestInvalidVideoPathSuccessful = invalidRecordSetting(15, 176, 144, MediaRecorder.VideoEncoder.H263,
+ MediaRecorder.OutputFormat.THREE_GPP, MediaNames.INVALD_VIDEO_PATH, false);
+ assertTrue("Invalid outputFile Path", isTestInvalidVideoPathSuccessful);
+ }
+
+ @Suppress
+ public void testInvalidVideoSize() throws Exception {
+ boolean isTestInvalidVideoSizeSuccessful = false;
+ isTestInvalidVideoSizeSuccessful = invalidRecordSetting(15, 800, 600, MediaRecorder.VideoEncoder.H263,
+ MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false);
+ assertTrue("Invalid video Size", isTestInvalidVideoSizeSuccessful);
+ }
+
+ @LargeTest
+ public void testInvalidFrameRate() throws Exception {
+ boolean isTestInvalidFrameRateSuccessful = false;
+ isTestInvalidFrameRateSuccessful = invalidRecordSetting(50, 176, 144, MediaRecorder.VideoEncoder.H263,
+ MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false);
+ assertTrue("Invalid FrameRate", isTestInvalidFrameRateSuccessful);
+ }
+
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
new file mode 100644
index 0000000..dbf937c
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaRecorderStressTest.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed 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 com.android.mediaframeworktest.stress;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+
+import android.hardware.Camera;
+import android.media.MediaPlayer;
+import android.media.MediaRecorder;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+/**
+ * Junit / Instrumentation test case for the media player api
+
+ */
+public class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+
+
+ private String TAG = "MediaRecorderStressTest";
+ private MediaRecorder mRecorder;
+ private Camera mCamera;
+
+ private static final int NUMBER_OF_CAMERA_STRESS_LOOPS = 100;
+ private static final int NUMBER_OF_RECORDER_STRESS_LOOPS = 100;
+ private static final int NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS = 50;
+ private static final int NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER = 200;
+ private static final long WAIT_TIME_CAMERA_TEST = 3000; // 3 second
+ private static final long WAIT_TIME_RECORDER_TEST = 60000; // 6 second
+ private static final long WAIT_TIME_RECORD = 100000; // 10 seconds
+ private static final long WAIT_TIME_PLAYBACK = 60000; // 6 second
+ private static final String OUTPUT_FILE = "/sdcard/temp";
+ private static final String OUTPUT_FILE_EXT = ".3gp";
+
+ public MediaRecorderStressTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ }
+
+ protected void setUp() throws Exception {
+ getActivity();
+ super.setUp();
+ }
+
+ //Test case for stressing the camera preview.
+ @LargeTest
+ public void testStressCamera() throws Exception {
+ SurfaceHolder mSurfaceHolder;
+ mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ try {
+ Log.v(TAG, "Start preview");
+ for (int i = 0; i< NUMBER_OF_CAMERA_STRESS_LOOPS; i++){
+ mCamera = Camera.open();
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ mCamera.startPreview();
+ Thread.sleep(WAIT_TIME_CAMERA_TEST);
+ mCamera.stopPreview();
+ mCamera.release();
+ }
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ }
+ }
+
+ //Test case for stressing the camera preview.
+ @LargeTest
+ public void testStressRecorder() throws Exception {
+ String filename;
+ SurfaceHolder mSurfaceHolder;
+ mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ try {
+ Log.v(TAG, "Start preview");
+ for (int i = 0; i < NUMBER_OF_RECORDER_STRESS_LOOPS; i++){
+ Log.v(TAG, "counter = " + i);
+ filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
+ Log.v(TAG, filename);
+ mRecorder = new MediaRecorder();
+ mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mRecorder.setOutputFile(filename);
+ mRecorder.setVideoFrameRate(20);
+ mRecorder.setVideoSize(176,144);
+ Log.v(TAG, "setEncoder");
+ mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
+ mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ Log.v(TAG, "setPreview");
+ mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+ Log.v(TAG, "prepare");
+ mRecorder.prepare();
+ Log.v(TAG, "before release");
+ Thread.sleep(WAIT_TIME_RECORDER_TEST);
+ mRecorder.reset();
+ mRecorder.release();
+ }
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ }
+ }
+
+
+ //Stress test case for switching camera and video recorder preview.
+ @LargeTest
+ public void testStressCameraSwitchRecorder() throws Exception {
+ String filename;
+ SurfaceHolder mSurfaceHolder;
+ mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ try {
+ Log.v(TAG, "Start preview");
+ for (int i = 0; i < NUMBER_OF_SWTICHING_LOOPS_BW_CAMERA_AND_RECORDER; i++){
+ mCamera = Camera.open();
+ mCamera.setPreviewDisplay(mSurfaceHolder);
+ mCamera.startPreview();
+ Thread.sleep(WAIT_TIME_CAMERA_TEST);
+ mCamera.stopPreview();
+ mCamera.release();
+ mCamera = null;
+ Log.v(TAG, "release camera");
+ filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
+ Log.v(TAG, filename);
+ mRecorder = new MediaRecorder();
+ mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mRecorder.setOutputFile(filename);
+ mRecorder.setVideoFrameRate(20);
+ mRecorder.setVideoSize(176,144);
+ Log.v(TAG, "Media recorder setEncoder");
+ mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
+ Log.v(TAG, "mediaRecorder setPreview");
+ mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+ Log.v(TAG, "prepare");
+ mRecorder.prepare();
+ Log.v(TAG, "before release");
+ Thread.sleep(WAIT_TIME_CAMERA_TEST);
+ mRecorder.release();
+ Log.v(TAG, "release video recorder");
+ }
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ }
+ }
+
+ //Stress test case for record a video and play right away.
+ @LargeTest
+ public void testStressRecordVideoAndPlayback() throws Exception {
+ String filename;
+ SurfaceHolder mSurfaceHolder;
+ mSurfaceHolder = MediaFrameworkTest.mSurfaceView.getHolder();
+ try {
+ for (int i = 0; i < NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS; i++){
+ filename = OUTPUT_FILE + i + OUTPUT_FILE_EXT;
+ Log.v(TAG, filename);
+ mRecorder = new MediaRecorder();
+ mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+ mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ mRecorder.setOutputFile(filename);
+ mRecorder.setVideoFrameRate(20);
+ mRecorder.setVideoSize(352,288);
+ mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
+ mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ Log.v(TAG, "mediaRecorder setPreview");
+ mRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
+ mRecorder.prepare();
+ mRecorder.start();
+ Thread.sleep(WAIT_TIME_RECORD);
+ Log.v(TAG, "Before stop");
+ mRecorder.stop();
+ mRecorder.release();
+ //start the playback
+ MediaPlayer mp = new MediaPlayer();
+ mp.setDataSource(filename);
+ mp.setDisplay(MediaFrameworkTest.mSurfaceView.getHolder());
+ mp.prepare();
+ mp.start();
+ Thread.sleep(WAIT_TIME_PLAYBACK);
+ mp.release();
+ }
+ } catch (Exception e) {
+ Log.v(TAG, e.toString());
+ }
+ }
+}
+
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java
index 366b6ff..dfd544a 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java
@@ -59,9 +59,6 @@ public class MediaRecorderPrepareStateUnitTest extends AndroidTestCase implement
}
}
- //TODO(elaurent)
- //reactivate the test until bug#1495237 fix
- @Suppress
@MediumTest
public void testPrepare() {
mTestTemplate.runTestOnMethod(this);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java
index a45f7ba..cae9e31 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java
@@ -54,9 +54,6 @@ public class MediaRecorderResetStateUnitTest extends AndroidTestCase implements
recorder.reset();
}
- //TODO(elaurent)
- //reactivate the test until bug#1495237 fix
- @Suppress
@MediumTest
public void testReset() {
mTestTemplate.runTestOnMethod(this);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java
index f17d017..4b5a818 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java
@@ -54,9 +54,6 @@ public class MediaRecorderSetAudioEncoderStateUnitTest extends AndroidTestCase i
recorder.setAudioEncoder(MediaRecorderStateUnitTestTemplate.AUDIO_ENCODER);
}
- //TODO(elaurent)
- //reactivate the test until bug#1495237 fix
- @Suppress
@MediumTest
public void testSetAudioEncoder() {
mTestTemplate.runTestOnMethod(this);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java
index a972dae..f8ab48cf 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java
@@ -54,9 +54,6 @@ public class MediaRecorderSetAudioSourceStateUnitTest extends AndroidTestCase im
recorder.setAudioSource(MediaRecorderStateUnitTestTemplate.AUDIO_SOURCE);
}
- //TODO(elaurent)
- //reactivate the test until bug#1495237 fix
- @Suppress
@MediumTest
public void testSetAudioSource() {
mTestTemplate.runTestOnMethod(this);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java
index b5e7bb7..50e235b 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java
@@ -53,9 +53,6 @@ public class MediaRecorderSetOutputFileStateUnitTest extends AndroidTestCase imp
recorder.setOutputFile(MediaRecorderStateUnitTestTemplate.RECORD_OUTPUT_PATH);
}
- //TODO(elaurent)
- //reactivate the test until bug#1495237 fix
- @Suppress
@MediumTest
public void testSetOutputFile() {
mTestTemplate.runTestOnMethod(this);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java
index 3d6f87f..cacdd87 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java
@@ -54,9 +54,6 @@ public class MediaRecorderSetOutputFormatStateUnitTest extends AndroidTestCase i
recorder.setOutputFormat(MediaRecorderStateUnitTestTemplate.OUTPUT_FORMAT);
}
- //TODO(elaurent)
- //reactivate the test until bug#1495237 fix
- @Suppress
@MediumTest
public void testSetOutputFormat() {
mTestTemplate.runTestOnMethod(this);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java
index 03180d5..d1232fc 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java
@@ -54,9 +54,6 @@ public class MediaRecorderStartStateUnitTest extends AndroidTestCase implements
recorder.start();
}
- //TODO(elaurent)
- //reactivate the test until bug#1495237 fix
- @Suppress
@MediumTest
public void testStart() {
mTestTemplate.runTestOnMethod(this);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
index 330e8ab..8737595 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
@@ -54,9 +54,6 @@ public class MediaRecorderStopStateUnitTest extends AndroidTestCase implements M
recorder.stop();
}
- //TODO(elaurent)
- //reactivate the test until bug#1495237 fix
- @Suppress
@MediumTest
public void testStop() {
mTestTemplate.runTestOnMethod(this);