public class

WebViewGlueCommunicator

extends java.lang.Object

 java.lang.Object

↳androidx.webkit.internal.WebViewGlueCommunicator

Gradle dependencies

compile group: 'androidx.webkit', name: 'webkit', version: '1.12.0-rc01'

  • groupId: androidx.webkit
  • artifactId: webkit
  • version: 1.12.0-rc01

Artifact androidx.webkit:webkit:1.12.0-rc01 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.webkit:webkit com.android.support:webkit

Overview

Utility class for calling into the WebView APK.

Summary

Methods
public static WebkitToCompatConvertergetCompatConverter()

public static WebViewProviderFactorygetFactory()

Fetch the one global support library WebViewProviderFactory from the WebView glue layer.

public static java.lang.ClassLoadergetWebViewClassLoader()

Load the WebView code from the WebView APK and return the classloader containing that code.

from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Methods

public static WebViewProviderFactory getFactory()

Fetch the one global support library WebViewProviderFactory from the WebView glue layer.

public static WebkitToCompatConverter getCompatConverter()

public static java.lang.ClassLoader getWebViewClassLoader()

Load the WebView code from the WebView APK and return the classloader containing that code.

Source

/*
 * Copyright 2018 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 androidx.webkit.internal;

import android.os.Build;
import android.webkit.WebView;

import androidx.annotation.NonNull;

import org.chromium.support_lib_boundary.WebViewProviderFactoryBoundaryInterface;
import org.chromium.support_lib_boundary.util.BoundaryInterfaceReflectionUtil;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Utility class for calling into the WebView APK.
 */
public class WebViewGlueCommunicator {
    private static final String GLUE_FACTORY_PROVIDER_FETCHER_CLASS =
            "org.chromium.support_lib_glue.SupportLibReflectionUtil";
    private static final String GLUE_FACTORY_PROVIDER_FETCHER_METHOD =
            "createWebViewProviderFactory";

    /**
     * Fetch the one global support library WebViewProviderFactory from the WebView glue layer.
     */
    @NonNull
    public static WebViewProviderFactory getFactory() {
        return LAZY_FACTORY_HOLDER.INSTANCE;
    }

    @NonNull
    public static WebkitToCompatConverter getCompatConverter() {
        return LAZY_COMPAT_CONVERTER_HOLDER.INSTANCE;
    }

    private static class LAZY_FACTORY_HOLDER {
        static final WebViewProviderFactory INSTANCE =
                        WebViewGlueCommunicator.createGlueProviderFactory();
    }

    private static class LAZY_COMPAT_CONVERTER_HOLDER {
        static final WebkitToCompatConverter INSTANCE = new WebkitToCompatConverter(
                WebViewGlueCommunicator.getFactory().getWebkitToCompatConverter());
    }

    private static InvocationHandler fetchGlueProviderFactoryImpl() throws IllegalAccessException,
            InvocationTargetException, ClassNotFoundException, NoSuchMethodException {
        Class<?> glueFactoryProviderFetcherClass = Class.forName(
                GLUE_FACTORY_PROVIDER_FETCHER_CLASS, false, getWebViewClassLoader());
        Method createProviderFactoryMethod = glueFactoryProviderFetcherClass.getDeclaredMethod(
                GLUE_FACTORY_PROVIDER_FETCHER_METHOD);
        return (InvocationHandler) createProviderFactoryMethod.invoke(null);
    }

    @SuppressWarnings("WeakerAccess") /* synthetic access */
    @NonNull
    static WebViewProviderFactory createGlueProviderFactory() {
        // We do not support pre-L devices since their WebView APKs cannot be updated.
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            return new IncompatibleApkWebViewProviderFactory();
        }
        InvocationHandler invocationHandler;
        try {
            invocationHandler = fetchGlueProviderFactoryImpl();
            // The only way we should fail to fetch the provider-factory is if the class we are
            // calling into doesn't exist - any other kind of failure is unexpected and should cause
            // a run-time exception.
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            // If WebView APK support library glue entry point doesn't exist then return a Provider
            // factory that declares that there are no features available.
            return new IncompatibleApkWebViewProviderFactory();
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
        return new WebViewProviderFactoryAdapter(BoundaryInterfaceReflectionUtil.castToSuppLibClass(
                WebViewProviderFactoryBoundaryInterface.class, invocationHandler));
    }

    /**
     * Load the WebView code from the WebView APK and return the classloader containing that code.
     */
    @NonNull
    public static ClassLoader getWebViewClassLoader() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            return ApiHelperForP.getWebViewClassLoader();
        } else {
            return getWebViewProviderFactory().getClass().getClassLoader();
        }
    }

    @SuppressWarnings({"JavaReflectionMemberAccess", "PrivateApi"})
    private static Object getWebViewProviderFactory() {
        try {
            Method getFactoryMethod = WebView.class.getDeclaredMethod("getFactory");
            getFactoryMethod.setAccessible(true);
            return getFactoryMethod.invoke(null);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    private WebViewGlueCommunicator() {
    }
}