diff options
| author | 2009-07-17 12:00:28 -0700 | |
|---|---|---|
| committer | 2009-07-17 12:00:28 -0700 | |
| commit | da3785ae9f165c2bced1f90e94f428a98c6e6ce7 (patch) | |
| tree | 2a3a8195eae517b78de5380560fff4282b4f0151 | |
| parent | eb7a869af613d64d4623200fb1472fd71223a8b2 (diff) | |
| parent | cb2e00eedce99b30faf5f238136a00bc5448c5f2 (diff) | |
Merge change 7624
* changes:
Impl. of the metadata getters.
| -rw-r--r-- | media/java/android/media/Metadata.java | 108 | ||||
| -rw-r--r-- | media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java | 232 |
2 files changed, 299 insertions, 41 deletions
diff --git a/media/java/android/media/Metadata.java b/media/java/android/media/Metadata.java index a345ef88b08d..8dbe51a7a7b3 100644 --- a/media/java/android/media/Metadata.java +++ b/media/java/android/media/Metadata.java @@ -20,10 +20,12 @@ import android.graphics.Bitmap; import android.os.Parcel; import android.util.Log; +import java.util.Calendar; import java.util.Collections; import java.util.Date; -import java.util.Set; import java.util.HashMap; +import java.util.Set; +import java.util.TimeZone; /** @@ -102,15 +104,20 @@ public class Metadata public static final Set<Integer> MATCH_NONE = Collections.EMPTY_SET; public static final Set<Integer> MATCH_ALL = Collections.singleton(ANY); - public static final int STRING_VAL = 1; - public static final int INTEGER_VAL = 2; - public static final int LONG_VAL = 3; - public static final int DOUBLE_VAL = 4; - public static final int TIMED_TEXT_VAL = 5; - private static final int LAST_TYPE = 5; + public static final int STRING_VAL = 1; + public static final int INTEGER_VAL = 2; + public static final int BOOLEAN_VAL = 3; + public static final int LONG_VAL = 4; + public static final int DOUBLE_VAL = 5; + public static final int TIMED_TEXT_VAL = 6; + public static final int DATE_VAL = 7; + public static final int BYTE_ARRAY_VAL = 8; + // FIXME: misses a type for shared heap is missing (MemoryFile). + // FIXME: misses a type for bitmaps. + private static final int LAST_TYPE = 8; private static final String TAG = "media.Metadata"; - private static final int kMetaHeaderSize = 8; // 8 bytes for the size + the marker + private static final int kMetaHeaderSize = 8; // size + marker private static final int kMetaMarker = 0x4d455441; // 'M' 'E' 'T' 'A' private static final int kRecordHeaderSize = 12; // size + id + type @@ -122,21 +129,28 @@ public class Metadata // Used to look up if a key was present too. // Key: Metadata ID // Value: Offset of the metadata type field in the record. - private final HashMap<Integer, Integer> mKeyToPosMap = new HashMap<Integer, Integer>(); + private final HashMap<Integer, Integer> mKeyToPosMap = + new HashMap<Integer, Integer>(); /** - * Helper class to hold a pair (time, text). Can be used to implement caption. + * Helper class to hold a triple (time, duration, text). Can be used to + * implement caption. */ public class TimedText { private Date mTime; + private int mDuration; // millisec private String mText; - public TimedText(final Date time, final String text) { + + public TimedText(Date time, int duration, String text) { mTime = time; + mDuration = duration; mText = text; } + public String toString() { StringBuilder res = new StringBuilder(80); - res.append(mTime).append(":").append(mText); + res.append(mTime).append("-").append(mDuration) + .append(":").append(mText); return res.toString(); } } @@ -300,44 +314,64 @@ public class Metadata return mKeyToPosMap.containsKey(metadataId); } - // Accessors + // Accessors. + // Caller must make sure the key is present using the {@code has} + // method otherwise a RuntimeException will occur. + public String getString(final int key) { - // FIXME: Implement. - return new String(); + checkType(key, STRING_VAL); + return mParcel.readString(); } public int getInt(final int key) { - // FIXME: Implement. - return 0; + checkType(key, INTEGER_VAL); + return mParcel.readInt(); + } + + public boolean getBoolean(final int key) { + checkType(key, BOOLEAN_VAL); + return mParcel.readInt() == 1; } public long getLong(final int key) { - // FIXME: Implement. - return 0; + checkType(key, LONG_VAL); + return mParcel.readLong(); } public double getDouble(final int key) { - // FIXME: Implement. - return 0.0; + checkType(key, DOUBLE_VAL); + return mParcel.readDouble(); } public byte[] getByteArray(final int key) { - return new byte[0]; - } - - public Bitmap getBitmap(final int key) { - // FIXME: Implement. - return null; + checkType(key, BYTE_ARRAY_VAL); + return mParcel.createByteArray(); } public Date getDate(final int key) { - // FIXME: Implement. - return new Date(); + checkType(key, DATE_VAL); + final long timeSinceEpoch = mParcel.readLong(); + final String timeZone = mParcel.readString(); + + if (timeZone.length() == 0) { + return new Date(timeSinceEpoch); + } else { + TimeZone tz = TimeZone.getTimeZone(timeZone); + Calendar cal = Calendar.getInstance(tz); + + cal.setTimeInMillis(timeSinceEpoch); + return cal.getTime(); + } } public TimedText getTimedText(final int key) { - // FIXME: Implement. - return new TimedText(new Date(0), "<missing>"); + checkType(key, TIMED_TEXT_VAL); + final Date startTime = new Date(mParcel.readLong()); // epoch + final int duration = mParcel.readInt(); // millisec + + return new TimedText(startTime, + duration, + mParcel.readString()); } // @return the last available system metadata id. Ids are @@ -360,4 +394,16 @@ public class Metadata } return true; } + + // Check the type of the data match what is expected. + private void checkType(final int key, final int expectedType) { + final int pos = mKeyToPosMap.get(key); + + mParcel.setDataPosition(pos); + + final int type = mParcel.readInt(); + if (type != expectedType) { + throw new IllegalStateException("Wrong type " + expectedType + " but got " + type); + } + } } diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java index f51b29e073ea..576dddd6cf3a 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaPlayerMetadataParserTest.java @@ -21,6 +21,9 @@ import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; import android.util.Log; +import java.util.Calendar; +import java.util.Date; + /* * Check the Java layer that parses serialized metadata in Parcel * works as expected. @@ -89,16 +92,6 @@ public class MediaPlayerMetadataParserTest extends AndroidTestCase { mParcel.writeInt(kMarker); } - // Insert a string record at the current position. - private void writeStringRecord(int metadataId, String val) { - final int start = mParcel.dataPosition(); - mParcel.writeInt(-1); // Placeholder for the length - mParcel.writeInt(metadataId); - mParcel.writeInt(Metadata.STRING_VAL); - mParcel.writeString(val); - adjustSize(start); - } - // ---------------------------------------------------------------------- // START OF THE TESTS @@ -133,7 +126,9 @@ public class MediaPlayerMetadataParserTest extends AndroidTestCase { assertParse(); } + // ---------------------------------------------------------------------- // RECORDS + // ---------------------------------------------------------------------- // A record header should be at least 12 bytes long @SmallTest @@ -223,4 +218,221 @@ public class MediaPlayerMetadataParserTest extends AndroidTestCase { assertFalse(mMetadata.has(Metadata.GENRE)); assertFalse(mMetadata.has(Metadata.firstCustomId())); } + + // ---------------------------------------------------------------------- + // GETTERS + // ---------------------------------------------------------------------- + + // getString + @SmallTest + public void testGetString() throws Exception { + writeStringRecord(Metadata.TITLE, "a title"); + writeStringRecord(Metadata.GENRE, "comedy"); + adjustSize(); + assertParse(); + + assertEquals("a title", mMetadata.getString(Metadata.TITLE)); + assertEquals("comedy", mMetadata.getString(Metadata.GENRE)); + } + + // get an empty string. + @SmallTest + public void testGetEmptyString() throws Exception { + writeStringRecord(Metadata.TITLE, ""); + adjustSize(); + assertParse(); + + assertEquals("", mMetadata.getString(Metadata.TITLE)); + } + + // get a string when a NULL value was in the parcel + @SmallTest + public void testGetNullString() throws Exception { + writeStringRecord(Metadata.TITLE, null); + adjustSize(); + assertParse(); + + assertEquals(null, mMetadata.getString(Metadata.TITLE)); + } + + // get a string when an integer is actually present + @SmallTest + public void testWrongType() throws Exception { + writeIntRecord(Metadata.DURATION, 5); + adjustSize(); + assertParse(); + + try { + mMetadata.getString(Metadata.DURATION); + } catch (IllegalStateException ise) { + return; + } + fail("Exception was not thrown"); + } + + // getInt + @SmallTest + public void testGetInt() throws Exception { + writeIntRecord(Metadata.CD_TRACK_NUM, 1); + adjustSize(); + assertParse(); + + assertEquals(1, mMetadata.getInt(Metadata.CD_TRACK_NUM)); + } + + // getBoolean + @SmallTest + public void testGetBoolean() throws Exception { + writeBooleanRecord(Metadata.DRM_CRIPPLED, true); + adjustSize(); + assertParse(); + + assertEquals(true, mMetadata.getBoolean(Metadata.DRM_CRIPPLED)); + } + + // getLong + @SmallTest + public void testGetLong() throws Exception { + writeLongRecord(Metadata.DURATION, 1L); + adjustSize(); + assertParse(); + + assertEquals(1L, mMetadata.getLong(Metadata.DURATION)); + } + + // getDouble + @SmallTest + public void testGetDouble() throws Exception { + writeDoubleRecord(Metadata.VIDEO_FRAME_RATE, 29.97); + adjustSize(); + assertParse(); + + assertEquals(29.97, mMetadata.getDouble(Metadata.VIDEO_FRAME_RATE)); + } + + // getByteArray + @SmallTest + public void testGetByteArray() throws Exception { + byte data[] = new byte[]{1,2,3,4,5}; + + writeByteArrayRecord(Metadata.ALBUM_ART, data); + adjustSize(); + assertParse(); + + byte res[] = mMetadata.getByteArray(Metadata.ALBUM_ART); + for (int i = 0; i < data.length; ++i) { + assertEquals(data[i], res[i]); + } + } + + // getDate + @SmallTest + public void testGetDate() throws Exception { + writeDateRecord(Metadata.DATE, 0, "PST"); + adjustSize(); + assertParse(); + + assertEquals(new Date(0), mMetadata.getDate(Metadata.DATE)); + } + + // getTimedText + @SmallTest + public void testGetTimedText() throws Exception { + Date now = Calendar.getInstance().getTime(); + writeTimedTextRecord(Metadata.CAPTION, now.getTime(), + 10, "Some caption"); + adjustSize(); + assertParse(); + + Metadata.TimedText caption = mMetadata.getTimedText(Metadata.CAPTION); + assertEquals("" + now + "-" + 10 + ":Some caption", caption.toString()); + } + + // ---------------------------------------------------------------------- + // HELPERS TO APPEND RECORDS + // ---------------------------------------------------------------------- + + // Insert a string record at the current position. + private void writeStringRecord(int metadataId, String val) { + final int start = mParcel.dataPosition(); + mParcel.writeInt(-1); // Placeholder for the length + mParcel.writeInt(metadataId); + mParcel.writeInt(Metadata.STRING_VAL); + mParcel.writeString(val); + adjustSize(start); + } + + // Insert an int record at the current position. + private void writeIntRecord(int metadataId, int val) { + final int start = mParcel.dataPosition(); + mParcel.writeInt(-1); // Placeholder for the length + mParcel.writeInt(metadataId); + mParcel.writeInt(Metadata.INTEGER_VAL); + mParcel.writeInt(val); + adjustSize(start); + } + + // Insert a boolean record at the current position. + private void writeBooleanRecord(int metadataId, boolean val) { + final int start = mParcel.dataPosition(); + mParcel.writeInt(-1); // Placeholder for the length + mParcel.writeInt(metadataId); + mParcel.writeInt(Metadata.BOOLEAN_VAL); + mParcel.writeInt(val ? 1 : 0); + adjustSize(start); + } + + // Insert a Long record at the current position. + private void writeLongRecord(int metadataId, long val) { + final int start = mParcel.dataPosition(); + mParcel.writeInt(-1); // Placeholder for the length + mParcel.writeInt(metadataId); + mParcel.writeInt(Metadata.LONG_VAL); + mParcel.writeLong(val); + adjustSize(start); + } + + // Insert a Double record at the current position. + private void writeDoubleRecord(int metadataId, double val) { + final int start = mParcel.dataPosition(); + mParcel.writeInt(-1); // Placeholder for the length + mParcel.writeInt(metadataId); + mParcel.writeInt(Metadata.DOUBLE_VAL); + mParcel.writeDouble(val); + adjustSize(start); + } + + // Insert a ByteArray record at the current position. + private void writeByteArrayRecord(int metadataId, byte[] val) { + final int start = mParcel.dataPosition(); + mParcel.writeInt(-1); // Placeholder for the length + mParcel.writeInt(metadataId); + mParcel.writeInt(Metadata.BYTE_ARRAY_VAL); + mParcel.writeByteArray(val); + adjustSize(start); + } + + // Insert a Date record at the current position. + private void writeDateRecord(int metadataId, long time, String tz) { + final int start = mParcel.dataPosition(); + mParcel.writeInt(-1); // Placeholder for the length + mParcel.writeInt(metadataId); + mParcel.writeInt(Metadata.DATE_VAL); + mParcel.writeLong(time); + mParcel.writeString(tz); + adjustSize(start); + } + + // Insert a TimedText record at the current position. + private void writeTimedTextRecord(int metadataId, long begin, + int duration, String text) { + final int start = mParcel.dataPosition(); + mParcel.writeInt(-1); // Placeholder for the length + mParcel.writeInt(metadataId); + mParcel.writeInt(Metadata.TIMED_TEXT_VAL); + mParcel.writeLong(begin); + mParcel.writeInt(duration); + mParcel.writeString(text); + adjustSize(start); + } } |