summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrace Kloba <klobag@google.com>2009-12-07 10:11:28 -0800
committerGrace Kloba <klobag@google.com>2009-12-07 12:36:05 -0800
commitbd5c823e28d907d85b8d0867133343ccda014451 (patch)
tree2f5d747a413982166a2fbf9646705f9249944e61
parent8c7ab034692eea550b97bebd7746e1a82735bbbd (diff)
downloadframeworks_base-bd5c823e28d907d85b8d0867133343ccda014451.zip
frameworks_base-bd5c823e28d907d85b8d0867133343ccda014451.tar.gz
frameworks_base-bd5c823e28d907d85b8d0867133343ccda014451.tar.bz2
Add "res" support for WebView.
http://b/issue?id=2296839
-rw-r--r--core/java/android/webkit/FileLoader.java89
-rw-r--r--core/java/android/webkit/FrameLoader.java8
-rw-r--r--core/java/android/webkit/Network.java8
-rw-r--r--core/java/android/webkit/URLUtil.java19
4 files changed, 108 insertions, 16 deletions
diff --git a/core/java/android/webkit/FileLoader.java b/core/java/android/webkit/FileLoader.java
index 085f1f4..974ccbf 100644
--- a/core/java/android/webkit/FileLoader.java
+++ b/core/java/android/webkit/FileLoader.java
@@ -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
@@ -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.
@@ -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)) :
@@ -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,
@@ -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();
}
diff --git a/core/java/android/webkit/FrameLoader.java b/core/java/android/webkit/FrameLoader.java
index c3dac6e..51f60c3 100644
--- a/core/java/android/webkit/FrameLoader.java
+++ b/core/java/android/webkit/FrameLoader.java
@@ -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
diff --git a/core/java/android/webkit/Network.java b/core/java/android/webkit/Network.java
index b53e404..598f20d 100644
--- a/core/java/android/webkit/Network.java
+++ b/core/java/android/webkit/Network.java
@@ -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;
}
diff --git a/core/java/android/webkit/URLUtil.java b/core/java/android/webkit/URLUtil.java
index 211e5e4..7c5f2b0 100644
--- a/core/java/android/webkit/URLUtil.java
+++ b/core/java/android/webkit/URLUtil.java
@@ -28,8 +28,14 @@ import android.util.Log;
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/";
@@ -166,7 +172,15 @@ public final class URLUtil {
public static boolean isAssetUrl(String url) {
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.
@@ -251,6 +265,7 @@ public final class URLUtil {
}
return (isAssetUrl(url) ||
+ isResourceUrl(url) ||
isFileUrl(url) ||
isAboutUrl(url) ||
isHttpUrl(url) ||