summaryrefslogtreecommitdiffstats
path: root/android_webview/java/src/org
diff options
context:
space:
mode:
authortimvolodine <timvolodine@chromium.org>2016-01-22 10:35:30 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-22 18:36:50 +0000
commit47612e474a203be05f6c4f8f257902615e8406d2 (patch)
treeba8d5fa69863518ec4766e08037bc0a8314bf926 /android_webview/java/src/org
parentf09fd446d4f8e0174bc6397eea73fc3f07a83621 (diff)
downloadchromium_src-47612e474a203be05f6c4f8f257902615e8406d2.zip
chromium_src-47612e474a203be05f6c4f8f257902615e8406d2.tar.gz
chromium_src-47612e474a203be05f6c4f8f257902615e8406d2.tar.bz2
[Android WebView] Implement initial settings and callback support for
Service Workers. Service Workers are not tied to AwContents as regular webviews are and therefore do not invoke callbacks provided in WebViewClient and WebChromeClient. This patch provides initial implementation of AwServiceWorkerClient, AwServiceWorkerSettings and related infrastructure. In particular it implements the shouldInterceptRequest callback mechanism for service worker related requests. The callback is invoked when a service worker script is registered and also for network fetches from within the service worker script. This patch also contains a fix for TestWebServer to make it work with service workers. BUG=566027 Review URL: https://codereview.chromium.org/1544863002 Cr-Commit-Position: refs/heads/master@{#370998}
Diffstat (limited to 'android_webview/java/src/org')
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java10
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java7
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwServiceWorkerClient.java18
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwServiceWorkerController.java117
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwServiceWorkerSettings.java134
5 files changed, 286 insertions, 0 deletions
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
index 3d62926..9559244 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
@@ -27,10 +27,13 @@ public class AwBrowserContext {
private HttpAuthDatabase mHttpAuthDatabase;
private AwMessagePortService mMessagePortService;
private AwMetricsServiceClient mMetricsServiceClient;
+ private AwServiceWorkerController mServiceWorkerController;
+ private Context mApplicationContext;
public AwBrowserContext(SharedPreferences sharedPreferences, Context applicationContext) {
mSharedPreferences = sharedPreferences;
mMetricsServiceClient = new AwMetricsServiceClient(applicationContext);
+ mApplicationContext = applicationContext;
}
public AwGeolocationPermissions getGeolocationPermissions() {
@@ -65,6 +68,13 @@ public class AwBrowserContext {
return mMetricsServiceClient;
}
+ public AwServiceWorkerController getServiceWorkerController() {
+ if (mServiceWorkerController == null) {
+ mServiceWorkerController = new AwServiceWorkerController(mApplicationContext, this);
+ }
+ return mServiceWorkerController;
+ }
+
/**
* @see android.webkit.WebView#pauseTimers()
*/
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
index ed9efd8..9e89add 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwContentsStatics.java
@@ -90,6 +90,11 @@ public class AwContentsStatics {
return nativeGetProductVersion();
}
+ public static void setServiceWorkerIoThreadClient(AwContentsIoThreadClient ioThreadClient,
+ AwBrowserContext browserContext) {
+ nativeSetServiceWorkerIoThreadClient(ioThreadClient, browserContext);
+ }
+
//--------------------------------------------------------------------------------------------
// Native methods
//--------------------------------------------------------------------------------------------
@@ -99,4 +104,6 @@ public class AwContentsStatics {
private static native String nativeGetUnreachableWebDataUrl();
private static native void nativeSetLegacyCacheRemovalDelayForTest(long timeoutMs);
private static native String nativeGetProductVersion();
+ private static native void nativeSetServiceWorkerIoThreadClient(
+ AwContentsIoThreadClient ioThreadClient, AwBrowserContext browserContext);
}
diff --git a/android_webview/java/src/org/chromium/android_webview/AwServiceWorkerClient.java b/android_webview/java/src/org/chromium/android_webview/AwServiceWorkerClient.java
new file mode 100644
index 0000000..cbfe3d0
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/AwServiceWorkerClient.java
@@ -0,0 +1,18 @@
+// Copyright 2016 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 org.chromium.android_webview.AwContentsClient.AwWebResourceRequest;
+
+/**
+ * Abstract base class that implementors of service worker related callbacks
+ * derive from.
+ */
+public abstract class AwServiceWorkerClient {
+
+ public abstract AwWebResourceResponse shouldInterceptRequest(AwWebResourceRequest request);
+
+ // TODO: add support for onReceivedError and onReceivedHttpError callbacks.
+} \ No newline at end of file
diff --git a/android_webview/java/src/org/chromium/android_webview/AwServiceWorkerController.java b/android_webview/java/src/org/chromium/android_webview/AwServiceWorkerController.java
new file mode 100644
index 0000000..699b0e9
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/AwServiceWorkerController.java
@@ -0,0 +1,117 @@
+// Copyright 2016 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;
+
+/**
+ * Manages clients and settings for Service Workers.
+ */
+public class AwServiceWorkerController {
+ private AwServiceWorkerClient mServiceWorkerClient;
+ private AwContentsIoThreadClient mServiceWorkerIoThreadClient;
+ private AwContentsBackgroundThreadClient mServiceWorkerBackgroundThreadClient;
+ private AwServiceWorkerSettings mServiceWorkerSettings;
+ private AwBrowserContext mBrowserContext;
+
+ public AwServiceWorkerController(Context applicationContext, AwBrowserContext browserContext) {
+ mServiceWorkerSettings = new AwServiceWorkerSettings(applicationContext);
+ mBrowserContext = browserContext;
+ }
+
+ /**
+ * Returns the current settings for Service Worker.
+ */
+ public AwServiceWorkerSettings getAwServiceWorkerSettings() {
+ return mServiceWorkerSettings;
+ }
+
+ /**
+ * Set custom client to receive callbacks from Service Workers. Can be null.
+ */
+ public void setServiceWorkerClient(AwServiceWorkerClient client) {
+ mServiceWorkerClient = client;
+ if (client != null) {
+ mServiceWorkerBackgroundThreadClient = new ServiceWorkerBackgroundThreadClientImpl();
+ mServiceWorkerIoThreadClient = new ServiceWorkerIoThreadClientImpl();
+ AwContentsStatics.setServiceWorkerIoThreadClient(mServiceWorkerIoThreadClient,
+ mBrowserContext);
+ } else {
+ mServiceWorkerBackgroundThreadClient = null;
+ mServiceWorkerIoThreadClient = null;
+ AwContentsStatics.setServiceWorkerIoThreadClient(null, mBrowserContext);
+ }
+ }
+
+ // Helper classes implementations
+
+ private class ServiceWorkerIoThreadClientImpl extends AwContentsIoThreadClient {
+ // All methods are called on the IO thread.
+
+ @Override
+ public int getCacheMode() {
+ return mServiceWorkerSettings.getCacheMode();
+ }
+
+ @Override
+ public AwContentsBackgroundThreadClient getBackgroundThreadClient() {
+ return mServiceWorkerBackgroundThreadClient;
+ }
+
+ @Override
+ public boolean shouldBlockContentUrls() {
+ return !mServiceWorkerSettings.getAllowContentAccess();
+ }
+
+ @Override
+ public boolean shouldBlockFileUrls() {
+ return !mServiceWorkerSettings.getAllowFileAccess();
+ }
+
+ @Override
+ public boolean shouldBlockNetworkLoads() {
+ return mServiceWorkerSettings.getBlockNetworkLoads();
+ }
+
+ @Override
+ public boolean shouldAcceptThirdPartyCookies() {
+ // We currently don't allow third party cookies in service workers,
+ // see e.g. AwCookieAccessPolicy::GetShouldAcceptThirdPartyCookies.
+ return false;
+ }
+
+ @Override
+ public void onDownloadStart(String url, String userAgent,
+ String contentDisposition, String mimeType, long contentLength) {}
+
+ @Override
+ public void newLoginRequest(String realm, String account, String args) {}
+
+ @Override
+ public void onReceivedError(AwContentsClient.AwWebResourceRequest request,
+ AwContentsClient.AwWebResourceError error) {
+ // TODO
+ }
+
+ @Override
+ public void onReceivedHttpError(AwContentsClient.AwWebResourceRequest request,
+ AwWebResourceResponse response) {
+ // TODO
+ }
+ }
+
+ private class ServiceWorkerBackgroundThreadClientImpl
+ extends AwContentsBackgroundThreadClient {
+ // All methods are called on the background thread.
+ @Override
+ public AwWebResourceResponse shouldInterceptRequest(
+ AwContentsClient.AwWebResourceRequest request) {
+ // TODO: Consider analogy with AwContentsClient, i.e.
+ // - do we need an onloadresource callback?
+ // - do we need to post an error if the response data == null?
+ return mServiceWorkerClient.shouldInterceptRequest(request);
+ }
+ }
+}
diff --git a/android_webview/java/src/org/chromium/android_webview/AwServiceWorkerSettings.java b/android_webview/java/src/org/chromium/android_webview/AwServiceWorkerSettings.java
new file mode 100644
index 0000000..f9b4d51
--- /dev/null
+++ b/android_webview/java/src/org/chromium/android_webview/AwServiceWorkerSettings.java
@@ -0,0 +1,134 @@
+// Copyright 2016 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;
+import android.webkit.WebSettings;
+
+import org.chromium.base.Log;
+import org.chromium.base.annotations.JNINamespace;
+
+/**
+ * Stores Android WebView Service Worker specific settings.
+ *
+ * Methods in this class can be called from any thread, including threads created by
+ * the client of WebView.
+ */
+@JNINamespace("android_webview")
+public class AwServiceWorkerSettings {
+ private static final String LOGTAG = AwServiceWorkerSettings.class.getSimpleName();
+ private static final boolean TRACE = false;
+
+ private int mCacheMode = WebSettings.LOAD_DEFAULT;
+ private boolean mAllowContentUrlAccess = true;
+ private boolean mAllowFileUrlAccess = true;
+ private boolean mBlockNetworkLoads; // Default depends on permission of the embedding APK
+ private boolean mAcceptThirdPartyCookies = false;
+
+ // Lock to protect all settings.
+ private final Object mAwServiceWorkerSettingsLock = new Object();
+
+ // Computed on construction.
+ private final boolean mHasInternetPermission;
+
+ public AwServiceWorkerSettings(Context context) {
+ boolean hasInternetPermission = context.checkPermission(
+ android.Manifest.permission.INTERNET,
+ Process.myPid(),
+ Process.myUid()) == PackageManager.PERMISSION_GRANTED;
+ synchronized (mAwServiceWorkerSettingsLock) {
+ mHasInternetPermission = hasInternetPermission;
+ mBlockNetworkLoads = !hasInternetPermission;
+ }
+ }
+
+ /**
+ * See {@link android.webkit.ServiceWorkerWebSettings#setCacheMode}.
+ */
+ public void setCacheMode(int mode) {
+ if (TRACE) Log.d(LOGTAG, "setCacheMode=" + mode);
+ synchronized (mAwServiceWorkerSettingsLock) {
+ if (mCacheMode != mode) {
+ mCacheMode = mode;
+ }
+ }
+ }
+
+ /**
+ * See {@link android.webkit.ServiceWorkerWebSettings#getCacheMode}.
+ */
+ public int getCacheMode() {
+ synchronized (mAwServiceWorkerSettingsLock) {
+ return mCacheMode;
+ }
+ }
+
+ /**
+ * See {@link android.webkit.ServiceWorkerWebSettings#setAllowContentAccess}.
+ */
+ public void setAllowContentAccess(boolean allow) {
+ if (TRACE) Log.d(LOGTAG, "setAllowContentAccess=" + allow);
+ synchronized (mAwServiceWorkerSettingsLock) {
+ if (mAllowContentUrlAccess != allow) {
+ mAllowContentUrlAccess = allow;
+ }
+ }
+ }
+
+ /**
+ * See {@link android.webkit.ServiceWorkerWebSettings#getAllowContentAccess}.
+ */
+ public boolean getAllowContentAccess() {
+ synchronized (mAwServiceWorkerSettingsLock) {
+ return mAllowContentUrlAccess;
+ }
+ }
+
+ /**
+ * See {@link android.webkit.ServiceWorkerWebSettings#setAllowFileAccess}.
+ */
+ public void setAllowFileAccess(boolean allow) {
+ if (TRACE) Log.d(LOGTAG, "setAllowFileAccess=" + allow);
+ synchronized (mAwServiceWorkerSettingsLock) {
+ if (mAllowFileUrlAccess != allow) {
+ mAllowFileUrlAccess = allow;
+ }
+ }
+ }
+
+ /**
+ * See {@link android.webkit.ServiceWorkerWebSettings#getAllowFileAccess}.
+ */
+ public boolean getAllowFileAccess() {
+ synchronized (mAwServiceWorkerSettingsLock) {
+ return mAllowFileUrlAccess;
+ }
+ }
+
+ /**
+ * See {@link android.webkit.ServiceWorkerWebSettings#setBlockNetworkLoads}.
+ */
+ public void setBlockNetworkLoads(boolean flag) {
+ if (TRACE) Log.d(LOGTAG, "setBlockNetworkLoads=" + flag);
+ synchronized (mAwServiceWorkerSettingsLock) {
+ if (!flag && !mHasInternetPermission) {
+ throw new SecurityException("Permission denied - "
+ + "application missing INTERNET permission");
+ }
+ mBlockNetworkLoads = flag;
+ }
+ }
+
+ /**
+ * See {@link android.webkit.ServiceWorkerWebSettings#getBlockNetworkLoads}.
+ */
+ public boolean getBlockNetworkLoads() {
+ synchronized (mAwServiceWorkerSettingsLock) {
+ return mBlockNetworkLoads;
+ }
+ }
+}