Merge "[WebView Support Library] Add WebViewClientCompat feature flags" into pi-androidx-dev
diff --git a/webkit/api/current.txt b/webkit/api/current.txt
index b001df8..dfb6bfa 100644
--- a/webkit/api/current.txt
+++ b/webkit/api/current.txt
@@ -58,7 +58,10 @@
     method public static boolean isFeatureSupported(java.lang.String);
     field public static final java.lang.String DISABLED_ACTION_MODE_MENU_ITEMS = "DISABLED_ACTION_MODE_MENU_ITEMS";
     field public static final java.lang.String OFF_SCREEN_PRERASTER = "OFF_SCREEN_PRERASTER";
+    field public static final java.lang.String RECEIVE_HTTP_ERROR = "RECEIVE_HTTP_ERROR";
+    field public static final java.lang.String RECEIVE_WEB_RESOURCE_ERROR = "RECEIVE_WEB_RESOURCE_ERROR";
     field public static final java.lang.String SAFE_BROWSING_ENABLE = "SAFE_BROWSING_ENABLE";
+    field public static final java.lang.String SAFE_BROWSING_HIT = "SAFE_BROWSING_HIT";
     field public static final java.lang.String SAFE_BROWSING_PRIVACY_POLICY_URL = "SAFE_BROWSING_PRIVACY_POLICY_URL";
     field public static final java.lang.String SAFE_BROWSING_WHITELIST = "SAFE_BROWSING_WHITELIST";
     field public static final java.lang.String SERVICE_WORKER_BASIC_USAGE = "SERVICE_WORKER_BASIC_USAGE";
@@ -67,6 +70,7 @@
     field public static final java.lang.String SERVICE_WORKER_CONTENT_ACCESS = "SERVICE_WORKER_CONTENT_ACCESS";
     field public static final java.lang.String SERVICE_WORKER_FILE_ACCESS = "SERVICE_WORKER_FILE_ACCESS";
     field public static final java.lang.String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = "SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST";
+    field public static final java.lang.String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS";
     field public static final java.lang.String START_SAFE_BROWSING = "START_SAFE_BROWSING";
     field public static final java.lang.String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
   }
diff --git a/webkit/src/main/java/androidx/webkit/WebViewClientCompat.java b/webkit/src/main/java/androidx/webkit/WebViewClientCompat.java
index 22a19fa..11676fa 100644
--- a/webkit/src/main/java/androidx/webkit/WebViewClientCompat.java
+++ b/webkit/src/main/java/androidx/webkit/WebViewClientCompat.java
@@ -29,6 +29,7 @@
 import androidx.annotation.RestrictTo;
 
 import org.chromium.support_lib_boundary.WebViewClientBoundaryInterface;
