diff options
Diffstat (limited to 'media/java/android')
| -rw-r--r-- | media/java/android/media/AudioTrack.java | 48 | ||||
| -rw-r--r-- | media/java/android/media/MediaScanner.java | 27 | ||||
| -rw-r--r-- | media/java/android/mtp/MtpServer.java | 30 |
3 files changed, 63 insertions, 42 deletions
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index b97c3c4..b20a6e9 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -32,24 +32,25 @@ import android.util.Log; * It allows to stream PCM audio buffers to the audio hardware for playback. This is * 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 or streaming.<br> * In Streaming mode, the application writes a continuous stream of 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 queued for playback. The streaming mode - * is most useful when playing blocks of audio data that for instance are: + * one of the {@code write()} methods. These are blocking and return when the data has been + * transferred from the Java layer to the native layer and 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>received or generated while previously queued audio is 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. AudioTrack instances in static mode - * can play the sound without the need to transfer the audio data from Java to native layer - * 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. - * + * that need to be played with the smallest latency possible. 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> @@ -816,6 +817,7 @@ public class AudioTrack //-------------------- /** * Starts playing an AudioTrack. + * * @throws IllegalStateException */ public void play() @@ -832,6 +834,7 @@ public class AudioTrack /** * Stops playing the audio data. + * * @throws IllegalStateException */ public void stop() @@ -848,7 +851,10 @@ public class AudioTrack } /** - * Pauses the playback of the audio data. + * Pauses the playback of the audio data. Data that has not been played + * back will not be discarded. Subsequent calls to {@link #play} will play + * this data back. + * * @throws IllegalStateException */ public void pause() @@ -871,9 +877,9 @@ public class AudioTrack //-------------------- /** - * Flushes the audio data currently queued for playback. + * Flushes the audio data currently queued for playback. Any data that has + * not been played back will be discarded. */ - public void flush() { if (mState == STATE_INITIALIZED) { // flush the data in native layer @@ -883,9 +889,14 @@ public class AudioTrack } /** - * Writes the audio data to the audio hardware for playback. + * Writes the audio data to the audio hardware for playback. Will block until + * all data has been written to the audio mixer. + * Note that the actual playback of this data might occur after this function + * returns. This function is thread safe with respect to {@link #stop} calls, + * in which case all of the specified data might not be written to the mixer. + * * @param audioData the array that holds the data to play. - * @param offsetInBytes the offset expressed in bytes in audioData where the data to play + * @param offsetInBytes the offset expressed in bytes 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 or {@link #ERROR_INVALID_OPERATION} @@ -914,7 +925,12 @@ public class AudioTrack /** - * Writes the audio data to the audio hardware for playback. + * Writes the audio data to the audio hardware for playback. Will block until + * all data has been written to the audio mixer. + * Note that the actual playback of this data might occur after this function + * returns. This function is thread safe with respect to {@link #stop} calls, + * in which case all of the specified data might not be written to the mixer. + * * @param audioData the array that holds the data to play. * @param offsetInShorts the offset expressed in shorts in audioData where the data to play * starts. @@ -988,7 +1004,7 @@ public class AudioTrack /** * Sets the send level of the audio track to the attached auxiliary effect - * {@see #attachAuxEffect(int)}. The level value range is 0 to 1.0. + * {@link #attachAuxEffect(int)}. The level value range is 0 to 1.0. * <p>By default the send level is 0, so even if an effect is attached to the player * this method must be called for the effect to be applied. * <p>Note that the passed level value is a raw scalar. UI controls should be scaled diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index e8ddd2d..8c8569a 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -707,7 +707,9 @@ public class MediaScanner map.put(MediaStore.MediaColumns.MIME_TYPE, mMimeType); map.put(MediaStore.MediaColumns.IS_DRM, mIsDrm); - if (!mNoMedia) { + if (mNoMedia) { + map.put(MediaStore.MediaColumns.NO_MEDIA, true); + } else { if (MediaFile.isVideoFileType(mFileType)) { map.put(Video.Media.ARTIST, (mArtist != null && mArtist.length() > 0 ? mArtist : MediaStore.UNKNOWN_STRING)); @@ -835,6 +837,9 @@ public class MediaScanner } } + // For inserts we always use the file URI so we can insert in bulk. + // For updates we compute the URI based on the media type. + Uri tableUri = mFilesUri; Uri result = null; if (rowId == 0) { if (mMtpObjectHandle != 0) { @@ -850,7 +855,7 @@ public class MediaScanner if (mFileInserter != null) { result = mFileInserter.insert(values); } else { - result = mMediaProvider.insert(mFilesUri, values); + result = mMediaProvider.insert(tableUri, values); } if (result != null) { @@ -858,8 +863,18 @@ public class MediaScanner entry.mRowId = rowId; } } else { + if (!mNoMedia) { + if (MediaFile.isVideoFileType(mFileType)) { + tableUri = mVideoUri; + } else if (MediaFile.isImageFileType(mFileType)) { + tableUri = mImagesUri; + } else if (MediaFile.isAudioFileType(mFileType)) { + tableUri = mAudioUri; + } + } + // updated file - result = ContentUris.withAppendedId(mFilesUri, rowId); + result = ContentUris.withAppendedId(tableUri, rowId); // path should never change, and we want to avoid replacing mixed cased paths // with squashed lower case paths values.remove(MediaStore.MediaColumns.DATA); @@ -909,19 +924,19 @@ public class MediaScanner if (notifications && !mDefaultNotificationSet) { if (TextUtils.isEmpty(mDefaultNotificationFilename) || doesPathHaveFilename(entry.mPath, mDefaultNotificationFilename)) { - setSettingIfNotSet(Settings.System.NOTIFICATION_SOUND, mFilesUri, rowId); + setSettingIfNotSet(Settings.System.NOTIFICATION_SOUND, tableUri, rowId); mDefaultNotificationSet = true; } } else if (ringtones && !mDefaultRingtoneSet) { if (TextUtils.isEmpty(mDefaultRingtoneFilename) || doesPathHaveFilename(entry.mPath, mDefaultRingtoneFilename)) { - setSettingIfNotSet(Settings.System.RINGTONE, mFilesUri, rowId); + setSettingIfNotSet(Settings.System.RINGTONE, tableUri, rowId); mDefaultRingtoneSet = true; } } else if (alarms && !mDefaultAlarmSet) { if (TextUtils.isEmpty(mDefaultAlarmAlertFilename) || doesPathHaveFilename(entry.mPath, mDefaultAlarmAlertFilename)) { - setSettingIfNotSet(Settings.System.ALARM_ALERT, mFilesUri, rowId); + setSettingIfNotSet(Settings.System.ALARM_ALERT, tableUri, rowId); mDefaultAlarmSet = true; } } diff --git a/media/java/android/mtp/MtpServer.java b/media/java/android/mtp/MtpServer.java index 0133cf6..f561cc0 100644 --- a/media/java/android/mtp/MtpServer.java +++ b/media/java/android/mtp/MtpServer.java @@ -16,18 +16,13 @@ package android.mtp; -import android.util.Log; - /** * Java wrapper for MTP/PTP support as USB responder. * {@hide} */ -public class MtpServer { - - private final Object mLock = new Object(); - private boolean mStarted; +public class MtpServer implements Runnable { - private static final String TAG = "MtpServer"; + private int mNativeContext; // accessed by native methods static { System.loadLibrary("media_jni"); @@ -38,19 +33,14 @@ public class MtpServer { } public void start() { - synchronized (mLock) { - native_start(); - mStarted = true; - } + Thread thread = new Thread(this, "MtpServer"); + thread.start(); } - public void stop() { - synchronized (mLock) { - if (mStarted) { - native_stop(); - mStarted = false; - } - } + @Override + public void run() { + native_run(); + native_cleanup(); } public void sendObjectAdded(int handle) { @@ -70,8 +60,8 @@ public class MtpServer { } private native final void native_setup(MtpDatabase database, boolean usePtp); - private native final void native_start(); - private native final void native_stop(); + private native final void native_run(); + private native final void native_cleanup(); private native final void native_send_object_added(int handle); private native final void native_send_object_removed(int handle); private native final void native_add_storage(MtpStorage storage); |
