MediaPlayerMetadataParserTest.java revision a5ccb22a3ddb342fe3f7e5493095c6e6dceda60b
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17package com.android.mediaframeworktest.unit; 18import android.media.Metadata; 19import android.os.Parcel; 20import android.test.AndroidTestCase; 21import android.test.suitebuilder.annotation.SmallTest; 22import android.util.Log; 23 24/* 25 * Check the Java layer that parses serialized metadata in Parcel 26 * works as expected. 27 * 28 */ 29 30public class MediaPlayerMetadataParserTest extends AndroidTestCase { 31 private static final String TAG = "MediaPlayerMetadataTest"; 32 private static final int kToken = 0xdeadbeef; 33 private static final int kMarker = 0x4d455441; // 'M' 'E' 'T' 'A' 34 private static final int kHeaderSize = 8; 35 36 private Metadata mMetadata = null; 37 private Parcel mParcel = null; 38 39 @Override 40 protected void setUp() throws Exception { 41 super.setUp(); 42 mMetadata = new Metadata(); 43 mParcel = Parcel.obtain(); 44 45 resetParcel(); 46 } 47 48 // Check parsing of the parcel fails. Make sure the parser rewind 49 // the parcel properly. 50 private void assertParseFail() throws Exception { 51 mParcel.setDataPosition(0); 52 assertFalse(mMetadata.parse(mParcel)); 53 assertEquals(0, mParcel.dataPosition()); 54 } 55 56 // Check parsing of the parcel is successful. Before the 57 // invocation of the parser a token is inserted. When the parser 58 // returns, the parcel should be positioned at the token (check it 59 // does not read too much data). 60 private void assertParse() throws Exception { 61 mParcel.writeInt(kToken); 62 mParcel.setDataPosition(0); 63 assertTrue(mMetadata.parse(mParcel)); 64 assertEquals(kToken, mParcel.readInt()); 65 } 66 67 // Write the number of bytes from the start of the parcel to the 68 // current position at the beginning of the parcel (offset 0). 69 private void adjustSize() { 70 adjustSize(0); 71 } 72 73 // Write the number of bytes from the offset to the current 74 // position at position pointed by offset. 75 private void adjustSize(int offset) { 76 final int pos = mParcel.dataPosition(); 77 78 mParcel.setDataPosition(offset); 79 mParcel.writeInt(pos - offset); 80 mParcel.setDataPosition(pos); 81 } 82 83 // Rewind the parcel and insert the header. 84 private void resetParcel() { 85 mParcel.setDataPosition(0); 86 // Most tests will use a properly formed parcel with a size 87 // and the meta marker so we add them by default. 88 mParcel.writeInt(-1); // Placeholder for the size 89 mParcel.writeInt(kMarker); 90 } 91 92 // Insert a string record at the current position. 93 private void writeStringRecord(int metadataId, String val) { 94 final int start = mParcel.dataPosition(); 95 mParcel.writeInt(-1); // Placeholder for the length 96 mParcel.writeInt(metadataId); 97 mParcel.writeInt(Metadata.STRING_VAL); 98 mParcel.writeString(val); 99 adjustSize(start); 100 } 101 102 // ---------------------------------------------------------------------- 103 // START OF THE TESTS 104 105 106 // There should be at least 8 bytes in the parcel, 4 for the size 107 // and 4 for the 'M' 'E' 'T' 'A' marker. 108 @SmallTest 109 public void testMissingSizeAndMarker() throws Exception { 110 for (int i = 0; i < kHeaderSize; ++i) { 111 mParcel.setDataPosition(0); 112 mParcel.setDataSize(i); 113 114 assertEquals(i, mParcel.dataAvail()); 115 assertParseFail(); 116 } 117 } 118 119 // There should be at least 'size' bytes in the parcel. 120 @SmallTest 121 public void testMissingData() throws Exception { 122 final int size = 20; 123 124 mParcel.writeInt(size); 125 mParcel.setDataSize(size - 1); 126 assertParseFail(); 127 } 128 129 // Empty parcel is fine 130 @SmallTest 131 public void testEmptyIsOk() throws Exception { 132 adjustSize(); 133 assertParse(); 134 } 135 136 // RECORDS 137 138 // A record header should be at least 12 bytes long 139 @SmallTest 140 public void testRecordMissingId() throws Exception { 141 mParcel.writeInt(13); // record length 142 // misses metadata id and metadata type. 143 adjustSize(); 144 assertParseFail(); 145 } 146 147 @SmallTest 148 public void testRecordMissingType() throws Exception { 149 mParcel.writeInt(13); // record length lies 150 mParcel.writeInt(Metadata.TITLE); 151 // misses metadata type 152 adjustSize(); 153 assertParseFail(); 154 } 155 156 @SmallTest 157 public void testRecordWithZeroPayload() throws Exception { 158 mParcel.writeInt(0); 159 adjustSize(); 160 assertParseFail(); 161 } 162 163 // A record cannot be empty. 164 @SmallTest 165 public void testRecordMissingPayload() throws Exception { 166 mParcel.writeInt(12); 167 mParcel.writeInt(Metadata.TITLE); 168 mParcel.writeInt(Metadata.STRING_VAL); 169 // misses payload 170 adjustSize(); 171 assertParseFail(); 172 } 173 174 // Check records can be found. 175 @SmallTest 176 public void testRecordsFound() throws Exception { 177 writeStringRecord(Metadata.TITLE, "a title"); 178 writeStringRecord(Metadata.GENRE, "comedy"); 179 writeStringRecord(Metadata.firstCustomId(), "custom"); 180 adjustSize(); 181 assertParse(); 182 assertTrue(mMetadata.has(Metadata.TITLE)); 183 assertTrue(mMetadata.has(Metadata.GENRE)); 184 assertTrue(mMetadata.has(Metadata.firstCustomId())); 185 assertFalse(mMetadata.has(Metadata.DRM_CRIPPLED)); 186 assertEquals(3, mMetadata.keySet().size()); 187 } 188 189 // Detects bad metadata type 190 @SmallTest 191 public void testBadMetadataType() throws Exception { 192 final int start = mParcel.dataPosition(); 193 mParcel.writeInt(-1); // Placeholder for the length 194 mParcel.writeInt(Metadata.TITLE); 195 mParcel.writeInt(0); // Invalid type. 196 mParcel.writeString("dummy"); 197 adjustSize(start); 198 199 adjustSize(); 200 assertParseFail(); 201 } 202 203 // Check a Metadata instance can be reused, i.e the parse method 204 // wipes out the existing states/keys. 205 @SmallTest 206 public void testParseClearState() throws Exception { 207 writeStringRecord(Metadata.TITLE, "a title"); 208 writeStringRecord(Metadata.GENRE, "comedy"); 209 writeStringRecord(Metadata.firstCustomId(), "custom"); 210 adjustSize(); 211 assertParse(); 212 213 resetParcel(); 214 writeStringRecord(Metadata.MIME_TYPE, "audio/mpg"); 215 adjustSize(); 216 assertParse(); 217 218 // Only the mime type metadata should be present. 219 assertEquals(1, mMetadata.keySet().size()); 220 assertTrue(mMetadata.has(Metadata.MIME_TYPE)); 221 222 assertFalse(mMetadata.has(Metadata.TITLE)); 223 assertFalse(mMetadata.has(Metadata.GENRE)); 224 assertFalse(mMetadata.has(Metadata.firstCustomId())); 225 } 226} 227