MediaResourceGetterTest.java revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.content.browser;
6
7import android.annotation.SuppressLint;
8import android.content.Context;
9import android.content.pm.PackageManager;
10import android.media.MediaMetadataRetriever;
11import android.net.ConnectivityManager;
12import android.test.InstrumentationTestCase;
13import android.test.mock.MockContext;
14import android.test.suitebuilder.annotation.SmallTest;
15import android.util.SparseArray;
16
17import org.chromium.content.browser.MediaResourceGetter.MediaMetadata;
18
19import java.io.File;
20import java.util.Collections;
21import java.util.HashMap;
22import java.util.Map;
23
24/**
25 * Tests for MediaResourceGetter.
26 */
27@SuppressLint("SdCardPath")
28public class MediaResourceGetterTest extends InstrumentationTestCase {
29    private static final String TEST_HTTP_URL = "http://example.com";
30    private static final String TEST_USER_AGENT = // Anything, really
31            "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 " +
32            "(KHTML, like Gecko) Chrome/32.0.1667.0 Safari/537.36";
33    private static final String TEST_FILE_PATH = "/mnt/sdcard/test";
34    private static final String TEST_FILE_URL = "file://" + TEST_FILE_PATH;
35    private static final String TEST_COOKIES = "yum yum yum!";
36    private static final MediaMetadata sEmptyMetadata = new MediaMetadata(0, 0, 0, false);
37    private static final String sExternalStorageDirectory = "/test_external_storage";
38
39    private static final Map<String, String> sHeadersCookieOnly;
40    private static final Map<String, String> sHeadersCookieAndUA;
41    private static final Map<String, String> sHeadersUAOnly;
42    static {
43        Map<String, String> headers = new HashMap<String, String>();
44        headers.put("Cookie", TEST_COOKIES);
45        sHeadersCookieOnly = Collections.unmodifiableMap(headers);
46
47        headers = new HashMap<String, String>();
48        headers.put("User-Agent", TEST_USER_AGENT);
49        sHeadersUAOnly = Collections.unmodifiableMap(headers);
50
51        headers = new HashMap<String, String>();
52        headers.putAll(sHeadersCookieOnly);
53        headers.putAll(sHeadersUAOnly);
54        sHeadersCookieAndUA = Collections.unmodifiableMap(headers);
55    }
56
57    private static class FakeFile extends File {
58        final boolean mExists;
59
60        public FakeFile(String path, boolean exists) {
61            super(path);
62            mExists = exists;
63        }
64
65        @Override
66        public int hashCode() {
67            final int prime = 31;
68            int result = super.hashCode();
69            result = prime * result + (mExists ? 1231 : 1237);
70            return result;
71        }
72
73        @Override
74        public boolean equals(Object obj) {
75            if (this == obj)
76                return true;
77            if (!super.equals(obj))
78                return false;
79            if (getClass() != obj.getClass())
80                return false;
81            FakeFile other = (FakeFile) obj;
82            if (mExists != other.mExists)
83                return false;
84            return true;
85        }
86
87        @Override
88        public boolean exists() {
89            return mExists;
90        }
91    }
92
93    /**
94     * Helper class that fakes functionality we cannot perform without real
95     * media resources. The class being faked here has been architected
96     * carefully to allow most of the functionality to be tested. What remains
97     * here is overrides of trivial functionality.
98     */
99    private static class FakeMediaResourceGetter extends MediaResourceGetter {
100        // Read these back in tests to ensure proper values passed through
101        String mUri = null;
102        Map<String, String> mHeaders = null;
103        String mPath = null;
104        int mFd;
105        long mOffset;
106        long mLength;
107
108        // Write these before tests to configure functionality
109        SparseArray<String> mMetadata = null;
110        Integer mNetworkType = null;
111        boolean mThrowExceptionInConfigure = false;
112        boolean mThrowExceptionInExtract = false;
113        boolean mFileExists = false;
114
115        // Can't use a real MediaMetadataRetriever as we have no media
116        @Override
117        public void configure(int fd, long offset, long length) {
118            if (mThrowExceptionInConfigure) {
119                throw new RuntimeException("test exception");
120            }
121            mFd = fd;
122            mOffset = offset;
123            mLength = length;
124        }
125
126        // Can't use a real MediaMetadataRetriever as we have no media
127        @Override
128        public void configure(String uri, Map<String, String> headers) {
129            if (mThrowExceptionInConfigure) {
130                throw new RuntimeException("test exception");
131            }
132            mUri = uri;
133            mHeaders = headers;
134        }
135
136        // Can't use a real MediaMetadataRetriever as we have no media
137        @Override
138        public void configure(String path) {
139            if (mThrowExceptionInConfigure) {
140                throw new RuntimeException("test exception");
141            }
142            mPath = path;
143        }
144
145        // Can't use a real MediaMetadataRetriever as we have no media
146        @Override
147        public String extractMetadata(int key) {
148            if (mThrowExceptionInExtract) {
149                throw new RuntimeException("test exception");
150            }
151            if (mMetadata == null) {
152                return null;
153            }
154            return mMetadata.get(key);
155        }
156
157        // Can't use a real NetworkInfo object because there is no way to
158        // mock the ConnectivityManager in Android.
159        @Override
160        Integer getNetworkType(Context context) {
161            return mNetworkType;
162        }
163
164        // Can't use Environment.getExternalStorageDirectory because it could
165        // be inconsistent depending upon the state of the real or emulated
166        // device upon which we are testing.
167        @Override
168        String getExternalStorageDirectory() {
169            return sExternalStorageDirectory;
170        }
171
172        // Can't use regular File because we need to control the return from
173        // File.exists() on arbitrary paths.
174        @Override
175        File uriToFile(String path) {
176            FakeFile result = new FakeFile(path, mFileExists);
177            return result;
178        }
179
180        /**
181         * Convenience method to bind a metadata value to a key.
182         * @param key the key
183         * @param value the value
184         */
185        void bind(int key, String value) {
186            if (mMetadata == null) {
187                mMetadata = new SparseArray<String>();
188            }
189            mMetadata.put(key, value);
190        }
191
192    }
193
194    /**
195     * Helper class to control the result of permission checks.
196     */
197    private static class InternalMockContext extends MockContext {
198        boolean mAllowPermission = false;
199        @Override
200        public int checkCallingOrSelfPermission(String permission) {
201            assertEquals(android.Manifest.permission.ACCESS_NETWORK_STATE,
202                    permission);
203            return mAllowPermission ? PackageManager.PERMISSION_GRANTED :
204                PackageManager.PERMISSION_DENIED;
205        }
206
207        @Override
208        public String getPackageName() {
209            return "org.some.app.package";
210        }
211    }
212
213    // Our test objects.
214    private FakeMediaResourceGetter mFakeMRG;
215    private InternalMockContext mMockContext;
216
217    @Override
218    protected void setUp() throws Exception {
219        super.setUp();
220        mFakeMRG = new FakeMediaResourceGetter();
221        mMockContext = new InternalMockContext();
222    }
223
224    @SmallTest
225    public void testMediaMetadataEquals() {
226        assertEquals(sEmptyMetadata, sEmptyMetadata);
227        assertEquals(sEmptyMetadata, new MediaMetadata(0, 0, 0, false));
228        assertFalse(sEmptyMetadata.equals(null));
229        assertFalse(sEmptyMetadata.equals("test"));
230        assertFalse(sEmptyMetadata.equals(new MediaMetadata(1, 0, 0, false)));
231        assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 1, 0, false)));
232        assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 0, 1, false)));
233        assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 0, 0, true)));
234    }
235
236    @SmallTest
237    public void testMediaMetadataHashCode() {
238        assertEquals(sEmptyMetadata.hashCode(), sEmptyMetadata.hashCode());
239        assertEquals(sEmptyMetadata.hashCode(), new MediaMetadata(0, 0, 0, false).hashCode());
240        assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(1, 0, 0, false).hashCode());
241        assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(0, 1, 0, false).hashCode());
242        assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(0, 0, 1, false).hashCode());
243        assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(0, 0, 0, true).hashCode());
244    }
245
246    @SmallTest
247    public void testMediaMetadataGetters() {
248        MediaMetadata data = new MediaMetadata(1, 2, 3, true);
249        assertEquals(1, data.getDurationInMilliseconds());
250        assertEquals(2, data.getWidth());
251        assertEquals(3, data.getHeight());
252        assertTrue(data.isSuccess());
253
254        // Validate no overlap of test values with defaults
255        data = new MediaMetadata(4, 5, 6, false);
256        assertEquals(4, data.getDurationInMilliseconds());
257        assertEquals(5, data.getWidth());
258        assertEquals(6, data.getHeight());
259        assertFalse(data.isSuccess());
260    }
261
262    @SmallTest
263    public void testConfigure_Net_NoPermissions() {
264        mMockContext.mAllowPermission = false;
265        assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
266                                       TEST_COOKIES, TEST_USER_AGENT));
267    }
268
269    @SmallTest
270    public void testConfigure_Net_NoActiveNetwork() {
271        mMockContext.mAllowPermission = true;
272        mFakeMRG.mNetworkType = null;
273        assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
274                                       TEST_COOKIES, TEST_USER_AGENT));
275    }
276
277    @SmallTest
278    public void testConfigure_Net_Disallowed_Mobile() {
279        mMockContext.mAllowPermission = true;
280        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_MOBILE;
281        assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
282                                       TEST_COOKIES, TEST_USER_AGENT));
283    }
284
285    @SmallTest
286    public void testConfigure_Net_Disallowed_Wimax() {
287        mMockContext.mAllowPermission = true;
288        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_WIMAX;
289        assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
290                                       TEST_COOKIES, TEST_USER_AGENT));
291    }
292
293    @SmallTest
294    public void testConfigure_Net_Allowed_Ethernet_Cookies_NoUA() {
295        mMockContext.mAllowPermission = true;
296        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
297        assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
298                                      TEST_COOKIES, null));
299        assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
300        assertEquals(sHeadersCookieOnly, mFakeMRG.mHeaders);
301        assertNull(mFakeMRG.mPath);
302    }
303
304    @SmallTest
305    public void testConfigure_Net_Allowed_Wifi_Cookies_NoUA() {
306        mMockContext.mAllowPermission = true;
307        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_WIFI;
308        assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
309                                      TEST_COOKIES, null));
310        assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
311        assertEquals(sHeadersCookieOnly, mFakeMRG.mHeaders);
312        assertNull(mFakeMRG.mPath);
313    }
314
315    @SmallTest
316    public void testConfigure_Net_Allowed_Ethernet_NoCookies_NoUA() {
317        mMockContext.mAllowPermission = true;
318        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
319        assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
320                                      "", null));
321        assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
322        assertEquals(Collections.emptyMap(), mFakeMRG.mHeaders);
323        assertNull(mFakeMRG.mPath);
324    }
325
326    @SmallTest
327    public void testConfigure_Net_Allowed_Ethernet_Cookies_WithUA() {
328        mMockContext.mAllowPermission = true;
329        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
330        assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
331                                      TEST_COOKIES, TEST_USER_AGENT));
332        assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
333        assertEquals(sHeadersCookieAndUA, mFakeMRG.mHeaders);
334        assertNull(mFakeMRG.mPath);
335    }
336
337    @SmallTest
338    public void testConfigure_Net_Allowed_Ethernet_NoCookies_WithUA() {
339        mMockContext.mAllowPermission = true;
340        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
341        assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
342                                      "", TEST_USER_AGENT));
343        assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
344        assertEquals(sHeadersUAOnly, mFakeMRG.mHeaders);
345        assertNull(mFakeMRG.mPath);
346    }
347
348    @SmallTest
349    public void testConfigure_Net_Allowed_Ethernet_Exception() {
350        mMockContext.mAllowPermission = true;
351        mFakeMRG.mThrowExceptionInConfigure = true;
352        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
353        assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
354                                       "", TEST_USER_AGENT));
355        assertNull(mFakeMRG.mUri);
356        assertNull(mFakeMRG.mHeaders);
357    }
358
359    @SmallTest
360    public void testConfigure_Net_Allowed_LocalHost_WithNoNetwork() {
361        String[] localHostUrls = {
362            "http://LocalHost",
363            "https://127.0.0.1/",
364            "http://[::1]:8888/",
365        };
366        mMockContext.mAllowPermission = true;
367        mFakeMRG.mNetworkType = null;
368        for (String localHostUrl : localHostUrls) {
369            assertTrue(mFakeMRG.configure(mMockContext, localHostUrl,
370                                          TEST_COOKIES, TEST_USER_AGENT));
371            assertEquals(localHostUrl, mFakeMRG.mUri);
372            assertEquals(sHeadersCookieAndUA, mFakeMRG.mHeaders);
373            assertNull(mFakeMRG.mPath);
374        }
375    }
376
377    @SmallTest
378    public void testConfigure_File_Allowed_MntSdcard() {
379        final String path = "/mnt/sdcard/test";
380        final String url = "file://" + path;
381        mFakeMRG.mFileExists = true;
382        assertTrue(mFakeMRG.configure(mMockContext, url, "", null));
383        assertEquals(path, mFakeMRG.mPath);
384        assertNull(mFakeMRG.mUri);
385        assertNull(mFakeMRG.mHeaders);
386    }
387
388    @SmallTest
389    public void testConfigure_File_Allowed_Sdcard() {
390        final String path = "/sdcard/test";
391        final String url = "file://" + path;
392        mFakeMRG.mFileExists = true;
393        assertTrue(mFakeMRG.configure(mMockContext, url, "", null));
394        assertEquals(path, mFakeMRG.mPath);
395        assertNull(mFakeMRG.mUri);
396        assertNull(mFakeMRG.mHeaders);
397    }
398
399    @SmallTest
400    public void testConfigure_File_Allowed_Sdcard_DoesntExist() {
401        final String path = "/sdcard/test";
402        final String url = "file://" + path;
403        mFakeMRG.mFileExists = false;
404        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
405        assertNull(mFakeMRG.mPath);
406    }
407
408    @SmallTest
409    public void testConfigure_File_Allowed_ExternalStorage() {
410        final String path = sExternalStorageDirectory + "/test";
411        final String url = "file://" + path;
412        mFakeMRG.mFileExists = true;
413        assertTrue(mFakeMRG.configure(mMockContext, url, "", null));
414        assertEquals(path, mFakeMRG.mPath);
415        assertNull(mFakeMRG.mUri);
416        assertNull(mFakeMRG.mHeaders);
417    }
418
419    @SmallTest
420    public void testConfigure_File_Disallowed_Innocent() {
421        final String path = "/malicious/path";
422        final String url = "file://" + path;
423        mFakeMRG.mFileExists = true;
424        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
425        assertNull(mFakeMRG.mPath);
426    }
427
428    @SmallTest
429    public void testConfigure_File_Disallowed_Malicious() {
430        final String path = "/mnt/sdcard/../../data";
431        final String url = "file://" + path;
432        mFakeMRG.mFileExists = true;
433        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
434        assertNull(mFakeMRG.mPath);
435    }
436
437    @SmallTest
438    public void testConfigure_File_Allowed_Exception() {
439        final String path = "/mnt/sdcard/test";
440        final String url = "file://" + path;
441        mFakeMRG.mFileExists = true;
442        mFakeMRG.mThrowExceptionInConfigure = true;
443        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
444        assertNull(mFakeMRG.mPath);
445    }
446
447    @SmallTest
448    public void testConfigure_Blob_Disallow_Null_Cache() {
449        final String path = "/data/data/" + null + "/cache/";
450        final String url = path;
451        mFakeMRG.mFileExists = true;
452        mFakeMRG.mThrowExceptionInConfigure = true;
453        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
454        assertNull(mFakeMRG.mPath);
455    }
456
457    @SmallTest
458    public void testConfigure_Blob_Disallowed_Incomplete_Path() {
459        final String path = "/data/data/";
460        final String url = path;
461        mFakeMRG.mFileExists = true;
462        mFakeMRG.mThrowExceptionInConfigure = true;
463        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
464        assertNull(mFakeMRG.mPath);
465    }
466
467    @SmallTest
468    public void testConfigure_Blob_Disallowed_Unknown_Path() {
469        final String path = "/unknown/path/";
470        final String url = path;
471        mFakeMRG.mFileExists = true;
472        mFakeMRG.mThrowExceptionInConfigure = true;
473        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
474        assertNull(mFakeMRG.mPath);
475    }
476
477    @SmallTest
478    public void testConfigure_Blob_Disallowed_Other_Application() {
479        final String path = "/data/data/org.some.other.app/cache/";
480        final String url = path;
481        mFakeMRG.mFileExists = true;
482        mFakeMRG.mThrowExceptionInConfigure = true;
483        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
484        assertNull(mFakeMRG.mPath);
485    }
486
487    @SmallTest
488    public void testExtract_NoMetadata() {
489        mFakeMRG.mFileExists = true;
490        assertEquals(sEmptyMetadata, mFakeMRG.extract(
491                mMockContext, TEST_FILE_URL, null, null));
492        assertEquals("configured successfully when we shouldn't have",
493                     TEST_FILE_PATH, mFakeMRG.mPath); // tricky
494    }
495
496    @SmallTest
497    public void testExtract_WithMetadata_ValidDuration() {
498        mFakeMRG.mFileExists = true;
499        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
500        final MediaMetadata expected = new MediaMetadata(1, 0, 0, true);
501        assertEquals(expected, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
502    }
503
504    @SmallTest
505    public void testExtract_WithMetadata_InvalidDuration() {
506        mFakeMRG.mFileExists = true;
507        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "i am not an integer");
508        assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
509    }
510
511    @SmallTest
512    public void testExtract_WithMetadata_ValidDuration_HasVideo_NoWidth_NoHeight() {
513        mFakeMRG.mFileExists = true;
514        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
515        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
516        assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
517    }
518
519    @SmallTest
520    public void testExtract_WithMetadata_ValidDuration_HasVideo_ValidWidth_NoHeight() {
521        mFakeMRG.mFileExists = true;
522        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
523        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
524        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "1");
525        assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
526    }
527
528    @SmallTest
529    public void testExtract_WithMetadata_ValidDuration_HasVideo_InvalidWidth_NoHeight() {
530        mFakeMRG.mFileExists = true;
531        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
532        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
533        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "i am not an integer");
534        assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
535    }
536
537    @SmallTest
538    public void testExtract_WithMetadata_ValidDuration_HasVideo_ValidWidth_ValidHeight() {
539        mFakeMRG.mFileExists = true;
540        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
541        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
542        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "2");
543        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT, "3");
544        final MediaMetadata expected = new MediaMetadata(1, 2, 3, true);
545        assertEquals(expected, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
546    }
547
548    @SmallTest
549    public void testExtract_WithMetadata_ValidDuration_HasVideo_ValidWidth_InvalidHeight() {
550        mFakeMRG.mFileExists = true;
551        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
552        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
553        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "1");
554        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT, "i am not an integer");
555        assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
556    }
557
558    @SmallTest
559    public void testExtract_WithMetadata_ValidDuration_ExceptionInExtract() {
560        mFakeMRG.mFileExists = true;
561        mFakeMRG.mThrowExceptionInExtract = true;
562        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
563        assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
564    }
565
566    @SmallTest
567    public void testExtractFromFileDescriptor_ValidMetadata() {
568        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
569        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
570        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "2");
571        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT, "3");
572        final MediaMetadata expected = new MediaMetadata(1, 2, 3, true);
573        int fd = 1234;
574        long offset = 1000;
575        long length = 9000;
576        assertEquals(expected, mFakeMRG.extract(fd, offset, length));
577        assertEquals(fd, mFakeMRG.mFd);
578        assertEquals(offset, mFakeMRG.mOffset);
579        assertEquals(length, mFakeMRG.mLength);
580    }
581
582    @SmallTest
583    public void testAndroidDeviceOk_BadModel_BadVersion() {
584        assertFalse(MediaResourceGetter.androidDeviceOk(
585                "GT-I9100", android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1));
586    }
587
588    @SmallTest
589    public void testAndroidDeviceOk_BadModel_GoodVersion() {
590        assertTrue(MediaResourceGetter.androidDeviceOk(
591                "GT-I9100", android.os.Build.VERSION_CODES.JELLY_BEAN));
592    }
593
594    @SmallTest
595    public void testAndroidDeviceOk_GoodModel_AnyVersion() {
596        assertTrue(MediaResourceGetter.androidDeviceOk(
597                "Happy Device", android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH));
598    }
599}
600