cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From agri...@apache.org
Subject [01/16] android commit: [CB-3384] Make UriResolver assert that IO is not on the UI nor WebCore threads. (cherry picked from commit 99341bce295d7ab373de9f91c43a4d2a59be22c2)
Date Tue, 22 Oct 2013 19:19:59 GMT
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 <agrieve@chromium.org>
Authored: Fri Jul 5 11:44:38 2013 -0400
Committer: Andrew Grieve <agrieve@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


Mime
View raw message