mirror of
https://github.com/apache/cordova-android.git
synced 2026-05-30 00:00:04 +08:00
[CB-3384] Reworked UriResolver into CordovaResourceApi.
Changes were made after trying to use the API for Camera, FileTransfer, Media. The main difference is separating the concept of URI remapping from the read/write helpers.
This commit is contained in:
@@ -45,7 +45,7 @@
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
|
||||
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
|
||||
|
||||
<uses-sdk android:minSdkVersion="7" />
|
||||
<uses-sdk android:minSdkVersion="8" />
|
||||
|
||||
<instrumentation
|
||||
android:name="android.test.InstrumentationTestRunner"
|
||||
|
||||
+73
-57
@@ -22,9 +22,9 @@ package org.apache.cordova.test;
|
||||
*
|
||||
*/
|
||||
|
||||
import org.apache.cordova.CordovaResourceApi;
|
||||
import org.apache.cordova.CordovaResourceApi.OpenForReadResult;
|
||||
import org.apache.cordova.CordovaWebView;
|
||||
import org.apache.cordova.UriResolver;
|
||||
import org.apache.cordova.UriResolvers;
|
||||
import org.apache.cordova.CallbackContext;
|
||||
import org.apache.cordova.CordovaPlugin;
|
||||
import org.apache.cordova.PluginEntry;
|
||||
@@ -34,6 +34,9 @@ import org.json.JSONException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Scanner;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
@@ -41,16 +44,17 @@ import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.test.ActivityInstrumentationTestCase2;
|
||||
import android.util.Log;
|
||||
|
||||
public class UriResolversTest extends ActivityInstrumentationTestCase2<CordovaWebViewTestActivity> {
|
||||
public class CordovaResourceApiTest extends ActivityInstrumentationTestCase2<CordovaWebViewTestActivity> {
|
||||
|
||||
public UriResolversTest()
|
||||
public CordovaResourceApiTest()
|
||||
{
|
||||
super(CordovaWebViewTestActivity.class);
|
||||
}
|
||||
|
||||
CordovaWebView cordovaWebView;
|
||||
CordovaResourceApi resourceApi;
|
||||
|
||||
private CordovaWebViewTestActivity activity;
|
||||
String execPayload;
|
||||
Integer execStatus;
|
||||
@@ -59,32 +63,26 @@ public class UriResolversTest extends ActivityInstrumentationTestCase2<CordovaWe
|
||||
super.setUp();
|
||||
activity = this.getActivity();
|
||||
cordovaWebView = activity.cordovaWebView;
|
||||
cordovaWebView.pluginManager.addService(new PluginEntry("UriResolverTestPlugin1", new CordovaPlugin() {
|
||||
resourceApi = cordovaWebView.getResourceApi();
|
||||
resourceApi.setThreadCheckingEnabled(false);
|
||||
cordovaWebView.pluginManager.addService(new PluginEntry("CordovaResourceApiTestPlugin1", new CordovaPlugin() {
|
||||
@Override
|
||||
public UriResolver resolveUri(Uri uri) {
|
||||
if ("plugin-uri".equals(uri.getScheme())) {
|
||||
return cordovaWebView.resolveUri(uri.buildUpon().scheme("file").build());
|
||||
public Uri remapUri(Uri uri) {
|
||||
if (uri.getQuery() != null && uri.getQuery().contains("pluginRewrite")) {
|
||||
return cordovaWebView.getResourceApi().remapUri(
|
||||
Uri.parse("data:text/plain;charset=utf-8,pass"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
||||
synchronized (UriResolversTest.this) {
|
||||
synchronized (CordovaResourceApiTest.this) {
|
||||
execPayload = args.getString(0);
|
||||
execStatus = args.getInt(1);
|
||||
UriResolversTest.this.notify();
|
||||
CordovaResourceApiTest.this.notify();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
cordovaWebView.pluginManager.addService(new PluginEntry("UriResolverTestPlugin2", new CordovaPlugin() {
|
||||
@Override
|
||||
public UriResolver resolveUri(Uri uri) {
|
||||
if (uri.getQueryParameter("pluginRewrite") != null) {
|
||||
return UriResolvers.createInline(uri, "pass", "my/mime");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private Uri createTestImageContentUri() {
|
||||
@@ -94,19 +92,15 @@ public class UriResolversTest extends ActivityInstrumentationTestCase2<CordovaWe
|
||||
return Uri.parse(stored);
|
||||
}
|
||||
|
||||
private void performResolverTest(Uri uri, String expectedMimeType, File expectedLocalFile,
|
||||
boolean expectedIsWritable,
|
||||
private void performApiTest(Uri uri, String expectedMimeType, File expectedLocalFile,
|
||||
boolean expectRead, boolean expectWrite) throws IOException {
|
||||
UriResolver resolver = cordovaWebView.resolveUri(uri);
|
||||
assertEquals(expectedLocalFile, resolver.getLocalFile());
|
||||
assertEquals(expectedMimeType, resolver.getMimeType());
|
||||
if (expectedIsWritable) {
|
||||
assertTrue(resolver.isWritable());
|
||||
} else {
|
||||
assertFalse(resolver.isWritable());
|
||||
}
|
||||
uri = resourceApi.remapUri(uri);
|
||||
assertEquals(expectedLocalFile, resourceApi.mapUriToFile(uri));
|
||||
|
||||
try {
|
||||
resolver.getInputStream().read();
|
||||
OpenForReadResult readResult = resourceApi.openForRead(uri);
|
||||
assertEquals(expectedMimeType, readResult.mimeType);
|
||||
readResult.inputStream.read();
|
||||
if (!expectRead) {
|
||||
fail("Expected getInputStream to throw.");
|
||||
}
|
||||
@@ -116,10 +110,12 @@ public class UriResolversTest extends ActivityInstrumentationTestCase2<CordovaWe
|
||||
}
|
||||
}
|
||||
try {
|
||||
resolver.getOutputStream().write(123);
|
||||
OutputStream outStream = resourceApi.openOutputStream(uri);
|
||||
outStream.write(123);
|
||||
if (!expectWrite) {
|
||||
fail("Expected getOutputStream to throw.");
|
||||
}
|
||||
outStream.close();
|
||||
} catch (IOException e) {
|
||||
if (expectWrite) {
|
||||
throw e;
|
||||
@@ -130,25 +126,27 @@ public class UriResolversTest extends ActivityInstrumentationTestCase2<CordovaWe
|
||||
public void testValidContentUri() throws IOException
|
||||
{
|
||||
Uri contentUri = createTestImageContentUri();
|
||||
performResolverTest(contentUri, "image/jpeg", null, true, true, true);
|
||||
File localFile = resourceApi.mapUriToFile(contentUri);
|
||||
assertNotNull(localFile);
|
||||
performApiTest(contentUri, "image/jpeg", localFile, true, true);
|
||||
}
|
||||
|
||||
public void testInvalidContentUri() throws IOException
|
||||
{
|
||||
Uri contentUri = Uri.parse("content://media/external/images/media/999999999");
|
||||
performResolverTest(contentUri, null, null, true, false, false);
|
||||
performApiTest(contentUri, null, null, false, false);
|
||||
}
|
||||
|
||||
public void testValidAssetUri() throws IOException
|
||||
{
|
||||
Uri assetUri = Uri.parse("file:///android_asset/www/index.html?foo#bar"); // Also check for stripping off ? and # correctly.
|
||||
performResolverTest(assetUri, "text/html", null, false, true, false);
|
||||
performApiTest(assetUri, "text/html", null, true, false);
|
||||
}
|
||||
|
||||
public void testInvalidAssetUri() throws IOException
|
||||
{
|
||||
Uri assetUri = Uri.parse("file:///android_asset/www/missing.html");
|
||||
performResolverTest(assetUri, "text/html", null, false, false, false);
|
||||
performApiTest(assetUri, "text/html", null, false, false);
|
||||
}
|
||||
|
||||
public void testFileUriToExistingFile() throws IOException
|
||||
@@ -156,7 +154,7 @@ public class UriResolversTest extends ActivityInstrumentationTestCase2<CordovaWe
|
||||
File f = File.createTempFile("te s t", ".txt"); // Also check for dealing with spaces.
|
||||
try {
|
||||
Uri fileUri = Uri.parse(f.toURI().toString() + "?foo#bar"); // Also check for stripping off ? and # correctly.
|
||||
performResolverTest(fileUri, "text/plain", f, true, true, true);
|
||||
performApiTest(fileUri, "text/plain", f, true, true);
|
||||
} finally {
|
||||
f.delete();
|
||||
}
|
||||
@@ -167,7 +165,7 @@ public class UriResolversTest extends ActivityInstrumentationTestCase2<CordovaWe
|
||||
File f = new File(Environment.getExternalStorageDirectory() + "/somefilethatdoesntexist");
|
||||
Uri fileUri = Uri.parse(f.toURI().toString());
|
||||
try {
|
||||
performResolverTest(fileUri, null, f, true, false, true);
|
||||
performApiTest(fileUri, null, f, false, true);
|
||||
} finally {
|
||||
f.delete();
|
||||
}
|
||||
@@ -175,52 +173,70 @@ public class UriResolversTest extends ActivityInstrumentationTestCase2<CordovaWe
|
||||
|
||||
public void testFileUriToMissingFileWithMissingParent() throws IOException
|
||||
{
|
||||
File f = new File(Environment.getExternalStorageDirectory() + "/somedirthatismissing/somefilethatdoesntexist");
|
||||
File f = new File(Environment.getExternalStorageDirectory() + "/somedirthatismissing" + System.currentTimeMillis() + "/somefilethatdoesntexist");
|
||||
Uri fileUri = Uri.parse(f.toURI().toString());
|
||||
performResolverTest(fileUri, null, f, false, false, false);
|
||||
performApiTest(fileUri, null, f, false, true);
|
||||
}
|
||||
|
||||
public void testUnrecognizedUri() throws IOException
|
||||
{
|
||||
Uri uri = Uri.parse("somescheme://foo");
|
||||
performResolverTest(uri, null, null, false, false, false);
|
||||
performApiTest(uri, null, null, false, false);
|
||||
}
|
||||
|
||||
public void testRelativeUri()
|
||||
{
|
||||
try {
|
||||
cordovaWebView.resolveUri(Uri.parse("/foo"));
|
||||
resourceApi.openForRead(Uri.parse("/foo"));
|
||||
fail("Should have thrown for relative URI 1.");
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
try {
|
||||
cordovaWebView.resolveUri(Uri.parse("//foo/bar"));
|
||||
resourceApi.openForRead(Uri.parse("//foo/bar"));
|
||||
fail("Should have thrown for relative URI 2.");
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
try {
|
||||
cordovaWebView.resolveUri(Uri.parse("foo.png"));
|
||||
resourceApi.openForRead(Uri.parse("foo.png"));
|
||||
fail("Should have thrown for relative URI 3.");
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testPluginOverrides1() throws IOException
|
||||
{
|
||||
Uri uri = Uri.parse("plugin-uri://foohost/android_asset/www/index.html");
|
||||
performResolverTest(uri, "text/html", null, false, true, false);
|
||||
}
|
||||
|
||||
public void testPluginOverrides2() throws IOException
|
||||
public void testPluginOverride() throws IOException
|
||||
{
|
||||
Uri uri = Uri.parse("plugin-uri://foohost/android_asset/www/index.html?pluginRewrite=yes");
|
||||
performResolverTest(uri, "my/mime", null, false, true, false);
|
||||
performApiTest(uri, "text/plain", null, true, false);
|
||||
}
|
||||
|
||||
public void testWhitelistRejection() throws IOException
|
||||
public void testMainThreadUsage() throws IOException
|
||||
{
|
||||
Uri uri = Uri.parse("http://foohost.com/");
|
||||
performResolverTest(uri, null, null, false, false, false);
|
||||
Uri assetUri = Uri.parse("file:///android_asset/www/index.html");
|
||||
resourceApi.setThreadCheckingEnabled(true);
|
||||
try {
|
||||
resourceApi.openForRead(assetUri);
|
||||
fail("Should have thrown for main thread check.");
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testDataUriPlain() throws IOException
|
||||
{
|
||||
Uri uri = Uri.parse("data:text/plain;charset=utf-8,pass");
|
||||
OpenForReadResult readResult = resourceApi.openForRead(uri);
|
||||
assertEquals("text/plain", readResult.mimeType);
|
||||
String data = new Scanner(readResult.inputStream, "UTF-8").useDelimiter("\\A").next();
|
||||
assertEquals("pass", data);
|
||||
}
|
||||
|
||||
public void testDataUriBase64() throws IOException
|
||||
{
|
||||
Uri uri = Uri.parse("data:text/js;charset=utf-8;base64,cGFzcw==");
|
||||
OpenForReadResult readResult = resourceApi.openForRead(uri);
|
||||
assertEquals("text/js", readResult.mimeType);
|
||||
String data = new Scanner(readResult.inputStream, "UTF-8").useDelimiter("\\A").next();
|
||||
assertEquals("pass", data);
|
||||
}
|
||||
|
||||
public void testWebViewRequestIntercept() throws IOException
|
||||
@@ -229,7 +245,7 @@ public class UriResolversTest extends ActivityInstrumentationTestCase2<CordovaWe
|
||||
"var x = new XMLHttpRequest;\n" +
|
||||
"x.open('GET', 'file://foo?pluginRewrite=1', false);\n" +
|
||||
"x.send();\n" +
|
||||
"cordova.require('cordova/exec')(null,null,'UriResolverTestPlugin1', 'foo', [x.responseText, x.status])");
|
||||
"cordova.require('cordova/exec')(null,null,'CordovaResourceApiTestPlugin1', 'foo', [x.responseText, x.status])");
|
||||
execPayload = null;
|
||||
execStatus = null;
|
||||
try {
|
||||
@@ -248,7 +264,7 @@ public class UriResolversTest extends ActivityInstrumentationTestCase2<CordovaWe
|
||||
"var x = new XMLHttpRequest;\n" +
|
||||
"x.open('GET', 'http://foo/bar', false);\n" +
|
||||
"x.send();\n" +
|
||||
"cordova.require('cordova/exec')(null,null,'UriResolverTestPlugin1', 'foo', [x.responseText, x.status])");
|
||||
"cordova.require('cordova/exec')(null,null,'CordovaResourceApiTestPlugin1', 'foo', [x.responseText, x.status])");
|
||||
execPayload = null;
|
||||
execStatus = null;
|
||||
try {
|
||||
Reference in New Issue
Block a user