MediaMetadataRetrieverTest.java revision f013e1afd1e68af5e3b868c26a653bbfb39538f8
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 android.test.suitebuilder.annotation.*;
26
27/**
28 * WARNING:
29 * Currently, captureFrame() does not work, due to hardware access permission problem.
30 * We are currently only testing the metadata/album art retrieval features.
31 */
32public class MediaMetadataRetrieverTest extends AndroidTestCase {
33
34    private static final String TAG         = "MediaMetadataRetrieverTest";
35
36    // Test album art extraction.
37    @MediumTest
38    public static void testAlbumArt() throws Exception {
39        Log.v(TAG, "testAlbumArt starts.");
40        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
41        retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
42        for (int i = 0, n = MediaNames.ALBUMART_TEST_FILES.length; i < n; ++i) {
43            try {
44                Log.v(TAG, "File " + i + ": " + MediaNames.ALBUMART_TEST_FILES[i]);
45                retriever.setDataSource(MediaNames.ALBUMART_TEST_FILES[i]);
46                byte[] albumArt = retriever.extractAlbumArt();
47
48                // TODO:
49                // A better test would be to compare the retrieved album art with the
50                // known result.
51                if (albumArt == null) {  // Do we have expect in JUnit?
52                    fail("Fails to extract album art for " + MediaNames.ALBUMART_TEST_FILES[i]);
53                }
54            } catch(Exception e) {
55                throw new Exception("Fails to setDataSource for " + MediaNames.ALBUMART_TEST_FILES[i], e);
56            }
57            Thread.yield();  // Don't be evil
58        }
59        retriever.release();
60        Log.v(TAG, "testAlbumArt completes.");
61    }
62
63    // Test frame capture
64    // Suppressing until 1259652 is fixed.
65    @Suppress
66    public static void disableTestThumbnailCapture() throws Exception {
67        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
68        Log.v(TAG, "Thumbnail processing starts");
69        long startedAt = System.currentTimeMillis();
70        for(int i = 0, n = MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length; i < n; ++i) {
71            try {
72                Log.v(TAG, "File " + i + ": " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
73                retriever.setDataSource(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i]);
74                Bitmap bitmap = retriever.captureFrame();
75                assertTrue(bitmap != null);
76                try {
77                    java.io.OutputStream stream = new FileOutputStream(MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i] + ".jpg");
78                    bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
79                    stream.close();
80                } catch (Exception e) {
81                    throw new Exception("Fails to convert the bitmap to a JPEG file for " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i], e);
82                }
83            } catch(Exception e) {
84                throw new Exception("Fails to setDataSource for file " + MediaNames.THUMBNAIL_CAPTURE_TEST_FILES[i], e);
85            }
86            Thread.yield();  // Don't be evil
87        }
88        long endedAt = System.currentTimeMillis();
89        Log.v(TAG, "Average processing time per thumbnail: " + (endedAt - startedAt)/MediaNames.THUMBNAIL_CAPTURE_TEST_FILES.length + " ms");
90        retriever.release();
91    }
92
93    @LargeTest
94    public static void testMetadataRetrieval() throws Exception {
95        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
96        retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
97        for(int i = 0, n = MediaNames.METADATA_RETRIEVAL_TEST_FILES.length; i < n; ++i) {
98            try {
99                retriever.setDataSource(MediaNames.METADATA_RETRIEVAL_TEST_FILES[i]);
100                extractAllSupportedMetadataValues(retriever);
101            } catch(Exception e) {
102                throw new Exception("Fails to setDataSource for file " + MediaNames.METADATA_RETRIEVAL_TEST_FILES[i], e);
103            }
104            Thread.yield();  // Don't be evil
105        }
106        retriever.release();
107    }
108
109    // If the specified call order and valid media file is used, no exception
110    // should be thrown.
111    @MediumTest
112    public static void testBasicNormalMethodCallSequence() throws Exception {
113        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
114        retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
115        try {
116            retriever.setDataSource(MediaNames.TEST_PATH_1);
117            /*
118             * captureFrame() fails due to lack of permission to access hardware decoder devices
119            Bitmap bitmap = retriever.captureFrame();
120            assertTrue(bitmap != null);
121            try {
122                java.io.OutputStream stream = new FileOutputStream("/sdcard/thumbnailout.jpg");
123                bitmap.compress(Bitmap.CompressFormat.JPEG, 75, stream);
124                stream.close();
125            } catch (Exception e) {
126                throw new Exception("Fails to convert the bitmap to a JPEG file for " + MediaNames.TEST_PATH_1, e);
127            }
128            */
129            extractAllSupportedMetadataValues(retriever);
130        } catch(Exception e) {
131            throw new Exception("Fails to setDataSource for " + MediaNames.TEST_PATH_1, e);
132        }
133        retriever.release();
134    }
135
136    // If setDataSource() has not been called, both captureFrame() and extractMetadata() must
137    // return null.
138    @MediumTest
139    public static void testBasicAbnormalMethodCallSequence() {
140        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
141        retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
142        assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM) == null);
143        assertTrue(retriever.captureFrame() == null);
144    }
145
146    // Test setDataSource()
147    @MediumTest
148    public static void testSetDataSource() {
149        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
150        retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
151
152        // Null pointer argument
153        try {
154            String path = null;
155            retriever.setDataSource(path);
156            fail("IllegalArgumentException must be thrown.");
157        } catch(Exception e) {
158            assertTrue(e instanceof IllegalArgumentException);
159        }
160
161        // Use mem:// path
162        try {
163            retriever.setDataSource(MediaNames.TEST_PATH_5);
164            fail("IllegalArgumentException must be thrown.");
165        } catch(Exception e) {
166            assertTrue(e instanceof IllegalArgumentException);
167        }
168
169        // The pathname does not correspond to any existing file
170        try {
171            retriever.setDataSource(MediaNames.TEST_PATH_4);
172            fail("Runtime exception must be thrown.");
173        } catch(Exception e) {
174            assertTrue(e instanceof RuntimeException);
175        }
176
177        // The pathname does correspond to a file, but this file
178        // is not a valid media file
179        try {
180            retriever.setDataSource(MediaNames.TEST_PATH_3);
181            fail("Runtime exception must be thrown.");
182        } catch(Exception e) {
183            assertTrue(e instanceof RuntimeException);
184        }
185
186        retriever.release();
187    }
188
189    // Due to the lack of permission to access hardware decoder, any calls
190    // attempting to capture a frame will fail. These are commented out for now
191    // until we find a solution to this access permission problem.
192    @MediumTest
193    public static void testIntendedUsage() {
194        // By default, capture frame and retrieve metadata
195        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
196        // retriever.setDataSource(MediaNames.TEST_PATH_1);
197        // assertTrue(retriever.captureFrame() != null);
198        // assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null);
199
200        // Do not capture frame or retrieve metadata
201        retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY & MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
202        retriever.setDataSource(MediaNames.TEST_PATH_1);
203        assertTrue(retriever.captureFrame() == null);
204        assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) == null);
205
206        // Capture frame only
207        // retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY);
208        // retriever.setDataSource(MediaNames.TEST_PATH_1);
209        // assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) == null);
210
211        // Retriever metadata only
212        retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
213        retriever.setDataSource(MediaNames.TEST_PATH_1);
214        assertTrue(retriever.captureFrame() == null);
215
216        // Capture frame and retrieve metadata
217        // retriever.setMode(MediaMetadataRetriever.MODE_CAPTURE_FRAME_ONLY | MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
218        // retriever.setDataSource(MediaNames.TEST_PATH_1);
219        // assertTrue(retriever.captureFrame() != null);
220        // assertTrue(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS) != null);
221        retriever.release();
222    }
223
224    // TODO:
225    // Encode and test for the correct mix of metadata elements on a per-file basis?
226    // We should be able to compare the actual returned metadata with the expected metadata
227    // with each given sample test file.
228    private static void extractAllSupportedMetadataValues(MediaMetadataRetriever retriever) {
229        String value = null;
230        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER)) == null? "not found": value);
231        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)) == null? "not found": value);
232        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS)) == null? "not found": value);
233        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM)) == null? "not found": value);
234        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST)) == null? "not found": value);
235        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_AUTHOR)) == null? "not found": value);
236        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_COMPOSER)) == null? "not found": value);
237        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DATE)) == null? "not found": value);
238        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE)) == null? "not found": value);
239        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)) == null? "not found": value);
240        Log.v(TAG, (value = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR)) == null? "not found": value);
241    }
242}
243