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;
18 
19 import android.content.Context;
20 import android.webkit.ValueCallback;
21 import android.webkit.WebResourceRequest;
22 import android.webkit.WebSettings;
23 
24 import androidx.annotation.NonNull;
25 import androidx.annotation.RestrictTo;
26 import androidx.annotation.StringDef;
27 import androidx.webkit.internal.WebViewFeatureInternal;
28 
29 import org.chromium.support_lib_boundary.util.Features;
30 
31 import java.lang.annotation.ElementType;
32 import java.lang.annotation.Retention;
33 import java.lang.annotation.RetentionPolicy;
34 import java.lang.annotation.Target;
35 import java.util.List;
36 
37 /**
38  * Utility class for checking which WebView Support Library features are supported on the device.
39  */
40 public class WebViewFeature {
41 
WebViewFeature()42     private WebViewFeature() {}
43 
44     /**
45      * @hide
46      */
47     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
48     @StringDef(value = {
49             VISUAL_STATE_CALLBACK,
50             OFF_SCREEN_PRERASTER,
51             SAFE_BROWSING_ENABLE,
52             DISABLED_ACTION_MODE_MENU_ITEMS,
53             START_SAFE_BROWSING,
54             SAFE_BROWSING_WHITELIST,
55             SAFE_BROWSING_PRIVACY_POLICY_URL,
56             SERVICE_WORKER_BASIC_USAGE,
57             SERVICE_WORKER_CACHE_MODE,
58             SERVICE_WORKER_CONTENT_ACCESS,
59             SERVICE_WORKER_FILE_ACCESS,
60             SERVICE_WORKER_BLOCK_NETWORK_LOADS,
61             SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST,
62             RECEIVE_WEB_RESOURCE_ERROR,
63             RECEIVE_HTTP_ERROR,
64             SHOULD_OVERRIDE_WITH_REDIRECTS,
65             SAFE_BROWSING_HIT,
66             WEB_RESOURCE_REQUEST_IS_REDIRECT,
67             WEB_RESOURCE_ERROR_GET_DESCRIPTION,
68             WEB_RESOURCE_ERROR_GET_CODE,
69             SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY,
70             SAFE_BROWSING_RESPONSE_PROCEED,
71             SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL
72     })
73     @Retention(RetentionPolicy.SOURCE)
74     @Target({ElementType.PARAMETER, ElementType.METHOD})
75     public @interface WebViewSupportFeature {}
76 
77     /**
78      * Feature for {@link #isFeatureSupported(String)}.
79      * This feature covers
80      * {@link androidx.webkit.WebViewCompat#postVisualStateCallback(android.webkit.WebView, long,
81      * WebViewCompat.VisualStateCallback)}, and {@link
82      * WebViewClientCompat#onPageCommitVisible(
83      * android.webkit.WebView, String)}.
84      */
85     public static final String VISUAL_STATE_CALLBACK = Features.VISUAL_STATE_CALLBACK;
86 
87     /**
88      * Feature for {@link #isFeatureSupported(String)}.
89      * This feature covers
90      * {@link androidx.webkit.WebSettingsCompat#getOffscreenPreRaster(WebSettings)}, and
91      * {@link androidx.webkit.WebSettingsCompat#setOffscreenPreRaster(WebSettings, boolean)}.
92      */
93     public static final String OFF_SCREEN_PRERASTER = Features.OFF_SCREEN_PRERASTER;
94 
95     /**
96      * Feature for {@link #isFeatureSupported(String)}.
97      * This feature covers
98      * {@link androidx.webkit.WebSettingsCompat#getSafeBrowsingEnabled(WebSettings)}, and
99      * {@link androidx.webkit.WebSettingsCompat#setSafeBrowsingEnabled(WebSettings, boolean)}.
100      */
101     public static final String SAFE_BROWSING_ENABLE = Features.SAFE_BROWSING_ENABLE;
102 
103     /**
104      * Feature for {@link #isFeatureSupported(String)}.
105      * This feature covers
106      * {@link androidx.webkit.WebSettingsCompat#getDisabledActionModeMenuItems(WebSettings)}, and
107      * {@link androidx.webkit.WebSettingsCompat#setDisabledActionModeMenuItems(WebSettings, int)}.
108      */
109     public static final String DISABLED_ACTION_MODE_MENU_ITEMS =
110             Features.DISABLED_ACTION_MODE_MENU_ITEMS;
111 
112     /**
113      * Feature for {@link #isFeatureSupported(String)}.
114      * This feature covers
115      * {@link androidx.webkit.WebViewCompat#startSafeBrowsing(Context, ValueCallback)}.
116      */
117     public static final String START_SAFE_BROWSING = Features.START_SAFE_BROWSING;
118 
119     /**
120      * Feature for {@link #isFeatureSupported(String)}.
121      * This feature covers
122      * {@link androidx.webkit.WebViewCompat#setSafeBrowsingWhitelist(List, ValueCallback)}.
123      */
124     public static final String SAFE_BROWSING_WHITELIST = Features.SAFE_BROWSING_WHITELIST;
125 
126     /**
127      * Feature for {@link #isFeatureSupported(String)}.
128      * This feature covers
129      * {@link WebViewCompat#getSafeBrowsingPrivacyPolicyUrl()}.
130      */
131     public static final String SAFE_BROWSING_PRIVACY_POLICY_URL =
132             Features.SAFE_BROWSING_PRIVACY_POLICY_URL;
133 
134     /**
135      * Feature for {@link #isFeatureSupported(String)}.
136      * This feature covers
137      * {@link ServiceWorkerControllerCompat#getInstance()}.
138      */
139     public static final String SERVICE_WORKER_BASIC_USAGE = Features.SERVICE_WORKER_BASIC_USAGE;
140 
141     /**
142      * Feature for {@link #isFeatureSupported(String)}.
143      * This feature covers
144      * {@link ServiceWorkerWebSettingsCompat#getCacheMode()}, and
145      * {@link ServiceWorkerWebSettingsCompat#setCacheMode(int)}.
146      */
147     public static final String SERVICE_WORKER_CACHE_MODE = Features.SERVICE_WORKER_CACHE_MODE;
148 
149     /**
150      * Feature for {@link #isFeatureSupported(String)}.
151      * This feature covers
152      * {@link ServiceWorkerWebSettingsCompat#getAllowContentAccess()}, and
153      * {@link ServiceWorkerWebSettingsCompat#setAllowContentAccess(boolean)}.
154      */
155     public static final String SERVICE_WORKER_CONTENT_ACCESS =
156             Features.SERVICE_WORKER_CONTENT_ACCESS;
157 
158     /**
159      * Feature for {@link #isFeatureSupported(String)}.
160      * This feature covers
161      * {@link ServiceWorkerWebSettingsCompat#getAllowFileAccess()}, and
162      * {@link ServiceWorkerWebSettingsCompat#setAllowFileAccess(boolean)}.
163      */
164     public static final String SERVICE_WORKER_FILE_ACCESS = Features.SERVICE_WORKER_FILE_ACCESS;
165 
166     /**
167      * Feature for {@link #isFeatureSupported(String)}.
168      * This feature covers
169      * {@link ServiceWorkerWebSettingsCompat#getBlockNetworkLoads()}, and
170      * {@link ServiceWorkerWebSettingsCompat#setBlockNetworkLoads(boolean)}.
171      */
172     public static final String SERVICE_WORKER_BLOCK_NETWORK_LOADS =
173             Features.SERVICE_WORKER_BLOCK_NETWORK_LOADS;
174 
175     /**
176      * Feature for {@link #isFeatureSupported(String)}.
177      * This feature covers
178      * {@link ServiceWorkerClientCompat#shouldInterceptRequest(WebResourceRequest)}.
179      */
180     public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST =
181             Features.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST;
182 
183     /**
184      * Feature for {@link #isFeatureSupported(String)}.
185      * This feature covers
186      * {@link WebViewClientCompat#onReceivedError(android.webkit.WebView, WebResourceRequest,
187      * WebResourceErrorCompat)}.
188      */
189     public static final String RECEIVE_WEB_RESOURCE_ERROR = Features.RECEIVE_WEB_RESOURCE_ERROR;
190 
191     /**
192      * Feature for {@link #isFeatureSupported(String)}.
193      * This feature covers
194      * {@link WebViewClientCompat#onReceivedHttpError(android.webkit.WebView, WebResourceRequest,
195      * WebResourceResponse)}.
196      */
197     public static final String RECEIVE_HTTP_ERROR = Features.RECEIVE_HTTP_ERROR;
198 
199     /**
200      * Feature for {@link #isFeatureSupported(String)}.
201      * This feature covers
202      * {@link WebViewClientCompat#shouldOverrideUrlLoading(android.webkit.WebView,
203      * WebResourceRequest)}.
204      */
205     public static final String SHOULD_OVERRIDE_WITH_REDIRECTS =
206             Features.SHOULD_OVERRIDE_WITH_REDIRECTS;
207 
208     /**
209      * Feature for {@link #isFeatureSupported(String)}.
210      * This feature covers
211      * {@link WebViewClientCompat#onSafeBrowsingHit(android.webkit.WebView,
212      * WebResourceRequest, int, SafeBrowsingResponseCompat)}.
213      */
214     public static final String SAFE_BROWSING_HIT = Features.SAFE_BROWSING_HIT;
215 
216     /**
217      * Feature for {@link #isFeatureSupported(String)}.
218      * This feature covers
219      * {@link WebResourceRequestCompat#isRedirect(WebResourceRequest)}.
220      */
221     public static final String WEB_RESOURCE_REQUEST_IS_REDIRECT =
222             Features.WEB_RESOURCE_REQUEST_IS_REDIRECT;
223 
224     /**
225      * Feature for {@link #isFeatureSupported(String)}.
226      * This feature covers
227      * {@link WebResourceErrorCompat#getDescription()}.
228      */
229     public static final String WEB_RESOURCE_ERROR_GET_DESCRIPTION =
230             Features.WEB_RESOURCE_ERROR_GET_DESCRIPTION;
231 
232     /**
233      * Feature for {@link #isFeatureSupported(String)}.
234      * This feature covers
235      * {@link WebResourceErrorCompat#getErrorCode()}.
236      */
237     public static final String WEB_RESOURCE_ERROR_GET_CODE =
238             Features.WEB_RESOURCE_ERROR_GET_CODE;
239 
240     /**
241      * Feature for {@link #isFeatureSupported(String)}.
242      * This feature covers
243      * {@link SafeBrowsingResponseCompat#backToSafety(boolean)}.
244      */
245     public static final String SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY =
246             Features.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY;
247 
248     /**
249      * Feature for {@link #isFeatureSupported(String)}.
250      * This feature covers
251      * {@link SafeBrowsingResponseCompat#proceed(boolean)}.
252      */
253     public static final String SAFE_BROWSING_RESPONSE_PROCEED =
254             Features.SAFE_BROWSING_RESPONSE_PROCEED;
255 
256     /**
257      * Feature for {@link #isFeatureSupported(String)}.
258      * This feature covers
259      * {@link SafeBrowsingResponseCompat#showInterstitial(boolean)}.
260      */
261     public static final String SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL =
262             Features.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL;
263 
264     /**
265      * Return whether a feature is supported at run-time. This depends on the Android version of the
266      * device and the WebView APK on the device.
267      */
isFeatureSupported(@onNull @ebViewSupportFeature String feature)268     public static boolean isFeatureSupported(@NonNull @WebViewSupportFeature String feature) {
269         WebViewFeatureInternal webviewFeature = WebViewFeatureInternal.getFeature(feature);
270         return webviewFeature.isSupportedByFramework() || webviewFeature.isSupportedByWebView();
271     }
272 }
273