Upstream version 9.37.195.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.annotation.SuppressLint;
8 import android.content.Context;
9 import android.content.pm.PackageManager;
10 import android.media.MediaMetadataRetriever;
11 import android.net.ConnectivityManager;
12 import android.test.InstrumentationTestCase;
13 import android.test.mock.MockContext;
14 import android.test.suitebuilder.annotation.SmallTest;
15 import android.util.SparseArray;
16
17 import org.chromium.content.browser.MediaResourceGetter.MediaMetadata;
18
19 import java.io.File;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.Map;
23
24 /**
25  * Tests for MediaResourceGetter.
26  */
27 @SuppressLint("SdCardPath")
28 public class MediaResourceGetterTest extends InstrumentationTestCase {
29     private static final String TEST_HTTP_URL = "http://example.com";
30     private static final String TEST_USER_AGENT = // Anyhting, 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
105         // Write these before tests to configure functionality
106         SparseArray<String> mMetadata = null;
107         Integer mNetworkType = null;
108         boolean mThrowExceptionInConfigure = false;
109         boolean mThrowExceptionInExtract = false;
110         boolean mFileExists = false;
111
112         // Can't use a real MediaMetadataRetriever as we have no media
113         @Override
114         public void configure(String uri, Map<String, String> headers) {
115             if (mThrowExceptionInConfigure) {
116                 throw new RuntimeException("test exception");
117             }
118             mUri = uri;
119             mHeaders = headers;
120         }
121
122         // Can't use a real MediaMetadataRetriever as we have no media
123         @Override
124         public void configure(String path) {
125             if (mThrowExceptionInConfigure) {
126                 throw new RuntimeException("test exception");
127             }
128             mPath = path;
129         }
130
131         // Can't use a real MediaMetadataRetriever as we have no media
132         @Override
133         public String extractMetadata(int key) {
134             if (mThrowExceptionInExtract) {
135                 throw new RuntimeException("test exception");
136             }
137             if (mMetadata == null) {
138                 return null;
139             }
140             return mMetadata.get(key);
141         }
142
143         // Can't use a real NetworkInfo object because there is no way to
144         // mock the ConnectivityManager in Android.
145         @Override
146         Integer getNetworkType(Context context) {
147             return mNetworkType;
148         }
149
150         // Can't use Environment.getExternalStorageDirectory because it could
151         // be inconsistent depending upon the state of the real or emulated
152         // device upon which we are testing.
153         @Override
154         String getExternalStorageDirectory() {
155             return sExternalStorageDirectory;
156         }
157
158         // Can't use regular File because we need to control the return from
159         // File.exists() on arbitrary paths.
160         @Override
161         File uriToFile(String path) {
162             FakeFile result = new FakeFile(path, mFileExists);
163             return result;
164         }
165
166         /**
167          * Convenience method to bind a metadata value to a key.
168          * @param key the key
169          * @param value the value
170          */
171         void bind(int key, String value) {
172             if (mMetadata == null) {
173                 mMetadata = new SparseArray<String>();
174             }
175             mMetadata.put(key, value);
176         }
177
178     }
179
180     /**
181      * Helper class to control the result of permission checks.
182      */
183     private static class InternalMockContext extends MockContext {
184         boolean allowPermission = false;
185         @Override
186         public int checkCallingOrSelfPermission(String permission) {
187             assertEquals(android.Manifest.permission.ACCESS_NETWORK_STATE,
188                     permission);
189             return allowPermission ? PackageManager.PERMISSION_GRANTED :
190                 PackageManager.PERMISSION_DENIED;
191         }
192     }
193
194     // Our test objects.
195     private FakeMediaResourceGetter mFakeMRG;
196     private InternalMockContext mMockContext;
197
198     @Override
199     protected void setUp() throws Exception {
200         super.setUp();
201         mFakeMRG = new FakeMediaResourceGetter();
202         mMockContext = new InternalMockContext();
203     }
204
205     @SmallTest
206     public void testMediaMetadataEquals() {
207         assertEquals(sEmptyMetadata, sEmptyMetadata);
208         assertEquals(sEmptyMetadata, new MediaMetadata(0, 0, 0, false));
209         assertFalse(sEmptyMetadata.equals(null));
210         assertFalse(sEmptyMetadata.equals("test"));
211         assertFalse(sEmptyMetadata.equals(new MediaMetadata(1, 0, 0, false)));
212         assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 1, 0, false)));
213         assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 0, 1, false)));
214         assertFalse(sEmptyMetadata.equals(new MediaMetadata(0, 0, 0, true)));
215     }
216
217     @SmallTest
218     public void testMediaMetadataHashCode() {
219         assertEquals(sEmptyMetadata.hashCode(), sEmptyMetadata.hashCode());
220         assertEquals(sEmptyMetadata.hashCode(), new MediaMetadata(0, 0, 0, false).hashCode());
221         assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(1, 0, 0, false).hashCode());
222         assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(0, 1, 0, false).hashCode());
223         assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(0, 0, 1, false).hashCode());
224         assertFalse(sEmptyMetadata.hashCode() == new MediaMetadata(0, 0, 0, true).hashCode());
225     }
226
227     @SmallTest
228     public void testMediaMetadataGetters() {
229         MediaMetadata data = new MediaMetadata(1, 2, 3, true);
230         assertEquals(1, data.getDurationInMilliseconds());
231         assertEquals(2, data.getWidth());
232         assertEquals(3, data.getHeight());
233         assertTrue(data.isSuccess());
234
235         // Validate no overlap of test values with defaults
236         data = new MediaMetadata(4, 5, 6, false);
237         assertEquals(4, data.getDurationInMilliseconds());
238         assertEquals(5, data.getWidth());
239         assertEquals(6, data.getHeight());
240         assertFalse(data.isSuccess());
241     }
242
243     @SmallTest
244     public void testConfigure_Net_NoPermissions() {
245         mMockContext.allowPermission = false;
246         assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
247                                        TEST_COOKIES, TEST_USER_AGENT));
248     }
249
250     @SmallTest
251     public void testConfigure_Net_NoActiveNetwork() {
252         mMockContext.allowPermission = true;
253         mFakeMRG.mNetworkType = null;
254         assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
255                                        TEST_COOKIES, TEST_USER_AGENT));
256     }
257
258     @SmallTest
259     public void testConfigure_Net_Disallowed_Mobile() {
260         mMockContext.allowPermission = true;
261         mFakeMRG.mNetworkType = ConnectivityManager.TYPE_MOBILE;
262         assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
263                                        TEST_COOKIES, TEST_USER_AGENT));
264     }
265
266     @SmallTest
267     public void testConfigure_Net_Disallowed_Wimax() {
268         mMockContext.allowPermission = true;
269         mFakeMRG.mNetworkType = ConnectivityManager.TYPE_WIMAX;
270         assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
271                                        TEST_COOKIES, TEST_USER_AGENT));
272     }
273
274     @SmallTest
275     public void testConfigure_Net_Allowed_Ethernet_Cookies_NoUA() {
276         mMockContext.allowPermission = true;
277         mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
278         assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
279                                       TEST_COOKIES, null));
280         assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
281         assertEquals(sHeadersCookieOnly, mFakeMRG.mHeaders);
282         assertNull(mFakeMRG.mPath);
283     }
284
285     @SmallTest
286     public void testConfigure_Net_Allowed_Wifi_Cookies_NoUA() {
287         mMockContext.allowPermission = true;
288         mFakeMRG.mNetworkType = ConnectivityManager.TYPE_WIFI;
289         assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
290                                       TEST_COOKIES, null));
291         assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
292         assertEquals(sHeadersCookieOnly, mFakeMRG.mHeaders);
293         assertNull(mFakeMRG.mPath);
294     }
295
296     @SmallTest
297     public void testConfigure_Net_Allowed_Ethernet_NoCookies_NoUA() {
298         mMockContext.allowPermission = true;
299         mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
300         assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
301                                       "", null));
302         assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
303         assertEquals(Collections.emptyMap(), mFakeMRG.mHeaders);
304         assertNull(mFakeMRG.mPath);
305     }
306
307     @SmallTest
308     public void testConfigure_Net_Allowed_Ethernet_Cookies_WithUA() {
309         mMockContext.allowPermission = true;
310         mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
311         assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
312                                       TEST_COOKIES, TEST_USER_AGENT));
313         assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
314         assertEquals(sHeadersCookieAndUA, mFakeMRG.mHeaders);
315         assertNull(mFakeMRG.mPath);
316     }
317
318     @SmallTest
319     public void testConfigure_Net_Allowed_Ethernet_NoCookies_WithUA() {
320         mMockContext.allowPermission = true;
321         mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
322         assertTrue(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
323                                       "", TEST_USER_AGENT));
324         assertEquals(TEST_HTTP_URL, mFakeMRG.mUri);
325         assertEquals(sHeadersUAOnly, mFakeMRG.mHeaders);
326         assertNull(mFakeMRG.mPath);
327     }
328
329     @SmallTest
330     public void testConfigure_Net_Allowed_Ethernet_Exception() {
331         mMockContext.allowPermission = true;
332         mFakeMRG.mThrowExceptionInConfigure = true;
333         mFakeMRG.mNetworkType = ConnectivityManager.TYPE_ETHERNET;
334         assertFalse(mFakeMRG.configure(mMockContext, TEST_HTTP_URL,
335                                        "", TEST_USER_AGENT));
336         assertNull(mFakeMRG.mUri);
337         assertNull(mFakeMRG.mHeaders);
338     }
339
340     @SmallTest
341     public void testConfigure_Net_Allowed_LocalHost_WithNoNetwork() {
342         String[] localHostUrls = {
343             "http://LocalHost",
344             "https://127.0.0.1/",
345             "http://[::1]:8888/",
346         };
347         mMockContext.allowPermission = true;
348         mFakeMRG.mNetworkType = null;
349         for (String localHostUrl : localHostUrls) {
350             assertTrue(mFakeMRG.configure(mMockContext, localHostUrl,
351                                           TEST_COOKIES, TEST_USER_AGENT));
352             assertEquals(localHostUrl, mFakeMRG.mUri);
353             assertEquals(sHeadersCookieAndUA, mFakeMRG.mHeaders);
354             assertNull(mFakeMRG.mPath);
355         }
356     }
357
358     @SmallTest
359     public void testConfigure_File_Allowed_MntSdcard() {
360         final String path = "/mnt/sdcard/test";
361         final String url = "file://" + path;
362         mFakeMRG.mFileExists = true;
363         assertTrue(mFakeMRG.configure(mMockContext, url, "", null));
364         assertEquals(path, mFakeMRG.mPath);
365         assertNull(mFakeMRG.mUri);
366         assertNull(mFakeMRG.mHeaders);
367     }
368
369     @SmallTest
370     public void testConfigure_File_Allowed_Sdcard() {
371         final String path = "/sdcard/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_Allowed_Sdcard_DoesntExist() {
382         final String path = "/sdcard/test";
383         final String url = "file://" + path;
384         mFakeMRG.mFileExists = false;
385         assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
386         assertNull(mFakeMRG.mPath);
387     }
388
389     @SmallTest
390     public void testConfigure_File_Allowed_ExternalStorage() {
391         final String path = sExternalStorageDirectory + "/test";
392         final String url = "file://" + path;
393         mFakeMRG.mFileExists = true;
394         assertTrue(mFakeMRG.configure(mMockContext, url, "", null));
395         assertEquals(path, mFakeMRG.mPath);
396         assertNull(mFakeMRG.mUri);
397         assertNull(mFakeMRG.mHeaders);
398     }
399
400     @SmallTest
401     public void testConfigure_File_Disallowed_Innocent() {
402         final String path = "/malicious/path";
403         final String url = "file://" + path;
404         mFakeMRG.mFileExists = true;
405         assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
406         assertNull(mFakeMRG.mPath);
407     }
408
409     @SmallTest
410     public void testConfigure_File_Disallowed_Malicious() {
411         final String path = "/mnt/sdcard/../../data";
412         final String url = "file://" + path;
413         mFakeMRG.mFileExists = true;
414         assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
415         assertNull(mFakeMRG.mPath);
416     }
417
418     @SmallTest
419     public void testConfigure_File_Allowed_Exception() {
420         final String path = "/mnt/sdcard/test";
421         final String url = "file://" + path;
422         mFakeMRG.mFileExists = true;
423         mFakeMRG.mThrowExceptionInConfigure = true;
424         assertFalse(mFakeMRG.configure(mMockContext, url, "", null));
425         assertNull(mFakeMRG.mPath);
426     }
427
428     @SmallTest
429     public void testExtract_NoMetadata() {
430         mFakeMRG.mFileExists = true;
431         assertEquals(sEmptyMetadata, mFakeMRG.extract(
432                 mMockContext, TEST_FILE_URL, null, null));
433         assertEquals("configured successfully when we shouldn't have",
434                      TEST_FILE_PATH, mFakeMRG.mPath); // tricky
435     }
436
437     @SmallTest
438     public void testExtract_WithMetadata_ValidDuration() {
439         mFakeMRG.mFileExists = true;
440         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
441         final MediaMetadata expected = new MediaMetadata(1, 0, 0, true);
442         assertEquals(expected, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
443     }
444
445     @SmallTest
446     public void testExtract_WithMetadata_InvalidDuration() {
447         mFakeMRG.mFileExists = true;
448         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "i am not an integer");
449         assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
450     }
451
452     @SmallTest
453     public void testExtract_WithMetadata_ValidDuration_HasVideo_NoWidth_NoHeight() {
454         mFakeMRG.mFileExists = true;
455         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
456         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
457         assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
458     }
459
460     @SmallTest
461     public void testExtract_WithMetadata_ValidDuration_HasVideo_ValidWidth_NoHeight() {
462         mFakeMRG.mFileExists = true;
463         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
464         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
465         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "1");
466         assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
467     }
468
469     @SmallTest
470     public void testExtract_WithMetadata_ValidDuration_HasVideo_InvalidWidth_NoHeight() {
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, "i am not an integer");
475         assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
476     }
477
478     @SmallTest
479     public void testExtract_WithMetadata_ValidDuration_HasVideo_ValidWidth_ValidHeight() {
480         mFakeMRG.mFileExists = true;
481         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
482         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
483         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "2");
484         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT, "3");
485         final MediaMetadata expected = new MediaMetadata(1, 2, 3, true);
486         assertEquals(expected, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
487     }
488
489     @SmallTest
490     public void testExtract_WithMetadata_ValidDuration_HasVideo_ValidWidth_InvalidHeight() {
491         mFakeMRG.mFileExists = true;
492         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
493         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO, "yes");
494         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH, "1");
495         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT, "i am not an integer");
496         assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
497     }
498
499     @SmallTest
500     public void testExtract_WithMetadata_ValidDuration_ExceptionInExtract() {
501         mFakeMRG.mFileExists = true;
502         mFakeMRG.mThrowExceptionInExtract = true;
503         mFakeMRG.bind(MediaMetadataRetriever.METADATA_KEY_DURATION, "1");
504         assertEquals(sEmptyMetadata, mFakeMRG.extract(mMockContext, TEST_FILE_URL, null, null));
505     }
506
507     @SmallTest
508     public void testAndroidDeviceOk_BadModel_BadVersion() {
509         assertFalse(MediaResourceGetter.androidDeviceOk(
510                 "GT-I9100", android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1));
511     }
512
513     @SmallTest
514     public void testAndroidDeviceOk_BadModel_GoodVersion() {
515         assertTrue(MediaResourceGetter.androidDeviceOk(
516                 "GT-I9100", android.os.Build.VERSION_CODES.JELLY_BEAN));
517     }
518
519     @SmallTest
520     public void testAndroidDeviceOk_GoodModel_AnyVersion() {
521         assertTrue(MediaResourceGetter.androidDeviceOk(
522                 "Happy Device", android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH));
523     }
524 }