+import org.chromium.support_lib_boundary.util.Features;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -42,6 +43,13 @@
 // still construct a WebViewClientCompat on a pre-Lollipop devices, and explicitly invoke these
 // methods, so each of these methods must also handle this case.
 public class WebViewClientCompat extends WebViewClient implements WebViewClientBoundaryInterface {
+    private static final String[] sSupportedFeatures = new String[] {
+        Features.VISUAL_STATE_CALLBACK,
+        Features.RECEIVE_WEB_RESOURCE_ERROR,
+        Features.RECEIVE_HTTP_ERROR,
+        Features.SHOULD_OVERRIDE_WITH_REDIRECTS,
+    };
+
     /** @hide */
     @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
     @IntDef(value = {
@@ -53,6 +61,49 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface SafeBrowsingThreat {}
 
+    /**
+     * Returns the list of features this client supports. This feature list should always be a
+     * subset of the Features declared in WebViewFeature.
+     *
+     * @hide
+     */
+    @Override
+    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+    public final String[] getSupportedFeatures() {
+        return sSupportedFeatures;
+    }
+
+    /**
+     * Notify the host application that {@link android.webkit.WebView} content left over from
+     * previous page navigations will no longer be drawn.
+     *
+     * <p>This callback can be used to determine the point at which it is safe to make a recycled
+     * {@link android.webkit.WebView} visible, ensuring that no stale content is shown. It is called
+     * at the earliest point at which it can be guaranteed that {@link WebView#onDraw} will no
+     * longer draw any content from previous navigations. The next draw will display either the
+     * {@link WebView#setBackgroundColor background color} of the {@link WebView}, or some of the
+     * contents of the newly loaded page.
+     *
+     * <p>This method is called when the body of the HTTP response has started loading, is reflected
+     * in the DOM, and will be visible in subsequent draws. This callback occurs early in the
+     * document loading process, and as such you should expect that linked resources (for example,
+     * CSS and images) may not be available.
+     *
+     * <p>For more fine-grained notification of visual state updates, see {@link
+     * WebViewCompat#postVisualStateCallback}.
+     *
+     * <p>Please note that all the conditions and recommendations applicable to
+     * {@link WebViewCompat#postVisualStateCallback} also apply to this API.
+     *
+     * <p>This callback is only called for main frame navigations.
+     *
+     * <p>This method is called only if {@link WebViewFeature#VISUAL_STATE_CALLBACK} is supported.
+     * You can check whether that flag is supported using {@link
+     * WebViewFeature#isFeatureSupported(String)}.
+     *
+     * @param view The {@link android.webkit.WebView} for which the navigation occurred.
+     * @param url  The URL corresponding to the page navigation that triggered this callback.
+     */
     @Override
     public void onPageCommitVisible(@NonNull WebView view, @NonNull String url) {
     }
@@ -94,6 +145,11 @@
      * inability to connect to the server. Note that unlike the deprecated version of the callback,
      * the new version will be called for any resource (iframe, image, etc.), not just for the main
      * page. Thus, it is recommended to perform minimum required work in this callback.
+     *
+     * <p>This method is called only if {@link WebViewFeature#RECEIVE_WEB_RESOURCE_ERROR} is
+     * supported. You can check whether that flag is supported using {@link
+     * WebViewFeature#isFeatureSupported(String)}.
+     *
      * @param view The WebView that is initiating the callback.
      * @param request The originating request.
      * @param error Information about the error occurred.
@@ -110,6 +166,21 @@
         }
     }
 
+    /**
+     * Notify the host application that an HTTP error has been received from the server while
+     * loading a resource.  HTTP errors have status codes &gt;= 400.  This callback will be called
+     * for any resource (iframe, image, etc.), not just for the main page. Thus, it is recommended
+     * to perform minimum required work in this callback. Note that the content of the server
+     * response may not be provided within the {@code errorResponse} parameter.
+     *
+     * <p>This method is called only if {@link WebViewFeature#RECEIVE_HTTP_ERROR} is supported. You
+     * can check whether that flag is supported using {@link
+     * WebViewFeature#isFeatureSupported(String)}.
+     *
+     * @param view The WebView that is initiating the callback.
+     * @param request The originating request.
+     * @param errorResponse Information about the error occurred.
+     */
     @Override
     public void onReceivedHttpError(@NonNull WebView view, @NonNull WebResourceRequest request,
             @NonNull WebResourceResponse errorResponse) {
@@ -130,6 +201,32 @@
         // TODO(ntfschr): implement this (b/73151460).
     }
 
+    /**
+     * Give the host application a chance to take over the control when a new
+     * url is about to be loaded in the current WebView. If WebViewClient is not
+     * provided, by default WebView will ask Activity Manager to choose the
+     * proper handler for the url. If WebViewClient is provided, return {@code true}
+     * means the host application handles the url, while return {@code false} means the
+     * current WebView handles the url.
+     *
+     * <p>Notes:
+     * <ul>
+     * <li>This method is not called for requests using the POST &quot;method&quot;.</li>
+     * <li>This method is also called for subframes with non-http schemes, thus it is
+     * strongly disadvised to unconditionally call {@link WebView#loadUrl(String)}
+     * with the request's url from inside the method and then return {@code true},
+     * as this will make WebView to attempt loading a non-http url, and thus fail.</li>
+     * </ul>
+     *
+     * <p>This method is called only if {@link WebViewFeature#SHOULD_OVERRIDE_WITH_REDIRECTS} is
+     * supported. You can check whether that flag is supported using {@link
+     * WebViewFeature#isFeatureSupported(String)}.
+     *
+     * @param view The WebView that is initiating the callback.
+     * @param request Object containing the details of the request.
+     * @return {@code true} if the host application wants to leave the current WebView
+     *         and handle the url itself, otherwise return {@code false}.
+     */
     @Override
     @SuppressWarnings("deprecation") // for invoking the old shouldOverrideUrlLoading.
     @RequiresApi(21)
diff --git a/webkit/src/main/java/androidx/webkit/WebViewFeature.java b/webkit/src/main/java/androidx/webkit/WebViewFeature.java
index d321c8c..4286880 100644
--- a/webkit/src/main/java/androidx/webkit/WebViewFeature.java
+++ b/webkit/src/main/java/androidx/webkit/WebViewFeature.java
@@ -58,8 +58,11 @@
             SERVICE_WORKER_CONTENT_ACCESS,
             SERVICE_WORKER_FILE_ACCESS,
             SERVICE_WORKER_BLOCK_NETWORK_LOADS,
-            SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST
-
+            SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST,
+            RECEIVE_WEB_RESOURCE_ERROR,
+            RECEIVE_HTTP_ERROR,
+            SHOULD_OVERRIDE_WITH_REDIRECTS,
+            SAFE_BROWSING_HIT
     })
     @Retention(RetentionPolicy.SOURCE)
     @Target({ElementType.PARAMETER, ElementType.METHOD})
@@ -69,7 +72,9 @@
      * Feature for {@link #isFeatureSupported(String)}.
      * This feature covers
      * {@link androidx.webkit.WebViewCompat#postVisualStateCallback(android.webkit.WebView, long,
-     * WebViewCompat.VisualStateCallback)}.
+     * WebViewCompat.VisualStateCallback)}, and {@link
+     * WebViewClientCompat#onPageCommitVisible(
+     * android.webkit.WebView, String)}.
      */
     public static final String VISUAL_STATE_CALLBACK = Features.VISUAL_STATE_CALLBACK;
 
