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