Loading core/java/android/webkit/FileLoader.java +81 −8 Original line number Diff line number Diff line Loading @@ -23,9 +23,12 @@ import android.content.res.AssetManager; import android.net.http.EventHandler; import android.net.http.Headers; import android.os.Environment; import android.util.Log; import android.util.TypedValue; import java.io.File; import java.io.FileInputStream; import java.lang.reflect.Field; /** * This class is a concrete implementation of StreamLoader that uses a Loading @@ -35,10 +38,19 @@ import java.io.FileInputStream; class FileLoader extends StreamLoader { private String mPath; // Full path to the file to load private Context mContext; // Application context, used for asset loads private boolean mIsAsset; // Indicates if the load is an asset or not private Context mContext; // Application context, used for asset/res loads private int mType; // Indicates the type of the load private boolean mAllowFileAccess; // Allow/block file system access // used for files under asset directory static final int TYPE_ASSET = 1; // used for files under res directory static final int TYPE_RES = 2; // generic file static final int TYPE_FILE = 3; private static final String LOGTAG = "webkit"; /** * Construct a FileLoader with the file URL specified as the content * source. Loading @@ -51,19 +63,24 @@ class FileLoader extends StreamLoader { * on the file system. */ FileLoader(String url, LoadListener loadListener, Context context, boolean asset, boolean allowFileAccess) { int type, boolean allowFileAccess) { super(loadListener); mIsAsset = asset; mType = type; mContext = context; mAllowFileAccess = allowFileAccess; // clean the Url int index = url.indexOf('?'); if (mIsAsset) { if (mType == TYPE_ASSET) { mPath = index > 0 ? URLUtil.stripAnchor( url.substring(URLUtil.ASSET_BASE.length(), index)) : URLUtil.stripAnchor(url.substring( URLUtil.ASSET_BASE.length())); } else if (mType == TYPE_RES) { mPath = index > 0 ? URLUtil.stripAnchor( url.substring(URLUtil.RESOURCE_BASE.length(), index)) : URLUtil.stripAnchor(url.substring( URLUtil.RESOURCE_BASE.length())); } else { mPath = index > 0 ? URLUtil.stripAnchor( url.substring(URLUtil.FILE_BASE.length(), index)) : Loading @@ -84,13 +101,69 @@ class FileLoader extends StreamLoader { @Override protected boolean setupStreamAndSendStatus() { try { if (mIsAsset) { if (mType == TYPE_ASSET) { try { mDataStream = mContext.getAssets().open(mPath); } catch (java.io.FileNotFoundException ex) { // try the rest files included in the package mDataStream = mContext.getAssets().openNonAsset(mPath); } } else if (mType == TYPE_RES) { // get the resource id from the path. e.g. for the path like // drawable/foo.png, the id is located at field "foo" of class // "<package>.R$drawable" if (mPath == null || mPath.length() == 0) { Log.e(LOGTAG, "Need a path to resolve the res file"); mHandler.error(EventHandler.FILE_ERROR, mContext .getString(R.string.httpErrorFileNotFound)); return false; } int slash = mPath.indexOf('/'); int dot = mPath.indexOf('.', slash); if (slash == -1 || dot == -1) { Log.e(LOGTAG, "Incorrect res path: " + mPath); mHandler.error(EventHandler.FILE_ERROR, mContext .getString(R.string.httpErrorFileNotFound)); return false; } String subClassName = mPath.substring(0, slash); String fieldName = mPath.substring(slash + 1, dot); String errorMsg = null; try { final Class<?> d = mContext.getApplicationContext() .getClassLoader().loadClass( mContext.getPackageName() + ".R$" + subClassName); final Field field = d.getField(fieldName); final int id = field.getInt(null); TypedValue value = new TypedValue(); mContext.getResources().getValue(id, value, true); if (value.type == TypedValue.TYPE_STRING) { mDataStream = mContext.getAssets().openNonAsset( value.assetCookie, value.string.toString(), AssetManager.ACCESS_STREAMING); } else { errorMsg = "Only support TYPE_STRING for the res files"; } } catch (ClassNotFoundException e) { errorMsg = "Can't find class: " + mContext.getPackageName() + ".R$" + subClassName; } catch (SecurityException e) { errorMsg = "Caught SecurityException: " + e; } catch (NoSuchFieldException e) { errorMsg = "Can't find field: " + fieldName + " in " + mContext.getPackageName() + ".R$" + subClassName; } catch (IllegalArgumentException e) { errorMsg = "Caught IllegalArgumentException: " + e; } catch (IllegalAccessException e) { errorMsg = "Caught IllegalAccessException: " + e; } if (errorMsg != null) { mHandler.error(EventHandler.FILE_ERROR, mContext .getString(R.string.httpErrorFileNotFound)); return false; } } else { if (!mAllowFileAccess) { mHandler.error(EventHandler.FILE_ERROR, Loading Loading @@ -131,8 +204,8 @@ class FileLoader extends StreamLoader { * file system. */ public static void requestUrl(String url, LoadListener loadListener, Context context, boolean asset, boolean allowFileAccess) { FileLoader loader = new FileLoader(url, loadListener, context, asset, Context context, int type, boolean allowFileAccess) { FileLoader loader = new FileLoader(url, loadListener, context, type, allowFileAccess); loader.load(); } Loading core/java/android/webkit/FrameLoader.java +6 −2 Original line number Diff line number Diff line Loading @@ -142,11 +142,15 @@ class FrameLoader { } if (URLUtil.isAssetUrl(url)) { FileLoader.requestUrl(url, loadListener, loadListener.getContext(), true, settings.getAllowFileAccess()); FileLoader.TYPE_ASSET, true); return true; } else if (URLUtil.isResourceUrl(url)) { FileLoader.requestUrl(url, loadListener, loadListener.getContext(), FileLoader.TYPE_RES, true); return true; } else if (URLUtil.isFileUrl(url)) { FileLoader.requestUrl(url, loadListener, loadListener.getContext(), false, settings.getAllowFileAccess()); FileLoader.TYPE_FILE, settings.getAllowFileAccess()); return true; } else if (URLUtil.isContentUrl(url)) { // Send the raw url to the ContentLoader because it will do a Loading core/java/android/webkit/Network.java +4 −4 Original line number Diff line number Diff line Loading @@ -163,10 +163,10 @@ class Network { return false; } // asset, file system or data stream are handled in the other code path. // This only handles network request. if (URLUtil.isAssetUrl(url) || URLUtil.isFileUrl(url) || URLUtil.isDataUrl(url)) { // asset, res, file system or data stream are handled in the other code // path. This only handles network request. if (URLUtil.isAssetUrl(url) || URLUtil.isResourceUrl(url) || URLUtil.isFileUrl(url) || URLUtil.isDataUrl(url)) { return false; } Loading core/java/android/webkit/URLUtil.java +17 −2 Original line number Diff line number Diff line Loading @@ -29,7 +29,13 @@ public final class URLUtil { private static final String LOGTAG = "webkit"; // to refer to bar.png under your package's asset/foo/ directory, use // "file:///android_asset/foo/bar.png". static final String ASSET_BASE = "file:///android_asset/"; // to refer to bar.png under your package's res/drawable/ directory, use // "file:///android_res/drawable/bar.png". Use "drawable" to refer to // "drawable-hdpi" directory as well. static final String RESOURCE_BASE = "file:///android_res/"; static final String FILE_BASE = "file://"; static final String PROXY_BASE = "file:///cookieless_proxy/"; Loading Loading @@ -167,6 +173,14 @@ public final class URLUtil { return (null != url) && url.startsWith(ASSET_BASE); } /** * @return True iff the url is a resource file. * @hide */ public static boolean isResourceUrl(String url) { return (null != url) && url.startsWith(RESOURCE_BASE); } /** * @return True iff the url is an proxy url to allow cookieless network * requests from a file url. Loading Loading @@ -251,6 +265,7 @@ public final class URLUtil { } return (isAssetUrl(url) || isResourceUrl(url) || isFileUrl(url) || isAboutUrl(url) || isHttpUrl(url) || Loading Loading
core/java/android/webkit/FileLoader.java +81 −8 Original line number Diff line number Diff line Loading @@ -23,9 +23,12 @@ import android.content.res.AssetManager; import android.net.http.EventHandler; import android.net.http.Headers; import android.os.Environment; import android.util.Log; import android.util.TypedValue; import java.io.File; import java.io.FileInputStream; import java.lang.reflect.Field; /** * This class is a concrete implementation of StreamLoader that uses a Loading @@ -35,10 +38,19 @@ import java.io.FileInputStream; class FileLoader extends StreamLoader { private String mPath; // Full path to the file to load private Context mContext; // Application context, used for asset loads private boolean mIsAsset; // Indicates if the load is an asset or not private Context mContext; // Application context, used for asset/res loads private int mType; // Indicates the type of the load private boolean mAllowFileAccess; // Allow/block file system access // used for files under asset directory static final int TYPE_ASSET = 1; // used for files under res directory static final int TYPE_RES = 2; // generic file static final int TYPE_FILE = 3; private static final String LOGTAG = "webkit"; /** * Construct a FileLoader with the file URL specified as the content * source. Loading @@ -51,19 +63,24 @@ class FileLoader extends StreamLoader { * on the file system. */ FileLoader(String url, LoadListener loadListener, Context context, boolean asset, boolean allowFileAccess) { int type, boolean allowFileAccess) { super(loadListener); mIsAsset = asset; mType = type; mContext = context; mAllowFileAccess = allowFileAccess; // clean the Url int index = url.indexOf('?'); if (mIsAsset) { if (mType == TYPE_ASSET) { mPath = index > 0 ? URLUtil.stripAnchor( url.substring(URLUtil.ASSET_BASE.length(), index)) : URLUtil.stripAnchor(url.substring( URLUtil.ASSET_BASE.length())); } else if (mType == TYPE_RES) { mPath = index > 0 ? URLUtil.stripAnchor( url.substring(URLUtil.RESOURCE_BASE.length(), index)) : URLUtil.stripAnchor(url.substring( URLUtil.RESOURCE_BASE.length())); } else { mPath = index > 0 ? URLUtil.stripAnchor( url.substring(URLUtil.FILE_BASE.length(), index)) : Loading @@ -84,13 +101,69 @@ class FileLoader extends StreamLoader { @Override protected boolean setupStreamAndSendStatus() { try { if (mIsAsset) { if (mType == TYPE_ASSET) { try { mDataStream = mContext.getAssets().open(mPath); } catch (java.io.FileNotFoundException ex) { // try the rest files included in the package mDataStream = mContext.getAssets().openNonAsset(mPath); } } else if (mType == TYPE_RES) { // get the resource id from the path. e.g. for the path like // drawable/foo.png, the id is located at field "foo" of class // "<package>.R$drawable" if (mPath == null || mPath.length() == 0) { Log.e(LOGTAG, "Need a path to resolve the res file"); mHandler.error(EventHandler.FILE_ERROR, mContext .getString(R.string.httpErrorFileNotFound)); return false; } int slash = mPath.indexOf('/'); int dot = mPath.indexOf('.', slash); if (slash == -1 || dot == -1) { Log.e(LOGTAG, "Incorrect res path: " + mPath); mHandler.error(EventHandler.FILE_ERROR, mContext .getString(R.string.httpErrorFileNotFound)); return false; } String subClassName = mPath.substring(0, slash); String fieldName = mPath.substring(slash + 1, dot); String errorMsg = null; try { final Class<?> d = mContext.getApplicationContext() .getClassLoader().loadClass( mContext.getPackageName() + ".R$" + subClassName); final Field field = d.getField(fieldName); final int id = field.getInt(null); TypedValue value = new TypedValue(); mContext.getResources().getValue(id, value, true); if (value.type == TypedValue.TYPE_STRING) { mDataStream = mContext.getAssets().openNonAsset( value.assetCookie, value.string.toString(), AssetManager.ACCESS_STREAMING); } else { errorMsg = "Only support TYPE_STRING for the res files"; } } catch (ClassNotFoundException e) { errorMsg = "Can't find class: " + mContext.getPackageName() + ".R$" + subClassName; } catch (SecurityException e) { errorMsg = "Caught SecurityException: " + e; } catch (NoSuchFieldException e) { errorMsg = "Can't find field: " + fieldName + " in " + mContext.getPackageName() + ".R$" + subClassName; } catch (IllegalArgumentException e) { errorMsg = "Caught IllegalArgumentException: " + e; } catch (IllegalAccessException e) { errorMsg = "Caught IllegalAccessException: " + e; } if (errorMsg != null) { mHandler.error(EventHandler.FILE_ERROR, mContext .getString(R.string.httpErrorFileNotFound)); return false; } } else { if (!mAllowFileAccess) { mHandler.error(EventHandler.FILE_ERROR, Loading Loading @@ -131,8 +204,8 @@ class FileLoader extends StreamLoader { * file system. */ public static void requestUrl(String url, LoadListener loadListener, Context context, boolean asset, boolean allowFileAccess) { FileLoader loader = new FileLoader(url, loadListener, context, asset, Context context, int type, boolean allowFileAccess) { FileLoader loader = new FileLoader(url, loadListener, context, type, allowFileAccess); loader.load(); } Loading
core/java/android/webkit/FrameLoader.java +6 −2 Original line number Diff line number Diff line Loading @@ -142,11 +142,15 @@ class FrameLoader { } if (URLUtil.isAssetUrl(url)) { FileLoader.requestUrl(url, loadListener, loadListener.getContext(), true, settings.getAllowFileAccess()); FileLoader.TYPE_ASSET, true); return true; } else if (URLUtil.isResourceUrl(url)) { FileLoader.requestUrl(url, loadListener, loadListener.getContext(), FileLoader.TYPE_RES, true); return true; } else if (URLUtil.isFileUrl(url)) { FileLoader.requestUrl(url, loadListener, loadListener.getContext(), false, settings.getAllowFileAccess()); FileLoader.TYPE_FILE, settings.getAllowFileAccess()); return true; } else if (URLUtil.isContentUrl(url)) { // Send the raw url to the ContentLoader because it will do a Loading
core/java/android/webkit/Network.java +4 −4 Original line number Diff line number Diff line Loading @@ -163,10 +163,10 @@ class Network { return false; } // asset, file system or data stream are handled in the other code path. // This only handles network request. if (URLUtil.isAssetUrl(url) || URLUtil.isFileUrl(url) || URLUtil.isDataUrl(url)) { // asset, res, file system or data stream are handled in the other code // path. This only handles network request. if (URLUtil.isAssetUrl(url) || URLUtil.isResourceUrl(url) || URLUtil.isFileUrl(url) || URLUtil.isDataUrl(url)) { return false; } Loading
core/java/android/webkit/URLUtil.java +17 −2 Original line number Diff line number Diff line Loading @@ -29,7 +29,13 @@ public final class URLUtil { private static final String LOGTAG = "webkit"; // to refer to bar.png under your package's asset/foo/ directory, use // "file:///android_asset/foo/bar.png". static final String ASSET_BASE = "file:///android_asset/"; // to refer to bar.png under your package's res/drawable/ directory, use // "file:///android_res/drawable/bar.png". Use "drawable" to refer to // "drawable-hdpi" directory as well. static final String RESOURCE_BASE = "file:///android_res/"; static final String FILE_BASE = "file://"; static final String PROXY_BASE = "file:///cookieless_proxy/"; Loading Loading @@ -167,6 +173,14 @@ public final class URLUtil { return (null != url) && url.startsWith(ASSET_BASE); } /** * @return True iff the url is a resource file. * @hide */ public static boolean isResourceUrl(String url) { return (null != url) && url.startsWith(RESOURCE_BASE); } /** * @return True iff the url is an proxy url to allow cookieless network * requests from a file url. Loading Loading @@ -251,6 +265,7 @@ public final class URLUtil { } return (isAssetUrl(url) || isResourceUrl(url) || isFileUrl(url) || isAboutUrl(url) || isHttpUrl(url) || Loading