You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by ag...@apache.org on 2013/10/22 21:19:59 UTC
[01/16] android commit: [CB-3384] Make UriResolver assert that IO is
not on the UI nor WebCore threads. (cherry picked from commit
99341bce295d7ab373de9f91c43a4d2a59be22c2)
Updated Branches:
refs/heads/2.9.x 6a57a3c45 -> 93b9b53ac
[CB-3384] Make UriResolver assert that IO is not on the UI nor WebCore threads.
(cherry picked from commit 99341bce295d7ab373de9f91c43a4d2a59be22c2)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/e9b46e5c
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/e9b46e5c
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/e9b46e5c
Branch: refs/heads/2.9.x
Commit: e9b46e5cf6d8a91918001795f2bd395e7573c186
Parents: 6a57a3c
Author: Andrew Grieve <ag...@chromium.org>
Authored: Fri Jul 5 11:44:38 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:04:08 2013 -0400
----------------------------------------------------------------------
.../src/org/apache/cordova/CordovaWebView.java | 22 ++--
.../cordova/IceCreamCordovaWebViewClient.java | 43 ++++---
.../src/org/apache/cordova/UriResolver.java | 3 -
.../src/org/apache/cordova/UriResolvers.java | 124 +++++++++++--------
4 files changed, 106 insertions(+), 86 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/e9b46e5c/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java
index 472f5af..278bfa4 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -961,22 +961,22 @@ public class CordovaWebView extends WebView {
if (!uri.isAbsolute()) {
throw new IllegalArgumentException("Relative URIs are not yet supported by resolveUri.");
}
+ UriResolver ret = null;
// Check the against the white-list before delegating to plugins.
if (("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) && !Config.isUrlWhiteListed(uri.toString()))
{
LOG.w(TAG, "resolveUri - URL is not in whitelist: " + uri);
- return new UriResolvers.ErrorUriResolver(uri, "Whitelist rejection");
- }
-
- // Give plugins a chance to handle the request.
- UriResolver resolver = ((org.apache.cordova.PluginManager)pluginManager).resolveUri(uri);
- if (resolver == null && !fromWebView) {
- resolver = UriResolvers.forUri(uri, cordova.getActivity());
- if (resolver == null) {
- resolver = new UriResolvers.ErrorUriResolver(uri, "Unresolvable URI");
+ ret = UriResolvers.createError("Whitelist rejection for: " + uri);
+ } else {
+ // Give plugins a chance to handle the request.
+ ret = ((org.apache.cordova.PluginManager)pluginManager).resolveUri(uri);
+ }
+ if (ret == null && !fromWebView) {
+ ret = UriResolvers.forUri(uri, cordova.getActivity());
+ if (ret == null) {
+ ret = UriResolvers.createError("Unresolvable URI: " + uri);
}
}
-
- return resolver;
+ return ret == null ? null : UriResolvers.makeThreadChecking(ret);
}
}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/e9b46e5c/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
index 8527d35..c23d580 100644
--- a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
@@ -44,27 +44,34 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
- UriResolver uriResolver = appView.resolveUri(Uri.parse(url), true);
-
- if (uriResolver == null && url.startsWith("file:///android_asset/")) {
- if (url.contains("?") || url.contains("#") || needsIceCreamSpecialsInAssetUrlFix(url)) {
- uriResolver = appView.resolveUri(Uri.parse(url), false);
+ // Disable checks during shouldInterceptRequest since there is no way to avoid IO here :(.
+ UriResolvers.webCoreThread = null;
+ try {
+ UriResolver uriResolver = appView.resolveUri(Uri.parse(url), true);
+
+ if (uriResolver == null && url.startsWith("file:///android_asset/")) {
+ if (url.contains("?") || url.contains("#") || needsIceCreamSpecialsInAssetUrlFix(url)) {
+ uriResolver = appView.resolveUri(Uri.parse(url), false);
+ }
}
- }
-
- if (uriResolver != null) {
- try {
- InputStream stream = uriResolver.getInputStream();
- String mimeType = uriResolver.getMimeType();
- // If we don't know how to open this file, let the browser continue loading
- return new WebResourceResponse(mimeType, "UTF-8", stream);
- } catch (IOException e) {
- LOG.e("IceCreamCordovaWebViewClient", "Error occurred while loading a file.", e);
- // Results in a 404.
- return new WebResourceResponse("text/plain", "UTF-8", null);
+
+ if (uriResolver != null) {
+ try {
+ InputStream stream = uriResolver.getInputStream();
+ String mimeType = uriResolver.getMimeType();
+ // If we don't know how to open this file, let the browser continue loading
+ return new WebResourceResponse(mimeType, "UTF-8", stream);
+ } catch (IOException e) {
+ LOG.e("IceCreamCordovaWebViewClient", "Error occurred while loading a file.", e);
+ // Results in a 404.
+ return new WebResourceResponse("text/plain", "UTF-8", null);
+ }
}
+ return null;
+ } finally {
+ // Tell the Thread-Checking resolve what thread the WebCore thread is.
+ UriResolvers.webCoreThread = Thread.currentThread();
}
- return null;
}
private static boolean needsIceCreamSpecialsInAssetUrlFix(String url) {
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/e9b46e5c/framework/src/org/apache/cordova/UriResolver.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/UriResolver.java b/framework/src/org/apache/cordova/UriResolver.java
index 42e9a3a..8341b18 100644
--- a/framework/src/org/apache/cordova/UriResolver.java
+++ b/framework/src/org/apache/cordova/UriResolver.java
@@ -31,9 +31,6 @@ import android.net.Uri;
*/
public interface UriResolver {
- /** Returns the URI that this instance will resolve. */
- Uri getUri();
-
/**
* Returns the InputStream for the resource.
* Throws an exception if it cannot be read.
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/e9b46e5c/framework/src/org/apache/cordova/UriResolvers.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/UriResolvers.java b/framework/src/org/apache/cordova/UriResolvers.java
index e8be407..dcb5001 100644
--- a/framework/src/org/apache/cordova/UriResolvers.java
+++ b/framework/src/org/apache/cordova/UriResolvers.java
@@ -34,76 +34,64 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.res.AssetManager;
import android.net.Uri;
+import android.os.Looper;
/*
* UriResolver implementations.
*/
public final class UriResolvers {
+ static Thread webCoreThread;
+
private UriResolvers() {}
private static final class FileUriResolver implements UriResolver {
- private final Uri uri;
+ private final File localFile;
private String mimeType;
- private File localFile;
FileUriResolver(Uri uri) {
- this.uri = uri;
- }
-
- public Uri getUri() {
- return uri;
+ localFile = new File(uri.getPath());
}
public InputStream getInputStream() throws IOException {
- return new FileInputStream(getLocalFile());
+ return new FileInputStream(localFile);
}
public OutputStream getOutputStream() throws FileNotFoundException {
- return new FileOutputStream(getLocalFile());
+ return new FileOutputStream(localFile);
}
public String getMimeType() {
if (mimeType == null) {
- mimeType = FileHelper.getMimeTypeForExtension(getLocalFile().getName());
+ mimeType = FileHelper.getMimeTypeForExtension(localFile.getName());
}
return mimeType;
}
public boolean isWritable() {
- File f = getLocalFile();
- if (f.isDirectory()) {
+ if (localFile.isDirectory()) {
return false;
}
- if (f.exists()) {
- return f.canWrite();
+ if (localFile.exists()) {
+ return localFile.canWrite();
}
- return f.getParentFile().canWrite();
+ return localFile.getParentFile().canWrite();
}
public File getLocalFile() {
- if (localFile == null) {
- localFile = new File(uri.getPath());
- }
return localFile;
}
}
private static final class AssetUriResolver implements UriResolver {
- private final Uri uri;
private final AssetManager assetManager;
private final String assetPath;
private String mimeType;
AssetUriResolver(Uri uri, AssetManager assetManager) {
- this.uri = uri;
this.assetManager = assetManager;
this.assetPath = uri.getPath().substring(15);
}
- public Uri getUri() {
- return uri;
- }
-
public InputStream getInputStream() throws IOException {
return assetManager.open(assetPath);
}
@@ -138,10 +126,6 @@ public final class UriResolvers {
this.contentResolver = contentResolver;
}
- public Uri getUri() {
- return uri;
- }
-
public InputStream getInputStream() throws IOException {
return contentResolver.openInputStream(uri);
}
@@ -166,88 +150,108 @@ public final class UriResolvers {
}
}
- static final class ErrorUriResolver implements UriResolver {
- final Uri uri;
+ private static final class ErrorUriResolver implements UriResolver {
final String errorMsg;
- ErrorUriResolver(Uri uri, String errorMsg) {
- this.uri = uri;
+ ErrorUriResolver(String errorMsg) {
this.errorMsg = errorMsg;
}
- @Override
public boolean isWritable() {
return false;
}
- @Override
- public Uri getUri() {
- return uri;
- }
-
- @Override
public File getLocalFile() {
return null;
}
- @Override
public OutputStream getOutputStream() throws IOException {
throw new FileNotFoundException(errorMsg);
}
- @Override
public String getMimeType() {
return null;
}
- @Override
public InputStream getInputStream() throws IOException {
throw new FileNotFoundException(errorMsg);
}
}
private static final class ReadOnlyResolver implements UriResolver {
- private Uri uri;
private InputStream inputStream;
private String mimeType;
public ReadOnlyResolver(Uri uri, InputStream inputStream, String mimeType) {
- this.uri = uri;
this.inputStream = inputStream;
this.mimeType = mimeType;
}
- @Override
public boolean isWritable() {
return false;
}
- @Override
- public Uri getUri() {
- return uri;
- }
-
- @Override
public File getLocalFile() {
return null;
}
- @Override
public OutputStream getOutputStream() throws IOException {
throw new FileNotFoundException("URI is not writable");
}
- @Override
public String getMimeType() {
return mimeType;
}
- @Override
public InputStream getInputStream() throws IOException {
return inputStream;
}
}
+ private static final class ThreadCheckingResolver implements UriResolver {
+ final UriResolver delegate;
+
+ ThreadCheckingResolver(UriResolver delegate) {
+ this.delegate = delegate;
+ }
+
+ private static void checkThread() {
+ Thread curThread = Thread.currentThread();
+ if (curThread == Looper.getMainLooper().getThread()) {
+ throw new IllegalStateException("Do not perform IO operations on the UI thread. Use CordovaInterface.getThreadPool() instead.");
+ }
+ if (curThread == webCoreThread) {
+ throw new IllegalStateException("Tried to perform an IO operation on the WebCore thread. Use CordovaInterface.getThreadPool() instead.");
+ }
+ }
+
+ public boolean isWritable() {
+ checkThread();
+ return delegate.isWritable();
+ }
+
+
+ public File getLocalFile() {
+ checkThread();
+ return delegate.getLocalFile();
+ }
+
+ public OutputStream getOutputStream() throws IOException {
+ checkThread();
+ return delegate.getOutputStream();
+ }
+
+ public String getMimeType() {
+ checkThread();
+ return delegate.getMimeType();
+ }
+
+ public InputStream getInputStream() throws IOException {
+ checkThread();
+ return delegate.getInputStream();
+ }
+ }
+
public static UriResolver createInline(Uri uri, String response, String mimeType) {
return createInline(uri, EncodingUtils.getBytes(response, "UTF-8"), mimeType);
}
@@ -260,6 +264,10 @@ public final class UriResolvers {
return new ReadOnlyResolver(uri, inputStream, mimeType);
}
+ public static UriResolver createError(String errorMsg) {
+ return new ErrorUriResolver(errorMsg);
+ }
+
/* Package-private to force clients to go through CordovaWebView.resolveUri(). */
static UriResolver forUri(Uri uri, Context context) {
String scheme = uri.getScheme();
@@ -274,4 +282,12 @@ public final class UriResolvers {
}
return null;
}
+
+ /* Used only by CordovaWebView.resolveUri(). */
+ static UriResolver makeThreadChecking(UriResolver resolver) {
+ if (resolver instanceof ThreadCheckingResolver) {
+ return resolver;
+ }
+ return new ThreadCheckingResolver(resolver);
+ }
}
\ No newline at end of file
[13/16] android commit: Log WebView IOExceptions only when they are
not 404s (cherry picked from commit 5451320350f8a814e3d09ab465710ddca462d243)
Posted by ag...@apache.org.
Log WebView IOExceptions only when they are not 404s
(cherry picked from commit 5451320350f8a814e3d09ab465710ddca462d243)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/64c617d8
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/64c617d8
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/64c617d8
Branch: refs/heads/2.9.x
Commit: 64c617d8abb7ce2677a1145c9c4d2751139e7c88
Parents: bcccb0c
Author: Andrew Grieve <ag...@chromium.org>
Authored: Thu Aug 15 11:33:38 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:15:45 2013 -0400
----------------------------------------------------------------------
.../src/org/apache/cordova/IceCreamCordovaWebViewClient.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/64c617d8/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
index 3f98f56..13f9431 100644
--- a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
@@ -18,6 +18,7 @@
*/
package org.apache.cordova;
+import java.io.FileNotFoundException;
import java.io.IOException;
import org.apache.cordova.CordovaResourceApi.OpenForReadResult;
@@ -65,7 +66,9 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
// If we don't need to special-case the request, let the browser load it.
return null;
} catch (IOException e) {
- LOG.e("IceCreamCordovaWebViewClient", "Error occurred while loading a file.", e);
+ if (!(e instanceof FileNotFoundException)) {
+ LOG.e("IceCreamCordovaWebViewClient", "Error occurred while loading a file (returning a 404).", e);
+ }
// Results in a 404.
return new WebResourceResponse("text/plain", "UTF-8", null);
}
[08/16] android commit: [CB-4198] bin/create should handle spaces in
activity better.
Posted by ag...@apache.org.
[CB-4198] bin/create should handle spaces in activity better.
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/624a8d37
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/624a8d37
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/624a8d37
Branch: refs/heads/2.9.x
Commit: 624a8d370cef21d9d6c1f991aba6f7ca3c97dd3e
Parents: 5814d66
Author: Fil Maj <ma...@gmail.com>
Authored: Wed Jul 24 21:21:41 2013 -0700
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:12:03 2013 -0400
----------------------------------------------------------------------
bin/create | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/624a8d37/bin/create
----------------------------------------------------------------------
diff --git a/bin/create b/bin/create
index 4dfd20f..3883227 100755
--- a/bin/create
+++ b/bin/create
@@ -38,7 +38,8 @@ VERSION=$(cat "$BUILD_PATH"/VERSION)
PROJECT_PATH="${1:-'./example'}"
PACKAGE=${2:-"org.apache.cordova.example"}
-ACTIVITY=${3:-"cordovaExample"}
+ACTIVITY=$(echo ${3:-"cordovaExample"} | tr -d ' ')
+APP_LABEL=${3:-"Cordova Example"};
# clobber any existing example
if [ -d "$PROJECT_PATH" ]
@@ -67,7 +68,7 @@ function replace {
# Mac OS X requires -i argument
if [[ "$OSTYPE" =~ "darwin" ]]
then
- /usr/bin/sed -i '' -e $pattern "$filename"
+ /usr/bin/sed -i '' -e "$pattern" "$filename"
elif [[ "$OSTYPE" =~ "linux" ]]
then
/bin/sed -i -e $pattern "$filename"
@@ -82,6 +83,7 @@ ANDROID_BIN="${ANDROID_BIN:=$( which android )}"
PACKAGE_AS_PATH=$(echo $PACKAGE | sed 's/\./\//g')
ACTIVITY_PATH="$PROJECT_PATH"/src/$PACKAGE_AS_PATH/$ACTIVITY.java
MANIFEST_PATH="$PROJECT_PATH"/AndroidManifest.xml
+STRINGS_PATH="$PROJECT_PATH"/res/values/strings.xml
TARGET=$("$ANDROID_BIN" list targets | grep id: | tail -1 | cut -f 2 -d ' ' )
API_LEVEL=$("$ANDROID_BIN" list target | grep "API level:" | tail -n 1 | cut -f 2 -d ':' | tr -d ' ')
@@ -129,6 +131,9 @@ cp "$BUILD_PATH"/bin/templates/project/Activity.java "$ACTIVITY_PATH"
replace "s/__ACTIVITY__/${ACTIVITY}/g" "$ACTIVITY_PATH"
replace "s/__ID__/${PACKAGE}/g" "$ACTIVITY_PATH"
+# interpolate the app name into strings.xml
+replace "s/>${ACTIVITY}</>${APP_LABEL}</g" "$STRINGS_PATH"
+
cp "$BUILD_PATH"/bin/templates/project/AndroidManifest.xml "$MANIFEST_PATH"
replace "s/__ACTIVITY__/${ACTIVITY}/g" "$MANIFEST_PATH"
replace "s/__PACKAGE__/${PACKAGE}/g" "$MANIFEST_PATH"
[09/16] android commit: [CB-4198] bin/create script should be better
at handling non-word characters in activity name. Patched windows script as
well. (cherry picked from commit b4236b978355a599cad77a4d2a776354dbfdbe09)
Posted by ag...@apache.org.
[CB-4198] bin/create script should be better at handling non-word characters in activity name. Patched windows script as well.
(cherry picked from commit b4236b978355a599cad77a4d2a776354dbfdbe09)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/dc494c85
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/dc494c85
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/dc494c85
Branch: refs/heads/2.9.x
Commit: dc494c85f2620a28eccd49bf99fcc8f7d1e90eb3
Parents: 624a8d3
Author: Fil Maj <ma...@gmail.com>
Authored: Thu Jul 25 10:33:05 2013 -0700
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:12:11 2013 -0400
----------------------------------------------------------------------
bin/create | 2 +-
bin/create.js | 424 +++++++++++++++++++++++++++--------------------------
2 files changed, 215 insertions(+), 211 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/dc494c85/bin/create
----------------------------------------------------------------------
diff --git a/bin/create b/bin/create
index 3883227..7c4ddbc 100755
--- a/bin/create
+++ b/bin/create
@@ -38,7 +38,7 @@ VERSION=$(cat "$BUILD_PATH"/VERSION)
PROJECT_PATH="${1:-'./example'}"
PACKAGE=${2:-"org.apache.cordova.example"}
-ACTIVITY=$(echo ${3:-"cordovaExample"} | tr -d ' ')
+ACTIVITY=$(echo ${3:-"cordovaExample"} | tr -d '[:blank:][:punct:]')
APP_LABEL=${3:-"Cordova Example"};
# clobber any existing example
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/dc494c85/bin/create.js
----------------------------------------------------------------------
diff --git a/bin/create.js b/bin/create.js
index 1cb794f..c723b12 100644
--- a/bin/create.js
+++ b/bin/create.js
@@ -1,210 +1,214 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-
-/*
- * create a cordova/android project
- *
- * USAGE
- * ./create [path package activity]
- */
-
-var args = WScript.Arguments, PROJECT_PATH="example",
- PACKAGE="org.apache.cordova.example", ACTIVITY="cordovaExample",
- shell=WScript.CreateObject("WScript.Shell"),
- fso = WScript.CreateObject('Scripting.FileSystemObject');
-
-function Usage() {
- Log("Usage: create PathTONewProject [ PackageName AppName ]");
- Log(" PathTONewProject : The path to where you wish to create the project");
- Log(" PackageName : The package for the project (default is org.apache.cordova.example)")
- Log(" AppName : The name of the application/activity (default is cordovaExample)");
- Log("examples:");
- Log(" create C:\\Users\\anonymous\\Desktop\\MyProject");
- Log(" create C:\\Users\\anonymous\\Desktop\\MyProject io.Cordova.Example AnApp");
-}
-
-// logs messaged to stdout and stderr
-function Log(msg, error) {
- if (error) {
- WScript.StdErr.WriteLine(msg);
- }
- else {
- WScript.StdOut.WriteLine(msg);
- }
-}
-
-function read(filename) {
- var fso=WScript.CreateObject("Scripting.FileSystemObject");
- var f=fso.OpenTextFile(filename, 1);
- var s=f.ReadAll();
- f.Close();
- return s;
-}
-
-function checkTargets(targets) {
- if(!targets) {
- Log("You do not have any android targets setup. Please create at least one target with the `android` command", true);
- WScript.Quit(69);
- }
-}
-
-function setTarget() {
- var targets = shell.Exec('android.bat list targets').StdOut.ReadAll().match(/id:\s\d+/g);
- checkTargets(targets);
- return targets[targets.length - 1].replace(/id: /, ""); // TODO: give users the option to set their target
-}
-function setApiLevel() {
- var targets = shell.Exec('android.bat list targets').StdOut.ReadAll().match(/API level:\s\d+/g);
- checkTargets(targets);
- return targets[targets.length - 1].replace(/API level: /, "");
-}
-function write(filename, contents) {
- var fso=WScript.CreateObject("Scripting.FileSystemObject");
- var f=fso.OpenTextFile(filename, 2, true);
- f.Write(contents);
- f.Close();
-}
-function replaceInFile(filename, regexp, replacement) {
- write(filename, read(filename).replace(regexp, replacement));
-}
-function exec(command) {
- var oShell=shell.Exec(command);
- while (oShell.Status == 0) {
- if(!oShell.StdOut.AtEndOfStream) {
- var line = oShell.StdOut.ReadLine();
- // XXX: Change to verbose mode
- // WScript.StdOut.WriteLine(line);
- }
- WScript.sleep(100);
- }
-}
-
-function createAppInfoJar() {
- if(!fso.FileExists(ROOT+"\\bin\\templates\\cordova\\appinfo.jar")) {
- Log("Creating appinfo.jar...");
- var cur = shell.CurrentDirectory;
- shell.CurrentDirectory = ROOT+"\\bin\\templates\\cordova\\ApplicationInfo";
- exec("javac ApplicationInfo.java");
- exec("jar -cfe ..\\appinfo.jar ApplicationInfo ApplicationInfo.class");
- shell.CurrentDirectory = cur;
- }
-}
-
-// working dir
-var ROOT = WScript.ScriptFullName.split('\\bin\\create.js').join('');
-if (args.Count() > 0) {
- // support help flags
- if (args(0) == "--help" || args(0) == "/?" ||
- args(0) == "help" || args(0) == "-help" || args(0) == "/help" || args(0) == "-h") {
- Usage();
- WScript.Quit(2);
- }
-
- PROJECT_PATH=args(0);
- if (args.Count() > 1) {
- PACKAGE = args(1);
- }
- if (args.Count() > 2) {
- ACTIVITY = args(2);
- }
-}
-else {
- Log("Error : No project path provided.");
- Usage();
- WScript.Quit(2);
-}
-
-if(fso.FolderExists(PROJECT_PATH)) {
- Log("Project path already exists!", true);
- WScript.Quit(2);
-}
-
-var PACKAGE_AS_PATH=PACKAGE.replace(/\./g, '\\');
-var ACTIVITY_DIR=PROJECT_PATH + '\\src\\' + PACKAGE_AS_PATH;
-var ACTIVITY_PATH=ACTIVITY_DIR+'\\'+ACTIVITY+'.java';
-var MANIFEST_PATH=PROJECT_PATH+'\\AndroidManifest.xml';
-var TARGET=setTarget();
-var API_LEVEL=setApiLevel();
-var VERSION=read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
-// create the project
-Log("Creating new android project...");
-exec('android.bat create project --target "'+TARGET+'" --path "'+PROJECT_PATH+'" --package "'+PACKAGE+'" --activity "'+ACTIVITY+'"');
-
-// build from source. distro should have these files
-if (!fso.FileExists(ROOT+'\\cordova-'+VERSION+'.jar') &&
- !fso.FileExists(ROOT+'\\cordova.js')) {
- Log("Building jar and js files...");
- // update the cordova framework project to a target that exists on this machine
- exec('android.bat update project --target "'+TARGET+'" --path "'+ROOT+'\\framework"');
- exec('ant.bat -f "'+ ROOT +'\\framework\\build.xml" jar');
-}
-
-// copy in the project template
-Log("Copying template files...");
-exec('%comspec% /c xcopy "'+ ROOT + '\\bin\\templates\\project\\res" "'+PROJECT_PATH+'\\res\\" /E /Y');
-exec('%comspec% /c xcopy "'+ ROOT + '\\bin\\templates\\project\\assets" "'+PROJECT_PATH+'\\assets\\" /E /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\project\\AndroidManifest.xml" "' + PROJECT_PATH + '\\AndroidManifest.xml" /Y');
-exec('%comspec% /c mkdir "' + ACTIVITY_DIR + '"');
-exec('%comspec% /c copy "' + ROOT + '"\\bin\\templates\\project\\Activity.java "' + ACTIVITY_PATH + '" /Y');
-
-// check if we have the source or the distro files
-Log("Copying js, jar & config.xml files...");
-if(fso.FolderExists(ROOT + '\\framework')) {
- exec('%comspec% /c copy "'+ROOT+'\\framework\\assets\\www\\cordova.js" "'+PROJECT_PATH+'\\assets\\www\\cordova.js" /Y');
- exec('%comspec% /c copy "'+ROOT+'\\framework\\cordova-'+VERSION+'.jar" "'+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar" /Y');
- fso.CreateFolder(PROJECT_PATH + '\\res\\xml');
- exec('%comspec% /c copy "'+ROOT+'\\framework\\res\\xml\\config.xml" "' + PROJECT_PATH + '\\res\\xml\\config.xml" /Y');
-} else {
- // copy in cordova.js
- exec('%comspec% /c copy "'+ROOT+'\\cordova.js" "'+PROJECT_PATH+'\\assets\\www\\cordova.js" /Y');
- // copy in cordova.jar
- exec('%comspec% /c copy "'+ROOT+'\\cordova-'+VERSION+'.jar" "'+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar" /Y');
- // copy in xml
- fso.CreateFolder(PROJECT_PATH + '\\res\\xml');
- exec('%comspec% /c copy "'+ROOT+'\\xml\\config.xml" "' + PROJECT_PATH + '\\res\\xml\\config.xml" /Y');
-}
-
-// copy cordova scripts
-fso.CreateFolder(PROJECT_PATH + '\\cordova');
-fso.CreateFolder(PROJECT_PATH + '\\cordova\\lib');
-createAppInfoJar();
-Log("Copying cordova command tools...");
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\appinfo.jar" "' + PROJECT_PATH + '\\cordova\\appinfo.jar" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\cordova.js" "' + PROJECT_PATH + '\\cordova\\lib\\cordova.js" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\install-device.bat" "' + PROJECT_PATH + '\\cordova\\lib\\install-device.bat" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\install-emulator.bat" "' + PROJECT_PATH + '\\cordova\\lib\\install-emulator.bat" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\list-emulator-images.bat" "' + PROJECT_PATH + '\\cordova\\lib\\list-emulator-images.bat" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\list-devices.bat" "' + PROJECT_PATH + '\\cordova\\lib\\list-devices.bat" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\list-started-emulators.bat" "' + PROJECT_PATH + '\\cordova\\lib\\list-started-emulators.bat" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\start-emulator.bat" "' + PROJECT_PATH + '\\cordova\\lib\\start-emulator.bat" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\cordova.bat" "' + PROJECT_PATH + '\\cordova\\cordova.bat" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\clean.bat" "' + PROJECT_PATH + '\\cordova\\clean.bat" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\build.bat" "' + PROJECT_PATH + '\\cordova\\build.bat" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\log.bat" "' + PROJECT_PATH + '\\cordova\\log.bat" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\run.bat" "' + PROJECT_PATH + '\\cordova\\run.bat" /Y');
-exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\version.bat" "' + PROJECT_PATH + '\\cordova\\version.bat" /Y');
-
-// interpolate the activity name and package
-Log("Updating AndroidManifest.xml and Main Activity...");
-replaceInFile(ACTIVITY_PATH, /__ACTIVITY__/, ACTIVITY);
-replaceInFile(ACTIVITY_PATH, /__ID__/, PACKAGE);
-
-replaceInFile(MANIFEST_PATH, /__ACTIVITY__/, ACTIVITY);
-replaceInFile(MANIFEST_PATH, /__PACKAGE__/, PACKAGE);
-replaceInFile(MANIFEST_PATH, /__APILEVEL__/, API_LEVEL);
\ No newline at end of file
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+/*
+ * create a cordova/android project
+ *
+ * USAGE
+ * ./create [path package activity]
+ */
+
+var args = WScript.Arguments, PROJECT_PATH="example",
+ PACKAGE="org.apache.cordova.example", ACTIVITY="cordovaExample",
+ shell=WScript.CreateObject("WScript.Shell"),
+ fso = WScript.CreateObject('Scripting.FileSystemObject');
+
+function Usage() {
+ Log("Usage: create PathTONewProject [ PackageName AppName ]");
+ Log(" PathTONewProject : The path to where you wish to create the project");
+ Log(" PackageName : The package for the project (default is org.apache.cordova.example)")
+ Log(" AppName : The name of the application/activity (default is cordovaExample)");
+ Log("examples:");
+ Log(" create C:\\Users\\anonymous\\Desktop\\MyProject");
+ Log(" create C:\\Users\\anonymous\\Desktop\\MyProject io.Cordova.Example AnApp");
+}
+
+// logs messaged to stdout and stderr
+function Log(msg, error) {
+ if (error) {
+ WScript.StdErr.WriteLine(msg);
+ }
+ else {
+ WScript.StdOut.WriteLine(msg);
+ }
+}
+
+function read(filename) {
+ var fso=WScript.CreateObject("Scripting.FileSystemObject");
+ var f=fso.OpenTextFile(filename, 1);
+ var s=f.ReadAll();
+ f.Close();
+ return s;
+}
+
+function checkTargets(targets) {
+ if(!targets) {
+ Log("You do not have any android targets setup. Please create at least one target with the `android` command", true);
+ WScript.Quit(69);
+ }
+}
+
+function setTarget() {
+ var targets = shell.Exec('android.bat list targets').StdOut.ReadAll().match(/id:\s\d+/g);
+ checkTargets(targets);
+ return targets[targets.length - 1].replace(/id: /, ""); // TODO: give users the option to set their target
+}
+function setApiLevel() {
+ var targets = shell.Exec('android.bat list targets').StdOut.ReadAll().match(/API level:\s\d+/g);
+ checkTargets(targets);
+ return targets[targets.length - 1].replace(/API level: /, "");
+}
+function write(filename, contents) {
+ var fso=WScript.CreateObject("Scripting.FileSystemObject");
+ var f=fso.OpenTextFile(filename, 2, true);
+ f.Write(contents);
+ f.Close();
+}
+function replaceInFile(filename, regexp, replacement) {
+ write(filename, read(filename).replace(regexp, replacement));
+}
+function exec(command) {
+ var oShell=shell.Exec(command);
+ while (oShell.Status == 0) {
+ if(!oShell.StdOut.AtEndOfStream) {
+ var line = oShell.StdOut.ReadLine();
+ // XXX: Change to verbose mode
+ // WScript.StdOut.WriteLine(line);
+ }
+ WScript.sleep(100);
+ }
+}
+
+function createAppInfoJar() {
+ if(!fso.FileExists(ROOT+"\\bin\\templates\\cordova\\appinfo.jar")) {
+ Log("Creating appinfo.jar...");
+ var cur = shell.CurrentDirectory;
+ shell.CurrentDirectory = ROOT+"\\bin\\templates\\cordova\\ApplicationInfo";
+ exec("javac ApplicationInfo.java");
+ exec("jar -cfe ..\\appinfo.jar ApplicationInfo ApplicationInfo.class");
+ shell.CurrentDirectory = cur;
+ }
+}
+
+// working dir
+var ROOT = WScript.ScriptFullName.split('\\bin\\create.js').join('');
+if (args.Count() > 0) {
+ // support help flags
+ if (args(0) == "--help" || args(0) == "/?" ||
+ args(0) == "help" || args(0) == "-help" || args(0) == "/help" || args(0) == "-h") {
+ Usage();
+ WScript.Quit(2);
+ }
+
+ PROJECT_PATH=args(0);
+ if (args.Count() > 1) {
+ PACKAGE = args(1);
+ }
+ if (args.Count() > 2) {
+ ACTIVITY = args(2);
+ }
+}
+else {
+ Log("Error : No project path provided.");
+ Usage();
+ WScript.Quit(2);
+}
+
+if(fso.FolderExists(PROJECT_PATH)) {
+ Log("Project path already exists!", true);
+ WScript.Quit(2);
+}
+
+var PACKAGE_AS_PATH=PACKAGE.replace(/\./g, '\\');
+var ACTIVITY_DIR=PROJECT_PATH + '\\src\\' + PACKAGE_AS_PATH;
+var SAFE_ACTIVITY = ACTIVITY.replace(/\W/g, '');
+var ACTIVITY_PATH=ACTIVITY_DIR+'\\'+SAFE_ACTIVITY+'.java';
+var MANIFEST_PATH=PROJECT_PATH+'\\AndroidManifest.xml';
+var STRINGS_PATH=PROJECT_PATH+'\\res\\values\\strings.xml';
+var TARGET=setTarget();
+var API_LEVEL=setApiLevel();
+var VERSION=read(ROOT+'\\VERSION').replace(/\r\n/,'').replace(/\n/,'');
+// create the project
+Log("Creating new android project...");
+exec('android.bat create project --target "'+TARGET+'" --path "'+PROJECT_PATH+'" --package "'+PACKAGE+'" --activity "'+SAFE_ACTIVITY+'"');
+
+// build from source. distro should have these files
+if (!fso.FileExists(ROOT+'\\cordova-'+VERSION+'.jar') &&
+ !fso.FileExists(ROOT+'\\cordova.js')) {
+ Log("Building jar and js files...");
+ // update the cordova framework project to a target that exists on this machine
+ exec('android.bat update project --target "'+TARGET+'" --path "'+ROOT+'\\framework"');
+ exec('ant.bat -f "'+ ROOT +'\\framework\\build.xml" jar');
+}
+
+// copy in the project template
+Log("Copying template files...");
+exec('%comspec% /c xcopy "'+ ROOT + '\\bin\\templates\\project\\res" "'+PROJECT_PATH+'\\res\\" /E /Y');
+exec('%comspec% /c xcopy "'+ ROOT + '\\bin\\templates\\project\\assets" "'+PROJECT_PATH+'\\assets\\" /E /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\project\\AndroidManifest.xml" "' + PROJECT_PATH + '\\AndroidManifest.xml" /Y');
+exec('%comspec% /c mkdir "' + ACTIVITY_DIR + '"');
+exec('%comspec% /c copy "' + ROOT + '"\\bin\\templates\\project\\Activity.java "' + ACTIVITY_PATH + '" /Y');
+
+// check if we have the source or the distro files
+Log("Copying js, jar & config.xml files...");
+if(fso.FolderExists(ROOT + '\\framework')) {
+ exec('%comspec% /c copy "'+ROOT+'\\framework\\assets\\www\\cordova.js" "'+PROJECT_PATH+'\\assets\\www\\cordova.js" /Y');
+ exec('%comspec% /c copy "'+ROOT+'\\framework\\cordova-'+VERSION+'.jar" "'+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar" /Y');
+ fso.CreateFolder(PROJECT_PATH + '\\res\\xml');
+ exec('%comspec% /c copy "'+ROOT+'\\framework\\res\\xml\\config.xml" "' + PROJECT_PATH + '\\res\\xml\\config.xml" /Y');
+} else {
+ // copy in cordova.js
+ exec('%comspec% /c copy "'+ROOT+'\\cordova.js" "'+PROJECT_PATH+'\\assets\\www\\cordova.js" /Y');
+ // copy in cordova.jar
+ exec('%comspec% /c copy "'+ROOT+'\\cordova-'+VERSION+'.jar" "'+PROJECT_PATH+'\\libs\\cordova-'+VERSION+'.jar" /Y');
+ // copy in xml
+ fso.CreateFolder(PROJECT_PATH + '\\res\\xml');
+ exec('%comspec% /c copy "'+ROOT+'\\xml\\config.xml" "' + PROJECT_PATH + '\\res\\xml\\config.xml" /Y');
+}
+
+// copy cordova scripts
+fso.CreateFolder(PROJECT_PATH + '\\cordova');
+fso.CreateFolder(PROJECT_PATH + '\\cordova\\lib');
+createAppInfoJar();
+Log("Copying cordova command tools...");
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\appinfo.jar" "' + PROJECT_PATH + '\\cordova\\appinfo.jar" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\cordova.js" "' + PROJECT_PATH + '\\cordova\\lib\\cordova.js" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\install-device.bat" "' + PROJECT_PATH + '\\cordova\\lib\\install-device.bat" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\install-emulator.bat" "' + PROJECT_PATH + '\\cordova\\lib\\install-emulator.bat" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\list-emulator-images.bat" "' + PROJECT_PATH + '\\cordova\\lib\\list-emulator-images.bat" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\list-devices.bat" "' + PROJECT_PATH + '\\cordova\\lib\\list-devices.bat" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\list-started-emulators.bat" "' + PROJECT_PATH + '\\cordova\\lib\\list-started-emulators.bat" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\lib\\start-emulator.bat" "' + PROJECT_PATH + '\\cordova\\lib\\start-emulator.bat" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\cordova.bat" "' + PROJECT_PATH + '\\cordova\\cordova.bat" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\clean.bat" "' + PROJECT_PATH + '\\cordova\\clean.bat" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\build.bat" "' + PROJECT_PATH + '\\cordova\\build.bat" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\log.bat" "' + PROJECT_PATH + '\\cordova\\log.bat" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\run.bat" "' + PROJECT_PATH + '\\cordova\\run.bat" /Y');
+exec('%comspec% /c copy "'+ROOT+'\\bin\\templates\\cordova\\version.bat" "' + PROJECT_PATH + '\\cordova\\version.bat" /Y');
+
+// interpolate the activity name and package
+Log("Updating AndroidManifest.xml and Main Activity...");
+replaceInFile(ACTIVITY_PATH, /__ACTIVITY__/, ACTIVITY);
+replaceInFile(ACTIVITY_PATH, /__ID__/, PACKAGE);
+
+replaceInFile(MANIFEST_PATH, /__ACTIVITY__/, ACTIVITY);
+replaceInFile(MANIFEST_PATH, /__PACKAGE__/, PACKAGE);
+replaceInFile(MANIFEST_PATH, /__APILEVEL__/, API_LEVEL);
+
+replaceInFile(STRINGS_PATH, new RegExp('>' + SAFE_ACTIVITY + '<'), '>' + ACTIVITY + '<');
\ No newline at end of file
[05/16] android commit: Prevent NPE in case webview is lately
initialized (cherry picked from commit
a9ebf50b86bcb9de40cbf4013e98fd1a24be25e8)
Posted by ag...@apache.org.
Prevent NPE in case webview is lately initialized
(cherry picked from commit a9ebf50b86bcb9de40cbf4013e98fd1a24be25e8)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/dd770ef3
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/dd770ef3
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/dd770ef3
Branch: refs/heads/2.9.x
Commit: dd770ef303e8b484bfc83e8ac93d38b08f2d4ba3
Parents: 8b3fa5c
Author: denis <de...@orange.com>
Authored: Mon Jul 1 15:37:29 2013 +0800
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:09:51 2013 -0400
----------------------------------------------------------------------
framework/src/org/apache/cordova/CordovaActivity.java | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/dd770ef3/framework/src/org/apache/cordova/CordovaActivity.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaActivity.java b/framework/src/org/apache/cordova/CordovaActivity.java
index 95cb2f1..5c90316 100755
--- a/framework/src/org/apache/cordova/CordovaActivity.java
+++ b/framework/src/org/apache/cordova/CordovaActivity.java
@@ -858,8 +858,8 @@ public class CordovaActivity extends Activity implements CordovaInterface {
LOG.d(TAG, "Incoming Result");
super.onActivityResult(requestCode, resultCode, intent);
Log.d(TAG, "Request code = " + requestCode);
- ValueCallback<Uri> mUploadMessage = this.appView.getWebChromeClient().getValueCallback();
- if (requestCode == CordovaChromeClient.FILECHOOSER_RESULTCODE) {
+ if (appView != null && requestCode == CordovaChromeClient.FILECHOOSER_RESULTCODE) {
+ ValueCallback<Uri> mUploadMessage = this.appView.getWebChromeClient().getValueCallback();
Log.d(TAG, "did we get here?");
if (null == mUploadMessage)
return;
@@ -1079,9 +1079,7 @@ public class CordovaActivity extends Activity implements CordovaInterface {
@Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
- //Get whatever has focus!
- View childView = appView.getFocusedChild();
- if ((appView.isCustomViewShowing() || childView != null ) &&
+ if (appView != null && (appView.isCustomViewShowing() || appView.getFocusedChild() != null ) &&
(keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU)) {
return appView.onKeyUp(keyCode, event);
} else {
@@ -1099,10 +1097,8 @@ public class CordovaActivity extends Activity implements CordovaInterface {
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
- //Get whatever has focus!
- View childView = appView.getFocusedChild();
//Determine if the focus is on the current view or not
- if (childView != null && (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU)) {
+ if (appView != null && appView.getFocusedChild() != null && (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_MENU)) {
return appView.onKeyDown(keyCode, event);
}
else
[14/16] android commit: [CB-4495] Modify start-emulator script to
exit immediately on a fatal emulator error. (cherry picked from commit
121b74fa0c8b5c2aea25173d128b5745c3b85390)
Posted by ag...@apache.org.
[CB-4495] Modify start-emulator script to exit immediately on a fatal emulator error.
(cherry picked from commit 121b74fa0c8b5c2aea25173d128b5745c3b85390)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/bb7bc33a
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/bb7bc33a
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/bb7bc33a
Branch: refs/heads/2.9.x
Commit: bb7bc33a8ab2a12bcd5540b4b6420b47a9ee76c9
Parents: 64c617d
Author: Tomaz Muraus <to...@tomaz.me>
Authored: Sat Aug 3 02:52:48 2013 +0200
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:15:58 2013 -0400
----------------------------------------------------------------------
bin/templates/cordova/lib/start-emulator | 30 ++++++++++++++++++++++-----
1 file changed, 25 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/bb7bc33a/bin/templates/cordova/lib/start-emulator
----------------------------------------------------------------------
diff --git a/bin/templates/cordova/lib/start-emulator b/bin/templates/cordova/lib/start-emulator
index 10e73ce..c7ce01a 100755
--- a/bin/templates/cordova/lib/start-emulator
+++ b/bin/templates/cordova/lib/start-emulator
@@ -24,7 +24,24 @@ function dot {
echo -n "."
}
-function wait_for_emulator {
+function wait_for_emulator() {
+ local emulator_log_path="$1"
+ local error_string
+ local status
+
+ # Try to detect fatal errors early
+ sleep 1.5
+ error_string=$(grep -F "ERROR: " ${emulator_log_path})
+ status=$?
+
+ if [ $status -eq 0 ]; then
+ echo "Emulator failed to start, fatal error detected"
+ echo "Error: ${error_string}"
+ echo "Full log available at: ${emulator_log_path}"
+ echo "Exiting..."
+ exit 1
+ fi
+
local i="0"
echo -n "Waiting for emulator"
emulator_string=$($DIR/list-started-emulators)
@@ -70,22 +87,25 @@ if [ $? != 0 ]; then
exit 2
fi
+# start first emulator
+log_path=$(mktemp -t android_emulator)
+
# if target emulator is provided
if [[ "$#" -eq 1 ]] ; then
# check that it exists
if [[ $emulator_images =~ $1 ]] ; then
#xterm -e emulator -avd $1 &
- emulator -avd $1 1> /dev/null 2>&1 &
+ emulator -avd $1 1> "${log_path}" 2>&1 &
else
echo "Could not find the provided emulator '$1', make sure the emulator exists"
echo " by checking 'cordova/lib/list-emulator-images'"
exit 2
fi
else
- # start first emulator
read -ra emulator_list <<< "$emulator_images"
#xterm -e emulator -avd ${emulator_list[0]} &
- emulator -avd ${emulator_list[0]} 1> /dev/null 2>&1 &
+ emulator -avd ${emulator_list[0]} 1> "${log_path}" 2>&1 &
fi
-wait_for_emulator
+echo "Saving emulator log to: ${log_path}"
+wait_for_emulator "$log_path"
[02/16] android commit: Let subclasses override focus behavior
Posted by ag...@apache.org.
Let subclasses override focus behavior
Signed-off-by: Joe Bowser <bo...@apache.org>
(cherry picked from commit 55865a4f1dcd0f24df5292e3621b77080939e6e1)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/4be84fbf
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/4be84fbf
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/4be84fbf
Branch: refs/heads/2.9.x
Commit: 4be84fbf124639525f4d1308e29619e28096e620
Parents: e9b46e5
Author: denis <de...@orange.com>
Authored: Mon Jul 1 16:28:22 2013 +0800
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:04:52 2013 -0400
----------------------------------------------------------------------
.../src/org/apache/cordova/CordovaWebView.java | 21 +++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/4be84fbf/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java
index 278bfa4..648b1f8 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -228,9 +228,10 @@ public class CordovaWebView extends WebView {
private void setup() {
this.setInitialScale(0);
this.setVerticalScrollBarEnabled(false);
- this.requestFocusFromTouch();
-
- // Enable JavaScript
+ if (shouldRequestFocusOnInit()) {
+ this.requestFocusFromTouch();
+ }
+ // Enable JavaScript
WebSettings settings = this.getSettings();
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
@@ -308,8 +309,18 @@ public class CordovaWebView extends WebView {
exposedJsApi = new ExposedJsApi(pluginManager, jsMessageQueue);
exposeJsInterface();
}
-
- private void updateUserAgentString() {
+
+ /**
+ * Override this method to decide wether or not you need to request the
+ * focus when your application start
+ *
+ * @return
+ */
+ protected boolean shouldRequestFocusOnInit() {
+ return true;
+ }
+
+ private void updateUserAgentString() {
this.getSettings().getUserAgentString();
}
[12/16] android commit: Fix data URI decoding in CordovaResourceApi
Posted by ag...@apache.org.
Fix data URI decoding in CordovaResourceApi
It was not URI-decoding first, and so was broken for non-base64-encoded
URIs.
(cherry picked from commit 4e1aa8aa59d0a3d9c0deb1f57c9136a76535691e)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/bcccb0c6
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/bcccb0c6
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/bcccb0c6
Branch: refs/heads/2.9.x
Commit: bcccb0c62058eb8bcbb0a54f156979945631807f
Parents: e1de55c
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Aug 13 14:08:30 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:14:36 2013 -0400
----------------------------------------------------------------------
framework/src/org/apache/cordova/CordovaResourceApi.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/bcccb0c6/framework/src/org/apache/cordova/CordovaResourceApi.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaResourceApi.java b/framework/src/org/apache/cordova/CordovaResourceApi.java
index cb85744..f03f1b5 100644
--- a/framework/src/org/apache/cordova/CordovaResourceApi.java
+++ b/framework/src/org/apache/cordova/CordovaResourceApi.java
@@ -315,7 +315,7 @@ public class CordovaResourceApi {
}
private OpenForReadResult readDataUri(Uri uri) {
- String uriAsString = uri.toString().substring(5);
+ String uriAsString = uri.getSchemeSpecificPart();
int commaPos = uriAsString.indexOf(',');
if (commaPos == -1) {
return null;
[16/16] android commit: CB-5080 Find resources in a way that works
with aapt's --rename-manifest-package (cherry picked from commit
16de12a3ba3c0ed8cfa15e9c9d7d68d384d178bb)
Posted by ag...@apache.org.
CB-5080 Find resources in a way that works with aapt's --rename-manifest-package
(cherry picked from commit 16de12a3ba3c0ed8cfa15e9c9d7d68d384d178bb)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/93b9b53a
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/93b9b53a
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/93b9b53a
Branch: refs/heads/2.9.x
Commit: 93b9b53acbf333f3cb8ba61bad732a2b9cf4d765
Parents: edb35b5
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Oct 15 12:17:14 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:18:44 2013 -0400
----------------------------------------------------------------------
framework/src/org/apache/cordova/Config.java | 4 ++--
framework/src/org/apache/cordova/PluginManager.java | 7 +------
2 files changed, 3 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/93b9b53a/framework/src/org/apache/cordova/Config.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/Config.java b/framework/src/org/apache/cordova/Config.java
index 3ef35a5..76eda1b 100644
--- a/framework/src/org/apache/cordova/Config.java
+++ b/framework/src/org/apache/cordova/Config.java
@@ -72,7 +72,7 @@ public class Config {
return;
}
- int id = action.getResources().getIdentifier("config", "xml", action.getPackageName());
+ int id = action.getResources().getIdentifier("config", "xml", action.getClass().getPackage().getName());
if (id == 0) {
id = action.getResources().getIdentifier("cordova", "xml", action.getPackageName());
LOG.i("CordovaLog", "config.xml missing, reverting to cordova.xml");
@@ -123,7 +123,7 @@ public class Config {
{
value = "splash";
}
- resource = action.getResources().getIdentifier(value, "drawable", action.getPackageName());
+ resource = action.getResources().getIdentifier(value, "drawable", action.getClass().getPackage().getName());
action.getIntent().putExtra(name, resource);
}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/93b9b53a/framework/src/org/apache/cordova/PluginManager.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/PluginManager.java b/framework/src/org/apache/cordova/PluginManager.java
index 2db9d56..5249f50 100755
--- a/framework/src/org/apache/cordova/PluginManager.java
+++ b/framework/src/org/apache/cordova/PluginManager.java
@@ -107,12 +107,7 @@ public class PluginManager {
* Load plugins from res/xml/config.xml
*/
public void loadPlugins() {
- int id = this.ctx.getActivity().getResources().getIdentifier("config", "xml", this.ctx.getActivity().getPackageName());
- if(id == 0)
- {
- id = this.ctx.getActivity().getResources().getIdentifier("plugins", "xml", this.ctx.getActivity().getPackageName());
- LOG.i(TAG, "Using plugins.xml instead of config.xml. plugins.xml will eventually be deprecated");
- }
+ int id = this.ctx.getActivity().getResources().getIdentifier("config", "xml", this.ctx.getActivity().getClass().getPackage().getName());
if (id == 0) {
this.pluginConfigurationMissing();
//We have the error, we need to exit without crashing!
[11/16] android commit: [CB-4466] fixed jscript check_reqs to get
target from project.properties (cherry picked from commit
53b8da81985464b82d87e1655e6561f2076b4206)
Posted by ag...@apache.org.
[CB-4466] fixed jscript check_reqs to get target from project.properties
(cherry picked from commit 53b8da81985464b82d87e1655e6561f2076b4206)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/e1de55cc
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/e1de55cc
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/e1de55cc
Branch: refs/heads/2.9.x
Commit: e1de55cc82c050911d36b1ccd12cf6e499df8edb
Parents: 4b501a5
Author: Benn Mapes <be...@gmail.com>
Authored: Thu Aug 1 17:57:58 2013 -0700
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:14:09 2013 -0400
----------------------------------------------------------------------
bin/check_reqs.js | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/e1de55cc/bin/check_reqs.js
----------------------------------------------------------------------
diff --git a/bin/check_reqs.js b/bin/check_reqs.js
index 7fc32b8..4a724a6 100644
--- a/bin/check_reqs.js
+++ b/bin/check_reqs.js
@@ -54,22 +54,28 @@ function Log(msg, error) {
else {
WScript.StdOut.WriteLine(msg);
}
-}
+}
// checks that android requirements are met
function check_requirements() {
+ var target = get_target();
+ if(target==null) {
+ Log('Unable to find android target in project.properties');
+ WScript.Quit(2);
+ }
var result = exec_out('%comspec% /c android list target');
if(result.error) {
Log('The command `android` failed. Make sure you have the latest Android SDK installed, and the `android` command (inside the tools/ folder) added to your path. Output: ' + result.output, true);
WScript.Quit(2);
}
- else if(!result.output.match(/android[-]18/)) {
- Log('Please install Android target 18 (the Android 4.3 SDK). Make sure you have the latest Android tools installed as well. Run `android` from your command-line to install/update any missing SDKs or tools.', true);
- Log('Output : ' + result.output);
+ else if(result.output.indexOf(target) == -1) {
+ Log(result.output.indexOf(target));
+ Log('Please install the latest Android target (' + target + '). Make sure you have the latest Android tools installed as well. Run `android` from your command-line to install/update any missing SDKs or tools.', true);
+ Log(result.output);
WScript.Quit(2);
}
else {
- var cmd = '%comspec% /c android update project -p ' + ROOT + '\\framework -t android-18';
+ var cmd = '%comspec% /c android update project -p ' + ROOT + '\\framework -t ' + target;
result = exec_out(cmd);
if(result.error) {
Log('Error updating the Cordova library to work with your Android environment. Command run: "' + cmd + '", output: ' + result.output, true);
@@ -78,4 +84,19 @@ function check_requirements() {
}
}
+function get_target() {
+ var fso=WScript.CreateObject("Scripting.FileSystemObject");
+ var f=fso.OpenTextFile(ROOT + '\\framework\\project.properties', 1);
+ var s=f.ReadAll();
+ var lines = s.split('\n');
+ for (var line in lines) {
+ if(lines[line].match(/target=/))
+ {
+ return lines[line].split('=')[1].replace(' ', '').replace('\r', '');
+ }
+ }
+ return null;
+}
+
check_requirements();
+
[04/16] android commit: [CB-3384] Reworked UriResolver into
CordovaResourceApi.
Posted by ag...@apache.org.
[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.
(cherry picked from commit 77e9092108b4997abdc08afa630b8c16ee094f90)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/8b3fa5c9
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/8b3fa5c9
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/8b3fa5c9
Branch: refs/heads/2.9.x
Commit: 8b3fa5c91e28e8bdd8a1b3ada0f95f4da5052497
Parents: 43bf47e
Author: Andrew Grieve <ag...@chromium.org>
Authored: Sun Jul 14 21:39:55 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:09:15 2013 -0400
----------------------------------------------------------------------
.../src/org/apache/cordova/CordovaPlugin.java | 8 +-
.../org/apache/cordova/CordovaResourceApi.java | 347 +++++++++++++++++++
.../src/org/apache/cordova/CordovaWebView.java | 37 +-
.../apache/cordova/CordovaWebViewClient.java | 2 +-
.../cordova/IceCreamCordovaWebViewClient.java | 61 ++--
.../src/org/apache/cordova/PluginManager.java | 6 +-
.../src/org/apache/cordova/UriResolver.java | 69 ----
.../src/org/apache/cordova/UriResolvers.java | 341 ------------------
test/AndroidManifest.xml | 2 +-
.../apache/cordova/test/UriResolversTest.java | 263 --------------
10 files changed, 393 insertions(+), 743 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/8b3fa5c9/framework/src/org/apache/cordova/CordovaPlugin.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaPlugin.java b/framework/src/org/apache/cordova/CordovaPlugin.java
index 22c8703..e947fcc 100644
--- a/framework/src/org/apache/cordova/CordovaPlugin.java
+++ b/framework/src/org/apache/cordova/CordovaPlugin.java
@@ -22,7 +22,6 @@ import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.api.CordovaInterface;
import org.apache.cordova.api.CallbackContext;
-import org.apache.cordova.UriResolver;
import org.json.JSONArray;
import org.json.JSONException;
@@ -165,13 +164,12 @@ public class CordovaPlugin {
}
/**
- * Hook for overriding the default URI handling mechanism.
- * Applies to WebView requests as well as requests made by plugins.
+ * Hook for redirecting requests. Applies to WebView requests as well as requests made by plugins.
*/
- public UriResolver resolveUri(Uri uri) {
+ public Uri remapUri(Uri uri) {
return null;
}
-
+
/**
* Called when the WebView does a top-level navigation or refreshes.
*
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/8b3fa5c9/framework/src/org/apache/cordova/CordovaResourceApi.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaResourceApi.java b/framework/src/org/apache/cordova/CordovaResourceApi.java
new file mode 100644
index 0000000..b891b51
--- /dev/null
+++ b/framework/src/org/apache/cordova/CordovaResourceApi.java
@@ -0,0 +1,347 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+ */
+package org.apache.cordova;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Looper;
+import android.util.Base64;
+import android.util.Base64InputStream;
+
+import com.squareup.okhttp.OkHttpClient;
+
+import org.apache.http.util.EncodingUtils;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.nio.channels.FileChannel;
+
+public class CordovaResourceApi {
+ @SuppressWarnings("unused")
+ private static final String LOG_TAG = "CordovaResourceApi";
+
+ public static final int URI_TYPE_FILE = 0;
+ public static final int URI_TYPE_ASSET = 1;
+ public static final int URI_TYPE_CONTENT = 2;
+ public static final int URI_TYPE_RESOURCE = 3;
+ public static final int URI_TYPE_DATA = 4;
+ public static final int URI_TYPE_HTTP = 5;
+ public static final int URI_TYPE_HTTPS = 6;
+ public static final int URI_TYPE_UNKNOWN = -1;
+
+ private static final String[] LOCAL_FILE_PROJECTION = { "_data" };
+
+ // Creating this is light-weight.
+ private static OkHttpClient httpClient = new OkHttpClient();
+
+ static Thread webCoreThread;
+
+ private final AssetManager assetManager;
+ private final ContentResolver contentResolver;
+ private final PluginManager pluginManager;
+ private boolean threadCheckingEnabled = true;
+
+
+ public CordovaResourceApi(Context context, PluginManager pluginManager) {
+ this.contentResolver = context.getContentResolver();
+ this.assetManager = context.getAssets();
+ this.pluginManager = pluginManager;
+ }
+
+ public void setThreadCheckingEnabled(boolean value) {
+ threadCheckingEnabled = value;
+ }
+
+ public boolean isThreadCheckingEnabled() {
+ return threadCheckingEnabled;
+ }
+
+ public static int getUriType(Uri uri) {
+ assertNonRelative(uri);
+ String scheme = uri.getScheme();
+ if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
+ return URI_TYPE_CONTENT;
+ }
+ if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {
+ return URI_TYPE_RESOURCE;
+ }
+ if (ContentResolver.SCHEME_FILE.equals(scheme)) {
+ if (uri.getPath().startsWith("/android_asset/")) {
+ return URI_TYPE_ASSET;
+ }
+ return URI_TYPE_FILE;
+ }
+ if ("data".equals(scheme)) {
+ return URI_TYPE_DATA;
+ }
+ if ("http".equals(scheme)) {
+ return URI_TYPE_HTTP;
+ }
+ if ("https".equals(scheme)) {
+ return URI_TYPE_HTTPS;
+ }
+ return URI_TYPE_UNKNOWN;
+ }
+
+ public Uri remapUri(Uri uri) {
+ assertNonRelative(uri);
+ Uri pluginUri = pluginManager.remapUri(uri);
+ return pluginUri != null ? pluginUri : uri;
+ }
+
+ public String remapPath(String path) {
+ return remapUri(Uri.fromFile(new File(path))).getPath();
+ }
+
+ /**
+ * Returns a File that points to the resource, or null if the resource
+ * is not on the local filesystem.
+ */
+ public File mapUriToFile(Uri uri) {
+ assertBackgroundThread();
+ switch (getUriType(uri)) {
+ case URI_TYPE_FILE:
+ return new File(uri.getPath());
+ case URI_TYPE_CONTENT: {
+ Cursor cursor = contentResolver.query(uri, LOCAL_FILE_PROJECTION, null, null, null);
+ if (cursor != null) {
+ try {
+ int columnIndex = cursor.getColumnIndex(LOCAL_FILE_PROJECTION[0]);
+ if (columnIndex != -1 && cursor.getCount() > 0) {
+ cursor.moveToFirst();
+ String realPath = cursor.getString(columnIndex);
+ if (realPath != null) {
+ return new File(realPath);
+ }
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Opens a stream to the givne URI, also providing the MIME type & length.
+ * @return Never returns null.
+ * @throws Throws an InvalidArgumentException for relative URIs. Relative URIs should be
+ * resolved before being passed into this function.
+ * @throws Throws an IOException if the URI cannot be opened.
+ */
+ public OpenForReadResult openForRead(Uri uri) throws IOException {
+ assertBackgroundThread();
+ switch (getUriType(uri)) {
+ case URI_TYPE_FILE: {
+ FileInputStream inputStream = new FileInputStream(uri.getPath());
+ String mimeType = FileHelper.getMimeTypeForExtension(uri.getPath());
+ long length = inputStream.getChannel().size();
+ return new OpenForReadResult(uri, inputStream, mimeType, length, null);
+ }
+ case URI_TYPE_ASSET: {
+ String assetPath = uri.getPath().substring(15);
+ AssetFileDescriptor assetFd = null;
+ InputStream inputStream;
+ long length = -1;
+ try {
+ assetFd = assetManager.openFd(assetPath);
+ inputStream = assetFd.createInputStream();
+ length = assetFd.getLength();
+ } catch (FileNotFoundException e) {
+ // Will occur if the file is compressed.
+ inputStream = assetManager.open(assetPath);
+ }
+ String mimeType = FileHelper.getMimeTypeForExtension(assetPath);
+ return new OpenForReadResult(uri, inputStream, mimeType, length, assetFd);
+ }
+ case URI_TYPE_CONTENT:
+ case URI_TYPE_RESOURCE: {
+ String mimeType = contentResolver.getType(uri);
+ AssetFileDescriptor assetFd = contentResolver.openAssetFileDescriptor(uri, "r");
+ InputStream inputStream = assetFd.createInputStream();
+ long length = assetFd.getLength();
+ return new OpenForReadResult(uri, inputStream, mimeType, length, assetFd);
+ }
+ case URI_TYPE_DATA: {
+ OpenForReadResult ret = readDataUri(uri);
+ if (ret == null) {
+ break;
+ }
+ return ret;
+ }
+ case URI_TYPE_HTTP:
+ case URI_TYPE_HTTPS: {
+ HttpURLConnection conn = httpClient.open(new URL(uri.toString()));
+ conn.setDoInput(true);
+ String mimeType = conn.getHeaderField("Content-Type");
+ int length = conn.getContentLength();
+ InputStream inputStream = conn.getInputStream();
+ return new OpenForReadResult(uri, inputStream, mimeType, length, null);
+ }
+ }
+ throw new FileNotFoundException("URI not supported by CordovaResourceApi: " + uri);
+ }
+
+ public OutputStream openOutputStream(Uri uri) throws IOException {
+ return openOutputStream(uri, false);
+ }
+
+ /**
+ * Opens a stream to the given URI.
+ * @return Never returns null.
+ * @throws Throws an InvalidArgumentException for relative URIs. Relative URIs should be
+ * resolved before being passed into this function.
+ * @throws Throws an IOException if the URI cannot be opened.
+ */
+ public OutputStream openOutputStream(Uri uri, boolean append) throws IOException {
+ assertBackgroundThread();
+ switch (getUriType(uri)) {
+ case URI_TYPE_FILE: {
+ File localFile = new File(uri.getPath());
+ File parent = localFile.getParentFile();
+ if (parent != null) {
+ parent.mkdirs();
+ }
+ return new FileOutputStream(localFile, append);
+ }
+ case URI_TYPE_CONTENT:
+ case URI_TYPE_RESOURCE: {
+ AssetFileDescriptor assetFd = contentResolver.openAssetFileDescriptor(uri, append ? "wa" : "w");
+ return assetFd.createOutputStream();
+ }
+ }
+ throw new FileNotFoundException("URI not supported by CordovaResourceApi: " + uri);
+ }
+
+ public HttpURLConnection createHttpConnection(Uri uri) throws IOException {
+ assertBackgroundThread();
+ return httpClient.open(new URL(uri.toString()));
+ }
+
+ // Copies the input to the output in the most efficient manner possible.
+ // Closes both streams.
+ public void copyResource(OpenForReadResult input, OutputStream outputStream) throws IOException {
+ assertBackgroundThread();
+ try {
+ InputStream inputStream = input.inputStream;
+ if (inputStream instanceof FileInputStream && outputStream instanceof FileOutputStream) {
+ FileChannel inChannel = ((FileInputStream)input.inputStream).getChannel();
+ FileChannel outChannel = ((FileOutputStream)outputStream).getChannel();
+ long offset = 0;
+ long length = input.length;
+ if (input.assetFd != null) {
+ offset = input.assetFd.getStartOffset();
+ }
+ outChannel.transferFrom(inChannel, offset, length);
+ } else {
+ final int BUFFER_SIZE = 8192;
+ byte[] buffer = new byte[BUFFER_SIZE];
+
+ for (;;) {
+ int bytesRead = inputStream.read(buffer, 0, BUFFER_SIZE);
+
+ if (bytesRead <= 0) {
+ break;
+ }
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ }
+ } finally {
+ input.inputStream.close();
+ if (outputStream != null) {
+ outputStream.close();
+ }
+ }
+ }
+
+ public void copyResource(Uri sourceUri, OutputStream outputStream) throws IOException {
+ copyResource(openForRead(sourceUri), outputStream);
+ }
+
+
+ private void assertBackgroundThread() {
+ if (threadCheckingEnabled) {
+ Thread curThread = Thread.currentThread();
+ if (curThread == Looper.getMainLooper().getThread()) {
+ throw new IllegalStateException("Do not perform IO operations on the UI thread. Use CordovaInterface.getThreadPool() instead.");
+ }
+ if (curThread == webCoreThread) {
+ throw new IllegalStateException("Tried to perform an IO operation on the WebCore thread. Use CordovaInterface.getThreadPool() instead.");
+ }
+ }
+ }
+
+ private OpenForReadResult readDataUri(Uri uri) {
+ String uriAsString = uri.toString().substring(5);
+ int commaPos = uriAsString.indexOf(',');
+ if (commaPos == -1) {
+ return null;
+ }
+ String[] mimeParts = uriAsString.substring(0, commaPos).split(";");
+ String contentType = null;
+ boolean base64 = false;
+ if (mimeParts.length > 0) {
+ contentType = mimeParts[0];
+ }
+ for (int i = 1; i < mimeParts.length; ++i) {
+ if ("base64".equalsIgnoreCase(mimeParts[i])) {
+ base64 = true;
+ }
+ }
+ String dataPartAsString = uriAsString.substring(commaPos + 1);
+ byte[] data = base64 ? Base64.decode(dataPartAsString, Base64.DEFAULT) : EncodingUtils.getBytes(dataPartAsString, "UTF-8");
+ InputStream inputStream = new ByteArrayInputStream(data);
+ return new OpenForReadResult(uri, inputStream, contentType, data.length, null);
+ }
+
+ private static void assertNonRelative(Uri uri) {
+ if (!uri.isAbsolute()) {
+ throw new IllegalArgumentException("Relative URIs are not supported.");
+ }
+ }
+
+ public static final class OpenForReadResult {
+ public final Uri uri;
+ public final InputStream inputStream;
+ public final String mimeType;
+ public final long length;
+ public final AssetFileDescriptor assetFd;
+
+ OpenForReadResult(Uri uri, InputStream inputStream, String mimeType, long length, AssetFileDescriptor assetFd) {
+ this.uri = uri;
+ this.inputStream = inputStream;
+ this.mimeType = mimeType;
+ this.length = length;
+ this.assetFd = assetFd;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/8b3fa5c9/framework/src/org/apache/cordova/CordovaWebView.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java
index 648b1f8..b97b03e 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -97,6 +97,8 @@ public class CordovaWebView extends WebView {
private ActivityResult mResult = null;
+ private CordovaResourceApi resourceApi;
+
class ActivityResult {
int request;
@@ -307,6 +309,7 @@ public class CordovaWebView extends WebView {
pluginManager = new PluginManager(this, this.cordova);
jsMessageQueue = new NativeToJsMessageQueue(this, cordova);
exposedJsApi = new ExposedJsApi(pluginManager, jsMessageQueue);
+ resourceApi = new CordovaResourceApi(this.getContext(), pluginManager);
exposeJsInterface();
}
@@ -957,37 +960,7 @@ public class CordovaWebView extends WebView {
mResult = new ActivityResult(requestCode, resultCode, intent);
}
- /**
- * Resolves the given URI, giving plugins a chance to re-route or customly handle the URI.
- * A white-list rejection will be returned if the URI does not pass the white-list.
- * @return Never returns null.
- * @throws Throws an InvalidArgumentException for relative URIs. Relative URIs should be
- * resolved before being passed into this function.
- */
- public UriResolver resolveUri(Uri uri) {
- return resolveUri(uri, false);
- }
-
- UriResolver resolveUri(Uri uri, boolean fromWebView) {
- if (!uri.isAbsolute()) {
- throw new IllegalArgumentException("Relative URIs are not yet supported by resolveUri.");
- }
- UriResolver ret = null;
- // Check the against the white-list before delegating to plugins.
- if (("http".equals(uri.getScheme()) || "https".equals(uri.getScheme())) && !Config.isUrlWhiteListed(uri.toString()))
- {
- LOG.w(TAG, "resolveUri - URL is not in whitelist: " + uri);
- ret = UriResolvers.createError("Whitelist rejection for: " + uri);
- } else {
- // Give plugins a chance to handle the request.
- ret = ((org.apache.cordova.PluginManager)pluginManager).resolveUri(uri);
- }
- if (ret == null && !fromWebView) {
- ret = UriResolvers.forUri(uri, cordova.getActivity());
- if (ret == null) {
- ret = UriResolvers.createError("Unresolvable URI: " + uri);
- }
- }
- return ret == null ? null : UriResolvers.makeThreadChecking(ret);
+ public CordovaResourceApi getResourceApi() {
+ return resourceApi;
}
}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/8b3fa5c9/framework/src/org/apache/cordova/CordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaWebViewClient.java b/framework/src/org/apache/cordova/CordovaWebViewClient.java
index c49611e..d782aa0 100755
--- a/framework/src/org/apache/cordova/CordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/CordovaWebViewClient.java
@@ -48,7 +48,7 @@ import android.webkit.WebViewClient;
*/
public class CordovaWebViewClient extends WebViewClient {
- private static final String TAG = "Cordova";
+ private static final String TAG = "CordovaWebViewClient";
private static final String CORDOVA_EXEC_URL_PREFIX = "http://cdv_exec/";
CordovaInterface cordova;
CordovaWebView appView;
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/8b3fa5c9/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
index c23d580..317acc2 100644
--- a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
@@ -19,20 +19,22 @@
package org.apache.cordova;
import java.io.IOException;
-import java.io.InputStream;
+import org.apache.cordova.CordovaResourceApi.OpenForReadResult;
import org.apache.cordova.api.CordovaInterface;
import org.apache.cordova.api.LOG;
import android.annotation.TargetApi;
import android.net.Uri;
import android.os.Build;
+import android.util.Log;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
+ private static final String TAG = "IceCreamCordovaWebViewClient";
public IceCreamCordovaWebViewClient(CordovaInterface cordova) {
super(cordova);
@@ -44,38 +46,44 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
- // Disable checks during shouldInterceptRequest since there is no way to avoid IO here :(.
- UriResolvers.webCoreThread = null;
+ // Tell the Thread-Checking resolve what thread the WebCore thread is.
+ CordovaResourceApi.webCoreThread = Thread.currentThread();
+ Log.e("WHAAAA", "FOOD " + CordovaResourceApi.webCoreThread);
try {
- UriResolver uriResolver = appView.resolveUri(Uri.parse(url), true);
-
- if (uriResolver == null && url.startsWith("file:///android_asset/")) {
- if (url.contains("?") || url.contains("#") || needsIceCreamSpecialsInAssetUrlFix(url)) {
- uriResolver = appView.resolveUri(Uri.parse(url), false);
- }
+ // Check the against the white-list.
+ if ((url.startsWith("http:") || url.startsWith("https:")) && !Config.isUrlWhiteListed(url)) {
+ LOG.w(TAG, "URL blocked by whitelist: " + url);
+ // Results in a 404.
+ return new WebResourceResponse("text/plain", "UTF-8", null);
}
+
+ CordovaResourceApi resourceApi = appView.getResourceApi();
+ Uri origUri = Uri.parse(url);
+ // Allow plugins to intercept WebView requests.
+ Uri remappedUri = resourceApi.remapUri(origUri);
- if (uriResolver != null) {
- try {
- InputStream stream = uriResolver.getInputStream();
- String mimeType = uriResolver.getMimeType();
- // If we don't know how to open this file, let the browser continue loading
- return new WebResourceResponse(mimeType, "UTF-8", stream);
- } catch (IOException e) {
- LOG.e("IceCreamCordovaWebViewClient", "Error occurred while loading a file.", e);
- // Results in a 404.
- return new WebResourceResponse("text/plain", "UTF-8", null);
- }
+ if (!origUri.equals(remappedUri) || needsSpecialsInAssetUrlFix(origUri)) {
+ OpenForReadResult result = resourceApi.openForRead(remappedUri);
+ return new WebResourceResponse(result.mimeType, "UTF-8", result.inputStream);
}
+ // If we don't need to special-case the request, let the browser load it.
return null;
- } finally {
- // Tell the Thread-Checking resolve what thread the WebCore thread is.
- UriResolvers.webCoreThread = Thread.currentThread();
+ } catch (IOException e) {
+ LOG.e("IceCreamCordovaWebViewClient", "Error occurred while loading a file.", e);
+ // Results in a 404.
+ return new WebResourceResponse("text/plain", "UTF-8", null);
}
}
+
+ private static boolean needsSpecialsInAssetUrlFix(Uri uri) {
+ if (CordovaResourceApi.getUriType(uri) != CordovaResourceApi.URI_TYPE_ASSET) {
+ return false;
+ }
+ if (uri.getQuery() != null || uri.getFragment() != null) {
+ return true;
+ }
- private static boolean needsIceCreamSpecialsInAssetUrlFix(String url) {
- if (!url.contains("%20")){
+ if (!uri.toString().contains("%")) {
return false;
}
@@ -83,8 +91,7 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
case android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH:
case android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1:
return true;
- default:
- return false;
}
+ return false;
}
}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/8b3fa5c9/framework/src/org/apache/cordova/PluginManager.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/PluginManager.java b/framework/src/org/apache/cordova/PluginManager.java
index 1f32ba6..2db9d56 100755
--- a/framework/src/org/apache/cordova/PluginManager.java
+++ b/framework/src/org/apache/cordova/PluginManager.java
@@ -26,7 +26,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.CordovaWebView;
-import org.apache.cordova.UriResolver;
import org.apache.cordova.api.CallbackContext;
import org.apache.cordova.api.CordovaInterface;
import org.apache.cordova.api.CordovaPlugin;
@@ -40,7 +39,6 @@ import android.content.res.XmlResourceParser;
import android.net.Uri;
import android.util.Log;
-import android.webkit.WebResourceResponse;
/**
* PluginManager is exposed to JavaScript in the Cordova WebView.
@@ -407,10 +405,10 @@ public class PluginManager {
LOG.e(TAG, "=====================================================================================");
}
- UriResolver resolveUri(Uri uri) {
+ Uri remapUri(Uri uri) {
for (PluginEntry entry : this.entries.values()) {
if (entry.plugin != null) {
- UriResolver ret = entry.plugin.resolveUri(uri);
+ Uri ret = entry.plugin.remapUri(uri);
if (ret != null) {
return ret;
}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/8b3fa5c9/framework/src/org/apache/cordova/UriResolver.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/UriResolver.java b/framework/src/org/apache/cordova/UriResolver.java
deleted file mode 100644
index b3bfa4d..0000000
--- a/framework/src/org/apache/cordova/UriResolver.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-package org.apache.cordova;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/*
- * Interface for a class that can resolve URIs.
- * See CordovaUriResolver for an example.
- */
-public abstract class UriResolver {
-
- /**
- * Returns the InputStream for the resource.
- * Throws an exception if it cannot be read.
- * Never returns null.
- */
- public abstract InputStream getInputStream() throws IOException;
-
- /**
- * Returns the MIME type of the resource.
- * Returns null if the MIME type cannot be determined (e.g. content: that doesn't exist).
- */
- public abstract String getMimeType();
-
- /** Returns whether the resource is writable. */
- public abstract boolean isWritable();
-
- /**
- * Returns a File that points to the resource, or null if the resource
- * is not on the local file system.
- */
- public abstract File getLocalFile();
-
- /**
- * Returns the OutputStream for the resource.
- * Throws an exception if it cannot be written to.
- * Never returns null.
- */
- public OutputStream getOutputStream() throws IOException {
- throw new IOException("Writing is not suppported");
- }
-
- /**
- * Returns the length of the input stream, or -1 if it is not computable.
- */
- public long computeLength() throws IOException {
- return -1;
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/8b3fa5c9/framework/src/org/apache/cordova/UriResolvers.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/UriResolvers.java b/framework/src/org/apache/cordova/UriResolvers.java
deleted file mode 100644
index 294fc6b..0000000
--- a/framework/src/org/apache/cordova/UriResolvers.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
-*/
-package org.apache.cordova;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import org.apache.cordova.FileHelper;
-import org.apache.http.util.EncodingUtils;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.AssetManager;
-import android.net.Uri;
-import android.os.Looper;
-
-/*
- * UriResolver implementations.
- */
-public final class UriResolvers {
- static Thread webCoreThread;
-
- private UriResolvers() {}
-
- private static long computeSizeFromResolver(UriResolver resolver) throws IOException {
- InputStream inputStream = resolver.getInputStream();
- if (inputStream instanceof FileInputStream) {
- return ((FileInputStream)inputStream).getChannel().size();
- }
- if (inputStream instanceof ByteArrayInputStream) {
- return ((ByteArrayInputStream)inputStream).available();
- }
- return -1;
- }
-
- private static final class FileUriResolver extends UriResolver {
- private final File localFile;
- private String mimeType;
- private FileInputStream cachedInputStream;
-
- FileUriResolver(Uri uri) {
- localFile = new File(uri.getPath());
- }
-
- public InputStream getInputStream() throws IOException {
- if (cachedInputStream == null) {
- cachedInputStream = new FileInputStream(localFile);
- }
- return cachedInputStream;
- }
-
- public OutputStream getOutputStream() throws FileNotFoundException {
- File parent = localFile.getParentFile();
- if (parent != null) {
- localFile.getParentFile().mkdirs();
- }
- return new FileOutputStream(localFile);
- }
-
- public String getMimeType() {
- if (mimeType == null) {
- mimeType = FileHelper.getMimeTypeForExtension(localFile.getName());
- }
- return mimeType;
- }
-
- public boolean isWritable() {
- if (localFile.isDirectory()) {
- return false;
- }
- if (localFile.exists()) {
- return localFile.canWrite();
- }
- return localFile.getParentFile().canWrite();
- }
-
- public File getLocalFile() {
- return localFile;
- }
-
- public long computeLength() throws IOException {
- return localFile.length();
- }
- }
-
- private static final class AssetUriResolver extends UriResolver {
- private final AssetManager assetManager;
- private final String assetPath;
- private String mimeType;
- private InputStream cachedInputStream;
-
- AssetUriResolver(Uri uri, AssetManager assetManager) {
- this.assetManager = assetManager;
- this.assetPath = uri.getPath().substring(15);
- }
-
- public InputStream getInputStream() throws IOException {
- if (cachedInputStream == null) {
- cachedInputStream = assetManager.open(assetPath);
- }
- return cachedInputStream;
- }
-
- public OutputStream getOutputStream() throws FileNotFoundException {
- throw new FileNotFoundException("URI not writable.");
- }
-
- public String getMimeType() {
- if (mimeType == null) {
- mimeType = FileHelper.getMimeTypeForExtension(assetPath);
- }
- return mimeType;
- }
-
- public boolean isWritable() {
- return false;
- }
-
- public File getLocalFile() {
- return null;
- }
-
- public long computeLength() throws IOException {
- return computeSizeFromResolver(this);
- }
- }
-
- private static final class ContentUriResolver extends UriResolver {
- private final Uri uri;
- private final ContentResolver contentResolver;
- private String mimeType;
- private InputStream cachedInputStream;
-
- ContentUriResolver(Uri uri, ContentResolver contentResolver) {
- this.uri = uri;
- this.contentResolver = contentResolver;
- }
-
- public InputStream getInputStream() throws IOException {
- if (cachedInputStream == null) {
- cachedInputStream = contentResolver.openInputStream(uri);
- }
- return cachedInputStream;
- }
-
- public OutputStream getOutputStream() throws FileNotFoundException {
- return contentResolver.openOutputStream(uri);
- }
-
- public String getMimeType() {
- if (mimeType == null) {
- mimeType = contentResolver.getType(uri);
- }
- return mimeType;
- }
-
- public boolean isWritable() {
- return uri.getScheme().equals(ContentResolver.SCHEME_CONTENT);
- }
-
- public File getLocalFile() {
- return null;
- }
-
- public long computeLength() throws IOException {
- return computeSizeFromResolver(this);
- }
- }
-
- private static final class ErrorUriResolver extends UriResolver {
- final String errorMsg;
-
- ErrorUriResolver(String errorMsg) {
- this.errorMsg = errorMsg;
- }
-
- public boolean isWritable() {
- return false;
- }
-
- public File getLocalFile() {
- return null;
- }
-
- public OutputStream getOutputStream() throws IOException {
- throw new FileNotFoundException(errorMsg);
- }
-
- public String getMimeType() {
- return null;
- }
-
- public InputStream getInputStream() throws IOException {
- throw new FileNotFoundException(errorMsg);
- }
- }
-
- private static final class ReadOnlyResolver extends UriResolver {
- private InputStream inputStream;
- private String mimeType;
-
- public ReadOnlyResolver(Uri uri, InputStream inputStream, String mimeType) {
- this.inputStream = inputStream;
- this.mimeType = mimeType;
- }
-
- public boolean isWritable() {
- return false;
- }
-
- public File getLocalFile() {
- return null;
- }
-
- public OutputStream getOutputStream() throws IOException {
- throw new FileNotFoundException("URI is not writable");
- }
-
- public String getMimeType() {
- return mimeType;
- }
-
- public InputStream getInputStream() throws IOException {
- return inputStream;
- }
-
- public long computeLength() throws IOException {
- return computeSizeFromResolver(this);
- }
- }
-
- private static final class ThreadCheckingResolver extends UriResolver {
- final UriResolver delegate;
-
- ThreadCheckingResolver(UriResolver delegate) {
- this.delegate = delegate;
- }
-
- private static void checkThread() {
- Thread curThread = Thread.currentThread();
- if (curThread == Looper.getMainLooper().getThread()) {
- throw new IllegalStateException("Do not perform IO operations on the UI thread. Use CordovaInterface.getThreadPool() instead.");
- }
- if (curThread == webCoreThread) {
- throw new IllegalStateException("Tried to perform an IO operation on the WebCore thread. Use CordovaInterface.getThreadPool() instead.");
- }
- }
-
- public boolean isWritable() {
- checkThread();
- return delegate.isWritable();
- }
-
-
- public File getLocalFile() {
- checkThread();
- return delegate.getLocalFile();
- }
-
- public OutputStream getOutputStream() throws IOException {
- checkThread();
- return delegate.getOutputStream();
- }
-
- public String getMimeType() {
- checkThread();
- return delegate.getMimeType();
- }
-
- public InputStream getInputStream() throws IOException {
- checkThread();
- return delegate.getInputStream();
- }
-
- public long computeLength() throws IOException {
- checkThread();
- return delegate.computeLength();
- }
- }
-
- public static UriResolver createInline(Uri uri, String response, String mimeType) {
- return createInline(uri, EncodingUtils.getBytes(response, "UTF-8"), mimeType);
- }
-
- public static UriResolver createInline(Uri uri, byte[] response, String mimeType) {
- return new ReadOnlyResolver(uri, new ByteArrayInputStream(response), mimeType);
- }
-
- public static UriResolver createReadOnly(Uri uri, InputStream inputStream, String mimeType) {
- return new ReadOnlyResolver(uri, inputStream, mimeType);
- }
-
- public static UriResolver createError(String errorMsg) {
- return new ErrorUriResolver(errorMsg);
- }
-
- /* Package-private to force clients to go through CordovaWebView.resolveUri(). */
- static UriResolver forUri(Uri uri, Context context) {
- String scheme = uri.getScheme();
- if (ContentResolver.SCHEME_CONTENT.equals(scheme) || ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {
- return new ContentUriResolver(uri, context.getContentResolver());
- }
- if (ContentResolver.SCHEME_FILE.equals(scheme)) {
- if (uri.getPath().startsWith("/android_asset/")) {
- return new AssetUriResolver(uri, context.getAssets());
- }
- return new FileUriResolver(uri);
- }
- return null;
- }
-
- /* Used only by CordovaWebView.resolveUri(). */
- static UriResolver makeThreadChecking(UriResolver resolver) {
- if (resolver instanceof ThreadCheckingResolver) {
- return resolver;
- }
- return new ThreadCheckingResolver(resolver);
- }
-}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/8b3fa5c9/test/AndroidManifest.xml
----------------------------------------------------------------------
diff --git a/test/AndroidManifest.xml b/test/AndroidManifest.xml
index f6c840e..04ef3c6 100755
--- a/test/AndroidManifest.xml
+++ b/test/AndroidManifest.xml
@@ -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"
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/8b3fa5c9/test/src/org/apache/cordova/test/UriResolversTest.java
----------------------------------------------------------------------
diff --git a/test/src/org/apache/cordova/test/UriResolversTest.java b/test/src/org/apache/cordova/test/UriResolversTest.java
deleted file mode 100644
index 21584b9..0000000
--- a/test/src/org/apache/cordova/test/UriResolversTest.java
+++ /dev/null
@@ -1,263 +0,0 @@
-
-package org.apache.cordova.test;
-
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
-import org.apache.cordova.CordovaWebView;
-import org.apache.cordova.UriResolver;
-import org.apache.cordova.UriResolvers;
-import org.apache.cordova.api.CallbackContext;
-import org.apache.cordova.api.CordovaPlugin;
-import org.apache.cordova.api.PluginEntry;
-import org.apache.cordova.test.actions.CordovaWebViewTestActivity;
-import org.json.JSONArray;
-import org.json.JSONException;
-
-import java.io.File;
-import java.io.IOException;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-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 UriResolversTest()
- {
- super(CordovaWebViewTestActivity.class);
- }
-
- CordovaWebView cordovaWebView;
- private CordovaWebViewTestActivity activity;
- String execPayload;
- Integer execStatus;
-
- protected void setUp() throws Exception {
- super.setUp();
- activity = this.getActivity();
- cordovaWebView = activity.cordovaWebView;
- cordovaWebView.pluginManager.addService(new PluginEntry("UriResolverTestPlugin1", new CordovaPlugin() {
- @Override
- public UriResolver resolveUri(Uri uri) {
- if ("plugin-uri".equals(uri.getScheme())) {
- return cordovaWebView.resolveUri(uri.buildUpon().scheme("file").build());
- }
- return null;
- }
- public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
- synchronized (UriResolversTest.this) {
- execPayload = args.getString(0);
- execStatus = args.getInt(1);
- UriResolversTest.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() {
- Bitmap imageBitmap = BitmapFactory.decodeResource(activity.getResources(), R.drawable.icon);
- String stored = MediaStore.Images.Media.insertImage(activity.getContentResolver(),
- imageBitmap, "app-icon", "desc");
- return Uri.parse(stored);
- }
-
- private void performResolverTest(Uri uri, String expectedMimeType, File expectedLocalFile,
- boolean expectedIsWritable,
- 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());
- }
- try {
- resolver.getInputStream().read();
- if (!expectRead) {
- fail("Expected getInputStream to throw.");
- }
- } catch (IOException e) {
- if (expectRead) {
- throw e;
- }
- }
- try {
- resolver.getOutputStream().write(123);
- if (!expectWrite) {
- fail("Expected getOutputStream to throw.");
- }
- } catch (IOException e) {
- if (expectWrite) {
- throw e;
- }
- }
- }
-
- public void testValidContentUri() throws IOException
- {
- Uri contentUri = createTestImageContentUri();
- performResolverTest(contentUri, "image/jpeg", null, true, true, true);
- }
-
- public void testInvalidContentUri() throws IOException
- {
- Uri contentUri = Uri.parse("content://media/external/images/media/999999999");
- performResolverTest(contentUri, null, null, true, 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);
- }
-
- public void testInvalidAssetUri() throws IOException
- {
- Uri assetUri = Uri.parse("file:///android_asset/www/missing.html");
- performResolverTest(assetUri, "text/html", null, false, false, false);
- }
-
- public void testFileUriToExistingFile() throws IOException
- {
- 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);
- } finally {
- f.delete();
- }
- }
-
- public void testFileUriToMissingFile() throws IOException
- {
- File f = new File(Environment.getExternalStorageDirectory() + "/somefilethatdoesntexist");
- Uri fileUri = Uri.parse(f.toURI().toString());
- try {
- performResolverTest(fileUri, null, f, true, false, true);
- } finally {
- f.delete();
- }
- }
-
- public void testFileUriToMissingFileWithMissingParent() throws IOException
- {
- File f = new File(Environment.getExternalStorageDirectory() + "/somedirthatismissing/somefilethatdoesntexist");
- Uri fileUri = Uri.parse(f.toURI().toString());
- performResolverTest(fileUri, null, f, false, false, false);
- }
-
- public void testUnrecognizedUri() throws IOException
- {
- Uri uri = Uri.parse("somescheme://foo");
- performResolverTest(uri, null, null, false, false, false);
- }
-
- public void testRelativeUri()
- {
- try {
- cordovaWebView.resolveUri(Uri.parse("/foo"));
- fail("Should have thrown for relative URI 1.");
- } catch (Throwable t) {
- }
- try {
- cordovaWebView.resolveUri(Uri.parse("//foo/bar"));
- fail("Should have thrown for relative URI 2.");
- } catch (Throwable t) {
- }
- try {
- cordovaWebView.resolveUri(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
- {
- Uri uri = Uri.parse("plugin-uri://foohost/android_asset/www/index.html?pluginRewrite=yes");
- performResolverTest(uri, "my/mime", null, false, true, false);
- }
-
- public void testWhitelistRejection() throws IOException
- {
- Uri uri = Uri.parse("http://foohost.com/");
- performResolverTest(uri, null, null, false, false, false);
- }
-
- public void testWebViewRequestIntercept() throws IOException
- {
- cordovaWebView.sendJavascript(
- "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])");
- execPayload = null;
- execStatus = null;
- try {
- synchronized (this) {
- this.wait(2000);
- }
- } catch (InterruptedException e) {
- }
- assertEquals("pass", execPayload);
- assertEquals(execStatus.intValue(), 200);
- }
-
- public void testWebViewWhiteListRejection() throws IOException
- {
- cordovaWebView.sendJavascript(
- "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])");
- execPayload = null;
- execStatus = null;
- try {
- synchronized (this) {
- this.wait(2000);
- }
- } catch (InterruptedException e) {
- }
- assertEquals("", execPayload);
- assertEquals(execStatus.intValue(), 404);
- }
-}
[07/16] android commit: [CB-3384] Fix thread assertion when plugins
remap URIs (cherry picked from commit
b915aafb5be31912129b04c7e70b9c0a9908ee9c)
Posted by ag...@apache.org.
[CB-3384] Fix thread assertion when plugins remap URIs
(cherry picked from commit b915aafb5be31912129b04c7e70b9c0a9908ee9c)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/5814d666
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/5814d666
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/5814d666
Branch: refs/heads/2.9.x
Commit: 5814d666ab2b0823d1967ef9a859dd0d6a382603
Parents: 53e3a12
Author: Andrew Grieve <ag...@chromium.org>
Authored: Thu Jul 18 01:38:47 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:11:42 2013 -0400
----------------------------------------------------------------------
.../src/org/apache/cordova/CordovaResourceApi.java | 17 ++++++++++++++++-
.../cordova/IceCreamCordovaWebViewClient.java | 2 +-
2 files changed, 17 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/5814d666/framework/src/org/apache/cordova/CordovaResourceApi.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaResourceApi.java b/framework/src/org/apache/cordova/CordovaResourceApi.java
index ebf8801..cb85744 100644
--- a/framework/src/org/apache/cordova/CordovaResourceApi.java
+++ b/framework/src/org/apache/cordova/CordovaResourceApi.java
@@ -156,9 +156,24 @@ public class CordovaResourceApi {
* @throws Throws an InvalidArgumentException for relative URIs. Relative URIs should be
* resolved before being passed into this function.
* @throws Throws an IOException if the URI cannot be opened.
+ * @throws Throws an IllegalStateException if called on a foreground thread.
*/
public OpenForReadResult openForRead(Uri uri) throws IOException {
- assertBackgroundThread();
+ return openForRead(uri, false);
+ }
+
+ /**
+ * Opens a stream to the givne URI, also providing the MIME type & length.
+ * @return Never returns null.
+ * @throws Throws an InvalidArgumentException for relative URIs. Relative URIs should be
+ * resolved before being passed into this function.
+ * @throws Throws an IOException if the URI cannot be opened.
+ * @throws Throws an IllegalStateException if called on a foreground thread and skipThreadCheck is false.
+ */
+ public OpenForReadResult openForRead(Uri uri, boolean skipThreadCheck) throws IOException {
+ if (!skipThreadCheck) {
+ assertBackgroundThread();
+ }
switch (getUriType(uri)) {
case URI_TYPE_FILE: {
FileInputStream inputStream = new FileInputStream(uri.getPath());
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/5814d666/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
index f0f372c..3f98f56 100644
--- a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
@@ -59,7 +59,7 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
Uri remappedUri = resourceApi.remapUri(origUri);
if (!origUri.equals(remappedUri) || needsSpecialsInAssetUrlFix(origUri)) {
- OpenForReadResult result = resourceApi.openForRead(remappedUri);
+ OpenForReadResult result = resourceApi.openForRead(remappedUri, true);
return new WebResourceResponse(result.mimeType, "UTF-8", result.inputStream);
}
// If we don't need to special-case the request, let the browser load it.
[06/16] android commit: [CB-3384] Use the ExposedJsApi to detect
webCore thread instead of IceCreamCordovaWebViewClient.
Posted by ag...@apache.org.
[CB-3384] Use the ExposedJsApi to detect webCore thread instead of IceCreamCordovaWebViewClient.
Also removes a debug log statement.
(cherry picked from commit 6fe18ae0abe137702da2072caa749c83cf326cf5)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/53e3a124
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/53e3a124
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/53e3a124
Branch: refs/heads/2.9.x
Commit: 53e3a124410e8355ba063ab0c4a8c7c0610c1e04
Parents: dd770ef
Author: Andrew Grieve <ag...@chromium.org>
Authored: Tue Jul 16 09:32:29 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:11:15 2013 -0400
----------------------------------------------------------------------
framework/src/org/apache/cordova/CordovaResourceApi.java | 5 ++---
framework/src/org/apache/cordova/ExposedJsApi.java | 3 +++
.../src/org/apache/cordova/IceCreamCordovaWebViewClient.java | 4 ----
3 files changed, 5 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/53e3a124/framework/src/org/apache/cordova/CordovaResourceApi.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaResourceApi.java b/framework/src/org/apache/cordova/CordovaResourceApi.java
index b891b51..ebf8801 100644
--- a/framework/src/org/apache/cordova/CordovaResourceApi.java
+++ b/framework/src/org/apache/cordova/CordovaResourceApi.java
@@ -26,7 +26,6 @@ import android.database.Cursor;
import android.net.Uri;
import android.os.Looper;
import android.util.Base64;
-import android.util.Base64InputStream;
import com.squareup.okhttp.OkHttpClient;
@@ -62,7 +61,7 @@ public class CordovaResourceApi {
// Creating this is light-weight.
private static OkHttpClient httpClient = new OkHttpClient();
- static Thread webCoreThread;
+ static Thread jsThread;
private final AssetManager assetManager;
private final ContentResolver contentResolver;
@@ -294,7 +293,7 @@ public class CordovaResourceApi {
if (curThread == Looper.getMainLooper().getThread()) {
throw new IllegalStateException("Do not perform IO operations on the UI thread. Use CordovaInterface.getThreadPool() instead.");
}
- if (curThread == webCoreThread) {
+ if (curThread == jsThread) {
throw new IllegalStateException("Tried to perform an IO operation on the WebCore thread. Use CordovaInterface.getThreadPool() instead.");
}
}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/53e3a124/framework/src/org/apache/cordova/ExposedJsApi.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/ExposedJsApi.java b/framework/src/org/apache/cordova/ExposedJsApi.java
index 221dd3d..c3887cf 100755
--- a/framework/src/org/apache/cordova/ExposedJsApi.java
+++ b/framework/src/org/apache/cordova/ExposedJsApi.java
@@ -48,6 +48,9 @@ import org.json.JSONException;
jsMessageQueue.setPaused(true);
try {
+ // Tell the resourceApi what thread the JS is running on.
+ CordovaResourceApi.jsThread = Thread.currentThread();
+
pluginManager.exec(service, action, callbackId, arguments);
String ret = "";
if (!NativeToJsMessageQueue.DISABLE_EXEC_CHAINING) {
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/53e3a124/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
index 317acc2..f0f372c 100644
--- a/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/IceCreamCordovaWebViewClient.java
@@ -27,7 +27,6 @@ import org.apache.cordova.api.LOG;
import android.annotation.TargetApi;
import android.net.Uri;
import android.os.Build;
-import android.util.Log;
import android.webkit.WebResourceResponse;
import android.webkit.WebView;
@@ -46,9 +45,6 @@ public class IceCreamCordovaWebViewClient extends CordovaWebViewClient {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
- // Tell the Thread-Checking resolve what thread the WebCore thread is.
- CordovaResourceApi.webCoreThread = Thread.currentThread();
- Log.e("WHAAAA", "FOOD " + CordovaResourceApi.webCoreThread);
try {
// Check the against the white-list.
if ((url.startsWith("http:") || url.startsWith("https:")) && !Config.isUrlWhiteListed(url)) {
[15/16] android commit: Tweak the online bridge to not send excess
online events.
Posted by ag...@apache.org.
Tweak the online bridge to not send excess online events.
It does so by having the JS tell it when online events have fired.
(cherry picked from commit 166b35bc6c5977cf547f4093690d554b57cb855a)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/edb35b5a
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/edb35b5a
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/edb35b5a
Branch: refs/heads/2.9.x
Commit: edb35b5a6d13159c69e1fc75ddbf8a149df6498e
Parents: bb7bc33
Author: Andrew Grieve <ag...@chromium.org>
Authored: Thu Aug 15 15:55:08 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:16:07 2013 -0400
----------------------------------------------------------------------
.../org/apache/cordova/CordovaChromeClient.java | 2 +-
.../src/org/apache/cordova/ExposedJsApi.java | 6 ++--
.../apache/cordova/NativeToJsMessageQueue.java | 29 ++++++++++++--------
3 files changed, 22 insertions(+), 15 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/edb35b5a/framework/src/org/apache/cordova/CordovaChromeClient.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/CordovaChromeClient.java b/framework/src/org/apache/cordova/CordovaChromeClient.java
index 4d338a5..3c0abd1 100755
--- a/framework/src/org/apache/cordova/CordovaChromeClient.java
+++ b/framework/src/org/apache/cordova/CordovaChromeClient.java
@@ -234,7 +234,7 @@ public class CordovaChromeClient extends WebChromeClient {
// Polling for JavaScript messages
else if (reqOk && defaultValue != null && defaultValue.equals("gap_poll:")) {
- String r = this.appView.exposedJsApi.retrieveJsMessages();
+ String r = this.appView.exposedJsApi.retrieveJsMessages("1".equals(message));
result.confirm(r == null ? "" : r);
}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/edb35b5a/framework/src/org/apache/cordova/ExposedJsApi.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/ExposedJsApi.java b/framework/src/org/apache/cordova/ExposedJsApi.java
index c3887cf..e2d730c 100755
--- a/framework/src/org/apache/cordova/ExposedJsApi.java
+++ b/framework/src/org/apache/cordova/ExposedJsApi.java
@@ -54,7 +54,7 @@ import org.json.JSONException;
pluginManager.exec(service, action, callbackId, arguments);
String ret = "";
if (!NativeToJsMessageQueue.DISABLE_EXEC_CHAINING) {
- ret = jsMessageQueue.popAndEncode();
+ ret = jsMessageQueue.popAndEncode(false);
}
return ret;
} catch (Throwable e) {
@@ -71,7 +71,7 @@ import org.json.JSONException;
}
@JavascriptInterface
- public String retrieveJsMessages() {
- return jsMessageQueue.popAndEncode();
+ public String retrieveJsMessages(boolean fromOnlineEvent) {
+ return jsMessageQueue.popAndEncode(fromOnlineEvent);
}
}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/edb35b5a/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/NativeToJsMessageQueue.java b/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
index 8a13213..328fb33 100755
--- a/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
+++ b/framework/src/org/apache/cordova/NativeToJsMessageQueue.java
@@ -138,8 +138,9 @@ public class NativeToJsMessageQueue {
* Combines as many messages as possible, while staying under MAX_PAYLOAD_SIZE.
* Returns null if the queue is empty.
*/
- public String popAndEncode() {
+ public String popAndEncode(boolean fromOnlineEvent) {
synchronized (this) {
+ registeredListeners[activeListenerIndex].notifyOfFlush(fromOnlineEvent);
if (queue.isEmpty()) {
return null;
}
@@ -274,12 +275,13 @@ public class NativeToJsMessageQueue {
return paused;
}
- private interface BridgeMode {
- void onNativeToJsMessageAvailable();
+ private abstract class BridgeMode {
+ abstract void onNativeToJsMessageAvailable();
+ void notifyOfFlush(boolean fromOnlineEvent) {}
}
/** Uses webView.loadUrl("javascript:") to execute messages. */
- private class LoadUrlBridgeMode implements BridgeMode {
+ private class LoadUrlBridgeMode extends BridgeMode {
final Runnable runnable = new Runnable() {
public void run() {
String js = popAndEncodeAsJs();
@@ -289,18 +291,17 @@ public class NativeToJsMessageQueue {
}
};
- public void onNativeToJsMessageAvailable() {
+ @Override void onNativeToJsMessageAvailable() {
cordova.getActivity().runOnUiThread(runnable);
}
}
/** Uses online/offline events to tell the JS when to poll for messages. */
- private class OnlineEventsBridgeMode implements BridgeMode {
- boolean online = true;
+ private class OnlineEventsBridgeMode extends BridgeMode {
+ boolean online = false;
final Runnable runnable = new Runnable() {
public void run() {
if (!queue.isEmpty()) {
- online = !online;
webView.setNetworkAvailable(online);
}
}
@@ -308,16 +309,22 @@ public class NativeToJsMessageQueue {
OnlineEventsBridgeMode() {
webView.setNetworkAvailable(true);
}
- public void onNativeToJsMessageAvailable() {
+ @Override void onNativeToJsMessageAvailable() {
cordova.getActivity().runOnUiThread(runnable);
}
+ // Track when online/offline events are fired so that we don't fire excess events.
+ @Override void notifyOfFlush(boolean fromOnlineEvent) {
+ if (fromOnlineEvent) {
+ online = !online;
+ }
+ }
}
/**
* Uses Java reflection to access an API that lets us eval JS.
* Requires Android 3.2.4 or above.
*/
- private class PrivateApiBridgeMode implements BridgeMode {
+ private class PrivateApiBridgeMode extends BridgeMode {
// Message added in commit:
// http://omapzoom.org/?p=platform/frameworks/base.git;a=commitdiff;h=9497c5f8c4bc7c47789e5ccde01179abc31ffeb2
// Which first appeared in 3.2.4ish.
@@ -355,7 +362,7 @@ public class NativeToJsMessageQueue {
}
}
- public void onNativeToJsMessageAvailable() {
+ @Override void onNativeToJsMessageAvailable() {
if (sendMessageMethod == null && !initFailed) {
initReflection();
}
[10/16] android commit: [CB-4463] Updated bin/check_reqs to looks for
android-18 target.Also fixed an issue in unix version of script that would
invoke the `android` command if an error occurred. (cherry picked from commit
c2c5f71018a6821388e2516a6084818
Posted by ag...@apache.org.
[CB-4463] Updated bin/check_reqs to looks for android-18 target.Also fixed an issue in unix version of script that would invoke the `android` command if an error occurred.
(cherry picked from commit c2c5f71018a6821388e2516a6084818453b82de0)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/4b501a5b
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/4b501a5b
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/4b501a5b
Branch: refs/heads/2.9.x
Commit: 4b501a5b63885e7a83a80758f417a6964c35add3
Parents: dc494c8
Author: Fil Maj <ma...@gmail.com>
Authored: Tue Jul 30 17:14:46 2013 -0700
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:14:03 2013 -0400
----------------------------------------------------------------------
bin/check_reqs | 10 +++++-----
bin/check_reqs.js | 8 ++++----
2 files changed, 9 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/4b501a5b/bin/check_reqs
----------------------------------------------------------------------
diff --git a/bin/check_reqs b/bin/check_reqs
index 0032778..cdc3fda 100755
--- a/bin/check_reqs
+++ b/bin/check_reqs
@@ -19,16 +19,16 @@
ROOT="$( cd "$( dirname "$0" )/.." && pwd )"
cmd=`android list target`
if [[ $? != 0 ]]; then
- echo "The command `android` failed. Make sure you have the latest Android SDK installed, and the `android` command (inside the tools/ folder) added to your path."
+ echo "The command \"android\" failed. Make sure you have the latest Android SDK installed, and the \"android\" command (inside the tools/ folder) added to your path."
exit 2
-elif [[ ! $cmd =~ "android-17" ]]; then
- echo "Please install Android target 17 (the Android 4.2 SDK). Make sure you have the latest Android tools installed as well. Run `android` from your command-line to install/update any missing SDKs or tools."
+elif [[ ! $cmd =~ "android-18" ]]; then
+ echo "Please install Android target 18 (the Android 4.3 SDK). Make sure you have the latest Android tools installed as well. Run \"android\" from your command-line to install/update any missing SDKs or tools."
exit 2
else
- cmd="android update project -p $ROOT -t android-17 1> /dev/null 2>&1"
+ cmd="android update project -p $ROOT -t android-18 1> /dev/null 2>&1"
eval $cmd
if [[ $? != 0 ]]; then
echo "Error updating the Cordova library to work with your Android environment."
exit 2
fi
-fi
\ No newline at end of file
+fi
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/4b501a5b/bin/check_reqs.js
----------------------------------------------------------------------
diff --git a/bin/check_reqs.js b/bin/check_reqs.js
index ef30991..7fc32b8 100644
--- a/bin/check_reqs.js
+++ b/bin/check_reqs.js
@@ -63,13 +63,13 @@ function check_requirements() {
Log('The command `android` failed. Make sure you have the latest Android SDK installed, and the `android` command (inside the tools/ folder) added to your path. Output: ' + result.output, true);
WScript.Quit(2);
}
- else if(!result.output.match(/android[-]17/)) {
- Log('Please install Android target 17 (the Android 4.2 SDK). Make sure you have the latest Android tools installed as well. Run `android` from your command-line to install/update any missing SDKs or tools.', true);
+ else if(!result.output.match(/android[-]18/)) {
+ Log('Please install Android target 18 (the Android 4.3 SDK). Make sure you have the latest Android tools installed as well. Run `android` from your command-line to install/update any missing SDKs or tools.', true);
Log('Output : ' + result.output);
WScript.Quit(2);
}
else {
- var cmd = '%comspec% /c android update project -p ' + ROOT + '\\framework -t android-17';
+ var cmd = '%comspec% /c android update project -p ' + ROOT + '\\framework -t android-18';
result = exec_out(cmd);
if(result.error) {
Log('Error updating the Cordova library to work with your Android environment. Command run: "' + cmd + '", output: ' + result.output, true);
@@ -78,4 +78,4 @@ function check_requirements() {
}
}
-check_requirements();
\ No newline at end of file
+check_requirements();
[03/16] android commit: [CB-3384] Add a length getter for
UriResolver. Change from interface -> abstract class.
Posted by ag...@apache.org.
[CB-3384] Add a length getter for UriResolver. Change from interface -> abstract class.
Thinking here is that we can maintain compatibility going forward with a
base class as opposed to interface by having new methods on it have
default implementations.
(cherry picked from commit 990d91360d64324ba332e821fe512d712d7d5521)
Project: http://git-wip-us.apache.org/repos/asf/cordova-android/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-android/commit/43bf47ea
Tree: http://git-wip-us.apache.org/repos/asf/cordova-android/tree/43bf47ea
Diff: http://git-wip-us.apache.org/repos/asf/cordova-android/diff/43bf47ea
Branch: refs/heads/2.9.x
Commit: 43bf47ea7b44fc06d62eaef715eede581a9b0682
Parents: 4be84fb
Author: Andrew Grieve <ag...@chromium.org>
Authored: Wed Jul 10 15:11:23 2013 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Tue Oct 22 15:05:15 2013 -0400
----------------------------------------------------------------------
.../src/org/apache/cordova/UriResolver.java | 35 ++++++----
.../src/org/apache/cordova/UriResolvers.java | 68 +++++++++++++++++---
2 files changed, 79 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/43bf47ea/framework/src/org/apache/cordova/UriResolver.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/UriResolver.java b/framework/src/org/apache/cordova/UriResolver.java
index 8341b18..b3bfa4d 100644
--- a/framework/src/org/apache/cordova/UriResolver.java
+++ b/framework/src/org/apache/cordova/UriResolver.java
@@ -23,40 +23,47 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import android.net.Uri;
-
/*
* Interface for a class that can resolve URIs.
* See CordovaUriResolver for an example.
*/
-public interface UriResolver {
+public abstract class UriResolver {
/**
* Returns the InputStream for the resource.
* Throws an exception if it cannot be read.
* Never returns null.
*/
- InputStream getInputStream() throws IOException;
+ public abstract InputStream getInputStream() throws IOException;
/**
- * Returns the OutputStream for the resource.
- * Throws an exception if it cannot be written to.
- * Never returns null.
- */
- OutputStream getOutputStream() throws IOException;
-
- /**
* Returns the MIME type of the resource.
* Returns null if the MIME type cannot be determined (e.g. content: that doesn't exist).
*/
- String getMimeType();
+ public abstract String getMimeType();
/** Returns whether the resource is writable. */
- boolean isWritable();
+ public abstract boolean isWritable();
/**
* Returns a File that points to the resource, or null if the resource
* is not on the local file system.
*/
- File getLocalFile();
+ public abstract File getLocalFile();
+
+ /**
+ * Returns the OutputStream for the resource.
+ * Throws an exception if it cannot be written to.
+ * Never returns null.
+ */
+ public OutputStream getOutputStream() throws IOException {
+ throw new IOException("Writing is not suppported");
+ }
+
+ /**
+ * Returns the length of the input stream, or -1 if it is not computable.
+ */
+ public long computeLength() throws IOException {
+ return -1;
+ }
}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/43bf47ea/framework/src/org/apache/cordova/UriResolvers.java
----------------------------------------------------------------------
diff --git a/framework/src/org/apache/cordova/UriResolvers.java b/framework/src/org/apache/cordova/UriResolvers.java
index dcb5001..294fc6b 100644
--- a/framework/src/org/apache/cordova/UriResolvers.java
+++ b/framework/src/org/apache/cordova/UriResolvers.java
@@ -44,19 +44,38 @@ public final class UriResolvers {
private UriResolvers() {}
- private static final class FileUriResolver implements UriResolver {
+ private static long computeSizeFromResolver(UriResolver resolver) throws IOException {
+ InputStream inputStream = resolver.getInputStream();
+ if (inputStream instanceof FileInputStream) {
+ return ((FileInputStream)inputStream).getChannel().size();
+ }
+ if (inputStream instanceof ByteArrayInputStream) {
+ return ((ByteArrayInputStream)inputStream).available();
+ }
+ return -1;
+ }
+
+ private static final class FileUriResolver extends UriResolver {
private final File localFile;
private String mimeType;
+ private FileInputStream cachedInputStream;
FileUriResolver(Uri uri) {
localFile = new File(uri.getPath());
}
public InputStream getInputStream() throws IOException {
- return new FileInputStream(localFile);
+ if (cachedInputStream == null) {
+ cachedInputStream = new FileInputStream(localFile);
+ }
+ return cachedInputStream;
}
public OutputStream getOutputStream() throws FileNotFoundException {
+ File parent = localFile.getParentFile();
+ if (parent != null) {
+ localFile.getParentFile().mkdirs();
+ }
return new FileOutputStream(localFile);
}
@@ -80,12 +99,17 @@ public final class UriResolvers {
public File getLocalFile() {
return localFile;
}
+
+ public long computeLength() throws IOException {
+ return localFile.length();
+ }
}
- private static final class AssetUriResolver implements UriResolver {
+ private static final class AssetUriResolver extends UriResolver {
private final AssetManager assetManager;
private final String assetPath;
private String mimeType;
+ private InputStream cachedInputStream;
AssetUriResolver(Uri uri, AssetManager assetManager) {
this.assetManager = assetManager;
@@ -93,7 +117,10 @@ public final class UriResolvers {
}
public InputStream getInputStream() throws IOException {
- return assetManager.open(assetPath);
+ if (cachedInputStream == null) {
+ cachedInputStream = assetManager.open(assetPath);
+ }
+ return cachedInputStream;
}
public OutputStream getOutputStream() throws FileNotFoundException {
@@ -114,12 +141,17 @@ public final class UriResolvers {
public File getLocalFile() {
return null;
}
+
+ public long computeLength() throws IOException {
+ return computeSizeFromResolver(this);
+ }
}
- private static final class ContentUriResolver implements UriResolver {
+ private static final class ContentUriResolver extends UriResolver {
private final Uri uri;
private final ContentResolver contentResolver;
private String mimeType;
+ private InputStream cachedInputStream;
ContentUriResolver(Uri uri, ContentResolver contentResolver) {
this.uri = uri;
@@ -127,7 +159,10 @@ public final class UriResolvers {
}
public InputStream getInputStream() throws IOException {
- return contentResolver.openInputStream(uri);
+ if (cachedInputStream == null) {
+ cachedInputStream = contentResolver.openInputStream(uri);
+ }
+ return cachedInputStream;
}
public OutputStream getOutputStream() throws FileNotFoundException {
@@ -148,9 +183,13 @@ public final class UriResolvers {
public File getLocalFile() {
return null;
}
+
+ public long computeLength() throws IOException {
+ return computeSizeFromResolver(this);
+ }
}
- private static final class ErrorUriResolver implements UriResolver {
+ private static final class ErrorUriResolver extends UriResolver {
final String errorMsg;
ErrorUriResolver(String errorMsg) {
@@ -178,7 +217,7 @@ public final class UriResolvers {
}
}
- private static final class ReadOnlyResolver implements UriResolver {
+ private static final class ReadOnlyResolver extends UriResolver {
private InputStream inputStream;
private String mimeType;
@@ -206,9 +245,13 @@ public final class UriResolvers {
public InputStream getInputStream() throws IOException {
return inputStream;
}
+
+ public long computeLength() throws IOException {
+ return computeSizeFromResolver(this);
+ }
}
- private static final class ThreadCheckingResolver implements UriResolver {
+ private static final class ThreadCheckingResolver extends UriResolver {
final UriResolver delegate;
ThreadCheckingResolver(UriResolver delegate) {
@@ -250,6 +293,11 @@ public final class UriResolvers {
checkThread();
return delegate.getInputStream();
}
+
+ public long computeLength() throws IOException {
+ checkThread();
+ return delegate.computeLength();
+ }
}
public static UriResolver createInline(Uri uri, String response, String mimeType) {
@@ -290,4 +338,4 @@ public final class UriResolvers {
}
return new ThreadCheckingResolver(resolver);
}
-}
\ No newline at end of file
+}