Merging latest master, including new tests

This commit is contained in:
Joe Bowser 2014-08-14 14:20:49 -07:00
commit a7ccb9243d
9 changed files with 198 additions and 12 deletions

View File

@ -197,7 +197,19 @@ public class AndroidWebViewClient extends WebViewClient {
// Clear timeout flag
appView.loadUrlTimeout++;
// Handle error
// If this is a "Protocol Not Supported" error, then revert to the previous
// page. If there was no previous page, then punt. The application's config
// is likely incorrect (start page set to sms: or something like that)
if (errorCode == WebViewClient.ERROR_UNSUPPORTED_SCHEME) {
if (view.canGoBack()) {
view.goBack();
return;
} else {
super.onReceivedError(view, errorCode, description, failingUrl);
}
}
// Handle other errors by passing them to the webview in JS
JSONObject data = new JSONObject();
try {
data.put("errorCode", errorCode);

View File

@ -394,6 +394,9 @@ public class CordovaActivity extends Activity implements CordovaInterface {
if (this.appView == null) {
return;
}
// Force window to have focus, so application always
// receive user input. Workaround for some devices (Samsung Galaxy Note 3 at least)
this.getWindow().getDecorView().requestFocus();
this.appView.handleResume(this.keepRunning, this.activityResultKeepRunning);

View File

@ -19,8 +19,11 @@
package org.apache.cordova;
import android.annotation.TargetApi;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.webkit.WebView;
public class CordovaUriHelper {
@ -43,6 +46,7 @@ public class CordovaUriHelper {
* @param url The url to be loaded.
* @return true to override, false for default behavior
*/
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
public boolean shouldOverrideUrlLoading(String url) {
// The WebView should support http and https when going on the Internet
if(url.startsWith("http:") || url.startsWith("https:"))
@ -68,6 +72,11 @@ public class CordovaUriHelper {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setComponent(null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
intent.setSelector(null);
}
this.cordova.getActivity().startActivity(intent);
} catch (android.content.ActivityNotFoundException e) {
LOG.e(TAG, "Error loading url " + url, e);

View File

@ -321,11 +321,16 @@ public class NativeToJsMessageQueue {
}
}
};
final Runnable resetNetworkRunnable = new Runnable() {
public void run() {
online = false;
// If the following call triggers a notifyOfFlush, then ignore it.
ignoreNextFlush = true;
webView.setNetworkAvailable(true);
}
};
@Override void reset() {
online = false;
// If the following call triggers a notifyOfFlush, then ignore it.
ignoreNextFlush = true;
webView.setNetworkAvailable(true);
cordova.getActivity().runOnUiThread(resetNetworkRunnable);
}
@Override void onNativeToJsMessageAvailable() {
cordova.getActivity().runOnUiThread(toggleNetworkRunnable);

View File

@ -124,15 +124,15 @@ public class Whitelist {
whiteList = null;
}
else { // specific access
Pattern parts = Pattern.compile("^((\\*|[A-Za-z-]+)://)?(\\*|((\\*\\.)?[^*/:]+))?(:(\\d+))?(/.*)?");
Pattern parts = Pattern.compile("^((\\*|[A-Za-z-]+):(//)?)?(\\*|((\\*\\.)?[^*/:]+))?(:(\\d+))?(/.*)?");
Matcher m = parts.matcher(origin);
if (m.matches()) {
String scheme = m.group(2);
String host = m.group(3);
String host = m.group(4);
// Special case for two urls which are allowed to have empty hosts
if (("file".equals(scheme) || "content".equals(scheme)) && host == null) host = "*";
String port = m.group(7);
String path = m.group(8);
String port = m.group(8);
String path = m.group(9);
if (scheme == null) {
// XXX making it stupid friendly for people who forget to include protocol/SSL
whiteList.add(new URLPattern("http", host, port, path));

View File

@ -0,0 +1,8 @@
<html>
<head>
<title>OH NOES!</title>
</head>
<body>
<h1>Things went terribly wrong!</h1>
</body>
</html>

View File

@ -22,6 +22,8 @@ package org.apache.cordova.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.cordova.AndroidChromeClient;
import org.apache.cordova.AndroidWebViewClient;
import org.apache.cordova.Config;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaInterface;
@ -45,10 +47,11 @@ public class CordovaWebViewTestActivity extends Activity implements CordovaInter
setContentView(R.layout.main);
cordovaWebView = (CordovaWebView) findViewById(R.id.cordovaWebView);
//CB-7238: This has to be added now, because it got removed from somewhere else
Config.init(this);
cordovaWebView.init(this,
Config.getPluginEntries(), Config.getWhitelist(), Config.getPreferences());
cordovaWebView = (CordovaWebView) findViewById(R.id.cordovaWebView);
cordovaWebView.init(this, Config.getPluginEntries(), Config.getWhitelist(), Config.getPreferences());
cordovaWebView.loadUrl("file:///android_asset/www/index.html");

View File

@ -0,0 +1,73 @@
package org.apache.cordova.test;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import org.apache.cordova.Config;
import org.apache.cordova.CordovaActivity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
public class SabotagedActivity extends CordovaActivity {
private String BAD_ASSET = "www/error.html";
private String LOG_TAG = "SabotagedActivity";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// copyErrorAsset();
super.init();
super.loadUrl(Config.getStartUrl());
}
/*
* Sometimes we need to move code around before we can do anything. This will
* copy the bad code out of the assets before we initalize Cordova so that when Cordova actually
* initializes, we have something for it to navigate to.
*/
private void copyErrorAsset () {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list(BAD_ASSET);
} catch (IOException e) {
Log.e(LOG_TAG, e.getMessage());
}
for(String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(BAD_ASSET);
out = new FileOutputStream(Environment.getExternalStorageDirectory().toString() +"/" + filename);
copy(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(Exception e) {
Log.e("tag", e.getMessage());
}
}
}
//Quick and Dirty Copy!
private void copy(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
}

View File

@ -0,0 +1,73 @@
package org.apache.cordova.test.junit;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.test.SabotagedActivity;
import org.apache.cordova.test.splashscreen;
import android.app.Instrumentation;
import android.content.Context;
import android.content.Intent;
import android.content.res.AssetManager;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
public class IntentUriOverrideTest extends ActivityInstrumentationTestCase2<SabotagedActivity> {
private int TIMEOUT = 1000;
private SabotagedActivity testActivity;
private FrameLayout containerView;
private LinearLayout innerContainer;
private CordovaWebView testView;
private Instrumentation mInstr;
private String BAD_URL = "file:///sdcard/download/wl-exploit.htm";
public IntentUriOverrideTest()
{
super("org.apache.cordova.test",SabotagedActivity.class);
}
protected void setUp() throws Exception {
super.setUp();
mInstr = this.getInstrumentation();
Intent badIntent = new Intent();
badIntent.setClassName("org.apache.cordova.test", "org.apache.cordova.test.SabotagedActivity");
badIntent.putExtra("url", BAD_URL);
setActivityIntent(badIntent);
testActivity = getActivity();
containerView = (FrameLayout) testActivity.findViewById(android.R.id.content);
innerContainer = (LinearLayout) containerView.getChildAt(0);
testView = (CordovaWebView) innerContainer.getChildAt(0);
}
public void testPreconditions(){
assertNotNull(innerContainer);
assertNotNull(testView);
}
public void testChangeStartUrl() throws Throwable
{
runTestOnUiThread(new Runnable() {
public void run()
{
boolean isBadUrl = testView.getUrl().equals(BAD_URL);
assertFalse(isBadUrl);
}
});
}
private void sleep() {
try {
Thread.sleep(TIMEOUT);
} catch (InterruptedException e) {
fail("Unexpected Timeout");
}
}
}