From 28c83564419de9f4f3d22aff630244dc4cbc3c2f Mon Sep 17 00:00:00 2001 From: Tim Volodine Date: Wed, 20 Jan 2016 19:23:03 +0000 Subject: [PATCH] Add Service Worker settings and callback support in WebView. Service Workers are not tied to WebView instances so currently there is no mechanism to capture callbacks originating from within Service Workers. This patch adds the necessary classes to capture callbacks and allows to set settings specifically for Service Workers. The main idea is that to control service workers the embedding app would obtain an instance of ServiceWorkerController using ServiceWorkerController.getInstance() first. After that it would be able to set a custom ServiceWorkerClient and change ServiceWorkerWebSettings via the controller object. BUG: 22709088 Change-Id: I0eb17be46b767851676b77a94757771611fa3a1b --- api/current.txt | 24 ++++++ api/system-current.txt | 25 ++++++ api/test-current.txt | 24 ++++++ core/java/android/webkit/ServiceWorkerClient.java | 41 ++++++++++ .../android/webkit/ServiceWorkerController.java | 52 +++++++++++++ .../android/webkit/ServiceWorkerWebSettings.java | 88 ++++++++++++++++++++++ .../android/webkit/WebViewFactoryProvider.java | 8 ++ 7 files changed, 262 insertions(+) create mode 100644 core/java/android/webkit/ServiceWorkerClient.java create mode 100644 core/java/android/webkit/ServiceWorkerController.java create mode 100644 core/java/android/webkit/ServiceWorkerWebSettings.java diff --git a/api/current.txt b/api/current.txt index e50eba11393f..facc7848d52e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -44092,6 +44092,30 @@ package android.webkit { method public abstract android.view.View getFullScreenView(int, android.content.Context); } + public class ServiceWorkerClient { + ctor public ServiceWorkerClient(); + method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebResourceRequest); + } + + public abstract class ServiceWorkerController { + ctor public ServiceWorkerController(); + method public static android.webkit.ServiceWorkerController getInstance(); + method public abstract android.webkit.ServiceWorkerWebSettings getServiceWorkerWebSettings(); + method public abstract void setServiceWorkerClient(android.webkit.ServiceWorkerClient); + } + + public abstract class ServiceWorkerWebSettings { + ctor public ServiceWorkerWebSettings(); + method public abstract boolean getAllowContentAccess(); + method public abstract boolean getAllowFileAccess(); + method public abstract boolean getBlockNetworkLoads(); + method public abstract int getCacheMode(); + method public abstract void setAllowContentAccess(boolean); + method public abstract void setAllowFileAccess(boolean); + method public abstract void setBlockNetworkLoads(boolean); + method public abstract void setCacheMode(int); + } + public class SslErrorHandler extends android.os.Handler { method public void cancel(); method public void proceed(); diff --git a/api/system-current.txt b/api/system-current.txt index 2d358bfe0bf8..acdc69021569 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -46576,6 +46576,30 @@ package android.webkit { method public abstract android.view.View getFullScreenView(int, android.content.Context); } + public class ServiceWorkerClient { + ctor public ServiceWorkerClient(); + method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebResourceRequest); + } + + public abstract class ServiceWorkerController { + ctor public ServiceWorkerController(); + method public static android.webkit.ServiceWorkerController getInstance(); + method public abstract android.webkit.ServiceWorkerWebSettings getServiceWorkerWebSettings(); + method public abstract void setServiceWorkerClient(android.webkit.ServiceWorkerClient); + } + + public abstract class ServiceWorkerWebSettings { + ctor public ServiceWorkerWebSettings(); + method public abstract boolean getAllowContentAccess(); + method public abstract boolean getAllowFileAccess(); + method public abstract boolean getBlockNetworkLoads(); + method public abstract int getCacheMode(); + method public abstract void setAllowContentAccess(boolean); + method public abstract void setAllowFileAccess(boolean); + method public abstract void setBlockNetworkLoads(boolean); + method public abstract void setCacheMode(int); + } + public class SslErrorHandler extends android.os.Handler { ctor public SslErrorHandler(); method public void cancel(); @@ -47215,6 +47239,7 @@ package android.webkit { method public abstract android.webkit.WebViewProvider createWebView(android.webkit.WebView, android.webkit.WebView.PrivateAccess); method public abstract android.webkit.CookieManager getCookieManager(); method public abstract android.webkit.GeolocationPermissions getGeolocationPermissions(); + method public abstract android.webkit.ServiceWorkerController getServiceWorkerController(); method public abstract android.webkit.WebViewFactoryProvider.Statics getStatics(); method public abstract android.webkit.TokenBindingService getTokenBindingService(); method public abstract android.webkit.WebIconDatabase getWebIconDatabase(); diff --git a/api/test-current.txt b/api/test-current.txt index bcdf5c1b22d9..3d57bba16f64 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -44108,6 +44108,30 @@ package android.webkit { method public abstract android.view.View getFullScreenView(int, android.content.Context); } + public class ServiceWorkerClient { + ctor public ServiceWorkerClient(); + method public android.webkit.WebResourceResponse shouldInterceptRequest(android.webkit.WebResourceRequest); + } + + public abstract class ServiceWorkerController { + ctor public ServiceWorkerController(); + method public static android.webkit.ServiceWorkerController getInstance(); + method public abstract android.webkit.ServiceWorkerWebSettings getServiceWorkerWebSettings(); + method public abstract void setServiceWorkerClient(android.webkit.ServiceWorkerClient); + } + + public abstract class ServiceWorkerWebSettings { + ctor public ServiceWorkerWebSettings(); + method public abstract boolean getAllowContentAccess(); + method public abstract boolean getAllowFileAccess(); + method public abstract boolean getBlockNetworkLoads(); + method public abstract int getCacheMode(); + method public abstract void setAllowContentAccess(boolean); + method public abstract void setAllowFileAccess(boolean); + method public abstract void setBlockNetworkLoads(boolean); + method public abstract void setCacheMode(int); + } + public class SslErrorHandler extends android.os.Handler { method public void cancel(); method public void proceed(); diff --git a/core/java/android/webkit/ServiceWorkerClient.java b/core/java/android/webkit/ServiceWorkerClient.java new file mode 100644 index 000000000000..85de698678d9 --- /dev/null +++ b/core/java/android/webkit/ServiceWorkerClient.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2016 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; + + +public class ServiceWorkerClient { + + /** + * Notify the host application of a resource request and allow the + * application to return the data. If the return value is null, the + * Service Worker will continue to load the resource as usual. + * Otherwise, the return response and data will be used. + * NOTE: This method is called on a thread other than the UI thread + * so clients should exercise caution when accessing private data + * or the view system. + * + * @param request Object containing the details of the request. + * @return A {@link android.webkit.WebResourceResponse} containing the + * response information or null if the WebView should load the + * resource itself. + * @see {@link WebViewClient#shouldInterceptRequest()} + */ + public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) { + return null; + } +} + diff --git a/core/java/android/webkit/ServiceWorkerController.java b/core/java/android/webkit/ServiceWorkerController.java new file mode 100644 index 000000000000..91155584a19d --- /dev/null +++ b/core/java/android/webkit/ServiceWorkerController.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2016 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.annotation.NonNull; +import android.annotation.Nullable; + +/** + * Manages Service Workers used by WebView. + */ +public abstract class ServiceWorkerController { + + /** + * Returns the default ServiceWorkerController instance. At present there is + * only one ServiceWorkerController instance for all WebView instances, + * however this restriction may be relaxed in the future. + * + * @return The default ServiceWorkerController instance. + */ + @NonNull + public static ServiceWorkerController getInstance() { + return WebViewFactory.getProvider().getServiceWorkerController(); + } + + /** + * Gets the settings for all service workers. + * + * @return The current ServiceWorkerWebSettings + */ + @NonNull + public abstract ServiceWorkerWebSettings getServiceWorkerWebSettings(); + + /** + * Sets the client to capture service worker related callbacks. + */ + public abstract void setServiceWorkerClient(@Nullable ServiceWorkerClient client); +} + diff --git a/core/java/android/webkit/ServiceWorkerWebSettings.java b/core/java/android/webkit/ServiceWorkerWebSettings.java new file mode 100644 index 000000000000..8b104d1c7e3b --- /dev/null +++ b/core/java/android/webkit/ServiceWorkerWebSettings.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2016 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; + +/** + * Manages settings state for all Service Workers. These settings are not tied to + * the lifetime of any WebView because service workers can outlive WebView instances. + * The settings are similar to {@link WebSettings} but only settings relevant to + * Service Workers are supported. + */ +// This is an abstract base class: concrete ServiceWorkerControllers must +// create a class derived from this, and return an instance of it in the +// ServiceWorkerController.getServiceWorkerWebSettings() method implementation. +public abstract class ServiceWorkerWebSettings { + + /** + * Overrides the way the cache is used, see {@link WebSettings#setCacheMode}. + * + * @param mode the mode to use + */ + public abstract void setCacheMode(int mode); + + /** + * Gets the current setting for overriding the cache mode. + * + * @return the current setting for overriding the cache mode + * @see #setCacheMode + */ + public abstract int getCacheMode(); + + /** + * Enables or disables content URL access from Service Workers, see + * {@link WebSettings#setAllowContentAccess}. + */ + public abstract void setAllowContentAccess(boolean allow); + + /** + * Gets whether Service Workers support content URL access. + * + * @see #setAllowContentAccess + */ + public abstract boolean getAllowContentAccess(); + + /** + * Enables or disables file access within Service Workers, see + * {@link WebSettings#setAllowFileAccess}. + */ + public abstract void setAllowFileAccess(boolean allow); + + /** + * Gets whether Service Workers support file access. + * + * @see #setAllowFileAccess + */ + public abstract boolean getAllowFileAccess(); + + /** + * Sets whether the Service Workers should not load resources from the network, + * see {@link WebSettings#setBlockNetworkLoads}. + * + * @param flag whether the Service Workers should not load any resources from the + * network + */ + public abstract void setBlockNetworkLoads(boolean flag); + + /** + * Gets whether Service Workers are prohibited from loading any resources from the network. + * + * @return true if the Service Workers are not allowed to load any resources from the network + * @see #setBlockNetworkLoads + */ + public abstract boolean getBlockNetworkLoads(); +} + diff --git a/core/java/android/webkit/WebViewFactoryProvider.java b/core/java/android/webkit/WebViewFactoryProvider.java index 2b66a835f36c..8359a102440c 100644 --- a/core/java/android/webkit/WebViewFactoryProvider.java +++ b/core/java/android/webkit/WebViewFactoryProvider.java @@ -111,6 +111,14 @@ public interface WebViewFactoryProvider { TokenBindingService getTokenBindingService(); /** + * Gets the ServiceWorkerController instance for this WebView implementation. The + * implementation must return the same instance on subsequent calls. + * + * @return the ServiceWorkerController instance + */ + ServiceWorkerController getServiceWorkerController(); + + /** * Gets the singleton WebIconDatabase instance for this WebView implementation. The * implementation must return the same instance on subsequent calls. * -- 2.11.0