summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.xml110
-rw-r--r--core/java/android/webkit/BrowserFrame.java34
-rw-r--r--core/java/android/webkit/CallbackProxy.java14
-rw-r--r--core/java/android/webkit/FrameLoader.java16
-rw-r--r--core/java/android/webkit/WebResourceResponse.java116
-rw-r--r--core/java/android/webkit/WebViewClient.java20
6 files changed, 283 insertions, 27 deletions
diff --git a/api/current.xml b/api/current.xml
index 4400a002ed5a..e022092a34fc 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -222269,6 +222269,101 @@
</parameter>
</method>
</interface>
+<class name="WebResourceResponse"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="WebResourceResponse"
+ type="android.webkit.WebResourceResponse"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mimeType" type="java.lang.String">
+</parameter>
+<parameter name="encoding" type="java.lang.String">
+</parameter>
+<parameter name="data" type="java.io.InputStream">
+</parameter>
+</constructor>
+<method name="getData"
+ return="java.io.InputStream"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getEncoding"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getMimeType"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setData"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="data" type="java.io.InputStream">
+</parameter>
+</method>
+<method name="setEncoding"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="encoding" type="java.lang.String">
+</parameter>
+</method>
+<method name="setMimeType"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mimeType" type="java.lang.String">
+</parameter>
+</method>
+</class>
<class name="WebSettings"
extends="java.lang.Object"
abstract="false"
@@ -225358,6 +225453,21 @@
<parameter name="event" type="android.view.KeyEvent">
</parameter>
</method>
+<method name="shouldInterceptRequest"
+ return="android.webkit.WebResourceResponse"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.webkit.WebView">
+</parameter>
+<parameter name="url" type="java.lang.String">
+</parameter>
+</method>
<method name="shouldOverrideKeyEvent"
return="boolean"
abstract="false"
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index ed5663e0f610..d3c0ffd17e14 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -654,23 +654,6 @@ class BrowserFrame extends Handler {
}
/**
- * Called by JNI.
- * Read from an InputStream into a supplied byte[]
- * This method catches any exceptions so they don't crash the JVM.
- * @param inputStream InputStream to read from.
- * @param output Bytearray that gets the output.
- * @return the number of bytes read, or -i if then end of stream has been reached
- */
- private static int readFromStream(InputStream inputStream, byte[] output) {
- try {
- return inputStream.read(output);
- } catch(java.io.IOException e) {
- // If we get an exception, return end of stream
- return -1;
- }
- }
-
- /**
* Get the InputStream for an Android resource
* There are three different kinds of android resources:
* - file:///android_res
@@ -859,8 +842,6 @@ class BrowserFrame extends Handler {
this, url, loaderHandle, synchronous, isMainFramePage,
mainResource, userGesture, postDataIdentifier, username, password);
- mCallbackProxy.onLoadResource(url);
-
if (LoadListener.getNativeLoaderCount() > MAX_OUTSTANDING_REQUESTS) {
// send an error message, so that loadListener can be deleted
// after this is returned. This is important as LoadListener's
@@ -872,7 +853,11 @@ class BrowserFrame extends Handler {
return loadListener;
}
- FrameLoader loader = new FrameLoader(loadListener, mSettings, method);
+ // Note that we are intentionally skipping
+ // inputStreamForAndroidResource. This is so that FrameLoader will use
+ // the various StreamLoader classes to handle assets.
+ FrameLoader loader = new FrameLoader(loadListener, mSettings, method,
+ mCallbackProxy.shouldInterceptRequest(url));
loader.setHeaders(headers);
loader.setPostData(postData);
// Set the load mode to the mode used for the current page.
@@ -889,6 +874,15 @@ class BrowserFrame extends Handler {
return !synchronous ? loadListener : null;
}
+ // Called by jni from the chrome network stack.
+ private WebResourceResponse shouldInterceptRequest(String url) {
+ InputStream androidResource = inputStreamForAndroidResource(url);
+ if (androidResource != null) {
+ return new WebResourceResponse(null, null, androidResource);
+ }
+ return mCallbackProxy.shouldInterceptRequest(url);
+ }
+
/**
* Set the progress for the browser activity. Called by native code.
* Uses a delay so it does not happen too often.
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 0078e7a90a8f..160fc2e84498 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -1008,13 +1008,17 @@ class CallbackProxy extends Handler {
sendMessage(obtainMessage(UPDATE_VISITED, isReload ? 1 : 0, 0, url));
}
- public void onLoadResource(String url) {
- // Do an unsynchronized quick check to avoid posting if no callback has
- // been set.
+ WebResourceResponse shouldInterceptRequest(String url) {
if (mWebViewClient == null) {
- return;
+ return null;
+ }
+ // Note: This method does _not_ send a message.
+ WebResourceResponse r =
+ mWebViewClient.shouldInterceptRequest(mWebView, url);
+ if (r == null) {
+ sendMessage(obtainMessage(LOAD_RESOURCE, url));
}
- sendMessage(obtainMessage(LOAD_RESOURCE, url));
+ return r;
}
public void onUnhandledKeyEvent(KeyEvent event) {
diff --git a/core/java/android/webkit/FrameLoader.java b/core/java/android/webkit/FrameLoader.java
index 0f127d561013..951dab36785a 100644
--- a/core/java/android/webkit/FrameLoader.java
+++ b/core/java/android/webkit/FrameLoader.java
@@ -38,6 +38,7 @@ class FrameLoader {
private String mReferrer;
private String mContentType;
private final String mUaprofHeader;
+ private final WebResourceResponse mInterceptResponse;
private static final int URI_PROTOCOL = 0x100;
@@ -54,12 +55,13 @@ class FrameLoader {
private static final String LOGTAG = "webkit";
FrameLoader(LoadListener listener, WebSettings settings,
- String method) {
+ String method, WebResourceResponse interceptResponse) {
mListener = listener;
mHeaders = null;
mMethod = method;
mCacheMode = WebSettings.LOAD_NORMAL;
mSettings = settings;
+ mInterceptResponse = interceptResponse;
mUaprofHeader = mListener.getContext().getResources().getString(
com.android.internal.R.string.config_useragentprofile_url, Build.MODEL);
}
@@ -100,7 +102,17 @@ class FrameLoader {
public boolean executeLoad() {
String url = mListener.url();
- if (URLUtil.isNetworkUrl(url)){
+ // Process intercepted requests first as they could be any url.
+ if (mInterceptResponse != null) {
+ if (mListener.isSynchronous()) {
+ mInterceptResponse.loader(mListener).load();
+ } else {
+ WebViewWorker.getHandler().obtainMessage(
+ WebViewWorker.MSG_ADD_STREAMLOADER,
+ mInterceptResponse.loader(mListener)).sendToTarget();
+ }
+ return true;
+ } else if (URLUtil.isNetworkUrl(url)){
if (mSettings.getBlockNetworkLoads()) {
mListener.error(EventHandler.ERROR_BAD_URL,
mListener.getContext().getString(
diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java
new file mode 100644
index 000000000000..e786838615a6
--- /dev/null
+++ b/core/java/android/webkit/WebResourceResponse.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2010 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 android.net.http.Headers;
+
+import java.io.InputStream;
+
+/**
+ * A WebResourceResponse is return by
+ * {@link WebViewClient#shouldInterceptRequest} and
+ * contains the response information for a particular resource.
+ */
+public class WebResourceResponse {
+
+ private class Loader extends StreamLoader {
+ Loader(LoadListener loadListener) {
+ super(loadListener);
+ mDataStream = mInputStream;
+ }
+ @Override
+ protected boolean setupStreamAndSendStatus() {
+ mLoadListener.status(1, 1, mDataStream != null ? 200 : 404, "");
+ return true;
+ }
+ @Override
+ protected void buildHeaders(Headers headers) {
+ headers.setContentType(mMimeType);
+ headers.setContentEncoding(mEncoding);
+ }
+ }
+
+ // Accessed by jni, do not rename without modifying the jni code.
+ private String mMimeType;
+ private String mEncoding;
+ private InputStream mInputStream;
+
+ /**
+ * Construct a response with the given mime type, encoding, and data.
+ * @param mimeType The mime type of the data (i.e. text/html).
+ * @param encoding The encoding of the bytes read from data.
+ * @param data An InputStream for reading custom data. The implementation
+ * must implement {@link InputStream#read(byte[])}.
+ */
+ public WebResourceResponse(String mimeType, String encoding,
+ InputStream data) {
+ mMimeType = mimeType;
+ mEncoding = encoding;
+ mInputStream = data;
+ }
+
+ /**
+ * Set the mime type of the response data (i.e. text/html).
+ * @param mimeType
+ */
+ public void setMimeType(String mimeType) {
+ mMimeType = mimeType;
+ }
+
+ /**
+ * @see #setMimeType
+ */
+ public String getMimeType() {
+ return mMimeType;
+ }
+
+ /**
+ * Set the encoding of the response data (i.e. utf-8). This will be used to
+ * decode the raw bytes from the input stream.
+ * @param encoding
+ */
+ public void setEncoding(String encoding) {
+ mEncoding = encoding;
+ }
+
+ /**
+ * @see #setEncoding
+ */
+ public String getEncoding() {
+ return mEncoding;
+ }
+
+ /**
+ * Set the input stream containing the data for this resource.
+ * @param data An InputStream for reading custom data. The implementation
+ * must implement {@link InputStream#read(byte[])}.
+ */
+ public void setData(InputStream data) {
+ mInputStream = data;
+ }
+
+ /**
+ * @see #setData
+ */
+ public InputStream getData() {
+ return mInputStream;
+ }
+
+ StreamLoader loader(LoadListener listener) {
+ return new Loader(listener);
+ }
+}
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index 1f8eeba9016c..db605de6dc77 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -78,6 +78,26 @@ public class WebViewClient {
}
/**
+ * Notify the host application of a resource request and allow the
+ * application to return the data. If the return value is null, the WebView
+ * will continue to load the resource as usual. Otherwise, the return
+ * response and data will be used. NOTE: This method is called by the
+ * network thread so clients should exercise caution when accessing private
+ * data.
+ *
+ * @param view The {@link android.webkit.WebView} that is requesting the
+ * resource.
+ * @param url The raw url of the resource.
+ * @return A {@link android.webkit.WebResourceResponse} containing the
+ * response information or null if the WebView should load the
+ * resource itself.
+ */
+ public WebResourceResponse shouldInterceptRequest(WebView view,
+ String url) {
+ return null;
+ }
+
+ /**
* Notify the host application that there have been an excessive number of
* HTTP redirects. As the host application if it would like to continue
* trying to load the resource. The default behavior is to send the cancel