Snap for 5946345 from 6542df0fa5f281b48fae9c3fdb4d40e11df5c156 to androidx-master-release

Change-Id: Iab5fdfafd037ce3ca3b8aff01e7baf84ff7d831d
diff --git a/.gitignore b/.gitignore
index b415ae7..aec6a57 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
 # For Android Studio, when we mirror this repo into the Android tree
 *.iml
+.gradle/
+.settings/
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
deleted file mode 100644
index abe20e7..0000000
--- a/AndroidManifest.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example">
-  <!-- This AndroidManifest file only exists to verify boundary interfaces
-       compile and lint correctly against API 14 (the minSdkVersion of the
-       support library code). As the minSdkVersion of the support library
-       increases, so should this value. See http://crbug.com/828184 for more
-       details. -->
-  <uses-sdk android:minSdkVersion="14" />
-</manifest>
diff --git a/BUILD.gn b/BUILD.gn
index 2111854..a6cc4b5 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -9,6 +9,7 @@
   java_files = [
     "src/org/chromium/support_lib_boundary/FeatureFlagHolderBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/IsomorphicObjectBoundaryInterface.java",
+    "src/org/chromium/support_lib_boundary/JsReplyProxyBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/ProxyControllerBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/SafeBrowsingResponseBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/ServiceWorkerClientBoundaryInterface.java",
@@ -17,9 +18,9 @@
     "src/org/chromium/support_lib_boundary/StaticsBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/TracingControllerBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/VisualStateCallbackBoundaryInterface.java",
-    "src/org/chromium/support_lib_boundary/WebkitToCompatConverterBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/WebMessageBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/WebMessageCallbackBoundaryInterface.java",
+    "src/org/chromium/support_lib_boundary/WebMessageListenerBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/WebMessagePortBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/WebResourceErrorBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/WebResourceRequestBoundaryInterface.java",
@@ -29,17 +30,24 @@
     "src/org/chromium/support_lib_boundary/WebViewProviderFactoryBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/WebViewRendererBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/WebViewRendererClientBoundaryInterface.java",
+    "src/org/chromium/support_lib_boundary/WebkitToCompatConverterBoundaryInterface.java",
     "src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java",
     "src/org/chromium/support_lib_boundary/util/Features.java",
   ]
 
   proguard_configs = [ "proguard.flags" ]
 
-  # We can't use ANY deps here, the support library should be able to build
-  # these interfaces without any other chromium dependencies.
-  deps = []
+  # Our choice of deps is limited, because boundary_interfaces/ must continue to
+  # build when we mirror this into AndroidX. We are only permitted to depend on
+  # core Android classes and other AndroidX classes (must be in the androidx.*
+  # package name).
+  deps = [
+    "//third_party/android_deps:androidx_annotation_annotation_java",
+  ]
 
   # This is to verify the boundary interfaces compile and lint correctly against
-  # the minSdkVersion of the webkit support library module.
-  android_manifest_for_lint = "AndroidManifest.xml"
+  # the minSdkVersion of the webkit support library module. As the minSdkVersion
+  # of the support library increases, so should this value. See
+  # http://crbug.com/828184 for more details.
+  min_sdk_version = 14
 }
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..4fbc108
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,25 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is to build WebView boundary interfaces as part of the AndroidX webkit library.
+// It is not meant to be used or build any targets in chromium project.
+
+import androidx.build.SdkHelperKt
+import androidx.build.SupportConfig
+
+plugins {
+    id('java-library')
+}
+
+dependencies {
+    api("androidx.annotation:annotation:1.1.0")
+    implementation fileTree(dir: "${SdkHelperKt.getSdkPath(project.rootDir)}/platforms/$SupportConfig.COMPILE_SDK_VERSION/",
+            include: "android.jar")
+}
+
+sourceSets {
+    main {
+        java.srcDirs = ['src']
+    }
+}
diff --git a/src/org/chromium/support_lib_boundary/JsReplyProxyBoundaryInterface.java b/src/org/chromium/support_lib_boundary/JsReplyProxyBoundaryInterface.java
new file mode 100644
index 0000000..e2da069
--- /dev/null
+++ b/src/org/chromium/support_lib_boundary/JsReplyProxyBoundaryInterface.java
@@ -0,0 +1,12 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.support_lib_boundary;
+
+/**
+ * Boundary interface for org.chromium.android_webview.WebMessageListener.
+ */
+public interface JsReplyProxyBoundaryInterface extends IsomorphicObjectBoundaryInterface {
+    void postMessage(String message);
+}
diff --git a/src/org/chromium/support_lib_boundary/WebMessageListenerBoundaryInterface.java b/src/org/chromium/support_lib_boundary/WebMessageListenerBoundaryInterface.java
new file mode 100644
index 0000000..92a393f
--- /dev/null
+++ b/src/org/chromium/support_lib_boundary/WebMessageListenerBoundaryInterface.java
@@ -0,0 +1,18 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.support_lib_boundary;
+
+import android.net.Uri;
+import android.webkit.WebView;
+
+import java.lang.reflect.InvocationHandler;
+
+/**
+ * Boundary interface for org.chromium.android_webview.WebMessageListener.
+ */
+public interface WebMessageListenerBoundaryInterface extends FeatureFlagHolderBoundaryInterface {
+    void onPostMessage(WebView view, /* WebMessage */ InvocationHandler message, Uri sourceOrigin,
+            boolean isMainFrame, /* JsReplyProxy */ InvocationHandler replyProxy);
+}
diff --git a/src/org/chromium/support_lib_boundary/WebSettingsBoundaryInterface.java b/src/org/chromium/support_lib_boundary/WebSettingsBoundaryInterface.java
index ef4ce36..426eb6d 100644
--- a/src/org/chromium/support_lib_boundary/WebSettingsBoundaryInterface.java
+++ b/src/org/chromium/support_lib_boundary/WebSettingsBoundaryInterface.java
@@ -8,6 +8,10 @@
 // android.webkit parameter or android.webkit return value. But for forwards compatibility all
 // app-facing classes should have a boundary-interface that the WebView glue layer can build
 // against.
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * Boundary interface for WebSettingsCompat.
  */
