MediaResourceGetterTest.java revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
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
208    // Our test objects.
209    private FakeMediaResourceGetter mFakeMRG;
210    private InternalMockContext mMockContext;
211
212    @Override
213    protected void setUp() throws Exception {
214        super.setUp();
215        mFakeMRG = new FakeMediaResourceGetter();
216        mMockContext = new InternalMockContext();
217    }
218
219    @SmallTest
220    public void testMediaMetadataEquals() {
221        assertEquals(sEmptyMetadata, sEmptyMetadata);
222        assertEquals(sEmptyMetadata, new MediaMetadata(0, 0, 0, false));
223        assertFalse(sEmptyMetadata.equals(null));
224        assertFalse(sEmptyMetadata.equals("test"));
225        assertFalse(sEmptyMetadata.equals(new MediaMetadata(1, 0, 0, false)));
226        assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 1, 0, false)));
227        assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 0, 1, false)));
228        assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 0, 0, true)));
229    }
230
231    @SmallTest
232    public void testMediaMetadataHashCode() {
233        assertEquals(sEmptyMetadata.hashCode(), sEmptyMetadata.hashCode());
234        assertEquals(sEmptyMetadata.hashCode(), new MediaMetadata(0, 0, 0, false).hashCode());
235        assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(1, 0, 0, false).hashCode());
236        assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(0, 1, 0, false).hashCode());
237        assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(0, 0, 1, false).hashCode());
238        assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(0, 0, 0, true).hashCode());
239    }
240
241    @SmallTest
242    public void testMediaMetadataGetters() {
243        MediaMetadata data = new MediaMetadata(1, 2, 3, true);
244        assertEquals(1, data.getDurationInMilliseconds());
245        assertEquals(2, data.getWidth());
246        assertEquals(3, data.getHeight());
247        assertTrue(data.isSuccess());
248
249        // Validate no overlap of test values with defaults
250        data = new MediaMetadata(4, 5, 6, false);
251        assertEquals(4, data.getDurationInMilliseconds());
252        assertEquals(5, data.getWidth());
253        assertEquals(6, data.getHeight());
254        assertFalse(data.isSuccess());
255    }
256
257    @SmallTest
258    public void testConfigure_Net_NoPermissions() {
259        mMockContext.mAllowPermission = false;
260        assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
261                                       TEST_COOKIES, TEST_USER_AGENT));
262    }
263
264    @SmallTest
265    public void testConfigure_Net_NoActiveNetwork() {
266        mMockContext.mAllowPermission = true;
267        mFakeMRG.mNetworkType = null;
268        assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
269                                       TEST_COOKIES, TEST_USER_AGENT));
270    }
271
272    @SmallTest
273    public void testConfigure_Net_Disallowed_Mobile() {
274        mMockContext.mAllowPermission = true;
275        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_MOBILE;
276        assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
277                                       TEST_COOKIES, TEST_USER_AGENT));
278    }
279
280    @SmallTest
281    public void testConfigure_Net_Disallowed_Wimax() {
282        mMockContext.mAllowPermission = true;
283        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_WIMAX;
284        assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
285                                       TEST_COOKIES, TEST_USER_AGENT));
286    }
287
288    @SmallTest
289    public void testConfigure_Net_Allowed_Ethernet_Cookies_NoUA() {
290        mMockContext.mAllowPermission = true;
291        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
292        assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
293                                      TEST_COOKIES, null));
294        assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
295        assertEquals(sHeadersCookieOnly, mFakeMRG.mHeaders);
296        assertNull(mFakeMRG.mPath);
297    }
298
299    @SmallTest
300    public void testConfigure_Net_Allowed_Wifi_Cookies_NoUA() {
301        mMockContext.mAllowPermission = true;
302        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_WIFI;
303        assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
304                                      TEST_COOKIES, null));
305        assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
306        assertEquals(sHeadersCookieOnly, mFakeMRG.mHeaders);
307        assertNull(mFakeMRG.mPath);
308    }
309
310    @SmallTest
311    public void testConfigure_Net_Allowed_Ethernet_NoCookies_NoUA() {
312        mMockContext.mAllowPermission = true;
313        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
314        assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
315                                      "", null));
316        assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
317        assertEquals(Collections.emptyMap(), mFakeMRG.mHeaders);
318        assertNull(mFakeMRG.mPath);
319    }
320
321    @SmallTest
322    public void testConfigure_Net_Allowed_Ethernet_Cookies_WithUA() {
323        mMockContext.mAllowPermission = true;
324        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
325        assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
326                                      TEST_COOKIES, TEST_USER_AGENT));
327        assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
328        assertEquals(sHeadersCookieAndUA, mFakeMRG.mHeaders);
329        assertNull(mFakeMRG.mPath);
330    }
331
332    @SmallTest
333    public void testConfigure_Net_Allowed_Ethernet_NoCookies_WithUA() {
334        mMockContext.mAllowPermission = true;
335        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
336        assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
337                                      "", TEST_USER_AGENT));
338        assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
339        assertEquals(sHeadersUAOnly, mFakeMRG.mHeaders);
340        assertNull(mFakeMRG.mPath);
341    }
342
343    @SmallTest
344    public void testConfigure_Net_Allowed_Ethernet_Exception() {
345        mMockContext.mAllowPermission = true;
346        mFakeMRG.mThrowExceptionInConfigure = true;
347        mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
348        assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
349                                       "", TEST_USER_AGENT));
350        assertNull(mFakeMRG.mUri);
351        assertNull(mFakeMRG.mHeaders);
352    }
353
354    @SmallTest
355    public void testConfigure_Net_Allowed_LocalHost_WithNoNetwork() {
356        String[] localHostUrls = {
357            "http://LocalHost",
358            "https://127.0.0.1/",
359            "http://[::1]:8888/",
360        };
361        mMockContext.mAllowPermission = true;
362        mFakeMRG.mNetworkType = null;
363        for (String localHostUrl : localHostUrls) {
364            assertTrue(mFakeMRG.configure(mMockContext, localHostUrl,
365                                          TEST_COOKIES, TEST_USER_AGENT));
366            assertEquals(localHostUrl, mFakeMRG.mUri);
367            assertEquals(sHeadersCookieAndUA, mFakeMRG.mHeaders);
368            assertNull(mFakeMRG.mPath);
369        }
370    }
371
372    @SmallTest
373    public void testConfigure_File_Allowed_MntSdcard() {
374        final String path = "/mnt/sdcard/test";
375        final String url = "file://" + path;
376        mFakeMRG.mFileExists = true;
377        assertTrue(mFakeMRG.configure(mMockContext, url, "", null));
378        assertEquals(path, mFakeMRG.mPath);
379        assertNull(mFakeMRG.mUri);
380        assertNull(mFakeMRG.mHeaders);
381    }
382
383    @SmallTest
384    public void testConfigure_File_Allowed_Sdcard() {
385        final String path = "/sdcard/test";
386        final String url = "file://" + path;
387        mFakeMRG.mFileExists = true;
388        assertTrue(mFakeMRG.configure(mMockContext, url, "", null));
389        assertEquals(path, mFakeMRG.mPath);
390        assertNull(mFakeMRG.mUri);
391        assertNull(mFakeMRG.mHeaders);
392    }
393
394    @SmallTest
395    public void testConfigure_File_Allowed_Sdcard_DoesntExist() {
396        final String path = "/sdcard/test";
397        final String url = "file://" + path;
398        mFakeMRG.mFileExists = false;
399        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
400        assertNull(mFakeMRG.mPath);
401    }
402
403    @SmallTest
404    public void testConfigure_File_Allowed_ExternalStorage() {
405        final String path = sExternalStorageDirectory + "/test";
406        final String url = "file://" + path;
407        mFakeMRG.mFileExists = true;
408        assertTrue(mFakeMRG.configure(mMockContext, url, "", null));
409        assertEquals(path, mFakeMRG.mPath);
410        assertNull(mFakeMRG.mUri);
411        assertNull(mFakeMRG.mHeaders);
412    }
413
414    @SmallTest
415    public void testConfigure_File_Disallowed_Innocent() {
416        final String path = "/malicious/path";
417        final String url = "file://" + path;
418        mFakeMRG.mFileExists = true;
419        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
420        assertNull(mFakeMRG.mPath);
421    }
422
423    @SmallTest
424    public void testConfigure_File_Disallowed_Malicious() {
425        final String path = "/mnt/sdcard/../../data";
426        final String url = "file://" + path;
427        mFakeMRG.mFileExists = true;
428        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
429        assertNull(mFakeMRG.mPath);
430    }
431
432    @SmallTest
433    public void testConfigure_File_Allowed_Exception() {
434        final String path = "/mnt/sdcard/test";
435        final String url = "file://" + path;
436        mFakeMRG.mFileExists = true;
437        mFakeMRG.mThrowExceptionInConfigure = true;
438        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
439        assertNull(mFakeMRG.mPath);
440    }
441
442    @SmallTest
443    public void testConfigure_Blob_Disallow_Null_Cache() {
444        final String path = "/data/data/" + null + "/cache/";
445        final String url = path;
446        mFakeMRG.mFileExists = true;
447        mFakeMRG.mThrowExceptionInConfigure = true;
448        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
449        assertNull(mFakeMRG.mPath);
450    }
451
452    @SmallTest
453    public void testConfigure_Blob_Disallowed_Incomplete_Path() {
454        final String path = "/data/data/";
455        final String url = path;
456        mFakeMRG.mFileExists = true;
457        mFakeMRG.mThrowExceptionInConfigure = true;
458        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
459        assertNull(mFakeMRG.mPath);
460    }
461
462    @SmallTest
463    public void testConfigure_Blob_Disallowed_Unknown_Path() {
464        final String path = "/unknown/path/";
465        final String url = path;
466        mFakeMRG.mFileExists = true;
467        mFakeMRG.mThrowExceptionInConfigure = true;
468        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
469        assertNull(mFakeMRG.mPath);
470    }
471
472    @SmallTest
473    public void testConfigure_Blob_Disallowed_Other_Application() {
474        final String path = "/data/data/org.some.other.app/cache/";
475        final String url = path;
476        mFakeMRG.mFileExists = true;
477        mFakeMRG.mThrowExceptionInConfigure = true;
478        assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
479        assertNull(mFakeMRG.mPath);
480    }
481
482    @SmallTest
483    public void testExtract_NoMetadata() {
484        mFakeMRG.mFileExists = true;
485        assertEquals(sEmptyMetadata, mFakeMRG.extract(
486                mMockContext, TEST_FILE_URL, null, null));
487        assertEquals("configured successfully when we shouldn't have",
488                     TEST_FILE_PATH, mFakeMRG.mPath); // tricky
489    }
490
491    @SmallTest
492    public void testExtract_WithMetadata_ValidDuration() {
493        mFakeMRG.mFileExists = true;
494        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
495        final MediaMetadata expected = new MediaMetadata(1, 0, 0, true);
496        assertEquals(expected, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
497    }
498
499    @SmallTest
500    public void testExtract_WithMetadata_InvalidDuration() {
501        mFakeMRG.mFileExists = true;
502        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "i am not an integer");
503        assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
504    }
505
506    @SmallTest
507    public void testExtract_WithMetadata_ValidDuration_HasVideo_NoWidth_NoHeight() {
508        mFakeMRG.mFileExists = true;
509        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
510        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
511        assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
512    }
513
514    @SmallTest
515    public void testExtract_WithMetadata_ValidDuration_HasVideo_ValidWidth_NoHeight() {
516        mFakeMRG.mFileExists = true;
517        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
518        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
519        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "1");
520        assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
521    }
522
523    @SmallTest
524    public void testExtract_WithMetadata_ValidDuration_HasVideo_InvalidWidth_NoHeight() {
525        mFakeMRG.mFileExists = true;
526        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
527        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
528        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "i am not an integer");
529        assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
530    }
531
532    @SmallTest
533    public void testExtract_WithMetadata_ValidDuration_HasVideo_ValidWidth_ValidHeight() {
534        mFakeMRG.mFileExists = true;
535        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
536        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
537        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "2");
538        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT, "3");
539        final MediaMetadata expected = new MediaMetadata(1, 2, 3, true);
540        assertEquals(expected, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
541    }
542
543    @SmallTest
544    public void testExtract_WithMetadata_ValidDuration_HasVideo_ValidWidth_InvalidHeight() {
545        mFakeMRG.mFileExists = true;
546        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
547        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
548        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "1");
549        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT, "i am not an integer");
550        assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
551    }
552
553    @SmallTest
554    public void testExtract_WithMetadata_ValidDuration_ExceptionInExtract() {
555        mFakeMRG.mFileExists = true;
556        mFakeMRG.mThrowExceptionInExtract = true;
557        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
558        assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
559    }
560
561    @SmallTest
562    public void testExtractFromFileDescriptor_ValidMetadata() {
563        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
564        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
565        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "2");
566        mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT, "3");
567        final MediaMetadata expected = new MediaMetadata(1, 2, 3, true);
568        int fd = 1234;
569        long offset = 1000;
570        long length = 9000;
571        assertEquals(expected, mFakeMRG.extract(fd, offset, length));
572        assertEquals(fd, mFakeMRG.mFd);
573        assertEquals(offset, mFakeMRG.mOffset);
574        assertEquals(length, mFakeMRG.mLength);
575    }
576
577    @SmallTest
578    public void testAndroidDeviceOk_BadModel_BadVersion() {
579        assertFalse(MediaResourceGetter.androidDeviceOk(
580                "GT-I9100", android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1));
581    }
582
583    @SmallTest
584    public void testAndroidDeviceOk_BadModel_GoodVersion() {
585        assertTrue(MediaResourceGetter.androidDeviceOk(
586                "GT-I9100", android.os.Build.VERSION_CODES.JELLY_BEAN));
587    }
588
589    @SmallTest
590    public void testAndroidDeviceOk_GoodModel_AnyVersion() {
591        assertTrue(MediaResourceGetter.androidDeviceOk(
592                "Happy Device", android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH));
593    }
594}
595