/*
 * Copyright (C) 2007 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.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Manages settings state for a WebView. When a WebView is first created, it
 * obtains a set of default settings. These default settings will be returned
 * from any getter call. A {@code WebSettings} object obtained from
 * {@link WebView#getSettings()} is tied to the life of the WebView. If a WebView has
 * been destroyed, any method call on {@code WebSettings} will throw an
 * {@link IllegalStateException}.
 */
// This is an abstract base class: concrete WebViewProviders must
// create a class derived from this, and return an instance of it in the
// WebViewProvider.getWebSettingsProvider() method implementation.
public abstract class WebSettings {
    /**
     * Enum for controlling the layout of html.
     * <ul>
     *   <li>{@code NORMAL} means no rendering changes. This is the recommended choice for maximum
     *       compatibility across different platforms and Android versions.</li>
     *   <li>{@code SINGLE_COLUMN} moves all content into one column that is the width of the
     *       view.</li>
     *   <li>{@code NARROW_COLUMNS} makes all columns no wider than the screen if possible. Only use
     *       this for API levels prior to {@link android.os.Build.VERSION_CODES#KITKAT}.</li>
     *   <li>{@code TEXT_AUTOSIZING} boosts font size of paragraphs based on heuristics to make
     *       the text readable when viewing a wide-viewport layout in the overview mode.
     *       It is recommended to enable zoom support {@link #setSupportZoom} when
     *       using this mode. Supported from API level
     *       {@link android.os.Build.VERSION_CODES#KITKAT}</li>
     * </ul>
     */
    // XXX: These must match LayoutAlgorithm in Settings.h in WebCore.
    public enum LayoutAlgorithm {
        NORMAL,
        /**
         * @deprecated This algorithm is now obsolete.
         */
        @Deprecated
        SINGLE_COLUMN,
        /**
         * @deprecated This algorithm is now obsolete.
         */
        @Deprecated
        NARROW_COLUMNS,
        TEXT_AUTOSIZING
    }

    /**
     * Enum for specifying the text size.
     * <ul>
     *   <li>SMALLEST is 50%</li>
     *   <li>SMALLER is 75%</li>
     *   <li>NORMAL is 100%</li>
     *   <li>LARGER is 150%</li>
     *   <li>LARGEST is 200%</li>
     * </ul>
     *
     * @deprecated Use {@link WebSettings#setTextZoom(int)} and {@link WebSettings#getTextZoom()} instead.
     */
    @Deprecated
    public enum TextSize {
        SMALLEST(50),
        SMALLER(75),
        NORMAL(100),
        LARGER(150),
        LARGEST(200);
        TextSize(int size) {
            value = size;
        }
        @UnsupportedAppUsage
        int value;
    }

    /**
     * Enum for specifying the WebView's desired density.
     * <ul>
     *   <li>{@code FAR} makes 100% looking like in 240dpi</li>
     *   <li>{@code MEDIUM} makes 100% looking like in 160dpi</li>
     *   <li>{@code CLOSE} makes 100% looking like in 120dpi</li>
     * </ul>
     */
    public enum ZoomDensity {
        FAR(150),      // 240dpi
        MEDIUM(100),    // 160dpi
        CLOSE(75);     // 120dpi
        ZoomDensity(int size) {
            value = size;
        }

        /**
         * @hide Only for use by WebViewProvider implementations
         */
        public int getValue() {
            return value;
        }

        int value;
    }

