MediaMetadataRetrieverTest.java revision 9efe47374b61afd0ce84afa64e9fa5b41dfaef22
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
17package com.android.mediaframeworktest.unit;
18
19import android.util.Log;
20import android.media.MediaMetadataRetriever;
21import android.graphics.Bitmap;
22import java.io.FileOutputStream;
23import android.test.AndroidTestCase;
24import com.android.mediaframeworktest.MediaNames;
25import com.android.mediaframeworktest.MediaProfileReader;
26import android.test.suitebuilder.annotation.*;
27
28/**
29 * WARNING:
30 * Currently, captureFrame() does not work, due to hardware access permission problem.
31 * We are currently only testing the metadata/album art retrieval features.
32 */
33public class MediaMetadataRetrieverTest extends AndroidTestCase {
34
35    private static final String TAG         = "MediaMetadataRetrieverTest";
36
37    // Test album art extraction.
38    @MediumTest
39    public static void testGetEmbeddedPicture() throws Exception {
40        Log.v(TAG, "testGetEmbeddedPicture starts.");
41        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
42        boolean supportWMA = MediaProfileReader.getWMAEnable();
43        boolean hasFailed = false;
44        boolean supportWMV = MediaProfileReader.getWMVEnable();
45        for (int i = 0, n = MediaNames.ALBUMART_TEST_FILES.length; i < n; ++i) {
46            try {
47                Log.v(TAG, "File " + i + ": " + MediaNames.ALBUMART_TEST_FILES[i]);
48                if ((MediaNames.ALBUMART_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
49                    (MediaNames.ALBUMART_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
50                   ) {
51                    Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
52                    continue;
53                }
54                retriever.setDataSource(MediaNames.ALBUMART_TEST_FILES[i]);
55                byte[] albumArt = retriever.getEmbeddedPicture();
56
57                // TODO:
58                // A better test would be to compare the retrieved album art with the
59                // known result.
60                if (albumArt == null) {  // Do we have expect in JUnit?
61                    Log.e(TAG, "Fails to get embedded picture for " + MediaNames.ALBUMART_TEST_FILES[i]);
62                    hasFailed = true;
63                }
64            } catch(Exception e) {
65                Log.e(TAG, "Fails to setDataSource for " + MediaNames.ALBUMART_TEST_FILES[i]);
66                hasFailed = true;
67            }
68            Thread.yield();  // Don't be evil
69        }
70        retriever.release();
71        Log.v(TAG, "testGetEmbeddedPicture completes.");
72        assertTrue(!hasFailed);
73    }
74
75    // Test frame capture
76    @LargeTest
77    public static void testThumbnailCapture() throws Exception {
78        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
79        boolean supportWMA = MediaProfileReader.getWMAEnable();
80        boolean supportWMV = MediaProfileReader.getWMVEnable();
81        boolean hasFailed = false;
82        Log.v(TAG, "Thumbnail processing starts");
83        long startedAt = System.currentTimeMillis();
84        for(int i = 0, n = MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length; i < n; ++i) {
85            try {
86                Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
87                if ((MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
88                    (MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
89                   ) {
90                    Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
91                    continue;
92                }
93                retriever.setDataSource(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
94                Bitmap bitmap = retriever.getFrameAtTime(-1);
95                assertTrue(bitmap != null);
96                try {
97                    java.io.OutputStream stream = new FileOutputStream(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i] + ".jpg");
98                    bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
99                    stream.close();
100                } catch (Exception e) {
101                    Log.e(TAG, "Fails to convert the bitmap to a JPEG file for " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
102                    hasFailed = true;
103                }
104            } catch(Exception e) {
105                Log.e(TAG, "Fails to setDataSource for file " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
106                hasFailed = true;
107            }
108            Thread.yield();  // Don't be evil
109        }
110        long endedAt = System.currentTimeMillis();
111        retriever.release();
112        assertTrue(!hasFailed);
113        Log.v(TAG, "Average processing time per thumbnail: " + (endedAt - startedAt)/MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length + " ms");
114    }
115
116    @LargeTest
117    public static void testMetadataRetrieval() throws Exception {
118        boolean supportWMA = MediaProfileReader.getWMAEnable();
119        boolean supportWMV = MediaProfileReader.getWMVEnable();
120        boolean hasFailed = false;
121        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
122        for(int i = 0, n = MediaNames.METADATA_RETRIEVAL_TEST_FILES.length; i < n; ++i) {
123            try {
124                Log.v(TAG, "File " + i + ": " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
125                if ((MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wma") && !supportWMA) ||
126                    (MediaNames.METADATA_RETRIEVAL_TEST_FILES[i].endsWith(".wmv") && !supportWMV)
127                   ) {
128                    Log.v(TAG, "windows media is not supported and thus we will skip the test for this file");
129                    continue;
130                }
131                retriever.setDataSource(MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
132                extractAllSupportedMetadataValues(retriever);
133            } catch(Exception e) {
134                Log.e(TAG, "Fails to setDataSource for file " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
135                hasFailed = true;
136            }
137            Thread.yield();  // Don't be evil
138        }
139        retriever.release();
140        assertTrue(!hasFailed);
141    }
142
143    // If the specified call order and valid media file is used, no exception
144    // should be thrown.
145    @MediumTest
146    public static void testBasicNormalMethodCallSequence() throws Exception {
147        boolean hasFailed = false;
148        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
149        try {
150            retriever.setDataSource(MediaNames.TEST_PATH_1);
151            Bitmap bitmap = retriever.getFrameAtTime(-1);
152            assertTrue(bitmap != null);
153            try {
154                java.io.OutputStream stream = new FileOutputStream("/sdcard/thumbnailout.jpg");
155                bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
156                stream.close();
157            } catch (Exception e) {
158                throw new Exception("Fails to convert the bitmap to a JPEG file for " + MediaNames.TEST_PATH_1, e);
159            }
160            extractAllSupportedMetadataValues(retriever);
161        } catch(Exception e) {
162            Log.e(TAG, "Fails to setDataSource for " + MediaNames.TEST_PATH_1, e);
163            hasFailed = true;
164        }
165        retriever.release();
166        assertTrue(!hasFailed);
167    }
168
169    // If setDataSource() has not been called, both getFrameAtTime() and extractMetadata() must
170    // return null.
171    @MediumTest
172    public static void testBasicAbnormalMethodCallSequence() {
173        boolean hasFailed = false;
174        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
175        if (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM) != null) {
176            Log.e(TAG, "No album metadata expected, but is available");
177            hasFailed = true;
178        }
179        if (retriever.getFrameAtTime(-1) != null) {
180            Log.e(TAG, "No frame expected, but is available");
181            hasFailed = true;
182        }
183        assertTrue(!hasFailed);
184    }
185
186    // Test setDataSource()
187    @MediumTest
188    public static void testSetDataSource() {
189        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
190        boolean hasFailed = false;
191
192        // Null pointer argument
193        try {
194            String path = null;
195            retriever.setDataSource(path);
196            Log.e(TAG, "IllegalArgumentException failed to be thrown.");
197            hasFailed = true;
198        } catch(Exception e) {
199            if (!(e instanceof IllegalArgumentException)) {
200                Log.e(TAG, "Expected a IllegalArgumentException, but got a different exception");
201                hasFailed = true;
202            }
203        }
204
205        // Use mem:// path
206        try {
207            retriever.setDataSource(MediaNames.TEST_PATH_5);
208            Log.e(TAG, "IllegalArgumentException failed to be thrown.");
209            hasFailed = true;
210        } catch(Exception e) {
211            if (!(e instanceof IllegalArgumentException)) {
212                Log.e(TAG, "Expected a IllegalArgumentException, but got a different exception");
213                hasFailed = true;
214            }
215        }
216
217        // The pathname does not correspond to any existing file
218        try {
219            retriever.setDataSource(MediaNames.TEST_PATH_4);
220            Log.e(TAG, "RuntimeException failed to be thrown.");
221            hasFailed = true;
222        } catch(Exception e) {
223            if (!(e instanceof RuntimeException)) {
224                Log.e(TAG, "Expected a RuntimeException, but got a different exception");
225                hasFailed = true;
226            }
227        }
228
229        // The pathname does correspond to a file, but this file
230        // is not a valid media file
231        try {
232            retriever.setDataSource(MediaNames.TEST_PATH_3);
233            Log.e(TAG, "RuntimeException failed to be thrown.");
234            hasFailed = true;
235        } catch(Exception e) {
236            if (!(e instanceof RuntimeException)) {
237                Log.e(TAG, "Expected a RuntimeException, but got a different exception");
238                hasFailed = true;
239            }
240        }
241
242        retriever.release();
243        assertTrue(!hasFailed);
244    }
245
246    // Due to the lack of permission to access hardware decoder, any calls
247    // attempting to capture a frame will fail. These are commented out for now
248    // until we find a solution to this access permission problem.
249    @MediumTest
250    public static void testIntendedUsage() {
251        // By default, capture frame and retrieve metadata
252        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
253        boolean hasFailed = false;
254        retriever.setDataSource(MediaNames.TEST_PATH_1);
255        assertTrue(retriever.getFrameAtTime(-1) != null);
256        assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null);
257
258        // Do not capture frame or retrieve metadata
259        retriever.setDataSource(MediaNames.TEST_PATH_1);
260        if (retriever.getFrameAtTime(-1) != null) {
261            Log.e(TAG, "No frame expected, but is available");
262            hasFailed = true;
263        }
264        if (retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null) {
265            Log.e(TAG, "No num track metadata expected, but is available");
266            hasFailed = true;
267        }
268
269        // Capture frame only
270        retriever.setDataSource(MediaNames.TEST_PATH_1);
271        assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) == null);
272
273        // Retriever metadata only
274        retriever.setDataSource(MediaNames.TEST_PATH_1);
275        if (retriever.getFrameAtTime(-1) != null) {
276            Log.e(TAG, "No frame expected, but is available");
277            hasFailed = true;
278        }
279
280        // Capture frame and retrieve metadata
281        retriever.setDataSource(MediaNames.TEST_PATH_1);
282        assertTrue(retriever.getFrameAtTime(-1) != null);
283        assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null);
284        retriever.release();
285        assertTrue(!hasFailed);
286    }
287
288    // TODO:
289    // Encode and test for the correct mix of metadata elements on a per-file basis?
290    // We should be able to compare the actual returned metadata with the expected metadata
291    // with each given sample test file.
292    private static void extractAllSupportedMetadataValues(MediaMetadataRetriever retriever) {
293        String value = null;
294        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER)) == null? "not found": value);
295        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)) == null? "not found": value);
296        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS)) == null? "not found": value);
297        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)) == null? "not found": value);
298        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)) == null? "not found": value);
299        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_AUTHOR)) == null? "not found": value);
300        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_COMPOSER)) == null? "not found": value);
301        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE)) == null? "not found": value);
302        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE)) == null? "not found": value);
303        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)) == null? "not found": value);
304        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR)) == null? "not found": value);
305    }
306}
307