@@ -169,6 +174,41 @@
     public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST =
             Features.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST;
 
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link WebViewClientCompat#onReceivedError(android.webkit.WebView, WebResourceRequest,
+     * WebResourceErrorCompat)}.
+     */
+    public static final String RECEIVE_WEB_RESOURCE_ERROR = Features.RECEIVE_WEB_RESOURCE_ERROR;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link WebViewClientCompat#onReceivedHttpError(android.webkit.WebView, WebResourceRequest,
+     * WebResourceResponse)}.
+     */
+    public static final String RECEIVE_HTTP_ERROR = Features.RECEIVE_HTTP_ERROR;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * {@link WebViewClientCompat#shouldOverrideUrlLoading(android.webkit.WebView,
+     * WebResourceRequest)}.
+     */
+    public static final String SHOULD_OVERRIDE_WITH_REDIRECTS =
+            Features.SHOULD_OVERRIDE_WITH_REDIRECTS;
+
+    /**
+     * Feature for {@link #isFeatureSupported(String)}.
+     * This feature covers
+     * WebViewClientCompat#onSafeBrowsingHit(android.webkit.WebView,
+     * WebResourceRequest, int, SafeBrowsingResponseCompat).
+     *
+     * TODO(ntfschr): turn this into a javadoc link once the method is implemented in
+     * http://ag/3858246.
+     */
+    public static final String SAFE_BROWSING_HIT = Features.SAFE_BROWSING_HIT;
 
     /**
      * Return whether a feature is supported at run-time. This depends on the Android version of the
diff --git a/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java b/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
index b019544..d804ee9 100644
--- a/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
+++ b/webkit/src/main/java/androidx/webkit/internal/WebViewFeatureInternal.java
@@ -23,6 +23,7 @@
 import android.webkit.WebSettings;
 
 import androidx.webkit.ServiceWorkerClientCompat;
+import androidx.webkit.WebViewClientCompat;
 import androidx.webkit.WebViewCompat;
 import androidx.webkit.WebViewFeature;
 import androidx.webkit.WebViewFeature.WebViewSupportFeature;
@@ -37,7 +38,8 @@
     /**
      * This feature covers
      * {@link androidx.webkit.WebViewCompat#postVisualStateCallback(android.webkit.WebView, long,
-     * androidx.webkit.WebViewCompat.VisualStateCallback)}.
+     * androidx.webkit.WebViewCompat.VisualStateCallback)}, and
+     * {@link WebViewClientCompat#onPageCommitVisible(android.webkit.WebView, String)}.
      */
     VISUAL_STATE_CALLBACK_FEATURE(WebViewFeature.VISUAL_STATE_CALLBACK, Build.VERSION_CODES.M),
 
@@ -123,7 +125,39 @@
      * {@link ServiceWorkerClientCompat#shouldInterceptRequest(WebResourceRequest)}.
      */
     SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST(WebViewFeature.SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST,
-            Build.VERSION_CODES.N);
+            Build.VERSION_CODES.N),
+
+    /**
+     * This feature covers
+     * {@link WebViewClientCompat#onReceivedError(android.webkit.WebView, WebResourceRequest,
+     * WebResourceErrorCompat)}.
+     */
+    RECEIVE_WEB_RESOURCE_ERROR(WebViewFeature.RECEIVE_WEB_RESOURCE_ERROR, Build.VERSION_CODES.M),
+
+    /**
+     * This feature covers
+     * {@link WebViewClientCompat#onReceivedHttpError(android.webkit.WebView, WebResourceRequest,
+     * WebResourceResponse)}.
+     */
+    RECEIVE_HTTP_ERROR(WebViewFeature.RECEIVE_HTTP_ERROR, Build.VERSION_CODES.M),
+
+    /**
+     * This feature covers
+     * {@link WebViewClientCompat#shouldOverrideUrlLoading(android.webkit.WebView,
+     * WebResourceRequest)}.
+     */
+    SHOULD_OVERRIDE_WITH_REDIRECTS(WebViewFeature.SHOULD_OVERRIDE_WITH_REDIRECTS,
+            Build.VERSION_CODES.N),
+
+    /**
+     * This feature covers
+     * WebViewClientCompat#onSafeBrowsingHit(android.webkit.WebView,
+     * WebResourceRequest, int, SafeBrowsingResponseCompat).
+     *
+     * TODO(ntfschr): turn this into a javadoc link once the method is implemented in
+     * http://ag/3858246.
+     */
+    SAFE_BROWSING_HIT(WebViewFeature.SAFE_BROWSING_HIT, Build.VERSION_CODES.O_MR1);
 
     private final String mFeatureValue;
     private final int mOsVersion;