Add global and per-WebContents java InterfaceRegistries.
BUG=634568, 637174
Review-Url: https://codereview.chromium.org/2217813003
Cr-Commit-Position: refs/heads/master@{#419886}
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 9c35476..4984e4d6 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -203,6 +203,8 @@
"android/interface_provider_android_impl.h",
"android/interface_registry_android_impl.cc",
"android/interface_registry_android_impl.h",
+ "android/java_interfaces_impl.cc",
+ "android/java_interfaces_impl.h",
"android/url_request_content_job.cc",
"android/url_request_content_job.h",
"appcache/appcache.cc",
diff --git a/content/browser/android/java_interfaces_impl.cc b/content/browser/android/java_interfaces_impl.cc
new file mode 100644
index 0000000..df2d8d6
--- /dev/null
+++ b/content/browser/android/java_interfaces_impl.cc
@@ -0,0 +1,61 @@
+// Copyright 2016 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.
+
+#include "content/browser/android/java_interfaces_impl.h"
+
+#include <jni.h>
+
+#include <utility>
+
+#include "base/android/context_utils.h"
+#include "base/android/jni_android.h"
+#include "base/memory/singleton.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
+#include "jni/InterfaceRegistrarImpl_jni.h"
+#include "mojo/public/cpp/system/message_pipe.h"
+#include "services/shell/public/cpp/interface_provider.h"
+
+namespace content {
+
+namespace {
+
+class JavaInterfaceProviderHolder {
+ public:
+ JavaInterfaceProviderHolder() {
+ shell::mojom::InterfaceProviderPtr provider;
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_InterfaceRegistrarImpl_createInterfaceRegistryForContext(
+ env, mojo::GetProxy(&provider).PassMessagePipe().release().value(),
+ base::android::GetApplicationContext());
+ interface_provider_.Bind(std::move(provider));
+ }
+
+ static JavaInterfaceProviderHolder* GetInstance() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ return base::Singleton<JavaInterfaceProviderHolder>::get();
+ }
+
+ shell::InterfaceProvider* GetJavaInterfaces() { return &interface_provider_; }
+
+ private:
+ shell::InterfaceProvider interface_provider_;
+};
+
+} // namespace
+
+shell::InterfaceProvider* GetGlobalJavaInterfaces() {
+ return JavaInterfaceProviderHolder::GetInstance()->GetJavaInterfaces();
+}
+
+void BindInterfaceRegistryForWebContents(
+ shell::mojom::InterfaceProviderRequest request,
+ WebContents* web_contents) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_InterfaceRegistrarImpl_createInterfaceRegistryForWebContents(
+ env, request.PassMessagePipe().release().value(),
+ web_contents->GetJavaWebContents().obj());
+}
+
+} // namespace content
diff --git a/content/browser/android/java_interfaces_impl.h b/content/browser/android/java_interfaces_impl.h
new file mode 100644
index 0000000..e49ddcd
--- /dev/null
+++ b/content/browser/android/java_interfaces_impl.h
@@ -0,0 +1,20 @@
+// Copyright 2016 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.
+
+#ifndef CONTENT_BROWSER_ANDROID_JAVA_INTERFACES_IMPL_H_
+#define CONTENT_BROWSER_ANDROID_JAVA_INTERFACES_IMPL_H_
+
+#include "content/public/browser/android/java_interfaces.h"
+#include "services/shell/public/interfaces/interface_provider.mojom.h"
+
+namespace content {
+class WebContents;
+
+void BindInterfaceRegistryForWebContents(
+ shell::mojom::InterfaceProviderRequest request,
+ WebContents* web_contents);
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_ANDROID_JAVA_INTERFACES_IMPL_H_
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 4d9458af..10187d1 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -123,6 +123,7 @@
#include "net/http/http_transaction_factory.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
+#include "services/shell/public/cpp/interface_provider.h"
#include "third_party/WebKit/public/web/WebSandboxFlags.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/accessibility/ax_tree_combiner.h"
@@ -133,6 +134,7 @@
#if defined(OS_ANDROID)
#include "content/browser/android/content_video_view.h"
#include "content/browser/android/date_time_chooser_android.h"
+#include "content/browser/android/java_interfaces_impl.h"
#include "content/browser/media/android/media_web_contents_observer_android.h"
#include "content/browser/web_contents/web_contents_android.h"
#endif // OS_ANDROID
@@ -4979,6 +4981,16 @@
frame_tree_.root()->current_replication_state());
}
+shell::InterfaceProvider* WebContentsImpl::GetJavaInterfaces() {
+ if (!java_interfaces_) {
+ shell::mojom::InterfaceProviderPtr provider;
+ BindInterfaceRegistryForWebContents(mojo::GetProxy(&provider), this);
+ java_interfaces_.reset(new shell::InterfaceProvider);
+ java_interfaces_->Bind(std::move(provider));
+ }
+ return java_interfaces_.get();
+}
+
#elif defined(OS_MACOSX)
void WebContentsImpl::SetAllowOtherViews(bool allow) {
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index e4b786f..935dc7d 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -51,6 +51,10 @@
struct ViewHostMsg_DateTimeDialogValue_Params;
+namespace shell {
+class InterfaceProvider;
+}
+
namespace content {
class BrowserPluginEmbedder;
class BrowserPluginGuest;
@@ -415,6 +419,7 @@
virtual WebContentsAndroid* GetWebContentsAndroid();
void ActivateNearestFindResult(float x, float y) override;
void RequestFindMatchRects(int current_version) override;
+ shell::InterfaceProvider* GetJavaInterfaces() override;
#elif defined(OS_MACOSX)
void SetAllowOtherViews(bool allow) override;
bool GetAllowOtherViews() override;
@@ -1448,6 +1453,10 @@
// there's no RenderWidgetHost holding a lock.
RenderWidgetHostImpl* mouse_lock_widget_;
+#if defined(OS_ANDROID)
+ std::unique_ptr<shell::InterfaceProvider> java_interfaces_;
+#endif
+
base::WeakPtrFactory<WebContentsImpl> loading_weak_factory_;
base::WeakPtrFactory<WebContentsImpl> weak_factory_;
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
index ea07710..b8bf208 100644
--- a/content/public/android/BUILD.gn
+++ b/content/public/android/BUILD.gn
@@ -46,6 +46,8 @@
"//mojo/public/java:bindings",
"//mojo/public/java:system",
"//net/android:net_java",
+ "//services/shell/public/interfaces:interfaces_java",
+ "//services/shell/public/java:shell_java",
"//third_party/WebKit/public:blink_headers_java",
"//third_party/android_tools:android_support_annotations_java",
"//third_party/jsr-305:jsr_305_javalib",
@@ -121,6 +123,7 @@
"java/src/org/chromium/content/browser/FloatingWebActionModeCallback.java",
"java/src/org/chromium/content/browser/InterfaceProvider.java",
"java/src/org/chromium/content/browser/InterfaceRegistrar.java",
+ "java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java",
"java/src/org/chromium/content/browser/InterfaceRegistry.java",
"java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java",
"java/src/org/chromium/content/browser/JavascriptInterface.java",
@@ -193,6 +196,7 @@
"java/src/org/chromium/content_public/browser/ContentBitmapCallback.java",
"java/src/org/chromium/content_public/browser/GestureStateListener.java",
"java/src/org/chromium/content_public/browser/ImageDownloadCallback.java",
+ "java/src/org/chromium/content_public/browser/InterfaceRegistrar.java",
"java/src/org/chromium/content_public/browser/JavaScriptCallback.java",
"java/src/org/chromium/content_public/browser/LoadUrlParams.java",
"java/src/org/chromium/content_public/browser/NavigationController.java",
@@ -298,6 +302,7 @@
"java/src/org/chromium/content/browser/DeviceSensors.java",
"java/src/org/chromium/content/browser/InterfaceProvider.java",
"java/src/org/chromium/content/browser/InterfaceRegistrar.java",
+ "java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java",
"java/src/org/chromium/content/browser/InterfaceRegistry.java",
"java/src/org/chromium/content/browser/InterstitialPageDelegateAndroid.java",
"java/src/org/chromium/content/browser/MediaResourceGetter.java",
diff --git a/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java b/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java
new file mode 100644
index 0000000..b1d920a
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java
@@ -0,0 +1,31 @@
+// Copyright 2016 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.content.browser;
+
+import android.content.Context;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.content_public.browser.InterfaceRegistrar;
+import org.chromium.content_public.browser.WebContents;
+import org.chromium.mojo.system.impl.CoreImpl;
+import org.chromium.services.shell.InterfaceRegistry;
+
+@JNINamespace("content")
+class InterfaceRegistrarImpl {
+ @CalledByNative
+ static void createInterfaceRegistryForContext(int nativeHandle, Context applicationContext) {
+ InterfaceRegistry registry = InterfaceRegistry.create(
+ CoreImpl.getInstance().acquireNativeHandle(nativeHandle).toMessagePipeHandle());
+ InterfaceRegistrar.Registry.applyContextRegistrars(registry, applicationContext);
+ }
+
+ @CalledByNative
+ static void createInterfaceRegistryForWebContents(int nativeHandle, WebContents webContents) {
+ InterfaceRegistry registry = InterfaceRegistry.create(
+ CoreImpl.getInstance().acquireNativeHandle(nativeHandle).toMessagePipeHandle());
+ InterfaceRegistrar.Registry.applyWebContentsRegistrars(registry, webContents);
+ }
+}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/InterfaceRegistrar.java b/content/public/android/java/src/org/chromium/content_public/browser/InterfaceRegistrar.java
new file mode 100644
index 0000000..e76061d
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content_public/browser/InterfaceRegistrar.java
@@ -0,0 +1,74 @@
+// Copyright 2016 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.content_public.browser;
+
+import android.content.Context;
+
+import org.chromium.services.shell.InterfaceRegistry;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A registrar for mojo interface implementations to provide to an InterfaceRegistry.
+ *
+ * @param <ParamType> the type of parameter to pass to the InterfaceRegistrar when adding its
+ * interfaces to an InterfaceRegistry
+ */
+public interface InterfaceRegistrar<ParamType> {
+ /** Invoked to register interfaces on |registry|, parametrized by |paramValue|. */
+ public void registerInterfaces(InterfaceRegistry registry, ParamType paramValue);
+
+ /** A registry of InterfaceRegistrars. */
+ public static class Registry<ParamType> {
+ private static Registry<Context> sContextRegistry = null;
+ private static Registry<WebContents> sWebContentsRegistry = null;
+
+ private List<InterfaceRegistrar<ParamType>> mRegistrars =
+ new ArrayList<InterfaceRegistrar<ParamType>>();
+
+ public static void applyContextRegistrars(
+ InterfaceRegistry interfaceRegistry, Context context) {
+ if (sContextRegistry == null) {
+ return;
+ }
+ sContextRegistry.applyRegistrars(interfaceRegistry, context);
+ }
+
+ public static void applyWebContentsRegistrars(
+ InterfaceRegistry interfaceRegistry, WebContents webContents) {
+ if (sWebContentsRegistry == null) {
+ return;
+ }
+ sWebContentsRegistry.applyRegistrars(interfaceRegistry, webContents);
+ }
+
+ public static void addContextRegistrar(InterfaceRegistrar<Context> registrar) {
+ if (sContextRegistry == null) {
+ sContextRegistry = new Registry<Context>();
+ }
+ sContextRegistry.addRegistrar(registrar);
+ }
+
+ public static void addWebContentsRegistrar(InterfaceRegistrar<WebContents> registrar) {
+ if (sWebContentsRegistry == null) {
+ sWebContentsRegistry = new Registry<WebContents>();
+ }
+ sWebContentsRegistry.addRegistrar(registrar);
+ }
+
+ private Registry() {}
+
+ private void addRegistrar(InterfaceRegistrar<ParamType> registrar) {
+ mRegistrars.add(registrar);
+ }
+
+ private void applyRegistrars(InterfaceRegistry interfaceRegistry, ParamType param) {
+ for (InterfaceRegistrar<ParamType> registrar : mRegistrars) {
+ registrar.registerInterfaces(interfaceRegistry, param);
+ }
+ }
+ }
+}
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index ef23893..1041c8c4 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -33,6 +33,7 @@
"android/external_video_surface_container.h",
"android/interface_provider_android.h",
"android/interface_registry_android.h",
+ "android/java_interfaces.h",
"android/synchronous_compositor.cc",
"android/synchronous_compositor.h",
"android/synchronous_compositor_client.h",
diff --git a/content/public/browser/android/java_interfaces.h b/content/public/browser/android/java_interfaces.h
new file mode 100644
index 0000000..aa4973d3
--- /dev/null
+++ b/content/public/browser/android/java_interfaces.h
@@ -0,0 +1,24 @@
+// Copyright 2016 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.
+
+#ifndef CONTENT_PUBLIC_BROWSER_ANDROID_JAVA_INTERFACES_H_
+#define CONTENT_PUBLIC_BROWSER_ANDROID_JAVA_INTERFACES_H_
+
+#include "content/common/content_export.h"
+
+namespace shell {
+class InterfaceProvider;
+}
+
+namespace content {
+
+// Returns an InterfaceProvider for global Java-implemented interfaces.
+// This provides access to interfaces implemented in Java in the browser process
+// to C++ code in the browser process. This and the returned InterfaceProvider
+// may only be used on the UI thread.
+CONTENT_EXPORT shell::InterfaceProvider* GetGlobalJavaInterfaces();
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_ANDROID_JAVA_INTERFACES_H_
diff --git a/content/public/browser/web_contents.h b/content/public/browser/web_contents.h
index 163a2ad..37b3bf2 100644
--- a/content/public/browser/web_contents.h
+++ b/content/public/browser/web_contents.h
@@ -46,6 +46,10 @@
struct LoadStateWithParam;
}
+namespace shell {
+class InterfaceProvider;
+}
+
namespace content {
class BrowserContext;
@@ -727,6 +731,11 @@
// TODO(paulmeyer): This process will change slightly once multi-process
// find-in-page is implemented. This comment should be updated at that time.
virtual void RequestFindMatchRects(int current_version) = 0;
+
+ // Returns an InterfaceProvider for Java-implemented interfaces that are
+ // scoped to this WebContents. This provides access to interfaces implemented
+ // in Java in the browser process to C++ code in the browser process.
+ virtual shell::InterfaceProvider* GetJavaInterfaces() = 0;
#elif defined(OS_MACOSX)
// Allowing other views disables optimizations which assume that only a single
// WebContents is present.