2 * Copyright (C) 2009 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.mediaframeworktest.unit;
18 import android.media.Metadata;
19 import android.os.Parcel;
20 import android.test.AndroidTestCase;
21 import android.test.suitebuilder.annotation.SmallTest;
22 import android.util.Log;
24 import java.util.Calendar;
25 import java.util.Date;
28 * Check the Java layer that parses serialized metadata in Parcel
33 public class MediaPlayerMetadataParserTest extends AndroidTestCase {
34 private static final String TAG = "MediaPlayerMetadataTest";
35 private static final int kMarker = 0x4d455441; // 'M' 'E' 'T' 'A'
36 private static final int kHeaderSize = 8;
38 private Metadata mMetadata = null;
39 private Parcel mParcel = null;
42 protected void setUp() throws Exception {
44 mMetadata = new Metadata();
45 mParcel = Parcel.obtain();
50 // Check parsing of the parcel fails. Make sure the parser rewind
51 // the parcel properly.
52 private void assertParseFail() throws Exception {
53 mParcel.setDataPosition(0);
54 assertFalse(mMetadata.parse(mParcel));
55 assertEquals(0, mParcel.dataPosition());
58 // Check parsing of the parcel is successful.
59 private void assertParse() throws Exception {
60 mParcel.setDataPosition(0);
61 assertTrue(mMetadata.parse(mParcel));
64 // Write the number of bytes from the start of the parcel to the
65 // current position at the beginning of the parcel (offset 0).
66 private void adjustSize() {
70 // Write the number of bytes from the offset to the current
71 // position at position pointed by offset.
72 private void adjustSize(int offset) {
73 final int pos = mParcel.dataPosition();
75 mParcel.setDataPosition(offset);
76 mParcel.writeInt(pos - offset);
77 mParcel.setDataPosition(pos);
80 // Rewind the parcel and insert the header.
81 private void resetParcel() {
82 mParcel.setDataPosition(0);
83 // Most tests will use a properly formed parcel with a size
84 // and the meta marker so we add them by default.
85 mParcel.writeInt(-1); // Placeholder for the size
86 mParcel.writeInt(kMarker);
89 // ----------------------------------------------------------------------
93 // There should be at least 8 bytes in the parcel, 4 for the size
94 // and 4 for the 'M' 'E' 'T' 'A' marker.
96 public void testMissingSizeAndMarker() throws Exception {
97 for (int i = 0; i < kHeaderSize; ++i) {
98 mParcel.setDataPosition(0);
99 mParcel.setDataSize(i);
101 assertEquals(i, mParcel.dataAvail());
106 // There should be at least 'size' bytes in the parcel.
108 public void testMissingData() throws Exception {
111 mParcel.writeInt(size);
112 mParcel.setDataSize(size - 1);
116 // Empty parcel is fine
118 public void testEmptyIsOk() throws Exception {
123 // ----------------------------------------------------------------------
125 // ----------------------------------------------------------------------
127 // A record header should be at least 12 bytes long
129 public void testRecordMissingId() throws Exception {
130 mParcel.writeInt(13); // record length
131 // misses metadata id and metadata type.
137 public void testRecordMissingType() throws Exception {
138 mParcel.writeInt(13); // record length lies
139 mParcel.writeInt(Metadata.TITLE);
140 // misses metadata type
146 public void testRecordWithZeroPayload() throws Exception {
152 // A record cannot be empty.
154 public void testRecordMissingPayload() throws Exception {
155 mParcel.writeInt(12);
156 mParcel.writeInt(Metadata.TITLE);
157 mParcel.writeInt(Metadata.STRING_VAL);
163 // Check records can be found.
165 public void testRecordsFound() throws Exception {
166 writeStringRecord(Metadata.TITLE, "a title");
167 writeStringRecord(Metadata.GENRE, "comedy");
168 writeStringRecord(Metadata.firstCustomId(), "custom");
171 assertTrue(mMetadata.has(Metadata.TITLE));
172 assertTrue(mMetadata.has(Metadata.GENRE));
173 assertTrue(mMetadata.has(Metadata.firstCustomId()));
174 assertFalse(mMetadata.has(Metadata.DRM_CRIPPLED));
175 assertEquals(3, mMetadata.keySet().size());
178 // Detects bad metadata type
180 public void testBadMetadataType() throws Exception {
181 final int start = mParcel.dataPosition();
182 mParcel.writeInt(-1); // Placeholder for the length
183 mParcel.writeInt(Metadata.TITLE);
184 mParcel.writeInt(0); // Invalid type.
185 mParcel.writeString("dummy");
192 // Check a Metadata instance can be reused, i.e the parse method
193 // wipes out the existing states/keys.
195 public void testParseClearState() throws Exception {
196 writeStringRecord(Metadata.TITLE, "a title");
197 writeStringRecord(Metadata.GENRE, "comedy");
198 writeStringRecord(Metadata.firstCustomId(), "custom");
203 writeStringRecord(Metadata.MIME_TYPE, "audio/mpg");
207 // Only the mime type metadata should be present.
208 assertEquals(1, mMetadata.keySet().size());
209 assertTrue(mMetadata.has(Metadata.MIME_TYPE));
211 assertFalse(mMetadata.has(Metadata.TITLE));
212 assertFalse(mMetadata.has(Metadata.GENRE));
213 assertFalse(mMetadata.has(Metadata.firstCustomId()));
216 // ----------------------------------------------------------------------
218 // ----------------------------------------------------------------------
222 public void testGetString() throws Exception {
223 writeStringRecord(Metadata.TITLE, "a title");
224 writeStringRecord(Metadata.GENRE, "comedy");
228 assertEquals("a title", mMetadata.getString(Metadata.TITLE));
229 assertEquals("comedy", mMetadata.getString(Metadata.GENRE));
232 // get an empty string.
234 public void testGetEmptyString() throws Exception {
235 writeStringRecord(Metadata.TITLE, "");
239 assertEquals("", mMetadata.getString(Metadata.TITLE));
242 // get a string when a NULL value was in the parcel
244 public void testGetNullString() throws Exception {
245 writeStringRecord(Metadata.TITLE, null);
249 assertEquals(null, mMetadata.getString(Metadata.TITLE));
252 // get a string when an integer is actually present
254 public void testWrongType() throws Exception {
255 writeIntRecord(Metadata.DURATION, 5);
260 mMetadata.getString(Metadata.DURATION);
261 } catch (IllegalStateException ise) {
264 fail("Exception was not thrown");
269 public void testGetInt() throws Exception {
270 writeIntRecord(Metadata.CD_TRACK_NUM, 1);
274 assertEquals(1, mMetadata.getInt(Metadata.CD_TRACK_NUM));
279 public void testGetBoolean() throws Exception {
280 writeBooleanRecord(Metadata.DRM_CRIPPLED, true);
284 assertEquals(true, mMetadata.getBoolean(Metadata.DRM_CRIPPLED));
289 public void testGetLong() throws Exception {
290 writeLongRecord(Metadata.DURATION, 1L);
294 assertEquals(1L, mMetadata.getLong(Metadata.DURATION));
299 public void testGetDouble() throws Exception {
300 writeDoubleRecord(Metadata.VIDEO_FRAME_RATE, 29.97);
304 assertEquals(29.97, mMetadata.getDouble(Metadata.VIDEO_FRAME_RATE));
309 public void testGetByteArray() throws Exception {
310 byte data[] = new byte[]{1,2,3,4,5};
312 writeByteArrayRecord(Metadata.ALBUM_ART, data);
316 byte res[] = mMetadata.getByteArray(Metadata.ALBUM_ART);
317 for (int i = 0; i < data.length; ++i) {
318 assertEquals(data[i], res[i]);
324 public void testGetDate() throws Exception {
325 writeDateRecord(Metadata.DATE, 0, "PST");
329 assertEquals(new Date(0), mMetadata.getDate(Metadata.DATE));
334 public void testGetTimedText() throws Exception {
335 Date now = Calendar.getInstance().getTime();
336 writeTimedTextRecord(Metadata.CAPTION, now.getTime(),
341 Metadata.TimedText caption = mMetadata.getTimedText(Metadata.CAPTION);
342 assertEquals("" + now + "-" + 10 + ":Some caption", caption.toString());
345 // ----------------------------------------------------------------------
346 // HELPERS TO APPEND RECORDS
347 // ----------------------------------------------------------------------
349 // Insert a string record at the current position.
350 private void writeStringRecord(int metadataId, String val) {
351 final int start = mParcel.dataPosition();
352 mParcel.writeInt(-1); // Placeholder for the length
353 mParcel.writeInt(metadataId);
354 mParcel.writeInt(Metadata.STRING_VAL);
355 mParcel.writeString(val);
359 // Insert an int record at the current position.
360 private void writeIntRecord(int metadataId, int val) {
361 final int start = mParcel.dataPosition();
362 mParcel.writeInt(-1); // Placeholder for the length
363 mParcel.writeInt(metadataId);
364 mParcel.writeInt(Metadata.INTEGER_VAL);
365 mParcel.writeInt(val);
369 // Insert a boolean record at the current position.
370 private void writeBooleanRecord(int metadataId, boolean val) {
371 final int start = mParcel.dataPosition();
372 mParcel.writeInt(-1); // Placeholder for the length
373 mParcel.writeInt(metadataId);
374 mParcel.writeInt(Metadata.BOOLEAN_VAL);
375 mParcel.writeInt(val ? 1 : 0);
379 // Insert a Long record at the current position.
380 private void writeLongRecord(int metadataId, long val) {
381 final int start = mParcel.dataPosition();
382 mParcel.writeInt(-1); // Placeholder for the length
383 mParcel.writeInt(metadataId);
384 mParcel.writeInt(Metadata.LONG_VAL);
385 mParcel.writeLong(val);
389 // Insert a Double record at the current position.
390 private void writeDoubleRecord(int metadataId, double val) {
391 final int start = mParcel.dataPosition();
392 mParcel.writeInt(-1); // Placeholder for the length
393 mParcel.writeInt(metadataId);
394 mParcel.writeInt(Metadata.DOUBLE_VAL);
395 mParcel.writeDouble(val);
399 // Insert a ByteArray record at the current position.
400 private void writeByteArrayRecord(int metadataId, byte[] val) {
401 final int start = mParcel.dataPosition();
402 mParcel.writeInt(-1); // Placeholder for the length
403 mParcel.writeInt(metadataId);
404 mParcel.writeInt(Metadata.BYTE_ARRAY_VAL);
405 mParcel.writeByteArray(val);
409 // Insert a Date record at the current position.
410 private void writeDateRecord(int metadataId, long time, String tz) {
411 final int start = mParcel.dataPosition();
412 mParcel.writeInt(-1); // Placeholder for the length
413 mParcel.writeInt(metadataId);
414 mParcel.writeInt(Metadata.DATE_VAL);
415 mParcel.writeLong(time);
416 mParcel.writeString(tz);
420 // Insert a TimedText record at the current position.
421 private void writeTimedTextRecord(int metadataId, long begin,
422 int duration, String text) {
423 final int start = mParcel.dataPosition();
424 mParcel.writeInt(-1); // Placeholder for the length
425 mParcel.writeInt(metadataId);
426 mParcel.writeInt(Metadata.TIMED_TEXT_VAL);
427 mParcel.writeLong(begin);
428 mParcel.writeInt(duration);
429 mParcel.writeString(text);