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