157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton/* 257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * Copyright 2018 The Android Open Source Project 357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * 457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * Licensed under the Apache License, Version 2.0 (the "License"); 557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * you may not use this file except in compliance with the License. 657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * You may obtain a copy of the License at 757d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * 857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * http://www.apache.org/licenses/LICENSE-2.0 957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * 1057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * Unless required by applicable law or agreed to in writing, software 1157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * distributed under the License is distributed on an "AS IS" BASIS, 1257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * See the License for the specific language governing permissions and 1457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * limitations under the License. 1557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton */ 1657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 1757d3714176493740842e8e2d0700106a6b64f048Gustav Senntonpackage androidx.webkit.internal; 1857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 1957d3714176493740842e8e2d0700106a6b64f048Gustav Senntonimport android.annotation.SuppressLint; 2057d3714176493740842e8e2d0700106a6b64f048Gustav Senntonimport android.webkit.ServiceWorkerWebSettings; 2157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 222ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Senntonimport androidx.annotation.NonNull; 232ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Senntonimport androidx.annotation.RequiresApi; 2457d3714176493740842e8e2d0700106a6b64f048Gustav Senntonimport androidx.webkit.ServiceWorkerWebSettingsCompat; 2557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 2657d3714176493740842e8e2d0700106a6b64f048Gustav Senntonimport org.chromium.support_lib_boundary.ServiceWorkerWebSettingsBoundaryInterface; 272ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Senntonimport org.chromium.support_lib_boundary.util.BoundaryInterfaceReflectionUtil; 282ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton 292ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Senntonimport java.lang.reflect.InvocationHandler; 302ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Senntonimport java.lang.reflect.Proxy; 3157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 3257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton/** 3357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * Implementation of {@link ServiceWorkerWebSettingsCompat}. 3457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * This class uses either the framework, the WebView APK, or both, to implement 3557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * {@link ServiceWorkerWebSettingsCompat} functionality. 3657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton */ 3757d3714176493740842e8e2d0700106a6b64f048Gustav Senntonpublic class ServiceWorkerWebSettingsImpl extends ServiceWorkerWebSettingsCompat { 382ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton private ServiceWorkerWebSettings mFrameworksImpl; 3957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton private ServiceWorkerWebSettingsBoundaryInterface mBoundaryInterface; 4057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 4157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton /** 4257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * This class handles three different scenarios: 4357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * 1. The Android version on the device is high enough to support all APIs used. 4457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * 2. The Android version on the device is too low to support any ServiceWorkerWebSettings APIs 4557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * so we use the support library glue instead through 4657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * {@link ServiceWorkerWebSettingsBoundaryInterface}. 4757d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * 3. The Android version on the device is high enough to support some ServiceWorkerWebSettings 4857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * APIs, so we call into them using {@link android.webkit.ServiceWorkerWebSettings}, but the 4957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * rest of the APIs are only supported by the support library glue, so whenever we call such an 5057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * API we fetch a {@link ServiceWorkerWebSettingsBoundaryInterface} corresponding to our 5157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton * {@link android.webkit.ServiceWorkerWebSettings}. 5257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton */ 532ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton public ServiceWorkerWebSettingsImpl(@NonNull ServiceWorkerWebSettings settings) { 542ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton mFrameworksImpl = settings; 552ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton } 562ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton 572ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton public ServiceWorkerWebSettingsImpl(@NonNull InvocationHandler invocationHandler) { 582ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton mBoundaryInterface = BoundaryInterfaceReflectionUtil.castToSuppLibClass( 592ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton ServiceWorkerWebSettingsBoundaryInterface.class, invocationHandler); 602ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton } 612ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton 622ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton @RequiresApi(24) 632ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton private ServiceWorkerWebSettings getFrameworksImpl() { 642ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton if (mFrameworksImpl == null) { 652ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton mFrameworksImpl = 662ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton WebViewGlueCommunicator.getCompatConverter().convertServiceWorkerSettings( 672ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton Proxy.getInvocationHandler(mBoundaryInterface)); 6857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 692ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton return mFrameworksImpl; 7057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 7157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 7257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton private ServiceWorkerWebSettingsBoundaryInterface getBoundaryInterface() { 732ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton if (mBoundaryInterface == null) { 742ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton // If the boundary interface is null we must have a working frameworks implementation to 752ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton // convert into a boundary interface. 762ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton // The case of the boundary interface being null here only occurs if we created the 772ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton // ServiceWorkerWebSettingsImpl using a frameworks API, but now want to call an API on 782ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton // the ServiceWorkerWebSettingsImpl that is only supported by the support library glue. 792ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton // This could happen for example if we introduce a new ServiceWorkerWebSettings API in 802ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton // level 30 and we run the support library on an N device (whose framework supports 812ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton // ServiceWorkerWebSettings). 822ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton mBoundaryInterface = BoundaryInterfaceReflectionUtil.castToSuppLibClass( 832ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton ServiceWorkerWebSettingsBoundaryInterface.class, 842ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton WebViewGlueCommunicator.getCompatConverter().convertServiceWorkerSettings( 852ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton mFrameworksImpl)); 862ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton } 8757d3714176493740842e8e2d0700106a6b64f048Gustav Sennton return mBoundaryInterface; 8857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 8957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 9057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @SuppressLint("NewApi") 9157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @Override 9257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton public void setCacheMode(int mode) { 9357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_CACHE_MODE; 9457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton if (feature.isSupportedByFramework()) { 952ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton getFrameworksImpl().setCacheMode(mode); 9657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else if (feature.isSupportedByWebView()) { 9757d3714176493740842e8e2d0700106a6b64f048Gustav Sennton getBoundaryInterface().setCacheMode(mode); 9857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else { 9957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton throw WebViewFeatureInternal.getUnsupportedOperationException(); 10057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 10157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 10257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 10357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @SuppressLint("NewApi") 10457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @Override 10557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton public int getCacheMode() { 10657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_CACHE_MODE; 10757d3714176493740842e8e2d0700106a6b64f048Gustav Sennton if (feature.isSupportedByFramework()) { 1082ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton return getFrameworksImpl().getCacheMode(); 10957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else if (feature.isSupportedByWebView()) { 11057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton return getBoundaryInterface().getCacheMode(); 11157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else { 11257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton throw WebViewFeatureInternal.getUnsupportedOperationException(); 11357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 11457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 11557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 11657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @SuppressLint("NewApi") 11757d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @Override 11857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton public void setAllowContentAccess(boolean allow) { 11957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_CONTENT_ACCESS; 12057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton if (feature.isSupportedByFramework()) { 1212ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton getFrameworksImpl().setAllowContentAccess(allow); 12257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else if (feature.isSupportedByWebView()) { 12357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton getBoundaryInterface().setAllowContentAccess(allow); 12457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else { 12557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton throw WebViewFeatureInternal.getUnsupportedOperationException(); 12657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 12757d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 12857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 12957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @SuppressLint("NewApi") 13057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @Override 13157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton public boolean getAllowContentAccess() { 13257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_CONTENT_ACCESS; 13357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton if (feature.isSupportedByFramework()) { 1342ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton return getFrameworksImpl().getAllowContentAccess(); 13557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else if (feature.isSupportedByWebView()) { 13657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton return getBoundaryInterface().getAllowContentAccess(); 13757d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else { 13857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton throw WebViewFeatureInternal.getUnsupportedOperationException(); 13957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 14057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 14157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 14257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @SuppressLint("NewApi") 14357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @Override 14457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton public void setAllowFileAccess(boolean allow) { 14557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_FILE_ACCESS; 14657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton if (feature.isSupportedByFramework()) { 1472ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton getFrameworksImpl().setAllowFileAccess(allow); 14857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else if (feature.isSupportedByWebView()) { 14957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton getBoundaryInterface().setAllowFileAccess(allow); 15057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else { 15157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton throw WebViewFeatureInternal.getUnsupportedOperationException(); 15257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 15357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 15457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 15557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @SuppressLint("NewApi") 15657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @Override 15757d3714176493740842e8e2d0700106a6b64f048Gustav Sennton public boolean getAllowFileAccess() { 15857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton final WebViewFeatureInternal feature = WebViewFeatureInternal.SERVICE_WORKER_FILE_ACCESS; 15957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton if (feature.isSupportedByFramework()) { 1602ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton return getFrameworksImpl().getAllowFileAccess(); 16157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else if (feature.isSupportedByWebView()) { 16257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton return getBoundaryInterface().getAllowFileAccess(); 16357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else { 16457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton throw WebViewFeatureInternal.getUnsupportedOperationException(); 16557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 16657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 16757d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 16857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @SuppressLint("NewApi") 16957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @Override 17057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton public void setBlockNetworkLoads(boolean flag) { 17157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton final WebViewFeatureInternal feature = 17257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton WebViewFeatureInternal.SERVICE_WORKER_BLOCK_NETWORK_LOADS; 17357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton if (feature.isSupportedByFramework()) { 1742ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton getFrameworksImpl().setBlockNetworkLoads(flag); 17557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else if (feature.isSupportedByWebView()) { 17657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton getBoundaryInterface().setBlockNetworkLoads(flag); 17757d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else { 17857d3714176493740842e8e2d0700106a6b64f048Gustav Sennton throw WebViewFeatureInternal.getUnsupportedOperationException(); 17957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 18057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 18157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton 18257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @SuppressLint("NewApi") 18357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton @Override 18457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton public boolean getBlockNetworkLoads() { 18557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton final WebViewFeatureInternal feature = 18657d3714176493740842e8e2d0700106a6b64f048Gustav Sennton WebViewFeatureInternal.SERVICE_WORKER_BLOCK_NETWORK_LOADS; 18757d3714176493740842e8e2d0700106a6b64f048Gustav Sennton if (feature.isSupportedByFramework()) { 1882ce86e26e35d90fc8a12484710c2cacedfaf9f9dGustav Sennton return getFrameworksImpl().getBlockNetworkLoads(); 18957d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else if (feature.isSupportedByWebView()) { 19057d3714176493740842e8e2d0700106a6b64f048Gustav Sennton return getBoundaryInterface().getBlockNetworkLoads(); 19157d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } else { 19257d3714176493740842e8e2d0700106a6b64f048Gustav Sennton throw WebViewFeatureInternal.getUnsupportedOperationException(); 19357d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 19457d3714176493740842e8e2d0700106a6b64f048Gustav Sennton } 19557d3714176493740842e8e2d0700106a6b64f048Gustav Sennton} 196