summaryrefslogtreecommitdiffstats
path: root/android_webview
diff options
context:
space:
mode:
authorboliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-01 23:38:46 +0000
committerboliu@chromium.org <boliu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-01 23:38:46 +0000
commite83c53f70b0bbd51d16d60f13e02b036bece6be4 (patch)
tree7907f270810e12a39025919996c980f34e4db71a /android_webview
parentc9348b5d43fabce2824a91384e115db0130bce85 (diff)
downloadchromium_src-e83c53f70b0bbd51d16d60f13e02b036bece6be4.zip
chromium_src-e83c53f70b0bbd51d16d60f13e02b036bece6be4.tar.gz
chromium_src-e83c53f70b0bbd51d16d60f13e02b036bece6be4.tar.bz2
Implement Android WebSettings.[get|set]BlockNetworkLoads
The existing implementation simply sets the net::LOAD_ONLY_FROM_CACHE load flag. Chromium also supports ftp which ignores this flag, so need to explicitly block ftp loads. BUG= Review URL: https://chromiumcodereview.appspot.com/10979045 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159588 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview')
-rw-r--r--android_webview/android_webview.gyp2
-rw-r--r--android_webview/browser/aw_contents_io_thread_client.h55
-rw-r--r--android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc35
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContents.java52
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContentsClient.java2
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContentsIoThreadClient.java6
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwSettings.java57
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestBase.java11
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java63
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/NullContentsClient.java6
-rw-r--r--android_webview/javatests/src/org/chromium/android_webview/test/TestWebServer.java11
-rw-r--r--android_webview/native/android_webview_jni_registrar.cc4
-rw-r--r--android_webview/native/aw_contents.cc4
-rw-r--r--android_webview/native/aw_contents_io_thread_client.h78
-rw-r--r--android_webview/native/aw_contents_io_thread_client_impl.cc (renamed from android_webview/native/aw_contents_io_thread_client.cc)65
-rw-r--r--android_webview/native/aw_contents_io_thread_client_impl.h51
-rw-r--r--android_webview/native/webview_native.gyp4
17 files changed, 369 insertions, 137 deletions
diff --git a/android_webview/android_webview.gyp b/android_webview/android_webview.gyp
index 6962450..695e93e 100644
--- a/android_webview/android_webview.gyp
+++ b/android_webview/android_webview.gyp
@@ -28,6 +28,7 @@
'common/render_view_messages.h',
'common/url_constants.cc',
'common/url_constants.h',
+ 'browser/aw_contents_io_thread_client.h',
'browser/aw_cookie_access_policy.cc',
'browser/aw_cookie_access_policy.h',
'browser/aw_http_auth_handler_base.cc',
@@ -43,6 +44,7 @@
'browser/renderer_host/aw_resource_dispatcher_host_delegate.cc',
'browser/renderer_host/aw_resource_dispatcher_host_delegate.h',
'browser/scoped_allow_wait_for_legacy_web_view_api.h',
+ 'browser/scoped_allow_wait_for_legacy_web_view_api.h',
'lib/aw_browser_dependency_factory_impl.cc',
'lib/aw_browser_dependency_factory_impl.h',
'lib/aw_content_browser_client.cc',
diff --git a/android_webview/browser/aw_contents_io_thread_client.h b/android_webview/browser/aw_contents_io_thread_client.h
new file mode 100644
index 0000000..ac55035
--- /dev/null
+++ b/android_webview/browser/aw_contents_io_thread_client.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_IO_THREAD_CLIENT_H_
+#define ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_IO_THREAD_CLIENT_H_
+
+#include "base/memory/scoped_ptr.h"
+
+class InterceptedRequestData;
+
+namespace net {
+class URLRequest;
+}
+
+namespace android_webview {
+
+// This class provides a means of calling Java methods on an instance that has
+// a 1:1 relationship with a WebContents instance directly from the IO thread.
+//
+// Specifically this is used to associate URLRequests with the WebContents that
+// the URLRequest is made for.
+//
+// The native class is intended to be a short-lived handle that pins the
+// Java-side instance. It is preferable to use the static getter methods to
+// obtain a new instance of the class rather than holding on to one for
+// prolonged periods of time (see note for more details).
+//
+// Note: The native AwContentsIoThreadClient instance has a Global ref to
+// the Java object. By keeping the native AwContentsIoThreadClient
+// instance alive you're also prolonging the lifetime of the Java instance, so
+// don't keep a AwContentsIoThreadClient if you don't need to.
+class AwContentsIoThreadClient {
+ public:
+ virtual ~AwContentsIoThreadClient() {}
+
+ // This will attempt to fetch the AwContentsIoThreadClient for the given
+ // |render_process_id|, |render_view_id| pair.
+ // This method can be called from any thread.
+ // An empty scoped_ptr is a valid return value.
+ static scoped_ptr<AwContentsIoThreadClient> FromID(int render_process_id,
+ int render_view_id);
+
+ // This method is called on the IO thread only.
+ virtual scoped_ptr<InterceptedRequestData> ShouldInterceptRequest(
+ const net::URLRequest* request) = 0;
+
+ // Retrieve the BlockNetworkLoads setting value of this AwContents.
+ // This method is called on the IO thread only.
+ virtual bool ShouldBlockNetworkLoads() const = 0;
+};
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_BROWSER_AW_CONTENTS_IO_THREAD_CLIENT_H_
diff --git a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
index d205a98..cb5d870 100644
--- a/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
+++ b/android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.cc
@@ -5,17 +5,32 @@
#include "android_webview/browser/renderer_host/aw_resource_dispatcher_host_delegate.h"
#include "android_webview/browser/aw_login_delegate.h"
+#include "android_webview/browser/aw_contents_io_thread_client.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
+#include "content/public/browser/resource_controller.h"
#include "content/public/browser/resource_dispatcher_host.h"
#include "content/public/browser/resource_dispatcher_host_login_delegate.h"
#include "content/public/browser/resource_throttle.h"
+#include "content/public/common/url_constants.h"
+#include "net/base/load_flags.h"
+#include "net/url_request/url_request.h"
namespace {
base::LazyInstance<android_webview::AwResourceDispatcherHostDelegate>
g_webview_resource_dispatcher_host_delegate = LAZY_INSTANCE_INITIALIZER;
+// Will unconditionally cancel this resource request.
+class CancelResourceThrottle : public content::ResourceThrottle {
+ public:
+ virtual void WillStartRequest(bool* defer) OVERRIDE;
+};
+
+void CancelResourceThrottle::WillStartRequest(bool* defer) {
+ controller()->Cancel();
+}
+
} // namespace
namespace android_webview {
@@ -42,6 +57,26 @@ void AwResourceDispatcherHostDelegate::RequestBeginning(
int route_id,
bool is_continuation_of_transferred_request,
ScopedVector<content::ResourceThrottle>* throttles) {
+
+ // Part of Implemention of WebSettings.blockNetworkLoads.
+ scoped_ptr<AwContentsIoThreadClient> io_client =
+ AwContentsIoThreadClient::FromID(child_id, route_id);
+ DCHECK(io_client.get());
+
+ if (io_client->ShouldBlockNetworkLoads()) {
+ // Need to cancel ftp since it does not support net::LOAD_ONLY_FROM_CACHE
+ // flag, so must cancel the request if network load is blocked.
+ if (request->url().SchemeIs(chrome::kFtpScheme)) {
+ throttles->push_back(new CancelResourceThrottle);
+ } else {
+ int load_flags = request->load_flags();
+ load_flags &= ~(net::LOAD_BYPASS_CACHE &
+ net::LOAD_VALIDATE_CACHE &
+ net::LOAD_PREFERRING_CACHE);
+ load_flags |= net::LOAD_ONLY_FROM_CACHE;
+ request->set_load_flags(load_flags);
+ }
+ }
}
bool AwResourceDispatcherHostDelegate::AcceptAuthRequest(
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java
index fa1dde2..635d16b 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContents.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -41,6 +41,8 @@ public class AwContents {
private ContentViewCore mContentViewCore;
private AwContentsClient mContentsClient;
private AwContentsIoThreadClient mIoThreadClient;
+ // This can be accessed on any thread after construction. See AwContentsIoThreadClient.
+ private final AwSettings mSettings;
private static final class DestroyRunnable implements Runnable {
private int mNativeAwContents;
@@ -55,8 +57,18 @@ public class AwContents {
private CleanupReference mCleanupReference;
- private AwContents(ContentViewCore contentViewCore,
- AwWebContentsDelegate webContentsDelegate) {
+ private class IoThreadClientImpl implements AwContentsIoThreadClient {
+ // Called on the IO thread.
+ @Override
+ public InterceptedRequestData shouldInterceptRequest(String url) {
+ return AwContents.this.mContentsClient.shouldInterceptRequest(url);
+ }
+
+ // Called on the IO thread.
+ @Override
+ public boolean shouldBlockNetworkLoads() {
+ return AwContents.this.mSettings.getBlockNetworkLoads();
+ }
}
/**
@@ -69,26 +81,34 @@ public class AwContents {
* @param isAccessFromFileURLsGrantedByDefault passed to ContentViewCore.initialize.
*/
public AwContents(ViewGroup containerView,
- ContentViewCore.InternalAccessDelegate internalAccessAdapter,
- ContentViewCore contentViewCore, AwContentsClient contentsClient,
- NativeWindow nativeWindow, boolean privateBrowsing,
- boolean isAccessFromFileURLsGrantedByDefault) {
- mNativeAwContents = nativeInit(contentsClient.getWebContentsDelegate(), privateBrowsing);
- mContentViewCore = contentViewCore;
- mContentsClient = contentsClient;
- mCleanupReference = new CleanupReference(this, new DestroyRunnable(mNativeAwContents));
-
- mContentViewCore.initialize(containerView, internalAccessAdapter,
- nativeGetWebContents(mNativeAwContents), nativeWindow,
- isAccessFromFileURLsGrantedByDefault);
- mContentViewCore.setContentViewClient(contentsClient);
- mContentsClient.installWebContentsObserver(mContentViewCore);
+ ContentViewCore.InternalAccessDelegate internalAccessAdapter,
+ ContentViewCore contentViewCore, AwContentsClient contentsClient,
+ NativeWindow nativeWindow, boolean privateBrowsing,
+ boolean isAccessFromFileURLsGrantedByDefault) {
+ mNativeAwContents = nativeInit(contentsClient.getWebContentsDelegate(), privateBrowsing);
+ mContentViewCore = contentViewCore;
+ mContentsClient = contentsClient;
+ mCleanupReference = new CleanupReference(this, new DestroyRunnable(mNativeAwContents));
+
+ mContentViewCore.initialize(containerView, internalAccessAdapter,
+ nativeGetWebContents(mNativeAwContents), nativeWindow,
+ isAccessFromFileURLsGrantedByDefault);
+ mContentViewCore.setContentViewClient(contentsClient);
+ mContentsClient.installWebContentsObserver(mContentViewCore);
+
+ mSettings = new AwSettings(mContentViewCore.getContext());
+ setIoThreadClient(new IoThreadClientImpl());
}
public ContentViewCore getContentViewCore() {
return mContentViewCore;
}
+ // Can be called from any thread.
+ public AwSettings getSettings() {
+ return mSettings;
+ }
+
public void setIoThreadClient(AwContentsIoThreadClient ioThreadClient) {
mIoThreadClient = ioThreadClient;
nativeSetIoThreadClient(mNativeAwContents, mIoThreadClient);
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
index 9f971e2..15be569 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsClient.java
@@ -145,6 +145,8 @@ public abstract class AwContentsClient extends ContentViewClient {
public abstract void onProgressChanged(int progress);
+ public abstract InterceptedRequestData shouldInterceptRequest(String url);
+
public abstract boolean shouldOverrideUrlLoading(String url);
public abstract void onUnhandledKeyEvent(KeyEvent event);
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsIoThreadClient.java b/android_webview/java/src/org/chromium/android_webview/AwContentsIoThreadClient.java
index ba1f91e..a81c06b 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsIoThreadClient.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsIoThreadClient.java
@@ -18,5 +18,9 @@ import org.chromium.base.JNINamespace;
public interface AwContentsIoThreadClient {
// Called on the IO thread.
@CalledByNative
- InterceptedRequestData shouldInterceptRequest(String url);
+ public InterceptedRequestData shouldInterceptRequest(String url);
+
+ // Called on the IO thread.
+ @CalledByNative
+ public boolean shouldBlockNetworkLoads();
}
diff --git a/android_webview/java/src/org/chromium/android_webview/AwSettings.java b/android_webview/java/src/org/chromium/android_webview/AwSettings.java
new file mode 100644
index 0000000..a6d2e17
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/AwSettings.java
@@ -0,0 +1,57 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.android_webview;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Process;
+
+/**
+ * Stores Android WebView specific settings that does not need to be synced to WebKit.
+ * Use {@link org.chromium.content.browser.ContentSettings} for WebKit settings.
+ *
+ * Methods in this class can be called from any thread, including threads created by
+ * the client of WebView.
+ */
+public class AwSettings {
+ // Lock to protect all settings.
+ private final Object mAwSettingsLock = new Object();
+
+ private final Context mContext;
+ private boolean mBlockNetworkLoads; // Default depends on permission of embedding APK.
+
+ public AwSettings(Context context) {
+ mContext = context;
+ mBlockNetworkLoads = mContext.checkPermission(
+ android.Manifest.permission.INTERNET,
+ Process.myPid(),
+ Process.myUid()) != PackageManager.PERMISSION_GRANTED;
+ }
+
+ /**
+ * See {@link android.webkit.WebSettings#setBlockNetworkLoads}.
+ */
+ public void setBlockNetworkLoads(boolean flag) {
+ synchronized (mAwSettingsLock) {
+ if (!flag && mContext.checkPermission(
+ android.Manifest.permission.INTERNET,
+ Process.myPid(),
+ Process.myUid()) != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Permission denied - " +
+ "application missing INTERNET permission");
+ }
+ mBlockNetworkLoads = flag;
+ }
+ }
+
+ /**
+ * See {@link android.webkit.WebSettings#getBlockNetworkLoads}.
+ */
+ public boolean getBlockNetworkLoads() {
+ synchronized (mAwSettingsLock) {
+ return mBlockNetworkLoads;
+ }
+ }
+}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestBase.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestBase.java
index 176db98..211f6dd 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestBase.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidWebViewTestBase.java
@@ -12,6 +12,7 @@ import junit.framework.Assert;
import org.chromium.android_webview.AwContents;
import org.chromium.android_webview.AwContentsClient;
+import org.chromium.android_webview.AwSettings;
import org.chromium.content.browser.ContentSettings;
import org.chromium.content.browser.ContentView;
import org.chromium.content.browser.ContentViewCore;
@@ -203,6 +204,16 @@ public class AndroidWebViewTestBase
});
}
+ protected AwSettings getAwSettingsOnUiThread(
+ final AwContents awContents) throws Throwable {
+ return runTestOnUiThreadAndGetResult(new Callable<AwSettings>() {
+ @Override
+ public AwSettings call() throws Exception {
+ return awContents.getSettings();
+ }
+ });
+ }
+
/**
* Executes the given snippet of JavaScript code within the given ContentView. Returns the
* result of its execution in JSON format.
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
index 7680da1..d3bf304 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwSettingsTest.java
@@ -10,6 +10,8 @@ import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair;
import org.chromium.android_webview.AndroidProtocolHandler;
+import org.chromium.android_webview.AwContents;
+import org.chromium.android_webview.AwSettings;
import org.chromium.base.test.util.Feature;
import org.chromium.base.test.util.TestFileUtil;
import org.chromium.base.test.util.UrlUtils;
@@ -1492,7 +1494,7 @@ public class AwSettingsTest extends AndroidWebViewTestBase {
imageHeaders.add(Pair.create("Content-Type", "image/png"));
final String imagePath = "/image.png";
webServer.setResponseBase64(
- imagePath, generator.getImageSourceNoAdvance(), imageHeaders);
+ imagePath, generator.getImageSourceNoAdvance(), imageHeaders);
final String pagePath = "/html_image.html";
final String httpUrlImageHtml = generator.getPageTemplateSource(imagePath);
@@ -1501,7 +1503,7 @@ public class AwSettingsTest extends AndroidWebViewTestBase {
settings.setImagesEnabled(false);
loadUrlSync(contentView, contentClient.getOnPageFinishedHelper(), httpImageUrl);
assertEquals(ImagePageGenerator.IMAGE_NOT_LOADED_STRING,
- getTitleOnUiThread(contentView));
+ getTitleOnUiThread(contentView));
settings.setImagesEnabled(true);
assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
@@ -1735,4 +1737,61 @@ public class AwSettingsTest extends AndroidWebViewTestBase {
private void resetResourceContext() {
AndroidProtocolHandler.setResourceContextForTesting(null);
}
+
+ @SmallTest
+ @Feature({"Android-WebView", "Preferences"})
+ public void testBlockNetworkLoadsWithHttpResources() throws Throwable {
+ final TestAwContentsClient contentClient = new TestAwContentsClient();
+ final AwTestContainerView testContainer =
+ createAwTestContainerViewOnMainSync(false, contentClient);
+ final ContentViewCore contentView = testContainer.getContentViewCore();
+ final ContentSettings contentSettings = getContentSettingsOnUiThread(contentView);
+ final AwSettings awSettings = getAwSettingsOnUiThread(testContainer.getAwContents());
+ contentSettings.setJavaScriptEnabled(true);
+ ImagePageGenerator generator = new ImagePageGenerator(0, false);
+
+ TestWebServer webServer = null;
+ String fileName = null;
+ try {
+ // Set up http image.
+ webServer = new TestWebServer(false);
+ List<Pair<String, String>> imageHeaders = new ArrayList<Pair<String, String>>();
+ imageHeaders.add(Pair.create("Content-Type", "image/png"));
+ imageHeaders.add(Pair.create("Cache-Control", "no-store"));
+ final String httpPath = "/image.png";
+ final String imageUrl = webServer.setResponseBase64(
+ httpPath, generator.getImageSourceNoAdvance(), imageHeaders);
+
+ // Set up file html that loads http iframe.
+ String pageHtml ="<img src='" + imageUrl + "' " +
+ "onload=\"document.title='img_onload_fired';\" " +
+ "onerror=\"document.title='img_onerror_fired';\" />";
+ Context context = getInstrumentation().getTargetContext();
+ fileName = context.getCacheDir() + "/block_network_loads_test.html";
+ TestFileUtil.deleteFile(fileName); // Remove leftover file if any.
+ TestFileUtil.createNewHtmlFile(fileName, "unset", pageHtml);
+
+ // Actual test. Note that image may have been cached before test started.
+ // Blocking should trigger onerror handler.
+ awSettings.setBlockNetworkLoads(true);
+ loadUrlSync(
+ contentView,
+ contentClient.getOnPageFinishedHelper(),
+ "file:///" + fileName);
+ assertEquals(0, webServer.getRequestCount(httpPath));
+ assertEquals("img_onerror_fired", getTitleOnUiThread(contentView));
+
+ // Unblock should load normally.
+ awSettings.setBlockNetworkLoads(false);
+ loadUrlSync(
+ contentView,
+ contentClient.getOnPageFinishedHelper(),
+ "file:///" + fileName);
+ assertEquals(1, webServer.getRequestCount(httpPath));
+ assertEquals("img_onload_fired", getTitleOnUiThread(contentView));
+ } finally {
+ if (fileName != null) TestFileUtil.deleteFile(fileName);
+ if (webServer != null) webServer.shutdown();
+ }
+ }
}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/NullContentsClient.java b/android_webview/javatests/src/org/chromium/android_webview/test/NullContentsClient.java
index e753795..5605715 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/NullContentsClient.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/NullContentsClient.java
@@ -10,6 +10,7 @@ import android.webkit.ConsoleMessage;
import org.chromium.android_webview.AwContentsClient;
import org.chromium.android_webview.AwHttpAuthHandler;
+import org.chromium.android_webview.InterceptedRequestData;
import org.chromium.android_webview.JsPromptResultReceiver;
import org.chromium.android_webview.JsResultReceiver;
@@ -32,6 +33,11 @@ class NullContentsClient extends AwContentsClient {
}
@Override
+ public InterceptedRequestData shouldInterceptRequest(String url) {
+ return null;
+ }
+
+ @Override
public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
return false;
}
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/TestWebServer.java b/android_webview/javatests/src/org/chromium/android_webview/test/TestWebServer.java
index 0e56f56..d52cd49 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/TestWebServer.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/TestWebServer.java
@@ -82,6 +82,7 @@ public class TestWebServer {
}
private Map<String, Response> mResponseMap = new HashMap<String, Response>();
+ private Map<String, Integer> mResponseCountMap = new HashMap<String, Integer>();
/**
* Create and start a local HTTP server instance.
@@ -155,6 +156,7 @@ public class TestWebServer {
String requestPath, String responseString,
List<Pair<String, String>> responseHeaders) {
mResponseMap.put(requestPath, new Response(responseString.getBytes(), responseHeaders));
+ mResponseCountMap.put(requestPath, new Integer(0));
return mServerUri + requestPath;
}
@@ -176,9 +178,16 @@ public class TestWebServer {
mResponseMap.put(requestPath,
new Response(Base64.decode(base64EncodedResponse, Base64.DEFAULT),
responseHeaders));
+ mResponseCountMap.put(requestPath, Integer.valueOf(0));
return mServerUri + requestPath;
}
+ public int getRequestCount(String requestPath) {
+ Integer count = mResponseCountMap.get(requestPath);
+ if (count == null) throw new IllegalArgumentException("Path not set: " + requestPath);
+ return count.intValue();
+ }
+
private URLConnection openConnection(URL url)
throws IOException, NoSuchAlgorithmException, KeyManagementException {
if (mSsl) {
@@ -258,6 +267,8 @@ public class TestWebServer {
for (Pair<String, String> header : response.mResponseHeaders) {
httpResponse.addHeader(header.first, header.second);
}
+ mResponseCountMap.put(path, Integer.valueOf(
+ mResponseCountMap.get(path).intValue() + 1));
}
StatusLine sl = httpResponse.getStatusLine();
Log.i(TAG, sl.getStatusCode() + "(" + sl.getReasonPhrase() + ")");
diff --git a/android_webview/native/android_webview_jni_registrar.cc b/android_webview/native/android_webview_jni_registrar.cc
index 8e877e1..f041015 100644
--- a/android_webview/native/android_webview_jni_registrar.cc
+++ b/android_webview/native/android_webview_jni_registrar.cc
@@ -8,7 +8,7 @@
#include "android_webview/native/android_stream_reader_url_request_job.h"
#include "android_webview/native/android_web_view_util.h"
#include "android_webview/native/aw_contents.h"
-#include "android_webview/native/aw_contents_io_thread_client.h"
+#include "android_webview/native/aw_contents_io_thread_client_impl.h"
#include "android_webview/native/aw_http_auth_handler.h"
#include "android_webview/native/cookie_manager.h"
#include "android_webview/native/js_result_handler.h"
@@ -24,7 +24,7 @@ static base::android::RegistrationMethod kWebViewRegisteredMethods[] = {
RegisterAndroidStreamReaderUrlRequestJob },
{ "AndroidWebViewUtil", RegisterAndroidWebViewUtil },
{ "AwContents", RegisterAwContents },
- { "AwContentsIoThreadClient", RegisterAwContentsIoThreadClient},
+ { "AwContentsIoThreadClientImpl", RegisterAwContentsIoThreadClientImpl},
{ "AwHttpAuthHandler", RegisterAwHttpAuthHandler },
{ "CookieManager", RegisterCookieManager },
{ "JsResultHandler", RegisterJsResultHandler },
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index 024da78..f1c6322 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -8,7 +8,7 @@
#include "android_webview/native/aw_browser_dependency_factory.h"
#include "android_webview/native/aw_contents_container.h"
#include "android_webview/native/aw_web_contents_delegate.h"
-#include "android_webview/native/aw_contents_io_thread_client.h"
+#include "android_webview/native/aw_contents_io_thread_client_impl.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
@@ -209,7 +209,7 @@ void AwContents::onReceivedHttpAuthRequest(
void AwContents::SetIoThreadClient(JNIEnv* env, jobject obj, jobject client) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
content::WebContents* web_contents = contents_container_->GetWebContents();
- AwContentsIoThreadClient::Associate(
+ AwContentsIoThreadClientImpl::Associate(
web_contents, ScopedJavaLocalRef<jobject>(env, client));
}
diff --git a/android_webview/native/aw_contents_io_thread_client.h b/android_webview/native/aw_contents_io_thread_client.h
deleted file mode 100644
index 3ba8b09..0000000
--- a/android_webview/native/aw_contents_io_thread_client.h
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_IO_THREAD_CLIENT_H_
-#define ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_IO_THREAD_CLIENT_H_
-
-#include "base/android/scoped_java_ref.h"
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-
-class GURL;
-class InterceptedRequestData;
-class JavaDelegateMapMaintainer;
-
-namespace content {
-class WebContents;
-}
-
-namespace net {
-class URLRequest;
-}
-
-namespace android_webview {
-
-// This class provides a means of calling Java methods on an instance that has
-// a 1:1 relationship with a WebContents instance directly from the IO thread.
-//
-// Specifically this is used to implement URLRequest intercepting in a way that
-// lets the embedder associate URLRequests with the WebContents that the
-// URLRequest is made for.
-//
-// The native class is intended to be a short-lived handle that pins the
-// Java-side instance. It is preferable to use the static getter methods to
-// obtain a new instance of the class rather than holding on to one for
-// prolonged periods of time (see note for more details).
-//
-// Note: The native AwContentsIoThreadClient instance has a Global ref to
-// the Java object. By keeping the native AwContentsIoThreadClient
-// instance alive you're also prolonging the lifetime of the Java instance, so
-// don't keep a AwContentsIoThreadClient if you don't need to.
-class AwContentsIoThreadClient {
- public:
- // This will attempt to fetch the AwContentsIoThreadClient for the given
- // |render_process_id|, |render_view_id| pair.
- // This method can be called from any thread.
- // An empty scoped_ptr is a valid return value.
- static AwContentsIoThreadClient FromID(int render_process_id,
- int render_view_id);
-
- // Associates the |jclient| instance (which must implement the
- // AwContentsIoThreadClient Java interface) with the |web_contents|.
- // This should be called at most once per |web_contents|.
- static void Associate(content::WebContents* web_contents,
- const base::android::JavaRef<jobject>& jclient);
-
- AwContentsIoThreadClient(const AwContentsIoThreadClient& orig);
- ~AwContentsIoThreadClient();
- void operator=(const AwContentsIoThreadClient& rhs);
-
- // This method is called on the IO thread only.
- scoped_ptr<InterceptedRequestData> ShouldInterceptRequest(
- const net::URLRequest* request);
-
- private:
- AwContentsIoThreadClient();
- AwContentsIoThreadClient(const base::android::JavaRef<jobject>& jclient);
-
- base::android::ScopedJavaGlobalRef<jobject> java_object_;
-};
-
-// JNI registration method.
-bool RegisterAwContentsIoThreadClient(JNIEnv* env);
-
-
-} // namespace android_webview
-
-#endif // ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_IO_THREAD_CLIENT_H_
diff --git a/android_webview/native/aw_contents_io_thread_client.cc b/android_webview/native/aw_contents_io_thread_client_impl.cc
index 820a418..0e80d44 100644
--- a/android_webview/native/aw_contents_io_thread_client.cc
+++ b/android_webview/native/aw_contents_io_thread_client_impl.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "android_webview/native/aw_contents_io_thread_client.h"
+#include "android_webview/native/aw_contents_io_thread_client_impl.h"
#include <map>
#include <utility>
@@ -54,18 +54,18 @@ class RvhToIoThreadClientMap {
void Erase(pair<int, int> rvh_id);
private:
- static LazyInstance<RvhToIoThreadClientMap> s_instance_;
+ static LazyInstance<RvhToIoThreadClientMap> g_instance_;
base::Lock map_lock_;
RenderViewHostToWeakDelegateMapType rvh_to_weak_delegate_map_;
};
// static
-LazyInstance<RvhToIoThreadClientMap> RvhToIoThreadClientMap::s_instance_ =
+LazyInstance<RvhToIoThreadClientMap> RvhToIoThreadClientMap::g_instance_ =
LAZY_INSTANCE_INITIALIZER;
// static
RvhToIoThreadClientMap* RvhToIoThreadClientMap::GetInstance() {
- return s_instance_.Pointer();
+ return g_instance_.Pointer();
}
void RvhToIoThreadClientMap::Insert(pair<int, int> rvh_id,
@@ -142,50 +142,37 @@ void ClientMapEntryUpdater::WebContentsDestroyed(WebContents* web_contents) {
} // namespace
-// AwContentsIoThreadClient ---------------------------------------------------
+// AwContentsIoThreadClientImpl -----------------------------------------------
// static
-void AwContentsIoThreadClient::Associate(
- WebContents* web_contents,
- const JavaRef<jobject>& jclient) {
- JNIEnv* env = AttachCurrentThread();
- // The ClientMapEntryUpdater lifespan is tied to the WebContents.
- new ClientMapEntryUpdater(env, web_contents, jclient.obj());
-}
-
-// static
-AwContentsIoThreadClient
+scoped_ptr<AwContentsIoThreadClient>
AwContentsIoThreadClient::FromID(int render_process_id, int render_view_id) {
pair<int, int> rvh_id(render_process_id, render_view_id);
ScopedJavaLocalRef<jobject> java_delegate =
RvhToIoThreadClientMap::GetInstance()->Get(rvh_id);
if (java_delegate.is_null())
- return AwContentsIoThreadClient();
-
- return AwContentsIoThreadClient(java_delegate);
-}
-
-AwContentsIoThreadClient::AwContentsIoThreadClient() {
-}
-
-AwContentsIoThreadClient::AwContentsIoThreadClient(const JavaRef<jobject>& obj)
- : java_object_(obj) {
-}
+ return scoped_ptr<AwContentsIoThreadClient>();
-AwContentsIoThreadClient::AwContentsIoThreadClient(
- const AwContentsIoThreadClient& orig)
- : java_object_(orig.java_object_) {
+ return scoped_ptr<AwContentsIoThreadClient>(
+ new AwContentsIoThreadClientImpl(java_delegate));
}
-void AwContentsIoThreadClient::operator=(const AwContentsIoThreadClient& rhs) {
- java_object_.Reset(rhs.java_object_);
+// static
+void AwContentsIoThreadClientImpl::Associate(
+ WebContents* web_contents,
+ const JavaRef<jobject>& jclient) {
+ JNIEnv* env = AttachCurrentThread();
+ // The ClientMapEntryUpdater lifespan is tied to the WebContents.
+ new ClientMapEntryUpdater(env, web_contents, jclient.obj());
}
-AwContentsIoThreadClient::~AwContentsIoThreadClient() {
+AwContentsIoThreadClientImpl::AwContentsIoThreadClientImpl(
+ const JavaRef<jobject>& obj)
+ : java_object_(obj) {
}
scoped_ptr<InterceptedRequestData>
-AwContentsIoThreadClient::ShouldInterceptRequest(
+AwContentsIoThreadClientImpl::ShouldInterceptRequest(
const net::URLRequest* request) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (java_object_.is_null())
@@ -203,7 +190,17 @@ AwContentsIoThreadClient::ShouldInterceptRequest(
new InterceptedRequestData(ret));
}
-bool RegisterAwContentsIoThreadClient(JNIEnv* env) {
+bool AwContentsIoThreadClientImpl::ShouldBlockNetworkLoads() const {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ if (java_object_.is_null())
+ return false;
+
+ JNIEnv* env = AttachCurrentThread();
+ return Java_AwContentsIoThreadClient_shouldBlockNetworkLoads(
+ env, java_object_.obj());
+}
+
+bool RegisterAwContentsIoThreadClientImpl(JNIEnv* env) {
return RegisterNativesImpl(env);
}
diff --git a/android_webview/native/aw_contents_io_thread_client_impl.h b/android_webview/native/aw_contents_io_thread_client_impl.h
new file mode 100644
index 0000000..b0529a1
--- /dev/null
+++ b/android_webview/native/aw_contents_io_thread_client_impl.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_IO_THREAD_CLIENT_IMPL_H_
+#define ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_IO_THREAD_CLIENT_IMPL_H_
+
+#include "android_webview/browser/aw_contents_io_thread_client.h"
+
+#include "base/android/scoped_java_ref.h"
+#include "base/memory/scoped_ptr.h"
+
+class InterceptedRequestData;
+
+namespace content {
+class WebContents;
+}
+
+namespace net {
+class URLRequest;
+}
+
+namespace android_webview {
+
+class AwContentsIoThreadClientImpl : public AwContentsIoThreadClient {
+ public:
+ // Associates the |jclient| instance (which must implement the
+ // AwContentsIoThreadClient Java interface) with the |web_contents|.
+ // This should be called at most once per |web_contents|.
+ static void Associate(content::WebContents* web_contents,
+ const base::android::JavaRef<jobject>& jclient);
+
+ AwContentsIoThreadClientImpl(const base::android::JavaRef<jobject>& jclient);
+
+ // Implementation of AwContentsIoThreadClient.
+ virtual scoped_ptr<InterceptedRequestData> ShouldInterceptRequest(
+ const net::URLRequest* request) OVERRIDE;
+ virtual bool ShouldBlockNetworkLoads() const OVERRIDE;
+
+ private:
+ base::android::ScopedJavaGlobalRef<jobject> java_object_;
+
+ DISALLOW_COPY_AND_ASSIGN(AwContentsIoThreadClientImpl);
+};
+
+// JNI registration method.
+bool RegisterAwContentsIoThreadClientImpl(JNIEnv* env);
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_NATIVE_AW_CONTENTS_IO_THREAD_CLIENT_IMPL_H_
diff --git a/android_webview/native/webview_native.gyp b/android_webview/native/webview_native.gyp
index 57d0e89..95f0cde 100644
--- a/android_webview/native/webview_native.gyp
+++ b/android_webview/native/webview_native.gyp
@@ -33,8 +33,8 @@
'aw_contents.cc',
'aw_contents.h',
'aw_contents_container.h',
- 'aw_contents_io_thread_client.cc',
- 'aw_contents_io_thread_client.h',
+ 'aw_contents_io_thread_client_impl.cc',
+ 'aw_contents_io_thread_client_impl.h',
'aw_http_auth_handler.cc',
'aw_http_auth_handler.h',
'aw_javascript_dialog_creator.cc',