    /** @hide */
    @IntDef(prefix = { "LOAD_" }, value = {
            LOAD_DEFAULT,
            LOAD_NORMAL,
            LOAD_CACHE_ELSE_NETWORK,
            LOAD_NO_CACHE,
            LOAD_CACHE_ONLY
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface CacheMode {}

    /**
     * Default cache usage mode. If the navigation type doesn't impose any
     * specific behavior, use cached resources when they are available
     * and not expired, otherwise load resources from the network.
     * Use with {@link #setCacheMode}.
     */
    public static final int LOAD_DEFAULT = -1;

    /**
     * Normal cache usage mode. Use with {@link #setCacheMode}.
     *
     * @deprecated This value is obsolete, as from API level
     * {@link android.os.Build.VERSION_CODES#HONEYCOMB} and onwards it has the
     * same effect as {@link #LOAD_DEFAULT}.
     */
    @Deprecated
    public static final int LOAD_NORMAL = 0;

    /**
     * Use cached resources when they are available, even if they have expired.
     * Otherwise load resources from the network.
     * Use with {@link #setCacheMode}.
     */
    public static final int LOAD_CACHE_ELSE_NETWORK = 1;

    /**
     * Don't use the cache, load from the network.
     * Use with {@link #setCacheMode}.
     */
    public static final int LOAD_NO_CACHE = 2;

    /**
     * Don't use the network, load from the cache.
     * Use with {@link #setCacheMode}.
     */
    public static final int LOAD_CACHE_ONLY = 3;

    public enum RenderPriority {
        NORMAL,
        HIGH,
        LOW
    }

    /**
     * The plugin state effects how plugins are treated on a page. ON means
     * that any object will be loaded even if a plugin does not exist to handle
     * the content. ON_DEMAND means that if there is a plugin installed that
     * can handle the content, a placeholder is shown until the user clicks on
     * the placeholder. Once clicked, the plugin will be enabled on the page.
     * OFF means that all plugins will be turned off and any fallback content
     * will be used.
     */
    public enum PluginState {
        ON,
        ON_DEMAND,
        OFF
    }

    /**
     * In this mode, the WebView will allow a secure origin to load content from any other origin,
     * even if that origin is insecure. This is the least secure mode of operation for the WebView,
     * and where possible apps should not set this mode.
     *
     * @see #setMixedContentMode
     */
    public static final int MIXED_CONTENT_ALWAYS_ALLOW = 0;

    /**
     * In this mode, the WebView will not allow a secure origin to load content from an insecure
     * origin. This is the preferred and most secure mode of operation for the WebView and apps are
     * strongly advised to use this mode.
     *
     * @see #setMixedContentMode
     */
    public static final int MIXED_CONTENT_NEVER_ALLOW = 1;

    /**
     * In this mode, the WebView will attempt to be compatible with the approach of a modern web
     * browser with regard to mixed content. Some insecure content may be allowed to be loaded by
     * a secure origin and other types of content will be blocked. The types of content are allowed
     * or blocked may change release to release and are not explicitly defined.
     *
     * This mode is intended to be used by apps that are not in control of the content that they
     * render but desire to operate in a reasonably secure environment. For highest security, apps
     * are recommended to use {@link #MIXED_CONTENT_NEVER_ALLOW}.
     *
     * @see #setMixedContentMode
     */
    public static final int MIXED_CONTENT_COMPATIBILITY_MODE = 2;

    /** @hide */
    @IntDef(prefix = { "FORCE_DARK_" }, value = {
            FORCE_DARK_OFF,
            FORCE_DARK_AUTO,
            FORCE_DARK_ON
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ForceDark {}

    /**
     * Disable force dark, irrespective of the force dark mode of the WebView parent. In this mode,
     * WebView content will always be rendered as-is, regardless of whether native views are being
     * automatically darkened.
     *
     * @see #setForceDark
     */
    public static final int FORCE_DARK_OFF = 0;

    /**
     * Enable force dark dependent on the state of the WebView parent view. If the WebView parent
     * view is being automatically force darkened
     * (see: {@link android.view.View#setForceDarkAllowed}), then WebView content will be rendered
     * so as to emulate a dark theme. WebViews that are not attached to the view hierarchy will not
     * be inverted.
     *
     * @see #setForceDark
     */
    public static final int FORCE_DARK_AUTO = 1;

    /**
     * Unconditionally enable force dark. In this mode WebView content will always be rendered so
     * as to emulate a dark theme.
     *
     * @see #setForceDark
     */
    public static final int FORCE_DARK_ON = 2;

    /**
     * Enables dumping the pages navigation cache to a text file. The default
     * is {@code false}.
     *
     * @deprecated This method is now obsolete.
     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
     */
    @SuppressWarnings("HiddenAbstractMethod")
    @SystemApi
    @Deprecated
    public abstract void setNavDump(boolean enabled);

    /**
     * Gets whether dumping the navigation cache is enabled.
     *
     * @return whether dumping the navigation cache is enabled
     * @see #setNavDump
     * @deprecated This method is now obsolete.
     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
     */
    @SuppressWarnings("HiddenAbstractMethod")
    @SystemApi
    @Deprecated
    public abstract boolean getNavDump();

    /**
     * Sets whether the WebView should support zooming using its on-screen zoom
     * controls and gestures. The particular zoom mechanisms that should be used
     * can be set with {@link #setBuiltInZoomControls}. This setting does not
     * affect zooming performed using the {@link WebView#zoomIn()} and
     * {@link WebView#zoomOut()} methods. The default is {@code true}.
     *
     * @param support whether the WebView should support zoom
     */
    public abstract void setSupportZoom(boolean support);

    /**
     * Gets whether the WebView supports zoom.
     *
     * @return {@code true} if the WebView supports zoom
     * @see #setSupportZoom
     */
    public abstract boolean supportZoom();

    /**
     * Sets whether the WebView requires a user gesture to play media.
     * The default is {@code true}.
     *
     * @param require whether the WebView requires a user gesture to play media
     */
    public abstract void setMediaPlaybackRequiresUserGesture(boolean require);

    /**
     * Gets whether the WebView requires a user gesture to play media.
     *
     * @return {@code true} if the WebView requires a user gesture to play media
     * @see #setMediaPlaybackRequiresUserGesture
     */
    public abstract boolean getMediaPlaybackRequiresUserGesture();

    /**
     * Sets whether the WebView should use its built-in zoom mechanisms. The
     * built-in zoom mechanisms comprise on-screen zoom controls, which are
     * displayed over the WebView's content, and the use of a pinch gesture to
     * control zooming. Whether or not these on-screen controls are displayed
     * can be set with {@link #setDisplayZoomControls}. The default is {@code false}.
     * <p>
     * The built-in mechanisms are the only currently supported zoom
     * mechanisms, so it is recommended that this setting is always enabled.
     * However, on-screen zoom controls are deprecated in Android (see
     * {@link android.widget.ZoomButtonsController}) so it's recommended to
     * disable {@link #setDisplayZoomControls}.
     *
     * @param enabled whether the WebView should use its built-in zoom mechanisms
     */
    // This method was intended to select between the built-in zoom mechanisms
    // and the separate zoom controls. The latter were obtained using
    // {@link WebView#getZoomControls}, which is now hidden.
    public abstract void setBuiltInZoomControls(boolean enabled);

    /**
     * Gets whether the zoom mechanisms built into WebView are being used.
     *
     * @return {@code true} if the zoom mechanisms built into WebView are being used
     * @see #setBuiltInZoomControls
     */
    public abstract boolean getBuiltInZoomControls();

    /**
     * Sets whether the WebView should display on-screen zoom controls when
     * using the built-in zoom mechanisms. See {@link #setBuiltInZoomControls}.
     * The default is {@code true}. However, on-screen zoom controls are deprecated
     * in Android (see {@link android.widget.ZoomButtonsController}) so it's
     * recommended to set this to {@code false}.
     *
     * @param enabled whether the WebView should display on-screen zoom controls
     */
    public abstract void setDisplayZoomControls(boolean enabled);

    /**
     * Gets whether the WebView displays on-screen zoom controls when using
     * the built-in zoom mechanisms.
     *
     * @return {@code true} if the WebView displays on-screen zoom controls when using
     *         the built-in zoom mechanisms
     * @see #setDisplayZoomControls
     */
    public abstract boolean getDisplayZoomControls();

    /**
     * Enables or disables file access within WebView.
     * Note that this enables or disables file system access only. Assets and resources
     * are still accessible using file:///android_asset and file:///android_res.
     * <p class="note">
     * <b>Note:</b> Apps should not open {@code file://} URLs from any external source in
     * WebView, don't enable this if your app accepts arbitrary URLs from external sources.
     * It's recommended to always use
     * <a href="{@docRoot}reference/androidx/webkit/WebViewAssetLoader">
     * androidx.webkit.WebViewAssetLoader</a> to access files including assets and resources over
     * {@code http(s)://} schemes, instead of {@code file://} URLs. To prevent possible security
     * issues targeting {@link android.os.Build.VERSION_CODES#Q} and earlier, you should explicitly
     * set this value to {@code false}.
     * <p>
     * The default value is {@code true} for apps targeting
     * {@link android.os.Build.VERSION_CODES#Q} and below, and {@code false} when targeting
     * {@link android.os.Build.VERSION_CODES#R} and above.
     */
    public abstract void setAllowFileAccess(boolean allow);

    /**
     * Gets whether this WebView supports file access.
     *
     * @see #setAllowFileAccess
     */
    public abstract boolean getAllowFileAccess();

    /**
     * Enables or disables content URL access within WebView.  Content URL
     * access allows WebView to load content from a content provider installed
     * in the system. The default is enabled.
     */
    public abstract void setAllowContentAccess(boolean allow);

    /**
     * Gets whether this WebView supports content URL access.
     *
     * @see #setAllowContentAccess
     */
    public abstract boolean getAllowContentAccess();

    /**
     * Sets whether the WebView loads pages in overview mode, that is,
     * zooms out the content to fit on screen by width. This setting is
     * taken into account when the content width is greater than the width
     * of the WebView control, for example, when {@link #getUseWideViewPort}
     * is enabled. The default is {@code false}.
     */
    public abstract void setLoadWithOverviewMode(boolean overview);

    /**
     * Gets whether this WebView loads pages in overview mode.
     *
     * @return whether this WebView loads pages in overview mode
     * @see #setLoadWithOverviewMode
     */
    public abstract boolean getLoadWithOverviewMode();

    /**
     * Sets whether the WebView will enable smooth transition while panning or
     * zooming or while the window hosting the WebView does not have focus.
     * If it is {@code true}, WebView will choose a solution to maximize the performance.
     * e.g. the WebView's content may not be updated during the transition.
     * If it is false, WebView will keep its fidelity. The default value is {@code false}.
     *
     * @deprecated This method is now obsolete, and will become a no-op in future.
     */
    @Deprecated
    public abstract void setEnableSmoothTransition(boolean enable);

    /**
     * Gets whether the WebView enables smooth transition while panning or
     * zooming.
     *
     * @see #setEnableSmoothTransition
     *
     * @deprecated This method is now obsolete, and will become a no-op in future.
     */
    @Deprecated
    public abstract  boolean enableSmoothTransition();

    /**
     * Sets whether the WebView uses its background for over scroll background.
     * If {@code true}, it will use the WebView's background. If {@code false}, it will use an
     * internal pattern. Default is {@code true}.
     *
     * @deprecated This method is now obsolete.
     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
     */
    @SuppressWarnings("HiddenAbstractMethod")
    @SystemApi
    @Deprecated
    public abstract  void setUseWebViewBackgroundForOverscrollBackground(boolean view);

    /**
     * Gets whether this WebView uses WebView's background instead of
     * internal pattern for over scroll background.
     *
     * @see #setUseWebViewBackgroundForOverscrollBackground
     * @deprecated This method is now obsolete.
     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
     */
    @SuppressWarnings("HiddenAbstractMethod")
    @SystemApi
    @Deprecated
    public abstract  boolean getUseWebViewBackgroundForOverscrollBackground();

    /**
     * Sets whether the WebView should save form data. In Android O, the
     * platform has implemented a fully functional Autofill feature to store
     * form data. Therefore, the Webview form data save feature is disabled.
     *
     * Note that the feature will continue to be supported on older versions of
     * Android as before.
     *
     * @deprecated In Android O and afterwards, this function does not have
     * any effect, the form data will be saved to platform's autofill service
     * if applicable.
     */
    @Deprecated
    public abstract  void setSaveFormData(boolean save);

    /**
     * Gets whether the WebView saves form data.
     *
     * @return whether the WebView saves form data
     * @see #setSaveFormData
     */
    @Deprecated
    public abstract boolean getSaveFormData();

    /**
     * Sets whether the WebView should save passwords. The default is {@code true}.
     * @deprecated Saving passwords in WebView will not be supported in future versions.
     */
    @Deprecated
    public abstract void setSavePassword(boolean save);

    /**
     * Gets whether the WebView saves passwords.
     *
     * @return whether the WebView saves passwords
     * @see #setSavePassword
     * @deprecated Saving passwords in WebView will not be supported in future versions.
     */
    @Deprecated
    public abstract boolean getSavePassword();

    /**
     * Sets the text zoom of the page in percent. The default is 100.
     *
     * @param textZoom the text zoom in percent
     */
    public abstract void setTextZoom(int textZoom);

    /**
     * Gets the text zoom of the page in percent.
     *
     * @return the text zoom of the page in percent
     * @see #setTextZoom
     */
    public abstract int getTextZoom();

    /**
     * Sets policy for third party cookies.
     * Developers should access this via {@link CookieManager#setShouldAcceptThirdPartyCookies}.
     * @hide Internal API.
     */
    @SuppressWarnings("HiddenAbstractMethod")
    @SystemApi
    public abstract void setAcceptThirdPartyCookies(boolean accept);

    /**
     * Gets policy for third party cookies.
     * Developers should access this via {@link CookieManager#getShouldAcceptThirdPartyCookies}.
     * @hide Internal API
     */
    @SuppressWarnings("HiddenAbstractMethod")
    @SystemApi
    public abstract boolean getAcceptThirdPartyCookies();

    /**
     * Sets the text size of the page. The default is {@link TextSize#NORMAL}.
     *
     * @param t the text size as a {@link TextSize} value
     * @deprecated Use {@link #setTextZoom} instead.
     */
    @Deprecated
    public synchronized void setTextSize(TextSize t) {
        setTextZoom(t.value);
    }

    /**
     * Gets the text size of the page. If the text size was previously specified
     * in percent using {@link #setTextZoom}, this will return the closest
     * matching {@link TextSize}.
     *
     * @return the text size as a {@link TextSize} value
     * @see #setTextSize
     * @deprecated Use {@link #getTextZoom} instead.
     */
    @Deprecated
    public synchronized TextSize getTextSize() {
        TextSize closestSize = null;
        int smallestDelta = Integer.MAX_VALUE;
        int textSize = getTextZoom();
        for (TextSize size : TextSize.values()) {
            int delta = Math.abs(textSize - size.value);
            if (delta == 0) {
                return size;
            }
            if (delta < smallestDelta) {
                smallestDelta = delta;
                closestSize = size;
            }
        }
        return closestSize != null ? closestSize : TextSize.NORMAL;
    }

    /**
     * Sets the default zoom density of the page. This must be called from the UI
     * thread. The default is {@link ZoomDensity#MEDIUM}.
     *
     * This setting is not recommended for use in new applications.  If the WebView
     * is utilized to display mobile-oriented pages, the desired effect can be achieved by
     * adjusting 'width' and 'initial-scale' attributes of page's 'meta viewport'
     * tag. For pages lacking the tag, {@link android.webkit.WebView#setInitialScale}
     * and {@link #setUseWideViewPort} can be used.
     *
     * @param zoom the zoom density
     * @deprecated This method is no longer supported, see the function documentation for
     *             recommended alternatives.
     */
    @Deprecated
    public abstract void setDefaultZoom(ZoomDensity zoom);

    /**
     * Gets the default zoom density of the page. This should be called from
     * the UI thread.
     *
     * This setting is not recommended for use in new applications.
     *
     * @return the zoom density
     * @see #setDefaultZoom
     * @deprecated Will only return the default value.
     */
    @Deprecated
    public abstract ZoomDensity getDefaultZoom();

    /**
     * Enables using light touches to make a selection and activate mouseovers.
     * @deprecated From {@link android.os.Build.VERSION_CODES#JELLY_BEAN} this
     *             setting is obsolete and has no effect.
     */
    @Deprecated
    public abstract void setLightTouchEnabled(boolean enabled);

    /**
     * Gets whether light touches are enabled.
     * @see #setLightTouchEnabled
     * @deprecated This setting is obsolete.
     */
    @Deprecated
    public abstract boolean getLightTouchEnabled();

    /**
     * Controlled a rendering optimization that is no longer present. Setting
     * it now has no effect.
     *
     * @deprecated This setting now has no effect.
     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
     */
    @Deprecated
    @UnsupportedAppUsage
    public void setUseDoubleTree(boolean use) {
        // Specified to do nothing, so no need for derived classes to override.
    }

    /**
     * Controlled a rendering optimization that is no longer present. Setting
     * it now has no effect.
     *
     * @deprecated This setting now has no effect.
     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
     */
    @Deprecated
    @UnsupportedAppUsage
    public boolean getUseDoubleTree() {
        // Returns false unconditionally, so no need for derived classes to override.
        return false;
    }

    /**
     * Sets the user-agent string using an integer code.
     * <ul>
     *   <li>0 means the WebView should use an Android user-agent string</li>
     *   <li>1 means the WebView should use a desktop user-agent string</li>
     * </ul>
     * Other values are ignored. The default is an Android user-agent string,
     * i.e. code value 0.
     *
     * @param ua the integer code for the user-agent string
     * @deprecated Please use {@link #setUserAgentString} instead.
     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
     */
    @SuppressWarnings("HiddenAbstractMethod")
    @SystemApi
    @Deprecated
    public abstract void setUserAgent(int ua);

    /**
     * Gets the user-agent as an integer code.
     * <ul>
     *   <li>-1 means the WebView is using a custom user-agent string set with
     *   {@link #setUserAgentString}</li>
     *   <li>0 means the WebView should use an Android user-agent string</li>
     *   <li>1 means the WebView should use a desktop user-agent string</li>
     * </ul>
     *
     * @return the integer code for the user-agent string
     * @see #setUserAgent
     * @deprecated Please use {@link #getUserAgentString} instead.
     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
     */
    @SuppressWarnings("HiddenAbstractMethod")
    @SystemApi
    @Deprecated
    public abstract int getUserAgent();

    /**
     * Sets whether the WebView should enable support for the &quot;viewport&quot;
     * HTML meta tag or should use a wide viewport.
     * When the value of the setting is {@code false}, the layout width is always set to the
     * width of the WebView control in device-independent (CSS) pixels.
     * When the value is {@code true} and the page contains the viewport meta tag, the value
     * of the width specified in the tag is used. If the page does not contain the tag or
     * does not provide a width, then a wide viewport will be used.
     *
     * @param use whether to enable support for the viewport meta tag
     */
    public abstract void setUseWideViewPort(boolean use);

    /**
     * Gets whether the WebView supports the &quot;viewport&quot;
     * HTML meta tag or will use a wide viewport.
     *
     * @return {@code true} if the WebView supports the viewport meta tag
     * @see #setUseWideViewPort
     */
    public abstract boolean getUseWideViewPort();

    /**
     * Sets whether the WebView whether supports multiple windows. If set to
     * true, {@link WebChromeClient#onCreateWindow} must be implemented by the
     * host application. The default is {@code false}.
     *
     * @param support whether to support multiple windows
     */
    public abstract void setSupportMultipleWindows(boolean support);

    /**
     * Gets whether the WebView supports multiple windows.
     *
     * @return {@code true} if the WebView supports multiple windows
     * @see #setSupportMultipleWindows
     */
    public abstract boolean supportMultipleWindows();

    /**
     * Sets the underlying layout algorithm. This will cause a re-layout of the
     * WebView. The default is {@link LayoutAlgorithm#NARROW_COLUMNS}.
     *
     * @param l the layout algorithm to use, as a {@link LayoutAlgorithm} value
     */
    public abstract void setLayoutAlgorithm(LayoutAlgorithm l);

    /**
     * Gets the current layout algorithm.
     *
     * @return the layout algorithm in use, as a {@link LayoutAlgorithm} value
     * @see #setLayoutAlgorithm
     */
    public abstract LayoutAlgorithm getLayoutAlgorithm();

    /**
     * Sets the standard font family name. The default is "sans-serif".
     *
     * @param font a font family name
     */
    public abstract void setStandardFontFamily(String font);

    /**
     * Gets the standard font family name.
     *
     * @return the standard font family name as a string
     * @see #setStandardFontFamily
     */
    public abstract String getStandardFontFamily();

    /**
     * Sets the fixed font family name. The default is "monospace".
     *
     * @param font a font family name
     */
    public abstract void setFixedFontFamily(String font);

    /**
     * Gets the fixed font family name.
     *
     * @return the fixed font family name as a string
     * @see #setFixedFontFamily
     */
    public abstract String getFixedFontFamily();

    /**
     * Sets the sans-serif font family name. The default is "sans-serif".
     *
     * @param font a font family name
     */
    public abstract void setSansSerifFontFamily(String font);

    /**
     * Gets the sans-serif font family name.
     *
     * @return the sans-serif font family name as a string
     * @see #setSansSerifFontFamily
     */
    public abstract String getSansSerifFontFamily();

    /**
     * Sets the serif font family name. The default is "sans-serif".
     *
     * @param font a font family name
     */
    public abstract void setSerifFontFamily(String font);

    /**
     * Gets the serif font family name. The default is "serif".
     *
     * @return the serif font family name as a string
     * @see #setSerifFontFamily
     */
    public abstract String getSerifFontFamily();

    /**
     * Sets the cursive font family name. The default is "cursive".
     *
     * @param font a font family name
     */
    public abstract void setCursiveFontFamily(String font);

    /**
     * Gets the cursive font family name.
     *
     * @return the cursive font family name as a string
     * @see #setCursiveFontFamily
     */
    public abstract String getCursiveFontFamily();

    /**
     * Sets the fantasy font family name. The default is "fantasy".
     *
     * @param font a font family name
     */
    public abstract void setFantasyFontFamily(String font);

    /**
     * Gets the fantasy font family name.
     *
     * @return the fantasy font family name as a string
     * @see #setFantasyFontFamily
     */
    public abstract String getFantasyFontFamily();

    /**
     * Sets the minimum font size. The default is 8.
     *
     * @param size a non-negative integer between 1 and 72. Any number outside
     *             the specified range will be pinned.
     */
    public abstract void setMinimumFontSize(int size);

    /**
     * Gets the minimum font size.
     *
     * @return a non-negative integer between 1 and 72
     * @see #setMinimumFontSize
     */
    public abstract int getMinimumFontSize();

    /**
     * Sets the minimum logical font size. The default is 8.
     *
     * @param size a non-negative integer between 1 and 72. Any number outside
     *             the specified range will be pinned.
     */
    public abstract void setMinimumLogicalFontSize(int size);

    /**
     * Gets the minimum logical font size.
     *
     * @return a non-negative integer between 1 and 72
     * @see #setMinimumLogicalFontSize
     */
    public abstract int getMinimumLogicalFontSize();

    /**
     * Sets the default font size. The default is 16.
     *
     * @param size a non-negative integer between 1 and 72. Any number outside
     *             the specified range will be pinned.
     */
    public abstract void setDefaultFontSize(int size);

    /**
     * Gets the default font size.
     *
     * @return a non-negative integer between 1 and 72
     * @see #setDefaultFontSize
     */
    public abstract int getDefaultFontSize();

    /**
     * Sets the default fixed font size. The default is 16.
     *
     * @param size a non-negative integer between 1 and 72. Any number outside
     *             the specified range will be pinned.
     */
    public abstract void setDefaultFixedFontSize(int size);

    /**
     * Gets the default fixed font size.
     *
     * @return a non-negative integer between 1 and 72
     * @see #setDefaultFixedFontSize
     */
    public abstract int getDefaultFixedFontSize();

    /**
     * Sets whether the WebView should load image resources. Note that this method
     * controls loading of all images, including those embedded using the data
     * URI scheme. Use {@link #setBlockNetworkImage} to control loading only
     * of images specified using network URI schemes. Note that if the value of this
     * setting is changed from {@code false} to {@code true}, all images resources referenced
     * by content currently displayed by the WebView are loaded automatically.
     * The default is {@code true}.
     *
     * @param flag whether the WebView should load image resources
     */
    public abstract void setLoadsImagesAutomatically(boolean flag);

    /**
     * Gets whether the WebView loads image resources. This includes
     * images embedded using the data URI scheme.
     *
     * @return {@code true} if the WebView loads image resources
     * @see #setLoadsImagesAutomatically
     */
    public abstract boolean getLoadsImagesAutomatically();

    /**
     * Sets whether the WebView should not load image resources from the
     * network (resources accessed via http and https URI schemes).  Note
     * that this method has no effect unless
     * {@link #getLoadsImagesAutomatically} returns {@code true}. Also note that
     * disabling all network loads using {@link #setBlockNetworkLoads}
     * will also prevent network images from loading, even if this flag is set
     * to false. When the value of this setting is changed from {@code true} to {@code false},
     * network images resources referenced by content currently displayed by
     * the WebView are fetched automatically. The default is {@code false}.
     *
     * @param flag whether the WebView should not load image resources from the
     *             network
     * @see #setBlockNetworkLoads
     */
    public abstract void setBlockNetworkImage(boolean flag);

    /**
     * Gets whether the WebView does not load image resources from the network.
     *
     * @return {@code true} if the WebView does not load image resources from the network
     * @see #setBlockNetworkImage
     */
    public abstract boolean getBlockNetworkImage();

    /**
     * Sets whether the WebView should not load resources from the network.
     * Use {@link #setBlockNetworkImage} to only avoid loading
     * image resources. Note that if the value of this setting is
     * changed from {@code true} to {@code false}, network resources referenced by content
     * currently displayed by the WebView are not fetched until
     * {@link android.webkit.WebView#reload} is called.
     * If the application does not have the
     * {@link android.Manifest.permission#INTERNET} permission, attempts to set
     * a value of {@code false} will cause a {@link java.lang.SecurityException}
     * to be thrown. The default value is {@code false} if the application has the
     * {@link android.Manifest.permission#INTERNET} permission, otherwise it is
     * {@code true}.
     *
     * @param flag {@code true} means block network loads by the WebView
     * @see android.webkit.WebView#reload
     */
    public abstract void setBlockNetworkLoads(boolean flag);

    /**
     * Gets whether the WebView does not load any resources from the network.
     *
     * @return {@code true} if the WebView does not load any resources from the network
     * @see #setBlockNetworkLoads
     */
    public abstract boolean getBlockNetworkLoads();

    /**
     * Tells the WebView to enable JavaScript execution.
     * <b>The default is {@code false}.</b>
     *
     * @param flag {@code true} if the WebView should execute JavaScript
     */
    public abstract void setJavaScriptEnabled(boolean flag);

    /**
     * Sets whether cross-origin requests in the context of a file scheme URL should be allowed to
     * access content from <i>any</i> origin. This includes access to content from other file
     * scheme URLs or web contexts. Note that some access such as image HTML elements doesn't
     * follow same-origin rules and isn't affected by this setting.
     * <p>
     * <b>Don't</b> enable this setting if you open files that may be created or altered by
     * external sources. Enabling this setting allows malicious scripts loaded in a {@code file://}
     * context to launch cross-site scripting attacks, either accessing arbitrary local files
     * including WebView cookies, app private data or even credentials used on arbitrary web sites.
     * <p class="note">
     * Loading content via {@code file://} URLs is generally discouraged. See the note in
     * {@link #setAllowFileAccess}.
     * <p>
     * The default value is {@code true} for apps targeting
     * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and below, and {@code false}
     * when targeting {@link android.os.Build.VERSION_CODES#JELLY_BEAN} and above. To prevent
     * possible violation of same domain policy when targeting
     * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and earlier, you should
     * explicitly set this value to {@code false}.
     *
     * @param flag whether JavaScript running in the context of a file scheme URL should be allowed
     *             to access content from any origin
     * @deprecated This setting is not secure, please use
     *             <a href="{@docRoot}reference/androidx/webkit/WebViewAssetLoader.html">
     *             androidx.webkit.WebViewAssetLoader</a> to load file content securely.
     */
    @Deprecated
    public abstract void setAllowUniversalAccessFromFileURLs(boolean flag);

    /**
     * Sets whether cross-origin requests in the context of a file scheme URL should be allowed to
     * access content from other file scheme URLs. Note that some accesses such as image HTML
     * elements don't follow same-origin rules and aren't affected by this setting.
     * <p>
     * <b>Don't</b> enable this setting if you open files that may be created or altered by
     * external sources. Enabling this setting allows malicious scripts loaded in a {@code file://}
     * context to access arbitrary local files including WebView cookies and app private data.
     * <p class="note">
     * Loading content via {@code file://} URLs is generally discouraged. See the note in
     * {@link #setAllowFileAccess}.
     * <p>
     * Note that the value of this setting is ignored if the value of
     * {@link #getAllowUniversalAccessFromFileURLs} is {@code true}. The default value is
     * {@code true} for apps targeting {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1}
     * and below, and {@code false} when targeting {@link android.os.Build.VERSION_CODES#JELLY_BEAN}
     * and above. To prevent possible violation of same domain policy when targeting
     * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and earlier, you should
     * explicitly set this value to {@code false}.
     *
     * @param flag whether JavaScript running in the context of a file scheme
     *             URL should be allowed to access content from other file
     *             scheme URLs
     * @deprecated This setting is not secure, please use
     *             <a href="{@docRoot}reference/androidx/webkit/WebViewAssetLoader.html">
     *             androidx.webkit.WebViewAssetLoader</a> to load file content securely.
     */
    @Deprecated
    public abstract void setAllowFileAccessFromFileURLs(boolean flag);

    /**
     * Sets whether the WebView should enable plugins. The default is {@code false}.
     *
     * @param flag {@code true} if plugins should be enabled
     * @deprecated This method has been deprecated in favor of
     *             {@link #setPluginState}
     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
     */
    @SuppressWarnings("HiddenAbstractMethod")
    @SystemApi
    @Deprecated
    public abstract void setPluginsEnabled(boolean flag);

    /**
     * Tells the WebView to enable, disable, or have plugins on demand. On
     * demand mode means that if a plugin exists that can handle the embedded
     * content, a placeholder icon will be shown instead of the plugin. When
     * the placeholder is clicked, the plugin will be enabled. The default is
     * {@link PluginState#OFF}.
     *
     * @param state a PluginState value
     * @deprecated Plugins are not supported in API level
     *             {@link android.os.Build.VERSION_CODES#KITKAT} or later;
     *             enabling plugins is a no-op.
     */
    @Deprecated
    public abstract void setPluginState(PluginState state);

    /**
     * Sets a custom path to plugins used by the WebView. This method is
     * obsolete since each plugin is now loaded from its own package.
     *
     * @param pluginsPath a String path to the directory containing plugins
     * @deprecated This method is no longer used as plugins are loaded from
     *             their own APK via the system's package manager.
     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
     */
    @Deprecated
    @UnsupportedAppUsage
    public void setPluginsPath(String pluginsPath) {
        // Specified to do nothing, so no need for derived classes to override.
    }

    /**
     * Sets the path to where database storage API databases should be saved.
     * In order for the database storage API to function correctly, this method
     * must be called with a path to which the application can write. This
     * method should only be called once: repeated calls are ignored.
     *
     * @param databasePath a path to the directory where databases should be
     *                     saved.
     * @deprecated Database paths are managed by the implementation and calling this method
     *             will have no effect.
     */
    @Deprecated
    public abstract void setDatabasePath(String databasePath);

    /**
     * Sets the path where the Geolocation databases should be saved. In order
     * for Geolocation permissions and cached positions to be persisted, this
     * method must be called with a path to which the application can write.
     *
     * @param databasePath a path to the directory where databases should be
     *                     saved.
     * @deprecated Geolocation database are managed by the implementation and calling this method
     *             will have no effect.
     */
    @Deprecated
    public abstract void setGeolocationDatabasePath(String databasePath);

    /**
     * Sets whether the Application Caches API should be enabled. The default
     * is {@code false}. Note that in order for the Application Caches API to be
     * enabled, a valid database path must also be supplied to
     * {@link #setAppCachePath}.
     *
     * @param flag {@code true} if the WebView should enable Application Caches
     * @deprecated The Application Cache API is deprecated and this method will
     *             become a no-op on all Android versions once support is
     *             removed in Chromium. Consider using Service Workers instead.
     *             See https://web.dev/appcache-removal/ for more information.
     */
    public abstract void setAppCacheEnabled(boolean flag);

    /**
     * Sets the path to the Application Caches files. In order for the
     * Application Caches API to be enabled, this method must be called with a
     * path to which the application can write. This method should only be
     * called once: repeated calls are ignored.
     *
     * @param appCachePath a String path to the directory containing
     *                     Application Caches files.
     * @see #setAppCacheEnabled
     * @deprecated The Application Cache API is deprecated and this method will
     *             become a no-op on all Android versions once support is
     *             removed in Chromium. Consider using Service Workers instead.
     *             See https://web.dev/appcache-removal/ for more information.
     */
    public abstract void setAppCachePath(String appCachePath);

    /**
     * Sets the maximum size for the Application Cache content. The passed size
     * will be rounded to the nearest value that the database can support, so
     * this should be viewed as a guide, not a hard limit. Setting the
     * size to a value less than current database size does not cause the
     * database to be trimmed. The default size is {@link Long#MAX_VALUE}.
     * It is recommended to leave the maximum size set to the default value.
     *
     * @param appCacheMaxSize the maximum size in bytes
     * @deprecated Quota is managed automatically; this method is a no-op.
     */
    @Deprecated
    public abstract void setAppCacheMaxSize(long appCacheMaxSize);

    /**
     * Sets whether the database storage API is enabled. The default value is
     * false. See also {@link #setDatabasePath} for how to correctly set up the
     * database storage API.
     *
     * This setting is global in effect, across all WebView instances in a process.
     * Note you should only modify this setting prior to making <b>any</b> WebView
     * page load within a given process, as the WebView implementation may ignore
     * changes to this setting after that point.
     *
     * @param flag {@code true} if the WebView should use the database storage API
     */
    public abstract void setDatabaseEnabled(boolean flag);

    /**
     * Sets whether the DOM storage API is enabled. The default value is {@code false}.
     *
     * @param flag {@code true} if the WebView should use the DOM storage API
     */
    public abstract void setDomStorageEnabled(boolean flag);

    /**
     * Gets whether the DOM Storage APIs are enabled.
     *
     * @return {@code true} if the DOM Storage APIs are enabled
     * @see #setDomStorageEnabled
     */
    public abstract boolean getDomStorageEnabled();

    /**
     * Gets the path to where database storage API databases are saved.
     *
     * @return the String path to the database storage API databases
     * @see #setDatabasePath
     * @deprecated Database paths are managed by the implementation this method is obsolete.
     */
    @Deprecated
    public abstract String getDatabasePath();

    /**
     * Gets whether the database storage API is enabled.
     *
     * @return {@code true} if the database storage API is enabled
     * @see #setDatabaseEnabled
     */
    public abstract boolean getDatabaseEnabled();

    /**
     * Sets whether Geolocation is enabled. The default is {@code true}.
     * <p>
     * Please note that in order for the Geolocation API to be usable
     * by a page in the WebView, the following requirements must be met:
     * <ul>
     *   <li>an application must have permission to access the device location,
     *   see {@link android.Manifest.permission#ACCESS_COARSE_LOCATION},
     *   {@link android.Manifest.permission#ACCESS_FINE_LOCATION};
     *   <li>an application must provide an implementation of the
     *   {@link WebChromeClient#onGeolocationPermissionsShowPrompt} callback
     *   to receive notifications that a page is requesting access to location
     *   via the JavaScript Geolocation API.
     * </ul>
     * <p>
     *
     * @param flag whether Geolocation should be enabled
     */
    public abstract void setGeolocationEnabled(boolean flag);

    /**
     * Gets whether JavaScript is enabled.
     *
     * @return {@code true} if JavaScript is enabled
     * @see #setJavaScriptEnabled
     */
    public abstract boolean getJavaScriptEnabled();

    /**
     * Gets whether JavaScript running in the context of a file scheme URL can
     * access content from any origin. This includes access to content from
     * other file scheme URLs.
     *
     * @return whether JavaScript running in the context of a file scheme URL
     *         can access content from any origin
     * @see #setAllowUniversalAccessFromFileURLs
     */
    public abstract boolean getAllowUniversalAccessFromFileURLs();

    /**
     * Gets whether JavaScript running in the context of a file scheme URL can
     * access content from other file scheme URLs.
     *
     * @return whether JavaScript running in the context of a file scheme URL
     *         can access content from other file scheme URLs
     * @see #setAllowFileAccessFromFileURLs
     */
    public abstract boolean getAllowFileAccessFromFileURLs();

    /**
     * Gets whether plugins are enabled.
     *
     * @return {@code true} if plugins are enabled
     * @see #setPluginsEnabled
     * @deprecated This method has been replaced by {@link #getPluginState}
     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
     */
    @SuppressWarnings("HiddenAbstractMethod")
    @SystemApi
    @Deprecated
    public abstract boolean getPluginsEnabled();

    /**
     * Gets the current state regarding whether plugins are enabled.
     *
     * @return the plugin state as a {@link PluginState} value
     * @see #setPluginState
     * @deprecated Plugins are not supported in API level
     *             {@link android.os.Build.VERSION_CODES#KITKAT} or later;
     *             enabling plugins is a no-op.
     */
    @Deprecated
    public abstract PluginState getPluginState();

    /**
     * Gets the directory that contains the plugin libraries. This method is
     * obsolete since each plugin is now loaded from its own package.
     *
     * @return an empty string
     * @deprecated This method is no longer used as plugins are loaded from
     * their own APK via the system's package manager.
     * @hide Since API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}
     */
    @Deprecated
    @UnsupportedAppUsage
    public String getPluginsPath() {
        // Unconditionally returns empty string, so no need for derived classes to override.
        return "";
    }

    /**
     * Tells JavaScript to open windows automatically. This applies to the
     * JavaScript function {@code window.open()}. The default is {@code false}.
     *
     * @param flag {@code true} if JavaScript can open windows automatically
     */
    public abstract void setJavaScriptCanOpenWindowsAutomatically(boolean flag);

    /**
     * Gets whether JavaScript can open windows automatically.
     *
     * @return {@code true} if JavaScript can open windows automatically during
     *         {@code window.open()}
     * @see #setJavaScriptCanOpenWindowsAutomatically
     */
    public abstract boolean getJavaScriptCanOpenWindowsAutomatically();

    /**
     * Sets the default text encoding name to use when decoding html pages.
     * The default is "UTF-8".
     *
     * @param encoding the text encoding name
     */
    public abstract void setDefaultTextEncodingName(String encoding);

    /**
     * Gets the default text encoding name.
     *
     * @return the default text encoding name as a string
     * @see #setDefaultTextEncodingName
     */
    public abstract String getDefaultTextEncodingName();

    /**
     * Sets the WebView's user-agent string. If the string is {@code null} or empty,
     * the system default value will be used.
     *
     * Note that starting from {@link android.os.Build.VERSION_CODES#KITKAT} Android
     * version, changing the user-agent while loading a web page causes WebView
     * to initiate loading once again.
     *
     * @param ua new user-agent string
     */
    public abstract void setUserAgentString(@Nullable String ua);

    /**
     * Gets the WebView's user-agent string.
     *
     * @return the WebView's user-agent string
     * @see #setUserAgentString
     */
    public abstract String getUserAgentString();

    /**
     * Returns the default User-Agent used by a WebView.
     * An instance of WebView could use a different User-Agent if a call
     * is made to {@link WebSettings#setUserAgentString(String)}.
     *
     * @param context a Context object used to access application assets
     */
    public static String getDefaultUserAgent(Context context) {
        return WebViewFactory.getProvider().getStatics().getDefaultUserAgent(context);
    }

    /**
     * Tells the WebView whether it needs to set a node to have focus when
     * {@link WebView#requestFocus(int, android.graphics.Rect)} is called. The
     * default value is {@code true}.
     *
     * @param flag whether the WebView needs to set a node
     */
    public abstract void setNeedInitialFocus(boolean flag);

    /**
     * Sets the priority of the Render thread. Unlike the other settings, this
     * one only needs to be called once per process. The default value is
     * {@link RenderPriority#NORMAL}.
     *
     * @param priority the priority
     * @deprecated It is not recommended to adjust thread priorities, and this will
     *             not be supported in future versions.
     */
    @Deprecated
    public abstract void setRenderPriority(RenderPriority priority);

    /**
     * Overrides the way the cache is used. The way the cache is used is based
     * on the navigation type. For a normal page load, the cache is checked
     * and content is re-validated as needed. When navigating back, content is
     * not revalidated, instead the content is just retrieved from the cache.
     * This method allows the client to override this behavior by specifying
     * one of {@link #LOAD_DEFAULT},
     * {@link #LOAD_CACHE_ELSE_NETWORK}, {@link #LOAD_NO_CACHE} or
     * {@link #LOAD_CACHE_ONLY}. The default value is {@link #LOAD_DEFAULT}.
     *
     * @param mode the mode to use
     */
    public abstract void setCacheMode(@CacheMode int mode);

    /**
     * Gets the current setting for overriding the cache mode.
     *
     * @return the current setting for overriding the cache mode
     * @see #setCacheMode
     */
    @CacheMode
    public abstract int getCacheMode();

    /**
     * Configures the WebView's behavior when a secure origin attempts to load a resource from an
     * insecure origin.
     *
     * By default, apps that target {@link android.os.Build.VERSION_CODES#KITKAT} or below default
     * to {@link #MIXED_CONTENT_ALWAYS_ALLOW}. Apps targeting
     * {@link android.os.Build.VERSION_CODES#LOLLIPOP} default to {@link #MIXED_CONTENT_NEVER_ALLOW}.
     *
     * The preferred and most secure mode of operation for the WebView is
     * {@link #MIXED_CONTENT_NEVER_ALLOW} and use of {@link #MIXED_CONTENT_ALWAYS_ALLOW} is
     * strongly discouraged.
     *
     * @param mode The mixed content mode to use. One of {@link #MIXED_CONTENT_NEVER_ALLOW},
     *     {@link #MIXED_CONTENT_ALWAYS_ALLOW} or {@link #MIXED_CONTENT_COMPATIBILITY_MODE}.
     */
    public abstract void setMixedContentMode(int mode);

    /**
     * Gets the current behavior of the WebView with regard to loading insecure content from a
     * secure origin.
     * @return The current setting, one of {@link #MIXED_CONTENT_NEVER_ALLOW},
     *     {@link #MIXED_CONTENT_ALWAYS_ALLOW} or {@link #MIXED_CONTENT_COMPATIBILITY_MODE}.
     */
    public abstract int getMixedContentMode();

    /**
     * Sets whether to use a video overlay for embedded encrypted video.
     * In API levels prior to {@link android.os.Build.VERSION_CODES#LOLLIPOP}, encrypted video can
     * only be rendered directly on a secure video surface, so it had been a hard problem to play
     * encrypted video in HTML.  When this flag is on, WebView can play encrypted video (MSE/EME)
     * by using a video overlay (aka hole-punching) for videos embedded using HTML &lt;video&gt;
     * tag.<br>
     * Caution: This setting is intended for use only in a narrow set of circumstances and apps
     * should only enable it if they require playback of encrypted video content. It will impose
     * the following limitations on the WebView:
     * <ul>
     * <li> Only one video overlay can be played at a time.
     * <li> Changes made to position or dimensions of a video element may be propagated to the
     * corresponding video overlay with a noticeable delay.
     * <li> The video overlay is not visible to web APIs and as such may not interact with
     * script or styling. For example, CSS styles applied to the &lt;video&gt; tag may be ignored.
     * </ul>
     * This is not an exhaustive set of constraints and it may vary with new versions of the
     * WebView.
     * @hide
     */
    @SuppressWarnings("HiddenAbstractMethod")
    @SystemApi
    public abstract void setVideoOverlayForEmbeddedEncryptedVideoEnabled(boolean flag);

    /**
     * Gets whether a video overlay will be used for embedded encrypted video.
     *
     * @return {@code true} if WebView uses a video overlay for embedded encrypted video.
     * @see #setVideoOverlayForEmbeddedEncryptedVideoEnabled
     * @hide
     */
    @SuppressWarnings("HiddenAbstractMethod")
    @SystemApi
    public abstract boolean getVideoOverlayForEmbeddedEncryptedVideoEnabled();

    /**
     * Sets whether this WebView should raster tiles when it is
     * offscreen but attached to a window. Turning this on can avoid
     * rendering artifacts when animating an offscreen WebView on-screen.
     * Offscreen WebViews in this mode use more memory. The default value is
     * false.<br>
     * Please follow these guidelines to limit memory usage:
     * <ul>
     * <li> WebView size should be not be larger than the device screen size.
     * <li> Limit use of this mode to a small number of WebViews. Use it for
     *   visible WebViews and WebViews about to be animated to visible.
     * </ul>
     */
    public abstract void setOffscreenPreRaster(boolean enabled);

    /**
     * Gets whether this WebView should raster tiles when it is
     * offscreen but attached to a window.
     * @return {@code true} if this WebView will raster tiles when it is
     * offscreen but attached to a window.
     */
    public abstract boolean getOffscreenPreRaster();


    /**
     * Sets whether Safe Browsing is enabled. Safe Browsing allows WebView to
     * protect against malware and phishing attacks by verifying the links.
     *
     * <p>
     * Safe Browsing can be disabled for all WebViews using a manifest tag (read <a
     * href="{@docRoot}reference/android/webkit/WebView.html">general Safe Browsing info</a>). The
     * manifest tag has a lower precedence than this API.
     *
     * <p>
     * Safe Browsing is enabled by default for devices which support it.
     *
     * @param enabled Whether Safe Browsing is enabled.
     */
    public abstract void setSafeBrowsingEnabled(boolean enabled);

    /**
     * Gets whether Safe Browsing is enabled.
     * See {@link #setSafeBrowsingEnabled}.
     *
     * @return {@code true} if Safe Browsing is enabled and {@code false} otherwise.
     */
    public abstract boolean getSafeBrowsingEnabled();


    /**
     * Set the force dark mode for this WebView.
     *
     * @param forceDark the force dark mode to set.
     * @see #getForceDark
     */
    public void setForceDark(@ForceDark int forceDark) {
        // Stub implementation to satisfy Roboelectrc shadows that don't override this yet.
    }

    /**
     * Get the force dark mode for this WebView.
     * The default force dark mode is {@link #FORCE_DARK_AUTO}.
     *
     * @return the currently set force dark mode.
     * @see #setForceDark
     */
    public @ForceDark int getForceDark() {
        // Stub implementation to satisfy Roboelectrc shadows that don't override this yet.
        return FORCE_DARK_AUTO;
    }

    /**
     * @hide
     */
    @IntDef(flag = true, prefix = { "MENU_ITEM_" }, value = {
            MENU_ITEM_NONE,
            MENU_ITEM_SHARE,
            MENU_ITEM_WEB_SEARCH,
            MENU_ITEM_PROCESS_TEXT
    })
    @Retention(RetentionPolicy.SOURCE)
    @Target({ElementType.PARAMETER, ElementType.METHOD})
    private @interface MenuItemFlags {}

    /**
     * Disables the action mode menu items according to {@code menuItems} flag.
     * @param menuItems an integer field flag for the menu items to be disabled.
     */
    public abstract void setDisabledActionModeMenuItems(@MenuItemFlags int menuItems);

    /**
     * Gets the action mode menu items that are disabled, expressed in an integer field flag.
     * The default value is {@link #MENU_ITEM_NONE}
     *
     * @return all the disabled menu item flags combined with bitwise OR.
     */
    public abstract @MenuItemFlags int getDisabledActionModeMenuItems();

    /**
     * No menu items should be disabled.
     *
     * @see #setDisabledActionModeMenuItems
     */
    public static final int MENU_ITEM_NONE = 0;

    /**
     * Disable menu item "Share".
     *
     * @see #setDisabledActionModeMenuItems
     */
    public static final int MENU_ITEM_SHARE = 1 << 0;

    /**
     * Disable menu item "Web Search".
     *
     * @see #setDisabledActionModeMenuItems
     */
    public static final int MENU_ITEM_WEB_SEARCH = 1 << 1;

    /**
     * Disable all the action mode menu items for text processing.
     * By default WebView searches for activities that are able to handle
     * {@link android.content.Intent#ACTION_PROCESS_TEXT} and show them in the
     * action mode menu. If this flag is set via {@link
     * #setDisabledActionModeMenuItems}, these menu items will be disabled.
     *
     * @see #setDisabledActionModeMenuItems
     */
    public static final int MENU_ITEM_PROCESS_TEXT = 1 << 2;
}
