diff options
Diffstat (limited to 'media/java')
-rw-r--r-- | media/java/android/media/MediaFile.java | 9 | ||||
-rw-r--r-- | media/java/android/media/MediaMetadataRetriever.java | 5 | ||||
-rw-r--r-- | media/java/android/media/MediaPlayer.java | 11 | ||||
-rw-r--r-- | media/java/android/media/MediaRecorder.java | 16 | ||||
-rw-r--r-- | media/java/android/media/MediaScanner.java | 83 | ||||
-rw-r--r-- | media/java/android/media/RingtoneManager.java | 21 | ||||
-rw-r--r-- | media/java/android/media/videoeditor/MediaArtistNativeHelper.java | 4 | ||||
-rw-r--r-- | media/java/android/mtp/MtpPropertyGroup.java | 1 | ||||
-rw-r--r-- | media/java/android/mtp/MtpStorage.java | 11 |
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; + } } |