@@ -26,4 +30,15 @@
 
     void setForceDark(int forceDarkMode);
     int getForceDark();
+
+    @Retention(RetentionPolicy.SOURCE)
+    @interface ForceDarkBehavior {
+        int FORCE_DARK_ONLY = 0;
+        int MEDIA_QUERY_ONLY = 1;
+        int PREFER_MEDIA_QUERY_OVER_FORCE_DARK = 2;
+    }
+
+    void setForceDarkBehavior(@ForceDarkBehavior int forceDarkBehavior);
+    @ForceDarkBehavior
+    int getForceDarkBehavior();
 }
diff --git a/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java b/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java
index c896d89..bb677ef 100644
--- a/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java
+++ b/src/org/chromium/support_lib_boundary/WebViewProviderBoundaryInterface.java
@@ -17,6 +17,9 @@
             /* VisualStateCallback */ InvocationHandler callback);
     /* WebMessagePort */ InvocationHandler[] createWebMessageChannel();
     void postMessageToMainFrame(/* WebMessage */ InvocationHandler message, Uri targetOrigin);
+    void addWebMessageListener(String jsObjectName, String[] allowedOriginRules,
+            /* WebMessageListener */ InvocationHandler listener);
+    void removeWebMessageListener(String jsObjectName);
     WebViewClient getWebViewClient();
     WebChromeClient getWebChromeClient();
     /* WebViewRenderer */ InvocationHandler getWebViewRenderer();
diff --git a/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java b/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java
index 931cc89..1c5f369 100644
--- a/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java
+++ b/src/org/chromium/support_lib_boundary/util/BoundaryInterfaceReflectionUtil.java
@@ -7,6 +7,9 @@
 import android.annotation.TargetApi;
 import android.os.Build;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -61,29 +64,57 @@
     /**
      * Returns an implementation of the boundary interface named clazz, by delegating method calls
      * to the {@link InvocationHandler} invocationHandler.
+     *
+     * <p>A {@code null} {@link InvocationHandler} is treated as representing a {@code null} object.
+     *
+     * @param clazz a {@link Class} object representing the desired boundary interface.
+     * @param invocationHandler an {@link InvocationHandler} compatible with this boundary
+     *     interface.
      */
