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