Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1214)

Unified Diff: android_webview/native/callback_jni_bridge.cc

Issue 12313042: [android_webview] Add a generic callback JNI bridge. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: android_webview/native/callback_jni_bridge.cc
diff --git a/android_webview/native/callback_jni_bridge.cc b/android_webview/native/callback_jni_bridge.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f0e79b53ab3560f34c75f4de38d8715bd9664fe6
--- /dev/null
+++ b/android_webview/native/callback_jni_bridge.cc
@@ -0,0 +1,254 @@
+// Copyright 2013 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/callback_jni_bridge.h"
+
+#include <vector>
+
+#include "base/android/scoped_java_ref.h"
+#include "base/bind.h"
+#include "base/threading/thread_checker.h"
+#include "jni/CallbackJNIBridge_jni.h"
+
+using base::Callback;
+using base::android::AttachCurrentThread;
+using base::android::ScopedJavaLocalRef;
+using base::android::ScopedJavaGlobalRef;
+
+namespace android_webview {
+
+namespace {
+
+// A bit of template magic lets us select the right JNI invoke and create
+// method depending on the type of arguments being processed.
+template<typename T>
+struct JNISelector {
+};
+
+template<>
+struct JNISelector<int> {
+ static void Invoke(JNIEnv* env, jobject obj, jint value) {
+ Java_JavaCallbackInt_invoke(env, obj, value);
+ }
+
+ static ScopedJavaLocalRef<jobject> create(JNIEnv* env, jint callbackPtr) {
+ return Java_NativeCallbackInt_create(env, callbackPtr);
+ }
+};
+
+template<>
+struct JNISelector<long> {
+ static void Invoke(JNIEnv* env, jobject obj, jlong value) {
+ Java_JavaCallbackLong_invoke(env, obj, value);
+ }
+
+ static ScopedJavaLocalRef<jobject> create(JNIEnv* env, jint callbackPtr) {
+ return Java_NativeCallbackLong_create(env, callbackPtr);
+ }
+};
+
+template<>
+struct JNISelector<bool> {
+ static void Invoke(JNIEnv* env, jobject obj, jboolean value) {
+ Java_JavaCallbackBoolean_invoke(env, obj, value);
+ }
+
+ static ScopedJavaLocalRef<jobject> create(JNIEnv* env, jint callbackPtr) {
+ return Java_NativeCallbackBoolean_create(env, callbackPtr);
+ }
+};
+
+template<>
+struct JNISelector<ScopedJavaLocalRef<jobject> > {
+ static void Invoke(JNIEnv* env,
+ jobject obj,
+ const ScopedJavaLocalRef<jobject>& value) {
+ Java_JavaCallback_invoke(env, obj, value.obj());
+ }
+
+ static ScopedJavaLocalRef<jobject> create(JNIEnv* env, jint callbackPtr) {
+ return Java_NativeCallback_create(env, callbackPtr);
+ }
+};
+
+// This wraps a Java-side ValueCallback instance.
+template<typename T>
+class JavaCallback {
+ public:
+ JavaCallback(JNIEnv* env,
+ const ScopedJavaLocalRef<jobject>& jvalue_callback) {
+ jvalue_callback_.Reset(env, jvalue_callback.obj());
mkosiba (inactive) 2013/02/25 23:43:44 I think I'll add a DCHECK here to see if jvalue_ca
+ }
+
+ void onReceiveValue(T value) {
+ DCHECK(!jvalue_callback_.is_null());
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ if (!jvalue_callback_.is_null()) {
+ JNIEnv* env = AttachCurrentThread();
+ JNISelector<T>::Invoke(env, jvalue_callback_.obj(), value);
+ jvalue_callback_.Reset();
+ }
+ }
+
+ private:
+ ScopedJavaGlobalRef<jobject> jvalue_callback_;
+ base::ThreadChecker thread_checker_;
+};
+
+template <typename T>
+static Callback<void(T)> FromJavaCallbackTemplate(
+ JNIEnv* env,
+ const ScopedJavaLocalRef<jobject>& jvalue_callback) {
+ JavaCallback<T>* value_callback = new JavaCallback<T>(env, jvalue_callback);
+ return base::Bind(&JavaCallback<T>::onReceiveValue,
+ base::Owned(value_callback));
+}
+
+} // namespace
+
+Callback<void(int)> CallbackJNIBridge::FromJavaCallbackInt(
+ JNIEnv* env,
+ const ScopedJavaLocalRef<jobject>& jvalue_callback) {
+ return FromJavaCallbackTemplate<int>(env, jvalue_callback);
+}
+
+Callback<void(long)> CallbackJNIBridge::FromJavaCallbackLong(
+ JNIEnv* env,
+ const ScopedJavaLocalRef<jobject>& jvalue_callback) {
+ return FromJavaCallbackTemplate<long>(env, jvalue_callback);
+}
+
+Callback<void(bool)> CallbackJNIBridge::FromJavaCallbackBool(
+ JNIEnv* env,
+ const ScopedJavaLocalRef<jobject>& jvalue_callback) {
+ return FromJavaCallbackTemplate<bool>(env, jvalue_callback);
+}
+
+base::Callback<void(ScopedJavaLocalRef<jobject>)>
+CallbackJNIBridge::FromJavaCallbackObj(
+ JNIEnv* env,
+ const ScopedJavaLocalRef<jobject>& jvalue_callback) {
+ return FromJavaCallbackTemplate<ScopedJavaLocalRef<jobject> >(
+ env, jvalue_callback);
+}
+
+namespace {
+
+template <typename T>
+ScopedJavaLocalRef<jobject> ToJavaCallbackTemplate(
+ JNIEnv* env,
+ const base::Callback<void(T)>& callback) {
+ Callback<void(T)>* native_callback = new Callback<void(T)>(callback);
+ ScopedJavaLocalRef<jobject> jvalue_callback = Java_NativeCallbackInt_create(
+ env, reinterpret_cast<int>(native_callback));
+
+ return jvalue_callback;
+}
+
+} // namespace
+
+ScopedJavaLocalRef<jobject> CallbackJNIBridge::ToJavaCallbackInt(
+ JNIEnv* env,
+ const Callback<void(int)>& callback) {
+ return ToJavaCallbackTemplate(env, callback);
+}
+
+ScopedJavaLocalRef<jobject> CallbackJNIBridge::ToJavaCallbackLong(
+ JNIEnv* env,
+ const Callback<void(long)>& callback) {
+ return ToJavaCallbackTemplate(env, callback);
+}
+
+ScopedJavaLocalRef<jobject> CallbackJNIBridge::ToJavaCallbackBool(
+ JNIEnv* env,
+ const Callback<void(bool)>& callback) {
+ return ToJavaCallbackTemplate(env, callback);
+}
+
+ScopedJavaLocalRef<jobject> CallbackJNIBridge::ToJavaCallbackObj(
+ JNIEnv* env,
+ const base::Callback<void(ScopedJavaLocalRef<jobject>)>& callback) {
+ Callback<void(ScopedJavaLocalRef<jobject>)>* native_callback =
+ new Callback<void(ScopedJavaLocalRef<jobject>)>(callback);
+ ScopedJavaLocalRef<jobject> jvalue_callback =
+ Java_NativeCallback_create(
+ env, reinterpret_cast<int>(native_callback));
+
+ return jvalue_callback;
+}
+
+// static methods -------------------------------------------------------------
+namespace {
+
+template <typename T>
+void DestroyTemplate(JNIEnv* env, jclass clazz, jint callbackPtr) {
+ Callback<void(T)>* native_callback =
+ reinterpret_cast<Callback<void(T)>*>(callbackPtr);
+ delete native_callback;
+}
+
+template <typename T, typename JT>
+static void InvokeTemplate(JNIEnv* env,
+ jclass clazz,
+ jint callbackPtr,
+ JT value) {
+ Callback<void(T)>* native_callback =
+ reinterpret_cast<Callback<void(T)>*>(callbackPtr);
+ native_callback->Run(value);
+}
+
+} // namespace
+
+static void DestroyInt(JNIEnv* env, jclass clazz, jint callbackPtr) {
+ DestroyTemplate<int>(env, clazz, callbackPtr);
+}
+
+static void InvokeInt(JNIEnv* env, jclass clazz, jint callbackPtr, jint value) {
+ InvokeTemplate<int, jint>(env, clazz, callbackPtr, value);
+}
+
+static void DestroyLong(JNIEnv* env, jclass clazz, jint callbackPtr) {
+ DestroyTemplate<long>(env, clazz, callbackPtr);
+}
+
+static void InvokeLong(JNIEnv* env,
+ jclass clazz,
+ jint callbackPtr,
+ jlong value) {
+ InvokeTemplate<long, jlong>(env, clazz, callbackPtr, value);
+}
+
+static void DestroyBoolean(JNIEnv* env, jclass clazz, jint callbackPtr) {
+ DestroyTemplate<bool>(env, clazz, callbackPtr);
+}
+
+static void InvokeBoolean(JNIEnv* env,
+ jclass clazz,
+ jint callbackPtr,
+ jboolean value) {
+ InvokeTemplate<bool, jboolean>(env, clazz, callbackPtr, value);
+}
+
+static void DestroyObj(JNIEnv* env, jclass clazz, jint callbackPtr) {
+ DestroyTemplate<ScopedJavaLocalRef<jobject> >(env, clazz, callbackPtr);
+}
+
+static void InvokeObj(JNIEnv* env,
+ jclass clazz,
+ jint callbackPtr,
+ jobject value) {
+ ScopedJavaLocalRef<jobject> jvalue(env, value);
+ InvokeTemplate<ScopedJavaLocalRef<jobject>,
+ const ScopedJavaLocalRef<jobject>&>(env,
+ clazz,
+ callbackPtr,
+ jvalue);
+}
+
+bool RegisterCallbackJNIBridge(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace android_webview

Powered by Google App Engine
This is Rietveld 408576698