-    public static <T> T castToSuppLibClass(Class<T> clazz, InvocationHandler invocationHandler) {
+    @Nullable
+    public static <T> T castToSuppLibClass(
+            @NonNull Class<T> clazz, @Nullable InvocationHandler invocationHandler) {
+        if (invocationHandler == null) return null;
         return clazz.cast(
                 Proxy.newProxyInstance(BoundaryInterfaceReflectionUtil.class.getClassLoader(),
                         new Class[] {clazz}, invocationHandler));
     }
 
     /**
-     * Create an {@link java.lang.reflect.InvocationHandler} that delegates method calls to
-     * {@param delegate}, making sure that the {@link java.lang.reflect.Method} and parameters being
-     * passed to {@param delegate} exist in the same {@link java.lang.ClassLoader} as {@param
-     * delegate}.
+     * Create an {@link InvocationHandler} that delegates method calls to {@code delegate}, making
+     * sure that the {@link Method} and parameters being passed exist in the same {@link
+     * ClassLoader} as {@code delegate}.
+     *
+     * <p>A {@code null} delegate is represented with a {@code null} {@link InvocationHandler}.
+     *
+     * @param delegate the object which the resulting {@link InvocationHandler} should delegate
+     *     method calls to.
+     * @return an InvocationHandlerWithDelegateGetter wrapping {@code delegate}
      */
     @TargetApi(Build.VERSION_CODES.KITKAT)
-    public static InvocationHandler createInvocationHandlerFor(final Object delegate) {
+    @Nullable
+    public static InvocationHandler createInvocationHandlerFor(@Nullable final Object delegate) {
+        if (delegate == null) return null;
         return new InvocationHandlerWithDelegateGetter(delegate);
     }
 
     /**
-     * Plural version of {@link #createInvocationHandlerFor(Object)}.
+     * Plural version of {@link #createInvocationHandlerFor(Object)}. The resulting array will be
+     * the same length as {@code delegates}, where the nth {@code InvocationHandler} wraps the nth
+     * delegate object.
+     *
+     * <p>A {@code null} array of delegates is represented with a {@code null} array of {@link
+     * InvocationHandler}s. Any individual {@code null} delegate is represented with a {@code null}
+     * {@link InvocationHandler}.
+
+     * @param delegates an array of objects to which to delegate.
+     * @return an array of InvocationHandlerWithDelegateGetter instances, each delegating to
+     *     the corresponding member of {@code delegates}.
      */
     @TargetApi(Build.VERSION_CODES.KITKAT)
-    public static InvocationHandler[] createInvocationHandlersForArray(final Object[] delegates) {
+    @Nullable
+    public static InvocationHandler[] createInvocationHandlersForArray(
+            @Nullable final Object[] delegates) {
         if (delegates == null) return null;
 
         InvocationHandler[] handlers = new InvocationHandler[delegates.length];
@@ -97,8 +128,16 @@
      * Assuming that the given InvocationHandler was created in the current classloader and is an
      * InvocationHandlerWithDelegateGetter, return the object the InvocationHandler delegates its
      * method calls to.
+     *
+     * <p>A {@code null} {@link InvocationHandler} is treated as wrapping a {@code null} delegate.
+     *
+     * @param invocationHandler a {@link Nullable} InvocationHandlerWithDelegateGetter.
+     * @return the corresponding delegate.
      */
-    public static Object getDelegateFromInvocationHandler(InvocationHandler invocationHandler) {
+    @Nullable
+    public static Object getDelegateFromInvocationHandler(
+            @Nullable InvocationHandler invocationHandler) {
+        if (invocationHandler == null) return null;
         InvocationHandlerWithDelegateGetter objectHolder =
                 (InvocationHandlerWithDelegateGetter) invocationHandler;
         return objectHolder.getDelegate();
@@ -113,7 +152,7 @@
     private static class InvocationHandlerWithDelegateGetter implements InvocationHandler {
         private final Object mDelegate;
 
-        public InvocationHandlerWithDelegateGetter(final Object delegate) {
+        public InvocationHandlerWithDelegateGetter(@NonNull final Object delegate) {
             mDelegate = delegate;
         }
 
@@ -130,6 +169,10 @@
             }
         }
 
+        /**
+         * Gets the delegate object (which is never {@code null}).
+         */
+        @NonNull
         public Object getDelegate() {
             return mDelegate;
         }
diff --git a/src/org/chromium/support_lib_boundary/util/Features.java b/src/org/chromium/support_lib_boundary/util/Features.java
index eaf6e30..40cd85b 100644
--- a/src/org/chromium/support_lib_boundary/util/Features.java
+++ b/src/org/chromium/support_lib_boundary/util/Features.java
@@ -163,4 +163,14 @@
     // WebSettingsCompat.setForceDark
     // WebSettingsCompat.getForceDark
     public static final String FORCE_DARK = "FORCE_DARK";
+
+    // Preferences between force dark and media query for dark theme support:
+    //
+    // WebSettingsCompat.setForceDarkBehavior
+    // WebSettingsCompat.getForceDarkBehavior
+    public static final String FORCE_DARK_BEHAVIOR = "FORCE_DARK_BEHAVIOR";
+
+    // WebViewCompat.addWebMessageListener
+    // WebViewCompat.removeWebMessageListener
+    public static final String WEB_MESSAGE_LISTENER = "WEB_MESSAGE_LISTENER";
 }