1 /* 2 * Copyright 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.webkit.internal; 18 19 import android.content.Context; 20 import android.os.Build; 21 import android.webkit.ValueCallback; 22 import android.webkit.WebResourceRequest; 23 import android.webkit.WebSettings; 24 25 import androidx.webkit.ServiceWorkerClientCompat; 26 import androidx.webkit.WebResourceRequestCompat; 27 import androidx.webkit.WebViewClientCompat; 28 import androidx.webkit.WebViewCompat; 29 import androidx.webkit.WebViewFeature; 30 import androidx.webkit.WebViewFeature.WebViewSupportFeature; 31 32 import java.util.List; 33 34 /** 35 * Enum representing a WebView feature, this provides functionality for determining whether a 36 * feature is supported by the current framework and/or WebView APK. 37 */ 38 public enum WebViewFeatureInternal { 39 /** 40 * This feature covers 41 * {@link androidx.webkit.WebViewCompat#postVisualStateCallback(android.webkit.WebView, long, 42 * androidx.webkit.WebViewCompat.VisualStateCallback)}, and 43 * {@link WebViewClientCompat#onPageCommitVisible(android.webkit.WebView, String)}. 44 */ 45 VISUAL_STATE_CALLBACK_FEATURE(WebViewFeature.VISUAL_STATE_CALLBACK, Build.VERSION_CODES.M), 46 47 /** 48 * This feature covers 49 * {@link androidx.webkit.WebSettingsCompat#getOffscreenPreRaster(WebSettings)}, and 50 * {@link androidx.webkit.WebSettingsCompat#setOffscreenPreRaster(WebSettings, boolean)}. 51 */ 52 OFF_SCREEN_PRERASTER(WebViewFeature.OFF_SCREEN_PRERASTER, Build.VERSION_CODES.M), 53 54 /** 55 * This feature covers 56 * {@link androidx.webkit.WebSettingsCompat#getSafeBrowsingEnabled(WebSettings)}, and 57 * {@link androidx.webkit.WebSettingsCompat#setSafeBrowsingEnabled(WebSettings, boolean)}. 58 */ 59 SAFE_BROWSING_ENABLE(WebViewFeature.SAFE_BROWSING_ENABLE, Build.VERSION_CODES.O), 60 61 /** 62 * This feature covers 63 * {@link androidx.webkit.WebSettingsCompat#getDisabledActionModeMenuItems(WebSettings)}, and 64 * {@link androidx.webkit.WebSettingsCompat#setDisabledActionModeMenuItems(WebSettings, int)}. 65 */ 66 DISABLED_ACTION_MODE_MENU_ITEMS(WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, 67 Build.VERSION_CODES.N), 68 69 /** 70 * This feature covers 71 * {@link androidx.webkit.WebViewCompat#startSafeBrowsing(Context, ValueCallback)}. 72 */ 73 START_SAFE_BROWSING(WebViewFeature.START_SAFE_BROWSING, Build.VERSION_CODES.O_MR1), 74 75 /** 76 * This feature covers 77 * {@link androidx.webkit.WebViewCompat#setSafeBrowsingWhitelist(List, ValueCallback)}. 78 */ 79 SAFE_BROWSING_WHITELIST(WebViewFeature.SAFE_BROWSING_WHITELIST, Build.VERSION_CODES.O_MR1), 80 81 /** 82 * This feature covers 83 * {@link WebViewCompat#getSafeBrowsingPrivacyPolicyUrl()}. 84 */ 85 SAFE_BROWSING_PRIVACY_POLICY_URL(WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL, 86 Build.VERSION_CODES.O_MR1), 87 88 /** 89 * This feature covers 90 * {@link androidx.webkit.ServiceWorkerControllerCompat#getInstance()}. 91 */ 92 SERVICE_WORKER_BASIC_USAGE(WebViewFeature.SERVICE_WORKER_BASIC_USAGE, Build.VERSION_CODES.N), 93 94 /** 95 * This feature covers 96 * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#getCacheMode()}, and 97 * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#setCacheMode(int)}. 98 */ 99 SERVICE_WORKER_CACHE_MODE(WebViewFeature.SERVICE_WORKER_CACHE_MODE, Build.VERSION_CODES.N), 100 101 /** 102 * This feature covers 103 * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#getAllowContentAccess()}, and 104 * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#setAllowContentAccess(boolean)}. 105 */ 106 SERVICE_WORKER_CONTENT_ACCESS(WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, 107 Build.VERSION_CODES.N), 108 109 /** 110 * This feature covers 111 * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#getAllowFileAccess()}, and 112 * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#setAllowFileAccess(boolean)}. 113 */ 114 SERVICE_WORKER_FILE_ACCESS(WebViewFeature.SERVICE_WORKER_FILE_ACCESS, Build.VERSION_CODES.N), 115 116 /** 117 * This feature covers 118 * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#getBlockNetworkLoads()}, and 119 * {@link androidx.webkit.ServiceWorkerWebSettingsCompat#setBlockNetworkLoads(boolean)}. 120 */ 121 SERVICE_WORKER_BLOCK_NETWORK_LOADS(WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, 122 Build.VERSION_CODES.N), 123 124 /** 125 * This feature covers 126 * {@link ServiceWorkerClientCompat#shouldInterceptRequest(WebResourceRequest)}. 127 */ 128 SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST(WebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST, 129 Build.VERSION_CODES.N), 130 131 /** 132 * This feature covers 133 * {@link WebViewClientCompat#onReceivedError(android.webkit.WebView, WebResourceRequest, 134 * WebResourceErrorCompat)}. 135 */ 136 RECEIVE_WEB_RESOURCE_ERROR(WebViewFeature.RECEIVE_WEB_RESOURCE_ERROR, Build.VERSION_CODES.M), 137 138 /** 139 * This feature covers 140 * {@link WebViewClientCompat#onReceivedHttpError(android.webkit.WebView, WebResourceRequest, 141 * WebResourceResponse)}. 142 */ 143 RECEIVE_HTTP_ERROR(WebViewFeature.RECEIVE_HTTP_ERROR, Build.VERSION_CODES.M), 144 145 /** 146 * This feature covers 147 * {@link WebViewClientCompat#shouldOverrideUrlLoading(android.webkit.WebView, 148 * WebResourceRequest)}. 149 */ 150 SHOULD_OVERRIDE_WITH_REDIRECTS(WebViewFeature.SHOULD_OVERRIDE_WITH_REDIRECTS, 151 Build.VERSION_CODES.N), 152 153 /** 154 * This feature covers 155 * {@link WebViewClientCompat#onSafeBrowsingHit(android.webkit.WebView, 156 * WebResourceRequest, int, SafeBrowsingResponseCompat)}. 157 */ 158 SAFE_BROWSING_HIT(WebViewFeature.SAFE_BROWSING_HIT, Build.VERSION_CODES.O_MR1), 159 160 /** 161 * This feature covers 162 * {@link WebResourceRequestCompat#isRedirect(WebResourceRequest)}. 163 */ 164 WEB_RESOURCE_REQUEST_IS_REDIRECT(WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT, 165 Build.VERSION_CODES.N), 166 167 /** 168 * This feature covers 169 * {@link WebResourceErrorCompat#getDescription()}. 170 */ 171 WEB_RESOURCE_ERROR_GET_DESCRIPTION(WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION, 172 Build.VERSION_CODES.M), 173 174 /** 175 * This feature covers 176 * {@link WebResourceErrorCompat#getErrorCode()}. 177 */ 178 WEB_RESOURCE_ERROR_GET_CODE(WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE, 179 Build.VERSION_CODES.M), 180 181 /** 182 * This feature covers 183 * {@link SafeBrowsingResponseCompat#backToSafety(boolean)}. 184 */ 185 SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY(WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY, 186 Build.VERSION_CODES.O_MR1), 187 188 /** 189 * This feature covers 190 * {@link SafeBrowsingResponseCompat#proceed(boolean)}. 191 */ 192 SAFE_BROWSING_RESPONSE_PROCEED(WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED, 193 Build.VERSION_CODES.O_MR1), 194 195 /** 196 * This feature covers 197 * {@link SafeBrowsingResponseCompat#showInterstitial(boolean)}. 198 */ 199 SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL( 200 WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL, 201 Build.VERSION_CODES.O_MR1); 202 203 private final String mFeatureValue; 204 private final int mOsVersion; 205 WebViewFeatureInternal(@ebViewSupportFeature String featureValue, int osVersion)206 WebViewFeatureInternal(@WebViewSupportFeature String featureValue, int osVersion) { 207 mFeatureValue = featureValue; 208 mOsVersion = osVersion; 209 } 210 211 /** 212 * Return the {@link WebViewFeatureInternal} corresponding to {@param feature}. 213 */ getFeature(@ebViewSupportFeature String feature)214 public static WebViewFeatureInternal getFeature(@WebViewSupportFeature String feature) { 215 for (WebViewFeatureInternal internalFeature : WebViewFeatureInternal.values()) { 216 if (internalFeature.mFeatureValue.equals(feature)) return internalFeature; 217 } 218 throw new RuntimeException("Unknown feature " + feature); 219 } 220 221 /** 222 * Return whether this {@link WebViewFeature} is supported by the framework of the current 223 * device. 224 */ isSupportedByFramework()225 public boolean isSupportedByFramework() { 226 return Build.VERSION.SDK_INT >= mOsVersion; 227 } 228 229 /** 230 * Return whether this {@link WebViewFeature} is supported by the current WebView APK. 231 */ isSupportedByWebView()232 public boolean isSupportedByWebView() { 233 String[] webviewFeatures = LAZY_HOLDER.WEBVIEW_APK_FEATURES; 234 for (String webviewFeature : webviewFeatures) { 235 if (webviewFeature.equals(mFeatureValue)) return true; 236 } 237 return false; 238 } 239 240 private static class LAZY_HOLDER { 241 static final String[] WEBVIEW_APK_FEATURES = 242 WebViewGlueCommunicator.getFactory().getWebViewFeatures(); 243 } 244 245 getWebViewApkFeaturesForTesting()246 public static String[] getWebViewApkFeaturesForTesting() { 247 return LAZY_HOLDER.WEBVIEW_APK_FEATURES; 248 } 249 250 /** 251 * Utility method for throwing an exception explaining that the feature the app trying to use 252 * isn't supported. 253 */ getUnsupportedOperationException()254 public static UnsupportedOperationException getUnsupportedOperationException() { 255 return new UnsupportedOperationException("This method is not supported by the current " 256 + "version of the framework and the current WebView APK"); 257 } 258 } 259