summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-27 15:38:40 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-27 15:38:40 -0700
commite1861133d51b9e6a6f658eb366630ad4f4d3ff8f (patch)
tree046aaac6d455ccd57d38f3a13df44ecd13ac0322 /media
parentd91450e1169b3a57b3507fe86d947de05549f4ed (diff)
parent3f2fd987b230740e1b28ccb541d1181cb2187ae6 (diff)
downloadframeworks_base-e1861133d51b9e6a6f658eb366630ad4f4d3ff8f.zip
frameworks_base-e1861133d51b9e6a6f658eb366630ad4f4d3ff8f.tar.gz
frameworks_base-e1861133d51b9e6a6f658eb366630ad4f4d3ff8f.tar.bz2
Merge commit 'korg/cupcake'
Conflicts: core/java/android/webkit/WebView.java core/java/android/widget/TwoLineListItem.java preloaded-classes
Diffstat (limited to 'media')
-rw-r--r--media/java/android/media/AudioManager.java27
-rw-r--r--media/java/android/media/AudioRecord.java161
-rw-r--r--media/java/android/media/AudioService.java85
-rw-r--r--media/java/android/media/AudioTrack.java18
-rw-r--r--media/java/android/media/JetPlayer.java180
-rw-r--r--media/java/android/media/MediaPlayer.java42
-rw-r--r--media/java/android/media/MediaRecorder.java27
-rw-r--r--media/jni/android_media_MediaRecorder.cpp14
-rw-r--r--media/jni/soundpool/NOTICE190
-rw-r--r--media/libmedia/AudioRecord.cpp18
-rw-r--r--media/libmedia/AudioTrack.cpp19
-rw-r--r--media/libmedia/JetPlayer.cpp14
-rw-r--r--media/libmedia/mediaplayer.cpp35
-rw-r--r--media/libmedia/mediarecorder.cpp5
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp1
-rw-r--r--media/sdutils/Android.mk1
-rwxr-xr-xmedia/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java10
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java139
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java13
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java4
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java4
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java4
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java4
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java4
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java4
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java4
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java4
27 files changed, 730 insertions, 301 deletions
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 077d016..f509fb5 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -160,7 +160,7 @@ public class AudioManager {
16, // STREAM_MUSIC
8, // STREAM_ALARM
8, // STREAM_NOTIFICATION
- 15, // STREAM_BLUETOOTH_SCO
+ 16, // STREAM_BLUETOOTH_SCO
};
/** @hide Default volume index values for audio streams */
@@ -220,7 +220,7 @@ public class AudioManager {
* By default this is on for the ring stream. 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)
*/
@@ -954,25 +954,21 @@ public class AudioManager {
/**
* IME standard keypress sound
* @see #playSoundEffect(int)
- * @hide FIXME: Unhide before release
*/
public static final int FX_KEYPRESS_STANDARD = 5;
/**
* IME spacebar keypress sound
* @see #playSoundEffect(int)
- * @hide FIXME: Unhide before release
*/
public static final int FX_KEYPRESS_SPACEBAR = 6;
/**
* IME delete keypress sound
* @see #playSoundEffect(int)
- * @hide FIXME: Unhide before release
*/
public static final int FX_KEYPRESS_DELETE = 7;
/**
* IME return_keypress sound
* @see #playSoundEffect(int)
- * @hide FIXME: Unhide before release
*/
public static final int FX_KEYPRESS_RETURN = 8;
/**
@@ -988,11 +984,10 @@ public class AudioManager {
* {@link #FX_FOCUS_NAVIGATION_DOWN},
* {@link #FX_FOCUS_NAVIGATION_LEFT},
* {@link #FX_FOCUS_NAVIGATION_RIGHT},
- * FIXME: include links before release
- * {link #FX_KEYPRESS_STANDARD},
- * {link #FX_KEYPRESS_SPACEBAR},
- * {link #FX_KEYPRESS_DELETE},
- * {link #FX_KEYPRESS_RETURN},
+ * {@link #FX_KEYPRESS_STANDARD},
+ * {@link #FX_KEYPRESS_SPACEBAR},
+ * {@link #FX_KEYPRESS_DELETE},
+ * {@link #FX_KEYPRESS_RETURN},
* NOTE: This version uses the UI settings to determine
* whether sounds are heard or not.
*/
@@ -1021,15 +1016,13 @@ public class AudioManager {
* {@link #FX_FOCUS_NAVIGATION_DOWN},
* {@link #FX_FOCUS_NAVIGATION_LEFT},
* {@link #FX_FOCUS_NAVIGATION_RIGHT},
- * FIXME: include links before release
- * {link #FX_KEYPRESS_STANDARD},
- * {link #FX_KEYPRESS_SPACEBAR},
- * {link #FX_KEYPRESS_DELETE},
- * {link #FX_KEYPRESS_RETURN},
+ * {@link #FX_KEYPRESS_STANDARD},
+ * {@link #FX_KEYPRESS_SPACEBAR},
+ * {@link #FX_KEYPRESS_DELETE},
+ * {@link #FX_KEYPRESS_RETURN},
* @param volume Sound effect volume
* NOTE: This version is for applications that have their own
* settings panel for enabling and controlling volume.
- * @hide FIXME: Unhide before release
*/
public void playSoundEffect(int effectType, float volume) {
if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 0ef7760..a49bd67 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -165,27 +165,24 @@ public class AudioRecord
*/
private Object mRecordingStateLock = new Object();
/**
- * The listener the AudioRecord notifies when a previously set marker is reached.
- * @see #setMarkerReachedListener(OnMarkerReachedListener)
+ * The listener the AudioRecord notifies when the record position reaches a marker
+ * or for periodic updates during the progression of the record head.
+ * @see #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)
+ * @see #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)
*/
- private OnMarkerReachedListener mMarkerListener = null;
+ private OnRecordPositionUpdateListener mPositionListener = null;
/**
- * Lock to protect marker listener updates against event notifications
+ * Lock to protect position listener updates against event notifications
*/
- private final Object mMarkerListenerLock = new Object();
+ private final Object mPositionListenerLock = new Object();
/**
- * The listener the AudioRecord notifies periodically during recording.
- * @see #setPeriodicNotificationListener(OnPeriodicNotificationListener)
+ * Handler for marker events coming from the native code
*/
- private OnPeriodicNotificationListener mPeriodicListener = null;
+ private NativeEventHandler mEventHandler = null;
/**
- * Lock to protect periodic listener updates against event notifications
+ * Looper associated with the thread that creates the AudioRecord instance
*/
- private final Object mPeriodicListenerLock = new Object();
- /**
- * Handler for events coming from the native code
- */
- private NativeEventHandler mNativeEventHandler = null;
+ private Looper mInitializationLooper = null;
/**
* Size of the native audio buffer.
*/
@@ -217,6 +214,11 @@ public class AudioRecord
throws IllegalArgumentException {
mState = STATE_UNINITIALIZED;
mRecordingState = RECORDSTATE_STOPPED;
+
+ // remember which looper is associated with the AudioRecord instanciation
+ if ((mInitializationLooper = Looper.myLooper()) == null) {
+ mInitializationLooper = Looper.getMainLooper();
+ }
audioParamCheck(audioSource, sampleRateInHz, channelConfig, audioFormat);
@@ -319,21 +321,6 @@ public class AudioRecord
}
- // Convenience method for the creation of the native event handler
- // It is called only when a non-null event listener is set.
- // precondition:
- // mNativeEventHandler is null
- private void createNativeEventHandler() {
- Looper looper;
- if ((looper = Looper.myLooper()) != null) {
- mNativeEventHandler = new NativeEventHandler(this, looper);
- } else if ((looper = Looper.getMainLooper()) != null) {
- mNativeEventHandler = new NativeEventHandler(this, looper);
- } else {
- mNativeEventHandler = null;
- }
- }
-
/**
* Releases the native AudioRecord resources.
@@ -433,7 +420,6 @@ public class AudioRecord
}
/**
- * {@hide}
* Returns the minimum buffer size required for the successful creation of an AudioRecord
* object.
* @param sampleRateInHz the sample rate expressed in Hertz.
@@ -602,36 +588,40 @@ public class AudioRecord
// Initialization / configuration
//--------------------
/**
- * Sets the listener the AudioRecord notifies when a previously set marker is reached.
+ * Sets the listener the AudioRecord notifies when a previously set marker is reached or
+ * for each periodic record head position update.
* @param listener
*/
- public void setMarkerReachedListener(OnMarkerReachedListener listener) {
- synchronized (mMarkerListenerLock) {
- mMarkerListener = listener;
- }
- if ((listener != null) && (mNativeEventHandler == null)) {
- createNativeEventHandler();
- }
+ public void setRecordPositionUpdateListener(OnRecordPositionUpdateListener listener) {
+ setRecordPositionUpdateListener(listener, null);
}
-
- /**
- * Sets the listener the AudioRecord notifies periodically during recording.
- * @param listener
- */
- public void setPeriodicNotificationListener(OnPeriodicNotificationListener listener) {
- synchronized (mPeriodicListenerLock) {
- mPeriodicListener = listener;
- }
- if ((listener != null) && (mNativeEventHandler == null)) {
- createNativeEventHandler();
+
+ public void setRecordPositionUpdateListener(OnRecordPositionUpdateListener listener,
+ Handler handler) {
+ synchronized (mPositionListenerLock) {
+
+ mPositionListener = listener;
+
+ if (listener != null) {
+ if (handler != null) {
+ mEventHandler = new NativeEventHandler(this, handler.getLooper());
+ } else {
+ // no given handler, use the looper the AudioRecord was created in
+ mEventHandler = new NativeEventHandler(this, mInitializationLooper);
+ }
+ } else {
+ mEventHandler = null;
+ }
}
+
}
/**
- * Sets the marker position at which the listener, if set with
- * {@link #setMarkerReachedListener(OnMarkerReachedListener)}, is called.
+ * Sets the marker position at which the listener is called, if set with
+ * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or
+ * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)}.
* @param markerInFrames marker position expressed in frames
* @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
* {@link #ERROR_INVALID_OPERATION}
@@ -642,8 +632,9 @@ public class AudioRecord
/**
- * Sets the period at which the listener, if set with
- * {@link #setPositionNotificationPeriod(int)}, is called.
+ * Sets the period at which the listener is called, if set with
+ * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or
+ * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)}.
* @param periodInFrames update period expressed in frames
* @return error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION}
*/
@@ -659,70 +650,65 @@ public class AudioRecord
* Interface definition for a callback to be invoked when an AudioRecord has
* reached a notification marker set by setNotificationMarkerPosition().
*/
- public interface OnMarkerReachedListener {
+ public interface OnRecordPositionUpdateListener {
/**
* Called on the listener to notify it that the previously set marker has been reached
* by the recording head.
*/
void onMarkerReached(AudioRecord recorder);
- }
-
-
- /**
- * Interface definition for a callback to be invoked for each periodic AudioRecord
- * update during recording. The update interval is set by setPositionNotificationPeriod().
- */
- public interface OnPeriodicNotificationListener {
+
/**
- * Called on the listener to periodically notify it that the recording head has reached
+ * Called on the listener to periodically notify it that the record head has reached
* a multiple of the notification period.
*/
void onPeriodicNotification(AudioRecord recorder);
}
+
+
//---------------------------------------------------------
// Inner classes
//--------------------
+
/**
- * Helper class to handle the forwarding of native events to the appropriate listeners
- */
- private class NativeEventHandler extends Handler
- {
- private AudioRecord mAudioRecord;
-
- public NativeEventHandler(AudioRecord ar, Looper looper) {
+ * Helper class to handle the forwarding of native events to the appropriate listener
+ * (potentially) handled in a different thread
+ */
+ private class NativeEventHandler extends Handler {
+
+ private final AudioRecord mAudioRecord;
+
+ NativeEventHandler(AudioRecord recorder, Looper looper) {
super(looper);
- mAudioRecord = ar;
+ mAudioRecord = recorder;
}
-
+
@Override
public void handleMessage(Message msg) {
- if (mAudioRecord == null) {
- return;
+ OnRecordPositionUpdateListener listener = null;
+ synchronized (mPositionListenerLock) {
+ listener = mAudioRecord.mPositionListener;
}
+
switch(msg.what) {
case NATIVE_EVENT_MARKER:
- synchronized (mMarkerListenerLock) {
- if (mAudioRecord.mMarkerListener != null) {
- mAudioRecord.mMarkerListener.onMarkerReached(mAudioRecord);
- }
+ if (listener != null) {
+ listener.onMarkerReached(mAudioRecord);
}
break;
case NATIVE_EVENT_NEW_POS:
- synchronized (mPeriodicListenerLock) {
- if (mAudioRecord.mPeriodicListener != null) {
- mAudioRecord.mPeriodicListener.onPeriodicNotification(mAudioRecord);
- }
+ if (listener != null) {
+ listener.onPeriodicNotification(mAudioRecord);
}
break;
default:
Log.e(TAG, "[ android.media.AudioRecord.NativeEventHandler ] " +
"Unknown event type: " + msg.what);
- break;
+ break;
}
}
- }
+ };
//---------------------------------------------------------
@@ -737,9 +723,10 @@ public class AudioRecord
return;
}
- if (recorder.mNativeEventHandler != null) {
- Message m = recorder.mNativeEventHandler.obtainMessage(what, arg1, arg2, obj);
- recorder.mNativeEventHandler.sendMessage(m);
+ if (recorder.mEventHandler != null) {
+ Message m =
+ recorder.mEventHandler.obtainMessage(what, arg1, arg2, obj);
+ recorder.mEventHandler.sendMessage(m);
}
}
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 83ede0d..2e3e460 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -21,6 +21,7 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.database.ContentObserver;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.os.Binder;
@@ -92,7 +93,8 @@ public class AudioService extends IAudioService.Stub {
private AudioHandler mAudioHandler;
/** @see VolumeStreamState */
private VolumeStreamState[] mStreamStates;
-
+ private SettingsObserver mSettingsObserver;
+
private boolean mMicMute;
private int mMode;
private int[] mRoutes = new int[AudioSystem.NUM_MODES];
@@ -157,9 +159,6 @@ public class AudioService extends IAudioService.Stub {
*/
private int mRingerMode;
- /** @see System#MODE_RINGER_STREAMS_AFFECTED */
- private int mRingerModeAffectedStreams;
-
/** @see System#MUTE_STREAMS_AFFECTED */
private int mMuteAffectedStreams;
@@ -181,7 +180,8 @@ public class AudioService extends IAudioService.Stub {
mContext = context;
mContentResolver = context.getContentResolver();
mVolumePanel = new VolumePanel(context, this);
-
+ mSettingsObserver = new SettingsObserver();
+
createAudioSystemThread();
createStreamStates();
readPersistedSettings();
@@ -275,8 +275,6 @@ public class AudioService extends IAudioService.Stub {
final ContentResolver cr = mContentResolver;
mRingerMode = System.getInt(cr, System.MODE_RINGER, AudioManager.RINGER_MODE_NORMAL);
- mRingerModeAffectedStreams = System.getInt(mContentResolver,
- System.MODE_RINGER_STREAMS_AFFECTED, 1 << AudioSystem.STREAM_RING);
mVibrateSetting = System.getInt(cr, System.VIBRATE_ON, 0);
@@ -494,32 +492,36 @@ public class AudioService extends IAudioService.Stub {
/** @see AudioManager#setRingerMode(int) */
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,
- 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, false);
- }
- }
+ setRingerModeInt(ringerMode);
// 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);
+ private void setRingerModeInt(int ringerMode) {
+ 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,
+ 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, false);
+ }
}
+
+ // 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) */
@@ -565,7 +567,6 @@ public class AudioService extends IAudioService.Stub {
/**
* @see #setVibrateSetting(int, int)
- * @hide
*/
public static int getValueForVibrateSetting(int existingValue, int vibrateType,
int vibrateSetting) {
@@ -659,7 +660,6 @@ public class AudioService extends IAudioService.Stub {
}
/** @see AudioManager#playSoundEffect(int, float) */
- /* @hide FIXME: unhide before release */
public void playSoundEffectVolume(int effectType, float volume) {
sendMsg(mAudioHandler, MSG_PLAY_SOUND_EFFECT, SHARED_MSG, SENDMSG_NOOP,
effectType, (int) (volume * 1000), null, 0);
@@ -783,7 +783,9 @@ public class AudioService extends IAudioService.Stub {
}
public boolean isStreamAffectedByRingerMode(int streamType) {
- return (mRingerModeAffectedStreams & (1 << streamType)) != 0;
+ int ringerModeAffectedStreams = Settings.System.getInt(mContentResolver,
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED, 0);
+ return (ringerModeAffectedStreams & (1 << streamType)) != 0;
}
public boolean isStreamAffectedByMute(int streamType) {
@@ -1233,4 +1235,25 @@ public class AudioService extends IAudioService.Stub {
}
}
+ private class SettingsObserver extends ContentObserver {
+
+ SettingsObserver() {
+ super(new Handler());
+ mContentResolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED), false, this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ super.onChange(selfChange);
+
+ /*
+ * Ensure all stream types that should be affected by ringer mode
+ * are in the proper state.
+ */
+ setRingerModeInt(getRingerMode());
+ }
+
+ }
+
}
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 316fa7a..4196ef3 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -171,6 +171,10 @@ public class AudioTrack
*/
private NativeEventHandlerDelegate mEventHandlerDelegate = null;
/**
+ * Looper associated with the thread that creates the AudioTrack instance
+ */
+ private Looper mInitializationLooper = null;
+ /**
* The audio data sampling rate in Hz.
*/
private int mSampleRate = 22050;
@@ -248,6 +252,11 @@ public class AudioTrack
int bufferSizeInBytes, int mode)
throws IllegalArgumentException {
mState = STATE_UNINITIALIZED;
+
+ // remember which looper is associated with the AudioTrack instanciation
+ if ((mInitializationLooper = Looper.myLooper()) == null) {
+ mInitializationLooper = Looper.getMainLooper();
+ }
audioParamCheck(streamType, sampleRateInHz, channelConfig, audioFormat, mode);
@@ -414,7 +423,6 @@ public class AudioTrack
}
/**
- * @hide
* Returns the current playback rate in Hz. Note that this rate may differ from one set using
* {@link #setPlaybackRate(int)} as the value effectively set is implementation-dependent.
*/
@@ -513,7 +521,6 @@ public class AudioTrack
}
/**
- * {@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.
@@ -902,11 +909,10 @@ public class AudioTrack
if (handler != null) {
looper = handler.getLooper();
} else {
- // no given handler, look for main looper
- if ((looper = Looper.myLooper()) == null) {
- looper = Looper.getMainLooper();
- }
+ // no given handler, use the looper the AudioTrack was created in
+ looper = mInitializationLooper;
}
+
// construct the event handler with this looper
if (looper != null) {
// implement the event handler delegate
diff --git a/media/java/android/media/JetPlayer.java b/media/java/android/media/JetPlayer.java
index 9de0eec..c9efac5 100644
--- a/media/java/android/media/JetPlayer.java
+++ b/media/java/android/media/JetPlayer.java
@@ -63,26 +63,33 @@ public class JetPlayer
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
+
+ // to keep in sync with values used in external/sonivox/arm-wt-22k/Android.mk
+ // Jet rendering audio parameters
+ private static final int JET_OUTPUT_RATE = 22050; // _SAMPLE_RATE_22050 in Android.mk
+ private static final int JET_OUTPUT_CHANNEL_CONFIG =
+ AudioFormat.CHANNEL_CONFIGURATION_STEREO; // NUM_OUTPUT_CHANNELS=2 in Android.mk
//--------------------------------------------
// Member variables
//------------------------
- private EventHandler mNativeEventHandler = null;
+ /**
+ * Handler for jet events and status updates coming from the native code
+ */
+ private NativeEventHandler mEventHandler = null;
/**
- * Lock to protect status listener updates against status change notifications
+ * Looper associated with the thread that creates the AudioTrack instance
*/
- private final Object mStatusListenerLock = new Object();
+ private Looper mInitializationLooper = null;
/**
* Lock to protect the event listener updates against event notifications
*/
private final Object mEventListenerLock = new Object();
- private JetStatusUpdateListener mJetStatusUpdateListener = null;
-
- private JetEventListener mJetEventListener = null;
+ private OnJetEventListener mJetEventListener = null;
private static JetPlayer singletonRef;
@@ -101,8 +108,9 @@ public class JetPlayer
// Constructor, finalize
//------------------------
public static JetPlayer getJetPlayer() {
- if (singletonRef == null)
+ if (singletonRef == null) {
singletonRef = new JetPlayer();
+ }
return singletonRef;
}
@@ -115,10 +123,24 @@ public class JetPlayer
private JetPlayer() {
-
- native_setup(new WeakReference<JetPlayer>(this),
- JetPlayer.getMaxTracks(),
- 1200); //TODO parametrize this (?)
+
+ // remember which looper is associated with the JetPlayer instanciation
+ if ((mInitializationLooper = Looper.myLooper()) == null) {
+ mInitializationLooper = Looper.getMainLooper();
+ }
+
+ int buffSizeInBytes = AudioTrack.getMinBufferSize(JET_OUTPUT_RATE,
+ JET_OUTPUT_CHANNEL_CONFIG, AudioFormat.ENCODING_PCM_16BIT);
+
+ if ((buffSizeInBytes != AudioTrack.ERROR)
+ && (buffSizeInBytes != AudioTrack.ERROR_BAD_VALUE)) {
+
+ native_setup(new WeakReference<JetPlayer>(this),
+ JetPlayer.getMaxTracks(),
+ // bytes to frame conversion: sample format is ENCODING_PCM_16BIT, 2 channels
+ // 1200 == minimum buffer size in frames on generation 1 hardware
+ Math.max(1200, buffSizeInBytes / 4));
+ }
}
@@ -132,18 +154,6 @@ public class JetPlayer
}
- private void createNativeEventHandler() {
- Looper looper;
- if ((looper = Looper.myLooper()) != null) {
- mNativeEventHandler = new EventHandler(this, looper);
- } else if ((looper = Looper.getMainLooper()) != null) {
- mNativeEventHandler = new EventHandler(this, looper);
- } else {
- mNativeEventHandler = null;
- }
- }
-
-
//--------------------------------------------
// Getters
//------------------------
@@ -235,24 +245,27 @@ public class JetPlayer
//---------------------------------------------------------
// Internal class to handle events posted from native code
//------------------------
- private class EventHandler extends Handler
+ private class NativeEventHandler extends Handler
{
private JetPlayer mJet;
- public EventHandler(JetPlayer jet, Looper looper) {
+ public NativeEventHandler(JetPlayer jet, Looper looper) {
super(looper);
mJet = jet;
}
@Override
public void handleMessage(Message msg) {
+ OnJetEventListener listener = null;
+ synchronized (mEventListenerLock) {
+ listener = mJet.mJetEventListener;
+ }
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(
+ if (listener != 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),
@@ -261,28 +274,21 @@ public class JetPlayer
(byte)(((msg.arg1 & JET_EVENT_CHAN_MASK) >> JET_EVENT_CHAN_SHIFT) + 1),
(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(mJet, msg.arg1, msg.arg2);
- }
+ if (listener != null) {
+ listener.onJetUserIdUpdate(mJet, msg.arg1, msg.arg2);
}
return;
case JET_NUMQUEUEDSEGMENT_UPDATE:
- synchronized (mStatusListenerLock) {
- if (mJetStatusUpdateListener != null) {
- mJetStatusUpdateListener.onJetNumQueuedSegmentUpdate(mJet, msg.arg1);
- }
+ if (listener != null) {
+ listener.onJetNumQueuedSegmentUpdate(mJet, msg.arg1);
}
return;
case JET_PAUSE_UPDATE:
- synchronized (mStatusListenerLock) {
- if (mJetStatusUpdateListener != null)
- mJetStatusUpdateListener.onJetPauseUpdate(mJet, msg.arg1);
- }
+ if (listener != null)
+ listener.onJetPauseUpdate(mJet, msg.arg1);
return;
default:
@@ -294,22 +300,48 @@ public class JetPlayer
//--------------------------------------------
- // Jet status update listener
+ // Jet event listener
//------------------------
- public void setStatusUpdateListener(JetStatusUpdateListener listener) {
- synchronized(mStatusListenerLock) {
- mJetStatusUpdateListener = listener;
- }
-
- if ((listener != null) && (mNativeEventHandler == null)) {
- createNativeEventHandler();
+ public void setEventListener(OnJetEventListener listener) {
+ setEventListener(listener, null);
+ }
+
+ public void setEventListener(OnJetEventListener listener, Handler handler) {
+ synchronized(mEventListenerLock) {
+
+ mJetEventListener = listener;
+
+ if (listener != null) {
+ if (handler != null) {
+ mEventHandler = new NativeEventHandler(this, handler.getLooper());
+ } else {
+ // no given handler, use the looper the AudioTrack was created in
+ mEventHandler = new NativeEventHandler(this, mInitializationLooper);
+ }
+ } else {
+ mEventHandler = null;
+ }
+
}
}
+
/**
- * Handles the notification when the JET status is updated.
+ * Handles the notification when the JET engine generates an event.
*/
- public interface JetStatusUpdateListener {
+ public interface OnJetEventListener {
+ /**
+ * 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);
/**
* Callback for when JET's currently playing segment userID is updated.
*
@@ -338,38 +370,6 @@ public class JetPlayer
//--------------------------------------------
- // 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);
- }
-
-
- //--------------------------------------------
// Native methods
//------------------------
private native final boolean native_setup(Object Jet_this,
@@ -397,13 +397,15 @@ public class JetPlayer
@SuppressWarnings("unused")
private static void postEventFromNative(Object jetplayer_ref,
int what, int arg1, int arg2) {
-
+ //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2);
JetPlayer jet = (JetPlayer)((WeakReference)jetplayer_ref).get();
- if( (jet!=null) && (jet.mNativeEventHandler!=null) ){
- Message m = jet.mNativeEventHandler.obtainMessage(what, arg1, arg2, null);
- jet.mNativeEventHandler.sendMessage(m);
+ if ((jet != null) && (jet.mEventHandler != null)) {
+ Message m =
+ jet.mEventHandler.obtainMessage(what, arg1, arg2, null);
+ jet.mEventHandler.sendMessage(m);
}
+
}
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 202d0ae..19ab0ad 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1036,11 +1036,11 @@ public class MediaPlayer
* Register a callback to be invoked when the media source is ready
* for playback.
*
- * @param l the callback that will be run
+ * @param listener the callback that will be run
*/
- public void setOnPreparedListener(OnPreparedListener l)
+ public void setOnPreparedListener(OnPreparedListener listener)
{
- mOnPreparedListener = l;
+ mOnPreparedListener = listener;
}
private OnPreparedListener mOnPreparedListener;
@@ -1063,11 +1063,11 @@ public class MediaPlayer
* Register a callback to be invoked when the end of a media source
* has been reached during playback.
*
- * @param l the callback that will be run
+ * @param listener the callback that will be run
*/
- public void setOnCompletionListener(OnCompletionListener l)
+ public void setOnCompletionListener(OnCompletionListener listener)
{
- mOnCompletionListener = l;
+ mOnCompletionListener = listener;
}
private OnCompletionListener mOnCompletionListener;
@@ -1092,11 +1092,11 @@ public class MediaPlayer
* Register a callback to be invoked when the status of a network
* stream's buffer has changed.
*
- * @param l the callback that will be run
+ * @param listener the callback that will be run.
*/
- public void setOnBufferingUpdateListener(OnBufferingUpdateListener l)
+ public void setOnBufferingUpdateListener(OnBufferingUpdateListener listener)
{
- mOnBufferingUpdateListener = l;
+ mOnBufferingUpdateListener = listener;
}
private OnBufferingUpdateListener mOnBufferingUpdateListener;
@@ -1119,11 +1119,11 @@ public class MediaPlayer
* Register a callback to be invoked when a seek operation has been
* completed.
*
- * @param l the callback that will be run
+ * @param listener the callback that will be run
*/
- public void setOnSeekCompleteListener(OnSeekCompleteListener l)
+ public void setOnSeekCompleteListener(OnSeekCompleteListener listener)
{
- mOnSeekCompleteListener = l;
+ mOnSeekCompleteListener = listener;
}
private OnSeekCompleteListener mOnSeekCompleteListener;
@@ -1131,8 +1131,6 @@ public class MediaPlayer
/**
* Interface definition of a callback to be invoked when the
* video size is first known or updated
- * FIXME: Unhide this API after approval
- * @hide
*/
public interface OnVideoSizeChangedListener
{
@@ -1142,7 +1140,6 @@ public class MediaPlayer
* @param mp the MediaPlayer associated with this callback
* @param width the width of the video
* @param height the height of the video
- * @hide
*/
public void onVideoSizeChanged(MediaPlayer mp, int width, int height);
}
@@ -1151,12 +1148,11 @@ public class MediaPlayer
* Register a callback to be invoked when the video size is
* known or updated.
*
- * @param l the callback that will be run
- * @hide
+ * @param listener the callback that will be run
*/
- public void setOnVideoSizeChangedListener(OnVideoSizeChangedListener l)
+ public void setOnVideoSizeChangedListener(OnVideoSizeChangedListener listener)
{
- mOnVideoSizeChangedListener = l;
+ mOnVideoSizeChangedListener = listener;
}
private OnVideoSizeChangedListener mOnVideoSizeChangedListener;
@@ -1178,7 +1174,7 @@ public class MediaPlayer
/** The video is streamed and its container is not valid for progressive
* playback i.e the video's index (e.g moov atom) is not at the start of the
* file.
- * @hide pending API council approval. Replace with @see tag after.
+ * @see android.media.MediaPlayer.OnErrorListener
*/
public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200;
@@ -1226,14 +1222,12 @@ public class MediaPlayer
*/
/** Unspecified media player info.
* @see android.media.MediaPlayer.OnInfoListener
- * @hide pending API council approval.
*/
public static final int MEDIA_INFO_UNKNOWN = 1;
/** The video is too complex for the decoder: it can't decode frames fast
* enough. Possibly only the audio plays fine at this stage.
* @see android.media.MediaPlayer.OnInfoListener
- * @hide pending API council approval.
*/
public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700;
@@ -1241,20 +1235,17 @@ public class MediaPlayer
* not interleaved at all, e.g has all the video samples first then all the
* audio ones. Video is playing but a lot of disk seeks may be happening.
* @see android.media.MediaPlayer.OnInfoListener
- * @hide pending API council approval.
*/
public static final int MEDIA_INFO_BAD_INTERLEAVING = 800;
/** The media cannot be seeked (e.g live stream)
* @see android.media.MediaPlayer.OnInfoListener
- * @hide pending API council approval.
*/
public static final int MEDIA_INFO_NOT_SEEKABLE = 801;
/**
* Interface definition of a callback to be invoked to communicate some
* info and/or warning about the media or its playback.
- * @hide pending API council approval.
*/
public interface OnInfoListener
{
@@ -1282,7 +1273,6 @@ public class MediaPlayer
* Register a callback to be invoked when an info/warning is available.
*
* @param listener the callback that will be run
- * @hide pending API council approval.
*/
public void setOnInfoListener(OnInfoListener listener)
{
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 1c08cba..676f241 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -259,6 +259,12 @@ public class MediaRecorder
/**
* Sets the maximum duration (in ms) of the recording session.
* Call this after setOutFormat() but before prepare().
+ * After recording reaches the specified duration, a notification
+ * will be sent to the {@link android.media.MediaRecorder.OnInfoListener}
+ * with a "what" code of {@link #MEDIA_RECORDER_INFO_MAX_DURATION_REACHED}
+ * and recording will be stopped. Stopping happens asynchronously, there
+ * is no guarantee that the recorder will have stopped by the time the
+ * listener is notified.
*
* @param max_duration_ms the maximum duration in ms (if zero or negative, disables the duration limit)
*
@@ -266,6 +272,21 @@ public class MediaRecorder
public native void setMaxDuration(int max_duration_ms) throws IllegalArgumentException;
/**
+ * Sets the maximum filesize (in bytes) of the recording session.
+ * Call this after setOutFormat() but before prepare().
+ * After recording reaches the specified filesize, a notification
+ * will be sent to the {@link android.media.MediaRecorder.OnInfoListener}
+ * with a "what" code of {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}
+ * and recording will be stopped. Stopping happens asynchronously, there
+ * is no guarantee that the recorder will have stopped by the time the
+ * listener is notified.
+ *
+ * @param max_filesize_bytes the maximum filesize in bytes (if zero or negative, disables the limit)
+ *
+ */
+ public native void setMaxFileSize(long max_filesize_bytes) throws IllegalArgumentException;
+
+ /**
* Sets the audio encoder to be used for recording. If this method is not
* called, the output file will not contain an audio track. Call this after
* setOutputFormat() but before prepare().
@@ -441,6 +462,10 @@ public class MediaRecorder
* @see android.media.MediaRecorder.OnInfoListener
*/
public static final int MEDIA_RECORDER_INFO_MAX_DURATION_REACHED = 800;
+ /** A maximum filesize had been setup and has now been reached.
+ * @see android.media.MediaRecorder.OnInfoListener
+ */
+ public static final int MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED = 801;
/**
* Interface definition for a callback to be invoked when an error
@@ -455,6 +480,8 @@ public class MediaRecorder
* @param what the type of error that has occurred:
* <ul>
* <li>{@link #MEDIA_RECORDER_INFO_UNKNOWN}
+ * <li>{@link #MEDIA_RECORDER_INFO_MAX_DURATION_REACHED}
+ * <li>{@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}
* </ul>
* @param extra an extra code, specific to the error type
*/
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 1e508d2..209b09f 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -268,6 +268,19 @@ android_media_MediaRecorder_setMaxDuration(JNIEnv *env, jobject thiz, jint max_d
}
static void
+android_media_MediaRecorder_setMaxFileSize(
+ JNIEnv *env, jobject thiz, jlong max_filesize_bytes)
+{
+ LOGV("setMaxFileSize(%lld)", max_filesize_bytes);
+ sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
+
+ char params[64];
+ sprintf(params, "max-filesize=%lld", max_filesize_bytes);
+
+ process_media_recorder_call(env, mr->setParameters(String8(params)), "java/lang/RuntimeException", "setMaxFileSize failed.");
+}
+
+static void
android_media_MediaRecorder_prepare(JNIEnv *env, jobject thiz)
{
LOGV("prepare");
@@ -370,6 +383,7 @@ static JNINativeMethod gMethods[] = {
{"setVideoSize", "(II)V", (void *)android_media_MediaRecorder_setVideoSize},
{"setVideoFrameRate", "(I)V", (void *)android_media_MediaRecorder_setVideoFrameRate},
{"setMaxDuration", "(I)V", (void *)android_media_MediaRecorder_setMaxDuration},
+ {"setMaxFileSize", "(J)V", (void *)android_media_MediaRecorder_setMaxFileSize},
{"_prepare", "()V", (void *)android_media_MediaRecorder_prepare},
{"getMaxAmplitude", "()I", (void *)android_media_MediaRecorder_native_getMaxAmplitude},
{"start", "()V", (void *)android_media_MediaRecorder_start},
diff --git a/media/jni/soundpool/NOTICE b/media/jni/soundpool/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/media/jni/soundpool/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2008, 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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 7594ff0..986f88e 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -200,6 +200,7 @@ status_t AudioRecord::set(
// TODO: add audio hardware input latency here
mLatency = (1000*mFrameCount) / mSampleRate;
mMarkerPosition = 0;
+ mMarkerReached = false;
mNewPosition = 0;
mUpdatePeriod = 0;
@@ -293,6 +294,9 @@ status_t AudioRecord::stop()
if (android_atomic_and(~1, &mActive) == 1) {
mAudioRecord->stop();
+ // the record head position will reset to 0, so if a marker is set, we need
+ // to activate it again
+ mMarkerReached = false;
if (t != 0) {
t->requestExit();
} else {
@@ -317,6 +321,7 @@ status_t AudioRecord::setMarkerPosition(uint32_t marker)
if (mCbf == 0) return INVALID_OPERATION;
mMarkerPosition = marker;
+ mMarkerReached = false;
return NO_ERROR;
}
@@ -492,10 +497,10 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread)
size_t readSize;
// Manage marker callback
- if (mMarkerPosition > 0) {
+ if (!mMarkerReached && (mMarkerPosition > 0)) {
if (mCblk->user >= mMarkerPosition) {
mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
- mMarkerPosition = 0;
+ mMarkerReached = true;
}
}
@@ -527,7 +532,14 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread)
readSize = audioBuffer.size;
// Sanity check on returned size
- if (ssize_t(readSize) <= 0) break;
+ if (ssize_t(readSize) <= 0) {
+ // The callback is done filling buffers
+ // Keep this thread going to handle timed events and
+ // still try to get more data in intervals of WAIT_PERIOD_MS
+ // but don't just loop and block the CPU, so wait
+ usleep(WAIT_PERIOD_MS*1000);
+ break;
+ }
if (readSize > reqSize) readSize = reqSize;
audioBuffer.size = readSize;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index d26b0c5..24f7281 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -259,6 +259,7 @@ status_t AudioTrack::set(
mLatency = afLatency + (1000*mFrameCount) / mSampleRate;
mLoopCount = 0;
mMarkerPosition = 0;
+ mMarkerReached = false;
mNewPosition = 0;
mUpdatePeriod = 0;
@@ -360,6 +361,9 @@ void AudioTrack::stop()
// Cancel loops (If we are in the middle of a loop, playback
// would not stop until loopCount reaches 0).
setLoop(0, 0, 0);
+ // the playback head position will reset to 0, so if a marker is set, we need
+ // to activate it again
+ mMarkerReached = false;
// Force flush if a shared buffer is used otherwise audioflinger
// will not stop before end of buffer is reached.
if (mSharedBuffer != 0) {
@@ -385,14 +389,18 @@ bool AudioTrack::stopped() const
void AudioTrack::flush()
{
LOGV("flush");
+
+ // clear playback marker and periodic update counter
+ mMarkerPosition = 0;
+ mMarkerReached = false;
+ mUpdatePeriod = 0;
+
if (!mActive) {
- mCblk->lock.lock();
mAudioTrack->flush();
// Release AudioTrack callback thread in case it was waiting for new buffers
// in AudioTrack::obtainBuffer()
mCblk->cv.signal();
- mCblk->lock.unlock();
}
}
@@ -443,7 +451,7 @@ void AudioTrack::setSampleRate(int rate)
if (rate > afSamplingRate*2) rate = afSamplingRate*2;
if (rate > MAX_SAMPLE_RATE) rate = MAX_SAMPLE_RATE;
- mCblk->sampleRate = rate;
+ mCblk->sampleRate = (uint16_t)rate;
}
uint32_t AudioTrack::getSampleRate()
@@ -510,6 +518,7 @@ status_t AudioTrack::setMarkerPosition(uint32_t marker)
if (mCbf == 0) return INVALID_OPERATION;
mMarkerPosition = marker;
+ mMarkerReached = false;
return NO_ERROR;
}
@@ -757,10 +766,10 @@ bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
}
// Manage marker callback
- if(mMarkerPosition > 0) {
+ if (!mMarkerReached && (mMarkerPosition > 0)) {
if (mCblk->server >= mMarkerPosition) {
mCbf(EVENT_MARKER, mUserData, (void *)&mMarkerPosition);
- mMarkerPosition = 0;
+ mMarkerReached = true;
}
}
diff --git a/media/libmedia/JetPlayer.cpp b/media/libmedia/JetPlayer.cpp
index 2c62104..586aacb 100644
--- a/media/libmedia/JetPlayer.cpp
+++ b/media/libmedia/JetPlayer.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#define LOG_TAG "JetPlayer-C"
#include <utils/Log.h>
@@ -194,8 +194,15 @@ int JetPlayer::render() {
}
while (1) {
+
mMutex.lock(); // [[[[[[[[ LOCK ---------------------------------------
+ if (mEasData == NULL) {
+ mMutex.unlock();
+ LOGV("JetPlayer::render(): NULL EAS data, exiting render.");
+ goto threadExit;
+ }
+
// nothing to render, wait for client thread to wake us up
while (!mRender)
{
@@ -255,7 +262,10 @@ int JetPlayer::render() {
}//while (1)
threadExit:
- mAudioTrack->flush();
+ if (mAudioTrack) {
+ mAudioTrack->stop();
+ mAudioTrack->flush();
+ }
if (mAudioBuffer) {
delete [] mAudioBuffer;
mAudioBuffer = NULL;
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 6b40412..809316a 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -91,6 +91,7 @@ MediaPlayer::MediaPlayer()
mLoop = false;
mLeftVolume = mRightVolume = 1.0;
mVideoWidth = mVideoHeight = 0;
+ mLockThreadId = 0;
}
void MediaPlayer::onFirstRef()
@@ -223,16 +224,24 @@ status_t MediaPlayer::prepare()
{
LOGV("prepare");
Mutex::Autolock _l(mLock);
- if (mPrepareSync) return -EALREADY;
+ mLockThreadId = getThreadId();
+ if (mPrepareSync) {
+ mLockThreadId = 0;
+ return -EALREADY;
+ }
mPrepareSync = true;
status_t ret = prepareAsync_l();
- if (ret != NO_ERROR) return ret;
+ if (ret != NO_ERROR) {
+ mLockThreadId = 0;
+ return ret;
+ }
if (mPrepareSync) {
mSignal.wait(mLock); // wait for prepare done
mPrepareSync = false;
}
LOGV("prepare complete - status=%d", mPrepareStatus);
+ mLockThreadId = 0;
return mPrepareStatus;
}
@@ -407,8 +416,12 @@ status_t MediaPlayer::seekTo_l(int msec)
status_t MediaPlayer::seekTo(int msec)
{
+ mLockThreadId = getThreadId();
Mutex::Autolock _l(mLock);
- return seekTo_l(msec);
+ status_t result = seekTo_l(msec);
+ mLockThreadId = 0;
+
+ return result;
}
status_t MediaPlayer::reset()
@@ -485,14 +498,24 @@ void MediaPlayer::notify(int msg, int ext1, int ext2)
{
LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
bool send = true;
+ bool locked = false;
// TODO: In the future, we might be on the same thread if the app is
// running in the same process as the media server. In that case,
// this will deadlock.
- mLock.lock();
+ //
+ // The threadId hack below works around this for the care of prepare
+ // and seekTo within the same process.
+ // FIXME: Remember, this is a hack, it's not even a hack that is applied
+ // consistently for all use-cases, this needs to be revisited.
+ if (mLockThreadId != getThreadId()) {
+ mLock.lock();
+ locked = true;
+ }
+
if (mPlayer == 0) {
LOGV("notify(%d, %d, %d) callback on disconnected mediaplayer", msg, ext1, ext2);
- mLock.unlock(); // release the lock when done.
+ if (locked) mLock.unlock(); // release the lock when done.
return;
}
@@ -561,7 +584,7 @@ void MediaPlayer::notify(int msg, int ext1, int ext2)
}
sp<MediaPlayerListener> listener = mListener;
- mLock.unlock();
+ if (locked) mLock.unlock();
// this prevents re-entrant calls into client code
if ((listener != 0) && send) {
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 23b3b9d..6b26faf 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -367,8 +367,9 @@ status_t MediaRecorder::setParameters(const String8& params) {
status_t ret = mMediaRecorder->setParameters(params);
if (OK != ret) {
LOGE("setParameters(%s) failed: %d", params.string(), ret);
- mCurrentState = MEDIA_RECORDER_ERROR;
- return ret;
+ // Do not change our current state to MEDIA_RECORDER_ERROR, failures
+ // of the only currently supported parameters, "max-duration" and
+ // "max-filesize" are _not_ fatal.
}
return ret;
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 95001c6..8ef0dc6 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -460,6 +460,7 @@ void MediaPlayerService::Client::disconnect()
Mutex::Autolock l(mLock);
p = mPlayer;
}
+ mClient.clear();
mPlayer.clear();
// clear the notification to prevent callbacks to dead client
diff --git a/media/sdutils/Android.mk b/media/sdutils/Android.mk
index 2009b3c..dafb8a6 100644
--- a/media/sdutils/Android.mk
+++ b/media/sdutils/Android.mk
@@ -9,6 +9,7 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := libhardware_legacy libcutils libutils libc
LOCAL_MODULE:= sdutil
+LOCAL_MODULE_TAGS := debug
include $(BUILD_EXECUTABLE)
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
index 3c449c9..6edc2cc 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTestRunner.java
@@ -16,12 +16,13 @@
package com.android.mediaframeworktest;
-import com.android.mediaframeworktest.functional.MediaPlayerApiTest;
-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 com.android.mediaframeworktest.functional.MediaMetadataTest;
+import com.android.mediaframeworktest.functional.MediaMimeTest;
+import com.android.mediaframeworktest.functional.MediaPlayerApiTest;
+import com.android.mediaframeworktest.functional.MediaRecorderTest;
+import com.android.mediaframeworktest.functional.SimTonesTest;
import junit.framework.TestSuite;
@@ -50,6 +51,7 @@ public class MediaFrameworkTestRunner extends InstrumentationTestRunner {
suite.addTestSuite(CameraTest.class);
suite.addTestSuite(MediaRecorderTest.class);
suite.addTestSuite(MediaAudioTrackTest.class);
+ suite.addTestSuite(MediaMimeTest.class);
return suite;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java
new file mode 100644
index 0000000..d2809c1
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaMimeTest.java
@@ -0,0 +1,139 @@
+/*
+ * 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 java.io.File;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.Suppress;
+import android.util.Log;
+import com.android.mediaframeworktest.MediaFrameworkTest;
+
+/*
+ * System tests for the handling of mime type in the media framework.
+ *
+ * To run this test suite:
+ make frameworks/base/media/tests/MediaFrameworkTest
+ make mediaframeworktest
+
+ adb install -r out/target/product/dream/data/app/mediaframeworktest.apk
+
+ adb shell am instrument -e class \
+ com.android.mediaframeworktest.functional.MediaMimeTest \
+ -w com.android.mediaframeworktest/.MediaFrameworkTestRunner
+ *
+ */
+public class MediaMimeTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
+ private final String TAG = "MediaMimeTest";
+ private Context mContext;
+ private final String MP3_FILE = "/sdcard/media_api/music/SHORTMP3.mp3";
+ private final String MEDIA_PLAYBACK_NAME = "com.android.music.MediaPlaybackActivity";
+
+ public MediaMimeTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mContext = getActivity();
+ // Checks you have all the test files on your SDCARD.
+ assertTrue(new File(MP3_FILE).exists());
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ // ----------------------------------------------------------------------
+ // AUDIO mime type resolution tests.
+
+ @MediumTest
+ // Checks the MediaPlaybackActivity handles audio/mp3.
+ public void testCheckMediaPlaybackHandlesAudioMp3() throws Exception {
+ assertMediaPlaybackActivityHandles("audio/mp3");
+ }
+
+ @MediumTest
+ // Checks the MediaPlaybackActivity handles audio/*.
+ public void testCheckMediaPlaybackHandlesAudio() throws Exception {
+ assertMediaPlaybackActivityHandles("audio/*");
+ }
+
+ @MediumTest
+ // Checks the MediaPlaybackActivity handles application/itunes. Some servers
+ // set the Content-type header to application/iTunes (with capital T, but
+ // the download manager downcasts it) for their MP3 podcasts. This is non
+ // standard but we try to support it anyway.
+ // See bug 1401491
+ public void testCheckMediaPlaybackHandlesApplicationItunes() throws Exception {
+ assertMediaPlaybackActivityHandles("application/itunes");
+ }
+
+ @MediumTest
+ // Checks the activity resolver handling of mime types is case sensitive.
+ // See bug 1710534
+ public void testCheckActivityResolverMimeHandlingIsCaseSensitive() throws Exception {
+ assertNoActivityHandles("AUDIO/MP3"); // <--- look uppercase
+ }
+
+ @MediumTest
+ // Checks the activity resolver does not trims leading whitespaces when
+ // resolving mime types. Trailing whitespaces seems to be non
+ // significant.
+ // See bug 1710534
+ public void testCheckWhiteSpacesInMimeTypeHandling() throws Exception {
+ assertNoActivityHandles(" audio/mp3");
+ assertNoActivityHandles(" audio/mp3 ");
+ assertMediaPlaybackActivityHandles("audio/mp3 ");
+ }
+
+ // @return a ResolveInfo instance for the mime type or null if the type is
+ // not handled by any activity.
+ private ResolveInfo resolveMime(String mime) {
+ Intent viewIntent = new Intent(Intent.ACTION_VIEW);
+ Uri uri = Uri.fromParts("file", MP3_FILE, null);
+
+ viewIntent.setDataAndType(uri, mime);
+ return mContext.getPackageManager().resolveActivity(
+ viewIntent, PackageManager.MATCH_DEFAULT_ONLY);
+ }
+
+ // Helper method to check the media playback activity handles the given mime type.
+ // @param mime type to test for
+ private void assertMediaPlaybackActivityHandles(String mime) throws Exception {
+ ResolveInfo ri = resolveMime(mime);
+
+ assertNotNull(ri);
+ assertEquals(MEDIA_PLAYBACK_NAME, ri.activityInfo.name.toString());
+ }
+
+ // Helper method to check that NO activity handles the given mime type.
+ // @param mime type to test for
+ private void assertNoActivityHandles(String mime) throws Exception {
+ assertNull(resolveMime(mime));
+ }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
index 4fa6735..61a8a29 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaMetadataRetrieverTest.java
@@ -22,8 +22,7 @@ import android.graphics.Bitmap;
import java.io.FileOutputStream;
import android.test.AndroidTestCase;
import com.android.mediaframeworktest.MediaNames;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.Suppress;
+import android.test.suitebuilder.annotation.*;
/**
* WARNING:
@@ -35,7 +34,7 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase {
private static final String TAG = "MediaMetadataRetrieverTest";
// Test album art extraction.
- @LargeTest
+ @MediumTest
public static void testAlbumArt() throws Exception {
Log.v(TAG, "testAlbumArt starts.");
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
@@ -109,7 +108,7 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase {
// If the specified call order and valid media file is used, no exception
// should be thrown.
- @LargeTest
+ @MediumTest
public static void testBasicNormalMethodCallSequence() throws Exception {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
@@ -136,7 +135,7 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase {
// If setDataSource() has not been called, both captureFrame() and extractMetadata() must
// return null.
- @LargeTest
+ @MediumTest
public static void testBasicAbnormalMethodCallSequence() {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
@@ -145,7 +144,7 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase {
}
// Test setDataSource()
- @LargeTest
+ @MediumTest
public static void testSetDataSource() {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
@@ -190,7 +189,7 @@ public class MediaMetadataRetrieverTest extends AndroidTestCase {
// Due to the lack of permission to access hardware decoder, any calls
// attempting to capture a frame will fail. These are commented out for now
// until we find a solution to this access permission problem.
- @LargeTest
+ @MediumTest
public static void testIntendedUsage() {
// By default, capture frame and retrieve metadata
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
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 bde000b..134144d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderPrepareStateUnitTest.java
@@ -18,7 +18,7 @@ package com.android.mediaframeworktest.unit;
import android.media.MediaRecorder;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
import java.io.IOException;
@@ -59,7 +59,7 @@ public class MediaRecorderPrepareStateUnitTest extends AndroidTestCase implement
}
}
- @LargeTest
+ @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 80532c3..cae9e31 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderResetStateUnitTest.java
@@ -18,7 +18,7 @@ package com.android.mediaframeworktest.unit;
import android.media.MediaRecorder;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
/**
@@ -54,7 +54,7 @@ public class MediaRecorderResetStateUnitTest extends AndroidTestCase implements
recorder.reset();
}
- @LargeTest
+ @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 e387a77..4b5a818 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioEncoderStateUnitTest.java
@@ -18,7 +18,7 @@ package com.android.mediaframeworktest.unit;
import android.media.MediaRecorder;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
/**
@@ -54,7 +54,7 @@ public class MediaRecorderSetAudioEncoderStateUnitTest extends AndroidTestCase i
recorder.setAudioEncoder(MediaRecorderStateUnitTestTemplate.AUDIO_ENCODER);
}
- @LargeTest
+ @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 60af54c..f8ab48cf 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetAudioSourceStateUnitTest.java
@@ -18,7 +18,7 @@ package com.android.mediaframeworktest.unit;
import android.media.MediaRecorder;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
/**
@@ -54,7 +54,7 @@ public class MediaRecorderSetAudioSourceStateUnitTest extends AndroidTestCase im
recorder.setAudioSource(MediaRecorderStateUnitTestTemplate.AUDIO_SOURCE);
}
- @LargeTest
+ @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 37d97e9..712a758 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFileStateUnitTest.java
@@ -18,7 +18,7 @@ package com.android.mediaframeworktest.unit;
import android.media.MediaRecorder;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
/**
@@ -51,7 +51,7 @@ public class MediaRecorderSetOutputFileStateUnitTest extends AndroidTestCase imp
recorder.setOutputFile(MediaRecorderStateUnitTestTemplate.RECORD_OUTPUT_PATH);
}
- @LargeTest
+ @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 a7ee2d4..cacdd87 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderSetOutputFormatStateUnitTest.java
@@ -18,7 +18,7 @@ package com.android.mediaframeworktest.unit;
import android.media.MediaRecorder;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
/**
@@ -54,7 +54,7 @@ public class MediaRecorderSetOutputFormatStateUnitTest extends AndroidTestCase i
recorder.setOutputFormat(MediaRecorderStateUnitTestTemplate.OUTPUT_FORMAT);
}
- @LargeTest
+ @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 4af5967..d1232fc 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStartStateUnitTest.java
@@ -18,7 +18,7 @@ package com.android.mediaframeworktest.unit;
import android.media.MediaRecorder;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
/**
@@ -54,7 +54,7 @@ public class MediaRecorderStartStateUnitTest extends AndroidTestCase implements
recorder.start();
}
- @LargeTest
+ @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 5475900..8737595 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaRecorderStopStateUnitTest.java
@@ -18,7 +18,7 @@ package com.android.mediaframeworktest.unit;
import android.media.MediaRecorder;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.Suppress;
/**
@@ -54,7 +54,7 @@ public class MediaRecorderStopStateUnitTest extends AndroidTestCase implements M
recorder.stop();
}
- @LargeTest
+ @MediumTest
public void testStop() {
mTestTemplate.runTestOnMethod(this);
}