• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 
17 package com.android.mediaframeworktest.unit;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertTrue;
22 
23 import android.graphics.Bitmap;
24 import android.media.MediaMetadataRetriever;
25 import android.platform.test.annotations.RequiresFlagsDisabled;
26 import android.platform.test.annotations.RequiresFlagsEnabled;
27 import android.platform.test.flag.junit.CheckFlagsRule;
28 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
29 import android.util.Log;
30 
31 import androidx.test.filters.LargeTest;
32 import androidx.test.filters.MediumTest;
33 import androidx.test.runner.AndroidJUnit4;
34 
35 import com.android.media.playback.flags.Flags;
36 import com.android.mediaframeworktest.MediaNames;
37 import com.android.mediaframeworktest.MediaProfileReader;
38 
39 import org.junit.Rule;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 
43 import java.io.FileOutputStream;
44 import java.io.IOException;
45 
46 @RunWith(AndroidJUnit4.class)
47 public class MediaMetadataRetrieverTest {
48 
49     private static final String TAG = "MediaMetadataRetrieverTest";
50 
51     @Rule
52     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
53 
54     // Test album art extraction.
55     @MediumTest
56     @Test
testGetEmbeddedPicture()57     public void testGetEmbeddedPicture() throws Exception {
58         Log.v(TAG, "testGetEmbeddedPicture starts.");
59         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
60         boolean supportWMA = MediaProfileReader.getWMAEnable();
61         boolean hasFailed = false;
62         boolean supportWMV = MediaProfileReader.getWMVEnable();
63         for (int i = 0, n = MediaNames.ALBUMART_TEST_FILES.length; i < n; ++i) {
64             try {
65                 Log.v(TAG, "File " + i + ": " + MediaNames.ALBUMART_TEST_FILES[i]);
66                 if ((MediaNames.ALBUMART_TEST_FILES[i].endsWith(".wma") && !supportWMA)
67                         || (MediaNames.ALBUMART_TEST_FILES[i].endsWith(".wmv") && !supportWMV)) {
68                     Log.v(
69                             TAG,
70                             "windows media is not supported and thus we will skip the test for this"
71                                     + " file");
72                     continue;
73                 }
74                 retriever.setDataSource(MediaNames.ALBUMART_TEST_FILES[i]);
75                 byte[] albumArt = retriever.getEmbeddedPicture();
76 
77                 // TODO:
78                 // A better test would be to compare the retrieved album art with the
79                 // known result.
80                 if (albumArt == null) { // Do we have expect in JUnit?
81                     Log.e(
82                             TAG,
83                             "Fails to get embedded picture for "
84                                     + MediaNames.ALBUMART_TEST_FILES[i]);
85                     hasFailed = true;
86                 }
87             } catch (Exception e) {
88                 Log.e(TAG, "Fails to setDataSource for " + MediaNames.ALBUMART_TEST_FILES[i]);
89                 hasFailed = true;
90             }
91             Thread.yield(); // Don't be evil
92         }
93         retriever.release();
94         Log.v(TAG, "testGetEmbeddedPicture completes.");
95         assertTrue(!hasFailed);
96     }
97 
98     // Test frame capture
99     @LargeTest
100     @Test
testThumbnailCapture()101     public void testThumbnailCapture() throws Exception {
102         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
103         boolean supportWMA = MediaProfileReader.getWMAEnable();
104         boolean supportWMV = MediaProfileReader.getWMVEnable();
105         boolean hasFailed = false;
106         Log.v(TAG, "Thumbnail processing starts");
107         long startedAt = System.currentTimeMillis();
108         for (int i = 0, n = MediaNames.THUMBNAIL_METADATA_TEST_FILES.length; i < n; ++i) {
109             try {
110                 Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
111                 if ((MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wma") && !supportWMA)
112                         || (MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wmv")
113                                 && !supportWMV)) {
114                     Log.v(
115                             TAG,
116                             "windows media is not supported and thus we will skip the test for this"
117                                     + " file");
118                     continue;
119                 }
120                 retriever.setDataSource(MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
121                 Bitmap bitmap = retriever.getFrameAtTime(-1);
122                 assertTrue(bitmap != null);
123                 try {
124                     java.io.OutputStream stream =
125                             new FileOutputStream(
126                                     MediaNames.THUMBNAIL_METADATA_TEST_FILES[i] + ".jpg");
127                     bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
128                     stream.close();
129                 } catch (Exception e) {
130                     Log.e(
131                             TAG,
132                             "Fails to convert the bitmap to a JPEG file for "
133                                     + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
134                     hasFailed = true;
135                     Log.e(TAG, e.toString());
136                 }
137             } catch (Exception e) {
138                 Log.e(
139                         TAG,
140                         "Fails to setDataSource for file "
141                                 + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
142                 hasFailed = true;
143             }
144             Thread.yield(); // Don't be evil
145         }
146         long endedAt = System.currentTimeMillis();
147         retriever.release();
148         assertTrue(!hasFailed);
149         Log.v(
150                 TAG,
151                 "Average processing time per thumbnail: "
152                         + (endedAt - startedAt) / MediaNames.THUMBNAIL_METADATA_TEST_FILES.length
153                         + " ms");
154     }
155 
156     @LargeTest
157     @Test
testMetadataRetrieval()158     public void testMetadataRetrieval() throws Exception {
159         boolean supportWMA = MediaProfileReader.getWMAEnable();
160         boolean supportWMV = MediaProfileReader.getWMVEnable();
161         boolean hasFailed = false;
162         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
163         for (int i = 0, n = MediaNames.THUMBNAIL_METADATA_TEST_FILES.length; i < n; ++i) {
164             try {
165                 Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
166                 if ((MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wma") && !supportWMA)
167                         || (MediaNames.THUMBNAIL_METADATA_TEST_FILES[i].endsWith(".wmv")
168                                 && !supportWMV)) {
169                     Log.v(
170                             TAG,
171                             "windows media is not supported and thus we will skip the test for this"
172                                     + " file");
173                     continue;
174                 }
175                 retriever.setDataSource(MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
176                 extractAllSupportedMetadataValues(retriever);
177             } catch (Exception e) {
178                 Log.e(
179                         TAG,
180                         "Fails to setDataSource for file "
181                                 + MediaNames.THUMBNAIL_METADATA_TEST_FILES[i]);
182                 hasFailed = true;
183             }
184             Thread.yield(); // Don't be evil
185         }
186         retriever.release();
187         assertTrue(!hasFailed);
188     }
189 
190     // If the specified call order and valid media file is used, no exception
191     // should be thrown.
192     @MediumTest
193     @Test
testBasicNormalMethodCallSequence()194     public void testBasicNormalMethodCallSequence() throws Exception {
195         boolean hasFailed = false;
196         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
197         try {
198             retriever.setDataSource(MediaNames.TEST_PATH_1);
199             Bitmap bitmap = retriever.getFrameAtTime(-1);
200             assertTrue(bitmap != null);
201             try {
202                 java.io.OutputStream stream = new FileOutputStream("/sdcard/thumbnailout.jpg");
203                 bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
204                 stream.close();
205             } catch (Exception e) {
206                 throw new Exception(
207                         "Fails to convert the bitmap to a JPEG file for " + MediaNames.TEST_PATH_1,
208                         e);
209             }
210             extractAllSupportedMetadataValues(retriever);
211         } catch (Exception e) {
212             Log.e(TAG, "Fails to setDataSource for " + MediaNames.TEST_PATH_1, e);
213             hasFailed = true;
214         }
215         retriever.release();
216         assertTrue(!hasFailed);
217     }
218 
219     // If setDataSource() has not been called, both getFrameAtTime() and extractMetadata() must
220     // return null.
221     @MediumTest
222     @Test
testBasicAbnormalMethodCallSequence()223     public void testBasicAbnormalMethodCallSequence() {
224         boolean hasFailed = false;
225         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
226         if (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM) != null) {
227             Log.e(TAG, "No album metadata expected, but is available");
228             hasFailed = true;
229         }
230         if (retriever.getFrameAtTime(-1) != null) {
231             Log.e(TAG, "No frame expected, but is available");
232             hasFailed = true;
233         }
234         assertTrue(!hasFailed);
235     }
236 
237     // Test setDataSource()
238     @MediumTest
239     @Test
testSetDataSource()240     public void testSetDataSource() throws IOException {
241         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
242         boolean hasFailed = false;
243 
244         // Null pointer argument
245         try {
246             String path = null;
247             retriever.setDataSource(path);
248             Log.e(TAG, "IllegalArgumentException failed to be thrown.");
249             hasFailed = true;
250         } catch (Exception e) {
251             if (!(e instanceof IllegalArgumentException)) {
252                 Log.e(TAG, "Expected a IllegalArgumentException, but got a different exception");
253                 hasFailed = true;
254             }
255         }
256 
257         // Use mem:// path
258         try {
259             retriever.setDataSource(MediaNames.TEST_PATH_5);
260             Log.e(TAG, "IllegalArgumentException failed to be thrown.");
261             hasFailed = true;
262         } catch (Exception e) {
263             if (!(e instanceof IllegalArgumentException)) {
264                 Log.e(TAG, "Expected a IllegalArgumentException, but got a different exception");
265                 hasFailed = true;
266             }
267         }
268 
269         // The pathname does not correspond to any existing file
270         try {
271             retriever.setDataSource(MediaNames.TEST_PATH_4);
272             Log.e(TAG, "RuntimeException failed to be thrown.");
273             hasFailed = true;
274         } catch (Exception e) {
275             if (!(e instanceof RuntimeException)) {
276                 Log.e(TAG, "Expected a RuntimeException, but got a different exception");
277                 hasFailed = true;
278             }
279         }
280 
281         // The pathname does correspond to a file, but this file
282         // is not a valid media file
283         try {
284             retriever.setDataSource(MediaNames.TEST_PATH_3);
285             Log.e(TAG, "RuntimeException failed to be thrown.");
286             hasFailed = true;
287         } catch (Exception e) {
288             if (!(e instanceof RuntimeException)) {
289                 Log.e(TAG, "Expected a RuntimeException, but got a different exception");
290                 hasFailed = true;
291             }
292         }
293 
294         retriever.release();
295         assertTrue(!hasFailed);
296     }
297 
298     /** Test the thumbnail is generated when the default is set to RGBA8888 */
299     @MediumTest
300     // TODO(b/305160754) Remove the following annotation and use SetFlagsRule.enableFlags
301     @RequiresFlagsEnabled(Flags.FLAG_MEDIAMETADATARETRIEVER_DEFAULT_RGBA8888)
302     @Test
testGetFrameAtTimeWithRGBA8888Flag_Set()303     public void testGetFrameAtTimeWithRGBA8888Flag_Set() throws IOException {
304         try (MediaMetadataRetriever retriever = new MediaMetadataRetriever()) {
305             retriever.setDataSource(MediaNames.TEST_PATH_1);
306             Bitmap bitmap = retriever.getFrameAtTime(-1);
307             assertNotNull(bitmap);
308             assertEquals(Bitmap.Config.ARGB_8888, bitmap.getConfig());
309         }
310     }
311 
312     /** Test the thumbnail is generated when the default is not set to RGBA8888 */
313     @MediumTest
314     // TODO(b/305160754) Remove the following annotation and use SetFlagsRule.disableFlags
315     @RequiresFlagsDisabled(Flags.FLAG_MEDIAMETADATARETRIEVER_DEFAULT_RGBA8888)
316     @Test
testGetFrameAtTimeWithRGBA8888Flag_Unset()317     public void testGetFrameAtTimeWithRGBA8888Flag_Unset() throws IOException {
318         try (MediaMetadataRetriever retriever = new MediaMetadataRetriever()) {
319             retriever.setDataSource(MediaNames.TEST_PATH_1);
320             Bitmap bitmap = retriever.getFrameAtTime(-1);
321             assertNotNull(bitmap);
322             assertEquals(Bitmap.Config.RGB_565, bitmap.getConfig());
323         }
324     }
325 
326     // TODO:
327     // Encode and test for the correct mix of metadata elements on a per-file basis?
328     // We should be able to compare the actual returned metadata with the expected metadata
329     // with each given sample test file.
extractAllSupportedMetadataValues(MediaMetadataRetriever retriever)330     private static void extractAllSupportedMetadataValues(MediaMetadataRetriever retriever) {
331         int[] metadataRetrieverKeys =
332                 new int[] {
333                     MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER,
334                     MediaMetadataRetriever.METADATA_KEY_DURATION,
335                     MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS,
336                     MediaMetadataRetriever.METADATA_KEY_ALBUM,
337                     MediaMetadataRetriever.METADATA_KEY_ARTIST,
338                     MediaMetadataRetriever.METADATA_KEY_AUTHOR,
339                     MediaMetadataRetriever.METADATA_KEY_COMPOSER,
340                     MediaMetadataRetriever.METADATA_KEY_DATE,
341                     MediaMetadataRetriever.METADATA_KEY_GENRE,
342                     MediaMetadataRetriever.METADATA_KEY_TITLE,
343                     MediaMetadataRetriever.METADATA_KEY_YEAR
344                 };
345         for (int metadataRetrieverKey : metadataRetrieverKeys) {
346             String value = retriever.extractMetadata(metadataRetrieverKey);
347             Log.v(TAG, value == null ? "not found" : value);
348         }
349     }
350 }
351