am 14467eb2: Merge change I234162b0 into eclair-mr2

Merge commit '14467eb2eea119b4d71dd7dd149479aa092e6de2' into eclair-mr2-plus-aosp

* commit '14467eb2eea119b4d71dd7dd149479aa092e6de2':
  Add "res" support for WebView.
This commit is contained in:
Grace Kloba
2009-12-07 13:09:49 -08:00
committed by Android Git Automerger
4 changed files with 108 additions and 16 deletions

View File

@@ -23,9 +23,12 @@ import android.content.res.AssetManager;
import android.net.http.EventHandler; import android.net.http.EventHandler;
import android.net.http.Headers; import android.net.http.Headers;
import android.os.Environment; import android.os.Environment;
import android.util.Log;
import android.util.TypedValue;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.lang.reflect.Field;
/** /**
* This class is a concrete implementation of StreamLoader that uses a * This class is a concrete implementation of StreamLoader that uses a
@@ -35,10 +38,19 @@ import java.io.FileInputStream;
class FileLoader extends StreamLoader { class FileLoader extends StreamLoader {
private String mPath; // Full path to the file to load private String mPath; // Full path to the file to load
private Context mContext; // Application context, used for asset loads private Context mContext; // Application context, used for asset/res loads
private boolean mIsAsset; // Indicates if the load is an asset or not private int mType; // Indicates the type of the load
private boolean mAllowFileAccess; // Allow/block file system access 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 * Construct a FileLoader with the file URL specified as the content
* source. * source.
@@ -51,19 +63,24 @@ class FileLoader extends StreamLoader {
* on the file system. * on the file system.
*/ */
FileLoader(String url, LoadListener loadListener, Context context, FileLoader(String url, LoadListener loadListener, Context context,
boolean asset, boolean allowFileAccess) { int type, boolean allowFileAccess) {
super(loadListener); super(loadListener);
mIsAsset = asset; mType = type;
mContext = context; mContext = context;
mAllowFileAccess = allowFileAccess; mAllowFileAccess = allowFileAccess;
// clean the Url // clean the Url
int index = url.indexOf('?'); int index = url.indexOf('?');
if (mIsAsset) { if (mType == TYPE_ASSET) {
mPath = index > 0 ? URLUtil.stripAnchor( mPath = index > 0 ? URLUtil.stripAnchor(
url.substring(URLUtil.ASSET_BASE.length(), index)) : url.substring(URLUtil.ASSET_BASE.length(), index)) :
URLUtil.stripAnchor(url.substring( URLUtil.stripAnchor(url.substring(
URLUtil.ASSET_BASE.length())); 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 { } else {
mPath = index > 0 ? URLUtil.stripAnchor( mPath = index > 0 ? URLUtil.stripAnchor(
url.substring(URLUtil.FILE_BASE.length(), index)) : url.substring(URLUtil.FILE_BASE.length(), index)) :
@@ -84,13 +101,69 @@ class FileLoader extends StreamLoader {
@Override @Override
protected boolean setupStreamAndSendStatus() { protected boolean setupStreamAndSendStatus() {
try { try {
if (mIsAsset) { if (mType == TYPE_ASSET) {
try { try {
mDataStream = mContext.getAssets().open(mPath); mDataStream = mContext.getAssets().open(mPath);
} catch (java.io.FileNotFoundException ex) { } catch (java.io.FileNotFoundException ex) {
// try the rest files included in the package // try the rest files included in the package
mDataStream = mContext.getAssets().openNonAsset(mPath); 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 { } else {
if (!mAllowFileAccess) { if (!mAllowFileAccess) {
mHandler.error(EventHandler.FILE_ERROR, mHandler.error(EventHandler.FILE_ERROR,
@@ -131,8 +204,8 @@ class FileLoader extends StreamLoader {
* file system. * file system.
*/ */
public static void requestUrl(String url, LoadListener loadListener, public static void requestUrl(String url, LoadListener loadListener,
Context context, boolean asset, boolean allowFileAccess) { Context context, int type, boolean allowFileAccess) {
FileLoader loader = new FileLoader(url, loadListener, context, asset, FileLoader loader = new FileLoader(url, loadListener, context, type,
allowFileAccess); allowFileAccess);
loader.load(); loader.load();
} }

View File

@@ -142,11 +142,15 @@ class FrameLoader {
} }
if (URLUtil.isAssetUrl(url)) { if (URLUtil.isAssetUrl(url)) {
FileLoader.requestUrl(url, loadListener, loadListener.getContext(), 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; return true;
} else if (URLUtil.isFileUrl(url)) { } else if (URLUtil.isFileUrl(url)) {
FileLoader.requestUrl(url, loadListener, loadListener.getContext(), FileLoader.requestUrl(url, loadListener, loadListener.getContext(),
false, settings.getAllowFileAccess()); FileLoader.TYPE_FILE, settings.getAllowFileAccess());
return true; return true;
} else if (URLUtil.isContentUrl(url)) { } else if (URLUtil.isContentUrl(url)) {
// Send the raw url to the ContentLoader because it will do a // Send the raw url to the ContentLoader because it will do a

View File

@@ -163,10 +163,10 @@ class Network {
return false; return false;
} }
// asset, file system or data stream are handled in the other code path. // asset, res, file system or data stream are handled in the other code
// This only handles network request. // path. This only handles network request.
if (URLUtil.isAssetUrl(url) || URLUtil.isFileUrl(url) || if (URLUtil.isAssetUrl(url) || URLUtil.isResourceUrl(url)
URLUtil.isDataUrl(url)) { || URLUtil.isFileUrl(url) || URLUtil.isDataUrl(url)) {
return false; return false;
} }

View File

@@ -28,8 +28,14 @@ import android.util.Log;
public final class URLUtil { public final class URLUtil {
private static final String LOGTAG = "webkit"; 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/"; 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 FILE_BASE = "file://";
static final String PROXY_BASE = "file:///cookieless_proxy/"; static final String PROXY_BASE = "file:///cookieless_proxy/";
@@ -166,7 +172,15 @@ public final class URLUtil {
public static boolean isAssetUrl(String url) { public static boolean isAssetUrl(String url) {
return (null != url) && url.startsWith(ASSET_BASE); 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 * @return True iff the url is an proxy url to allow cookieless network
* requests from a file url. * requests from a file url.
@@ -251,6 +265,7 @@ public final class URLUtil {
} }
return (isAssetUrl(url) || return (isAssetUrl(url) ||
isResourceUrl(url) ||
isFileUrl(url) || isFileUrl(url) ||
isAboutUrl(url) || isAboutUrl(url) ||
isHttpUrl(url) || isHttpUrl(url) ||