190 lines
7.6 KiB
Java
190 lines
7.6 KiB
Java
/*
|
|
* Copyright (C) 2007 The Android Open Source Project
|
|
*
|
|
* Licensed 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 android.webkit;
|
|
|
|
import com.android.internal.R;
|
|
|
|
import android.content.res.AssetManager;
|
|
import android.net.http.EventHandler;
|
|
import android.net.http.Headers;
|
|
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
|
|
* file or asset as the source for the stream.
|
|
*
|
|
*/
|
|
class FileLoader extends StreamLoader {
|
|
|
|
private String mPath; // Full path to the file to load
|
|
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.
|
|
*
|
|
* @param url Full file url pointing to content to be loaded
|
|
* @param loadListener LoadListener to pass the content to
|
|
* @param asset true if url points to an asset.
|
|
* @param allowFileAccess true if this WebView is allowed to access files
|
|
* on the file system.
|
|
*/
|
|
FileLoader(String url, LoadListener loadListener, int type,
|
|
boolean allowFileAccess) {
|
|
super(loadListener);
|
|
mType = type;
|
|
mAllowFileAccess = allowFileAccess;
|
|
|
|
// clean the Url
|
|
int index = url.indexOf('?');
|
|
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)) :
|
|
URLUtil.stripAnchor(url.substring(
|
|
URLUtil.FILE_BASE.length()));
|
|
}
|
|
}
|
|
|
|
private String errString(Exception ex) {
|
|
String exMessage = ex.getMessage();
|
|
String errString = mContext.getString(R.string.httpErrorFileNotFound);
|
|
if (exMessage != null) {
|
|
errString += " " + exMessage;
|
|
}
|
|
return errString;
|
|
}
|
|
|
|
@Override
|
|
protected boolean setupStreamAndSendStatus() {
|
|
try {
|
|
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");
|
|
mLoadListener.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);
|
|
mLoadListener.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) {
|
|
mLoadListener.error(EventHandler.FILE_ERROR, mContext
|
|
.getString(R.string.httpErrorFileNotFound));
|
|
return false;
|
|
}
|
|
} else {
|
|
if (!mAllowFileAccess) {
|
|
mLoadListener.error(EventHandler.FILE_ERROR,
|
|
mContext.getString(R.string.httpErrorFileNotFound));
|
|
return false;
|
|
}
|
|
|
|
mDataStream = new FileInputStream(mPath);
|
|
mContentLength = (new File(mPath)).length();
|
|
}
|
|
mLoadListener.status(1, 1, 200, "OK");
|
|
|
|
} catch (java.io.FileNotFoundException ex) {
|
|
mLoadListener.error(EventHandler.FILE_NOT_FOUND_ERROR, errString(ex));
|
|
return false;
|
|
|
|
} catch (java.io.IOException ex) {
|
|
mLoadListener.error(EventHandler.FILE_ERROR, errString(ex));
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
protected void buildHeaders(Headers headers) {
|
|
// do nothing.
|
|
}
|
|
}
|