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