summaryrefslogtreecommitdiffstats
path: root/android_webview/native
diff options
context:
space:
mode:
authorsgurun <sgurun@chromium.org>2015-01-23 12:54:05 -0800
committerCommit bot <commit-bot@chromium.org>2015-01-23 20:55:32 +0000
commitd2a4306024cc3bd6c52c70646ad6ec37f0259622 (patch)
tree4872f4b3a7f746bd4cb1c8e63e820925a9404af8 /android_webview/native
parentd2e1ece564dc9b309d8d97bd988e635b5cb41047 (diff)
downloadchromium_src-d2a4306024cc3bd6c52c70646ad6ec37f0259622.zip
chromium_src-d2a4306024cc3bd6c52c70646ad6ec37f0259622.tar.gz
chromium_src-d2a4306024cc3bd6c52c70646ad6ec37f0259622.tar.bz2
Enable posting a message from JS to Android webview.
For future CL: queueing messages, sending messages from Java to JS through message channel, transferring ports in message channels, closing channels. BUG=393291 Review URL: https://codereview.chromium.org/831523004 Cr-Commit-Position: refs/heads/master@{#312922}
Diffstat (limited to 'android_webview/native')
-rw-r--r--android_webview/native/android_webview_jni_registrar.cc2
-rw-r--r--android_webview/native/aw_contents.cc79
-rw-r--r--android_webview/native/aw_contents.h3
-rw-r--r--android_webview/native/aw_message_port_service_impl.cc161
-rw-r--r--android_webview/native/aw_message_port_service_impl.h65
-rw-r--r--android_webview/native/webview_native.gyp3
6 files changed, 261 insertions, 52 deletions
diff --git a/android_webview/native/android_webview_jni_registrar.cc b/android_webview/native/android_webview_jni_registrar.cc
index 253a070..e81853f 100644
--- a/android_webview/native/android_webview_jni_registrar.cc
+++ b/android_webview/native/android_webview_jni_registrar.cc
@@ -14,6 +14,7 @@
#include "android_webview/native/aw_dev_tools_server.h"
#include "android_webview/native/aw_form_database.h"
#include "android_webview/native/aw_http_auth_handler.h"
+#include "android_webview/native/aw_message_port_service_impl.h"
#include "android_webview/native/aw_pdf_exporter.h"
#include "android_webview/native/aw_picture.h"
#include "android_webview/native/aw_quota_manager_bridge_impl.h"
@@ -58,6 +59,7 @@ static base::android::RegistrationMethod kWebViewRegisteredMethods[] = {
{ "AwWebResourceResponseImpl", RegisterAwWebResourceResponse },
{ "InputStream", RegisterInputStream },
{ "JavaBrowserViewRendererHelper", RegisterJavaBrowserViewRendererHelper },
+ { "AwMessagePortService", RegisterAwMessagePortService },
};
bool RegisterJni(JNIEnv* env) {
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index 2a9a35f..64cd9a9 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -21,6 +21,7 @@
#include "android_webview/native/aw_browser_dependency_factory.h"
#include "android_webview/native/aw_contents_client_bridge.h"
#include "android_webview/native/aw_contents_io_thread_client_impl.h"
+#include "android_webview/native/aw_message_port_service_impl.h"
#include "android_webview/native/aw_pdf_exporter.h"
#include "android_webview/native/aw_picture.h"
#include "android_webview/native/aw_web_contents_delegate.h"
@@ -133,23 +134,6 @@ void OnIoThreadClientReady(content::RenderFrameHost* rfh) {
render_process_id, render_frame_id);
}
-void OnMessageChannelCreated(ScopedJavaGlobalRef<jobject>* callback,
- int* port1,
- int* port2) {
- JNIEnv* env = AttachCurrentThread();
- Java_AwContents_onMessageChannelCreated(env, *port1, *port2,
- callback->obj());
-}
-
-void PostMessageToFrameOnIOThread(WebContents* web_contents,
- base::string16* source_origin,
- base::string16* target_origin,
- base::string16* data,
- std::vector<int>* ports) {
- content::MessagePortProvider::PostMessageToFrame(web_contents,
- *source_origin, *target_origin, *data, *ports);
-}
-
} // namespace
// static
@@ -1084,49 +1068,40 @@ void AwContents::PostMessageToFrame(JNIEnv* env, jobject obj,
jstring frame_name, jstring message, jstring source_origin,
jstring target_origin, jintArray msgPorts) {
- base::string16* j_source_origin = new base::string16;
- ConvertJavaStringToUTF16(env, source_origin, j_source_origin);
- base::string16* j_target_origin = new base::string16;
- ConvertJavaStringToUTF16(env, target_origin, j_target_origin);
- base::string16* j_message = new base::string16;
- ConvertJavaStringToUTF16(env, message, j_message);
- std::vector<int>* j_ports = new std::vector<int>;
-
+ base::string16 j_source_origin(ConvertJavaStringToUTF16(env, source_origin));
+ base::string16 j_target_origin(ConvertJavaStringToUTF16(env, target_origin));
+ base::string16 j_message(ConvertJavaStringToUTF16(env, message));
+ std::vector<int> j_ports;
if (msgPorts != nullptr)
- base::android::JavaIntArrayToIntVector(env, msgPorts, j_ports);
-
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&PostMessageToFrameOnIOThread,
- web_contents_.get(),
- base::Owned(j_source_origin),
- base::Owned(j_target_origin),
- base::Owned(j_message),
- base::Owned(j_ports)));
+ base::android::JavaIntArrayToIntVector(env, msgPorts, &j_ports);
+
+ content::MessagePortProvider::PostMessageToFrame(web_contents_.get(),
+ j_source_origin,
+ j_target_origin,
+ j_message,
+ j_ports);
+}
+
+scoped_refptr<AwMessagePortMessageFilter>
+AwContents::GetMessagePortMessageFilter() {
+ // Create a message port message filter if necessary
+ if (message_port_message_filter_.get() == nullptr) {
+ message_port_message_filter_ =
+ new AwMessagePortMessageFilter(
+ web_contents_->GetMainFrame()->GetRoutingID());
+ web_contents_->GetRenderProcessHost()->AddFilter(
+ message_port_message_filter_.get());
+ }
+ return message_port_message_filter_;
}
void AwContents::CreateMessageChannel(JNIEnv* env, jobject obj,
jobject callback) {
- ScopedJavaGlobalRef<jobject>* j_callback = new ScopedJavaGlobalRef<jobject>();
- j_callback->Reset(env, callback);
- int* port1 = new int;
- int* port2 = new int;
- BrowserThread::PostTaskAndReply(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&content::MessagePortProvider::CreateMessageChannel,
- web_contents_.get(),
- port1,
- port2),
- base::Bind(&OnMessageChannelCreated,
- base::Owned(j_callback),
- base::Owned(port1),
- base::Owned(port2)));
+ AwMessagePortServiceImpl::GetInstance()->CreateMessageChannel(env, callback,
+ GetMessagePortMessageFilter());
}
-
void SetShouldDownloadFavicons(JNIEnv* env, jclass jclazz) {
g_should_download_favicons = true;
}
diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h
index 4a4afbb..13ad67c 100644
--- a/android_webview/native/aw_contents.h
+++ b/android_webview/native/aw_contents.h
@@ -11,6 +11,7 @@
#include <utility>
#include "android_webview/browser/aw_browser_permission_request_delegate.h"
+#include "android_webview/browser/aw_message_port_message_filter.h"
#include "android_webview/browser/browser_view_renderer.h"
#include "android_webview/browser/browser_view_renderer_client.h"
#include "android_webview/browser/find_helper.h"
@@ -220,6 +221,7 @@ class AwContents : public FindHelper::Listener,
void SetJsOnlineProperty(JNIEnv* env, jobject obj, jboolean network_up);
void TrimMemory(JNIEnv* env, jobject obj, jint level, jboolean visible);
+ scoped_refptr<AwMessagePortMessageFilter> GetMessagePortMessageFilter();
void PostMessageToFrame(JNIEnv* env, jobject obj, jstring frame_id,
jstring message, jstring source_origin, jstring target_origin,
jintArray msgPorts);
@@ -244,6 +246,7 @@ class AwContents : public FindHelper::Listener,
BrowserViewRenderer browser_view_renderer_;
scoped_ptr<AwPdfExporter> pdf_exporter_;
scoped_ptr<PermissionRequestHandler> permission_request_handler_;
+ scoped_refptr<AwMessagePortMessageFilter> message_port_message_filter_;
// GURL is supplied by the content layer as requesting frame.
// Callback is supplied by the content layer, and is invoked with the result
diff --git a/android_webview/native/aw_message_port_service_impl.cc b/android_webview/native/aw_message_port_service_impl.cc
new file mode 100644
index 0000000..5fa4e1b
--- /dev/null
+++ b/android_webview/native/aw_message_port_service_impl.cc
@@ -0,0 +1,161 @@
+// Copyright 2015 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 "android_webview/native/aw_message_port_service_impl.h"
+
+#include "android_webview/browser/aw_browser_context.h"
+#include "android_webview/browser/aw_message_port_message_filter.h"
+#include "android_webview/native/aw_contents.h"
+#include "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "base/bind.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/message_port_provider.h"
+#include "jni/AwMessagePortService_jni.h"
+
+namespace android_webview {
+
+using base::android::AttachCurrentThread;
+using base::android::ConvertUTF16ToJavaString;
+using base::android::ScopedJavaGlobalRef;
+using base::android::ScopedJavaLocalRef;
+using base::android::ToJavaIntArray;
+using content::BrowserThread;
+using content::MessagePortProvider;
+
+//static
+AwMessagePortServiceImpl* AwMessagePortServiceImpl::GetInstance() {
+ return static_cast<AwMessagePortServiceImpl*>(
+ AwBrowserContext::GetDefault()->GetMessagePortService());
+}
+
+AwMessagePortServiceImpl::AwMessagePortServiceImpl() {
+}
+
+AwMessagePortServiceImpl::~AwMessagePortServiceImpl() {
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+ Java_AwMessagePortService_unregisterNativeAwMessagePortService(env,
+ obj.obj());
+}
+
+void AwMessagePortServiceImpl::Init(JNIEnv* env, jobject obj) {
+ java_ref_ = JavaObjectWeakGlobalRef(env, obj);
+}
+
+void AwMessagePortServiceImpl::CreateMessageChannel(
+ JNIEnv* env,
+ jobject callback,
+ scoped_refptr<AwMessagePortMessageFilter> filter) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ ScopedJavaGlobalRef<jobject>* j_callback = new ScopedJavaGlobalRef<jobject>();
+ j_callback->Reset(env, callback);
+
+ int* portId1 = new int;
+ int* portId2 = new int;
+ BrowserThread::PostTaskAndReply(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&AwMessagePortServiceImpl::CreateMessageChannelOnIOThread,
+ base::Unretained(this),
+ filter,
+ portId1,
+ portId2),
+ base::Bind(&AwMessagePortServiceImpl::OnMessageChannelCreated,
+ base::Unretained(this),
+ base::Owned(j_callback),
+ base::Owned(portId1),
+ base::Owned(portId2)));
+}
+
+void AwMessagePortServiceImpl::OnConvertedMessage(
+ int message_port_id,
+ const base::ListValue& message,
+ const std::vector<int>& sent_message_port_ids) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> jobj = java_ref_.get(env);
+ if (jobj.is_null())
+ return;
+
+ if (message.GetSize() != 1) {
+ NOTREACHED();
+ return;
+ }
+
+ base::string16 value;
+ if (!message.GetString(0, &value)) {
+ LOG(WARNING) << "Converting post message to a string failed for port "
+ << message_port_id;
+ return;
+ }
+ ScopedJavaLocalRef<jstring> jmsg = ConvertUTF16ToJavaString(env, value);
+ ScopedJavaLocalRef<jintArray> jports =
+ ToJavaIntArray(env, sent_message_port_ids);
+ Java_AwMessagePortService_onPostMessage(env,
+ jobj.obj(),
+ message_port_id,
+ jmsg.obj(),
+ jports.obj());
+}
+
+void AwMessagePortServiceImpl::OnMessagePortMessageFilterClosing(
+ AwMessagePortMessageFilter* filter) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ for (MessagePorts::iterator iter = ports_.begin();
+ iter != ports_.end(); iter++) {
+ if (iter->second == filter) {
+ ports_.erase(iter);
+ }
+ }
+}
+
+void AwMessagePortServiceImpl::CreateMessageChannelOnIOThread(
+ scoped_refptr<AwMessagePortMessageFilter> filter,
+ int* portId1,
+ int* portId2) {
+ content::MessagePortProvider::CreateMessageChannel(filter.get(), portId1,
+ portId2);
+ AddPort(*portId1, filter.get());
+ AddPort(*portId2, filter.get());
+}
+
+void AwMessagePortServiceImpl::OnMessageChannelCreated(
+ ScopedJavaGlobalRef<jobject>* callback,
+ int* port1,
+ int* port2) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jobject> obj = java_ref_.get(env);
+ if (obj.is_null())
+ return;
+ Java_AwMessagePortService_onMessageChannelCreated(env, obj.obj(), *port1,
+ *port2, callback->obj());
+}
+
+void AwMessagePortServiceImpl::AddPort(int message_port_id,
+ AwMessagePortMessageFilter* filter) {
+ DCHECK_CURRENTLY_ON(BrowserThread::IO);
+ if (ports_.count(message_port_id)) {
+ NOTREACHED();
+ return;
+ }
+ ports_[message_port_id] = filter;
+}
+
+bool RegisterAwMessagePortService(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+// static
+jlong InitAwMessagePortService(JNIEnv* env, jobject obj) {
+ AwMessagePortServiceImpl* service = AwMessagePortServiceImpl::GetInstance();
+ service->Init(env, obj);
+ return reinterpret_cast<intptr_t>(service);
+}
+
+} // namespace android_webview
diff --git a/android_webview/native/aw_message_port_service_impl.h b/android_webview/native/aw_message_port_service_impl.h
new file mode 100644
index 0000000..d938b6e
--- /dev/null
+++ b/android_webview/native/aw_message_port_service_impl.h
@@ -0,0 +1,65 @@
+// Copyright 2015 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 ANDROID_WEBVIEW_NATIVE_AW_MESSAGE_PORT_SERVICE_IMPL_H_
+#define ANDROID_WEBVIEW_NATIVE_AW_MESSAGE_PORT_SERVICE_IMPL_H_
+
+#include <jni.h>
+#include <map>
+
+#include "android_webview/browser/aw_message_port_service.h"
+#include "base/android/jni_weak_ref.h"
+#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/strings/string16.h"
+
+namespace android_webview {
+
+// This class is the native peer of AwMessagePortService.java. Please see the
+// java class for an explanation of use, ownership and lifetime.
+
+// Threading: Created and initialized on UI thread. For other methods, see
+// the method level DCHECKS or documentation.
+class AwMessagePortServiceImpl : public AwMessagePortService {
+ public:
+ static AwMessagePortServiceImpl* GetInstance();
+
+ AwMessagePortServiceImpl();
+ ~AwMessagePortServiceImpl();
+ void Init(JNIEnv* env, jobject object);
+
+ void CreateMessageChannel(JNIEnv* env, jobject callback,
+ scoped_refptr<AwMessagePortMessageFilter> filter);
+
+ // AwMessagePortService implementation
+ void OnConvertedMessage(
+ int message_port_id,
+ const base::ListValue& message,
+ const std::vector<int>& sent_message_port_ids) override;
+ void OnMessagePortMessageFilterClosing(
+ AwMessagePortMessageFilter* filter) override;
+
+private:
+ void CreateMessageChannelOnIOThread(
+ scoped_refptr<AwMessagePortMessageFilter> filter,
+ int* port1,
+ int* port2);
+ void OnMessageChannelCreated(
+ base::android::ScopedJavaGlobalRef<jobject>* callback,
+ int* port1,
+ int* port2);
+ void AddPort(int message_port_id, AwMessagePortMessageFilter* filter);
+
+ JavaObjectWeakGlobalRef java_ref_;
+ typedef std::map<int, AwMessagePortMessageFilter*> MessagePorts;
+ MessagePorts ports_; // Access on IO thread
+
+ DISALLOW_COPY_AND_ASSIGN(AwMessagePortServiceImpl);
+};
+
+bool RegisterAwMessagePortService(JNIEnv* env);
+
+} // namespace android_webview
+
+#endif // ANDROID_WEBVIEW_NATIVE_AW_MESSAGE_PORT_SERVICE_IMPL_H_
diff --git a/android_webview/native/webview_native.gyp b/android_webview/native/webview_native.gyp
index 52b3e45..34889e1 100644
--- a/android_webview/native/webview_native.gyp
+++ b/android_webview/native/webview_native.gyp
@@ -58,6 +58,8 @@
'aw_http_auth_handler.h',
'aw_media_url_interceptor.cc',
'aw_media_url_interceptor.h',
+ 'aw_message_port_service_impl.cc',
+ 'aw_messagE_port_service_impl.h',
'aw_pdf_exporter.cc',
'aw_pdf_exporter.h',
'aw_picture.cc',
@@ -131,6 +133,7 @@
'../java/src/org/chromium/android_webview/AwDevToolsServer.java',
'../java/src/org/chromium/android_webview/AwFormDatabase.java',
'../java/src/org/chromium/android_webview/AwHttpAuthHandler.java',
+ '../java/src/org/chromium/android_webview/AwMessagePortService.java',
'../java/src/org/chromium/android_webview/AwPdfExporter.java',
'../java/src/org/chromium/android_webview/AwPicture.java',
'../java/src/org/chromium/android_webview/AwQuotaManagerBridge.java',