summaryrefslogtreecommitdiffstats
path: root/media/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'media/java/android')
-rw-r--r--media/java/android/media/MediaFile.java9
-rw-r--r--media/java/android/media/MediaMetadataRetriever.java5
-rw-r--r--media/java/android/media/MediaPlayer.java11
-rw-r--r--media/java/android/media/MediaRecorder.java16
-rw-r--r--media/java/android/media/MediaScanner.java83
-rw-r--r--media/java/android/media/RingtoneManager.java21
-rw-r--r--media/java/android/media/videoeditor/MediaArtistNativeHelper.java4
-rw-r--r--media/java/android/mtp/MtpPropertyGroup.java1
-rw-r--r--media/java/android/mtp/MtpStorage.java11
9 files changed, 108 insertions, 53 deletions
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 7634c6c..816d215 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -104,10 +104,9 @@ public class MediaFile {
public static final int FILE_TYPE_MS_POWERPOINT = 106;
public static final int FILE_TYPE_ZIP = 107;
- static class MediaFileType {
-
- int fileType;
- String mimeType;
+ public static class MediaFileType {
+ public final int fileType;
+ public final String mimeType;
MediaFileType(int fileType, String mimeType) {
this.fileType = fileType;
@@ -214,7 +213,7 @@ public class MediaFile {
addFileType("PNG", FILE_TYPE_PNG, "image/png", MtpConstants.FORMAT_PNG);
addFileType("BMP", FILE_TYPE_BMP, "image/x-ms-bmp", MtpConstants.FORMAT_BMP);
addFileType("WBMP", FILE_TYPE_WBMP, "image/vnd.wap.wbmp");
- addFileType("WEBP", FILE_TYPE_WBMP, "image/webp");
+ addFileType("WEBP", FILE_TYPE_WEBP, "image/webp");
addFileType("M3U", FILE_TYPE_M3U, "audio/x-mpegurl", MtpConstants.FORMAT_M3U_PLAYLIST);
addFileType("M3U", FILE_TYPE_M3U, "application/x-mpegurl", MtpConstants.FORMAT_M3U_PLAYLIST);
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 7ebedaf..10694c3 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -453,5 +453,10 @@ public class MediaMetadataRetriever
* @hide
*/
public static final int METADATA_KEY_TIMED_TEXT_LANGUAGES = 21;
+ /**
+ * If this key exists the media is drm-protected.
+ * @hide
+ */
+ public static final int METADATA_KEY_IS_DRM = 22;
// Add more here...
}
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 33312d1..482b437 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -611,15 +611,11 @@ public class MediaPlayer
* needed. Not calling this method when playing back a video will
* result in only the audio track being played.
*
- * @param sh the SurfaceHolder to use for video display
- */
- /*
- * This portion of comment has a non-Javadoc prefix so as not to refer to a
- * hidden method. When unhidden, merge it with the previous javadoc comment.
- *
* Either a surface or surface texture must be set if a display or video sink
* is needed. Not calling this method or {@link #setTexture(SurfaceTexture)}
* when playing back a video will result in only the audio track being played.
+ *
+ * @param sh the SurfaceHolder to use for video display
*/
public void setDisplay(SurfaceHolder sh) {
mSurfaceHolder = sh;
@@ -648,7 +644,8 @@ public class MediaPlayer
* SurfaceTexture set as the video sink have an unspecified zero point,
* and cannot be directly compared between different media sources or different
* instances of the same media source, or across multiple runs of the same
- * program.
+ * program. The timestamp is normally monotonically increasing and unaffected
+ * by time-of-day adjustments, but is reset when the position is set.
*/
public void setTexture(SurfaceTexture st) {
ParcelSurfaceTexture pst = null;
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index dd45111..e3cbd57 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -16,17 +16,16 @@
package android.media;
-import android.media.CamcorderProfile;
import android.hardware.Camera;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.Surface;
-import java.io.IOException;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
+
import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.lang.ref.WeakReference;
/**
@@ -112,7 +111,8 @@ public class MediaRecorder
/**
* Sets a Camera to use for recording. Use this function to switch
* quickly between preview and capture mode without a teardown of
- * the camera object. Must call before prepare().
+ * the camera object. {@link android.hardware.Camera#unlock()} should be
+ * called before this. Must call before prepare().
*
* @param c the Camera to use for recording
*/
@@ -718,6 +718,12 @@ public class MediaRecorder
* Begins capturing and encoding data to the file specified with
* setOutputFile(). Call this after prepare().
*
+ * <p>Since API level 13, if applications set a camera via
+ * {@link #setCamera(Camera)}, the apps can use the camera after this method
+ * call. The apps do not need to lock the camera again. However, if this
+ * method fails, the apps should still lock the camera back. The apps should
+ * not start another recording session during recording.
+ *
* @throws IllegalStateException if it is called before
* prepare().
*/
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 790eaa3..e8ddd2d 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -101,6 +101,8 @@ import java.util.Iterator;
* Java MyMediaScanner handleStringTag.
* Once MediaScanner processFile returns, an entry is inserted in to the database.
*
+ * The MediaScanner class is not thread-safe, so it should only be used in a single threaded manner.
+ *
* {@hide}
*/
public class MediaScanner
@@ -368,6 +370,34 @@ public class MediaScanner
}
}
+ private class FileInserter {
+
+ ContentValues[] mValues = new ContentValues[1000];
+ int mIndex = 0;
+
+ public Uri insert(ContentValues values) {
+ if (mIndex == mValues.length) {
+ flush();
+ }
+ mValues[mIndex++] = values;
+ // URI not needed when doing bulk inserts
+ return null;
+ }
+
+ public void flush() {
+ while (mIndex < mValues.length) {
+ mValues[mIndex++] = null;
+ }
+ try {
+ mMediaProvider.bulkInsert(mFilesUri, mValues);
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in FileInserter.flush()", e);
+ }
+ mIndex = 0;
+ }
+ }
+ private FileInserter mFileInserter;
+
// hashes file path to FileCacheEntry.
// path should be lower case if mCaseInsensitivePaths is true
private HashMap<String, FileCacheEntry> mFileCache;
@@ -422,6 +452,7 @@ public class MediaScanner
private long mFileSize;
private String mWriter;
private int mCompilation;
+ private boolean mIsDrm;
private boolean mNoMedia; // flag to suppress file from appearing in media tables
public FileCacheEntry beginFile(String path, String mimeType, long lastModified,
@@ -497,6 +528,7 @@ public class MediaScanner
mLastModified = lastModified;
mWriter = null;
mCompilation = 0;
+ mIsDrm = false;
return entry;
}
@@ -599,6 +631,8 @@ public class MediaScanner
mWriter = value.trim();
} else if (name.equalsIgnoreCase("compilation")) {
mCompilation = parseSubstring(value, 0, 0);
+ } else if (name.equalsIgnoreCase("isdrm")) {
+ mIsDrm = (parseSubstring(value, 0, 0) == 1);
}
}
@@ -671,6 +705,7 @@ public class MediaScanner
map.put(MediaStore.MediaColumns.DATE_MODIFIED, mLastModified);
map.put(MediaStore.MediaColumns.SIZE, mFileSize);
map.put(MediaStore.MediaColumns.MIME_TYPE, mMimeType);
+ map.put(MediaStore.MediaColumns.IS_DRM, mIsDrm);
if (!mNoMedia) {
if (MediaFile.isVideoFileType(mFileType)) {
@@ -800,37 +835,31 @@ public class MediaScanner
}
}
- Uri tableUri = mFilesUri;
- if (!mNoMedia) {
- if (MediaFile.isVideoFileType(mFileType)) {
- tableUri = mVideoUri;
- } else if (MediaFile.isImageFileType(mFileType)) {
- tableUri = mImagesUri;
- } else if (MediaFile.isAudioFileType(mFileType)) {
- tableUri = mAudioUri;
- }
- }
Uri result = null;
if (rowId == 0) {
if (mMtpObjectHandle != 0) {
values.put(MediaStore.MediaColumns.MEDIA_SCANNER_NEW_OBJECT_ID, mMtpObjectHandle);
}
- if (tableUri == mFilesUri) {
- int format = entry.mFormat;
- if (format == 0) {
- format = MediaFile.getFormatCode(entry.mPath, mMimeType);
- }
- values.put(Files.FileColumns.FORMAT, format);
+ int format = entry.mFormat;
+ if (format == 0) {
+ format = MediaFile.getFormatCode(entry.mPath, mMimeType);
}
+ values.put(Files.FileColumns.FORMAT, format);
+
// new file, insert it
- result = mMediaProvider.insert(tableUri, values);
+ if (mFileInserter != null) {
+ result = mFileInserter.insert(values);
+ } else {
+ result = mMediaProvider.insert(mFilesUri, values);
+ }
+
if (result != null) {
rowId = ContentUris.parseId(result);
entry.mRowId = rowId;
}
} else {
// updated file
- result = ContentUris.withAppendedId(tableUri, rowId);
+ result = ContentUris.withAppendedId(mFilesUri, rowId);
// path should never change, and we want to avoid replacing mixed cased paths
// with squashed lower case paths
values.remove(MediaStore.MediaColumns.DATA);
@@ -849,7 +878,7 @@ public class MediaScanner
new String[] { genre }, null);
if (cursor == null || cursor.getCount() == 0) {
// genre does not exist, so create the genre in the genre table
- values.clear();
+ values = new ContentValues();
values.put(MediaStore.Audio.Genres.NAME, genre);
uri = mMediaProvider.insert(mGenresUri, values);
} else {
@@ -871,7 +900,7 @@ public class MediaScanner
if (uri != null) {
// add entry to audio_genre_map
- values.clear();
+ values = new ContentValues();
values.put(MediaStore.Audio.Genres.Members.AUDIO_ID, Long.valueOf(rowId));
mMediaProvider.insert(uri, values);
}
@@ -880,19 +909,19 @@ public class MediaScanner
if (notifications && !mDefaultNotificationSet) {
if (TextUtils.isEmpty(mDefaultNotificationFilename) ||
doesPathHaveFilename(entry.mPath, mDefaultNotificationFilename)) {
- setSettingIfNotSet(Settings.System.NOTIFICATION_SOUND, tableUri, rowId);
+ setSettingIfNotSet(Settings.System.NOTIFICATION_SOUND, mFilesUri, rowId);
mDefaultNotificationSet = true;
}
} else if (ringtones && !mDefaultRingtoneSet) {
if (TextUtils.isEmpty(mDefaultRingtoneFilename) ||
doesPathHaveFilename(entry.mPath, mDefaultRingtoneFilename)) {
- setSettingIfNotSet(Settings.System.RINGTONE, tableUri, rowId);
+ setSettingIfNotSet(Settings.System.RINGTONE, mFilesUri, rowId);
mDefaultRingtoneSet = true;
}
} else if (alarms && !mDefaultAlarmSet) {
if (TextUtils.isEmpty(mDefaultAlarmAlertFilename) ||
doesPathHaveFilename(entry.mPath, mDefaultAlarmAlertFilename)) {
- setSettingIfNotSet(Settings.System.ALARM_ALERT, tableUri, rowId);
+ setSettingIfNotSet(Settings.System.ALARM_ALERT, mFilesUri, rowId);
mDefaultAlarmSet = true;
}
}
@@ -1147,10 +1176,6 @@ public class MediaScanner
mPlaylistsUri = Playlists.getContentUri(volumeName);
mCaseInsensitivePaths = true;
- if (!Process.supportsProcesses()) {
- // Simulator uses host file system, so it should be case sensitive.
- mCaseInsensitivePaths = false;
- }
}
}
@@ -1160,10 +1185,14 @@ public class MediaScanner
initialize(volumeName);
prescan(null, true);
long prescan = System.currentTimeMillis();
+ mFileInserter = new FileInserter();
for (int i = 0; i < directories.length; i++) {
processDirectory(directories[i], mClient);
}
+ mFileInserter.flush();
+ mFileInserter = null;
+
long scan = System.currentTimeMillis();
postscan(directories);
long end = System.currentTimeMillis();
diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index 8481410..9c0819f 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -487,7 +487,7 @@ public class RingtoneManager {
private Cursor getInternalRingtones() {
return query(
MediaStore.Audio.Media.INTERNAL_CONTENT_URI, INTERNAL_COLUMNS,
- constructBooleanTrueWhereClause(mFilterColumns),
+ constructBooleanTrueWhereClause(mFilterColumns, mIncludeDrm),
null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
}
@@ -506,7 +506,7 @@ public class RingtoneManager {
status.equals(Environment.MEDIA_MOUNTED_READ_ONLY))
? query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MEDIA_COLUMNS,
- constructBooleanTrueWhereClause(mFilterColumns), null,
+ constructBooleanTrueWhereClause(mFilterColumns, mIncludeDrm), null,
MediaStore.Audio.Media.DEFAULT_SORT_ORDER)
: null;
}
@@ -536,11 +536,13 @@ public class RingtoneManager {
* @param columns The columns that must be true.
* @return The where clause.
*/
- private static String constructBooleanTrueWhereClause(List<String> columns) {
+ private static String constructBooleanTrueWhereClause(List<String> columns, boolean includeDrm) {
if (columns == null) return null;
StringBuilder sb = new StringBuilder();
+ sb.append("(");
+
for (int i = columns.size() - 1; i >= 0; i--) {
sb.append(columns.get(i)).append("=1 or ");
}
@@ -549,7 +551,18 @@ public class RingtoneManager {
// Remove last ' or '
sb.setLength(sb.length() - 4);
}
-
+
+ sb.append(")");
+
+ if (!includeDrm) {
+ // If not DRM files should be shown, the where clause
+ // will be something like "(is_notification=1) and is_drm=0"
+ sb.append(" and ");
+ sb.append(MediaStore.MediaColumns.IS_DRM);
+ sb.append("=0");
+ }
+
+
return sb.toString();
}
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index 29c4b89..0d2bcd5 100644
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -957,12 +957,8 @@ class MediaArtistNativeHelper {
public static final int FADE_FROM_BLACK = 8;
- public static final int CURTAIN_OPENING = 9;
-
public static final int FADE_TO_BLACK = 16;
- public static final int CURTAIN_CLOSING = 17;
-
public static final int EXTERNAL = 256;
public static final int BLACK_AND_WHITE = 257;
diff --git a/media/java/android/mtp/MtpPropertyGroup.java b/media/java/android/mtp/MtpPropertyGroup.java
index b75b11a..76c8569 100644
--- a/media/java/android/mtp/MtpPropertyGroup.java
+++ b/media/java/android/mtp/MtpPropertyGroup.java
@@ -330,7 +330,6 @@ class MtpPropertyGroup {
}
int count = (c == null ? 1 : c.getCount());
- Log.d(TAG, "count: " + count);
MtpPropertyList result = new MtpPropertyList(count * mProperties.length,
MtpConstants.RESPONSE_OK);
diff --git a/media/java/android/mtp/MtpStorage.java b/media/java/android/mtp/MtpStorage.java
index 7932d34..da190a6 100644
--- a/media/java/android/mtp/MtpStorage.java
+++ b/media/java/android/mtp/MtpStorage.java
@@ -32,6 +32,7 @@ public class MtpStorage {
private final String mDescription;
private final long mReserveSpace;
private final boolean mRemovable;
+ private final long mMaxFileSize;
public MtpStorage(StorageVolume volume) {
mStorageId = volume.getStorageId();
@@ -39,6 +40,7 @@ public class MtpStorage {
mDescription = volume.getDescription();
mReserveSpace = volume.getMtpReserveSpace();
mRemovable = volume.isRemovable();
+ mMaxFileSize = volume.getMaxFileSize();
}
/**
@@ -98,4 +100,13 @@ public class MtpStorage {
public final boolean isRemovable() {
return mRemovable;
}
+
+ /**
+ * Returns maximum file size for the storage, or zero if it is unbounded.
+ *
+ * @return maximum file size
+ */
+ public long getMaxFileSize() {
+ return mMaxFileSize;
+ }
}