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

Side by Side 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, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "android_webview/native/callback_jni_bridge.h"
6
7 #include <vector>
8
9 #include "base/android/scoped_java_ref.h"
10 #include "base/bind.h"
11 #include "base/threading/thread_checker.h"
12 #include "jni/CallbackJNIBridge_jni.h"
13
14 using base::Callback;
15 using base::android::AttachCurrentThread;
16 using base::android::ScopedJavaLocalRef;
17 using base::android::ScopedJavaGlobalRef;
18
19 namespace android_webview {
20
21 namespace {
22
23 // A bit of template magic lets us select the right JNI invoke and create
24 // method depending on the type of arguments being processed.
25 template<typename T>
26 struct JNISelector {
27 };
28
29 template<>
30 struct JNISelector<int> {
31 static void Invoke(JNIEnv* env, jobject obj, jint value) {
32 Java_JavaCallbackInt_invoke(env, obj, value);
33 }
34
35 static ScopedJavaLocalRef<jobject> create(JNIEnv* env, jint callbackPtr) {
36 return Java_NativeCallbackInt_create(env, callbackPtr);
37 }
38 };
39
40 template<>
41 struct JNISelector<long> {
42 static void Invoke(JNIEnv* env, jobject obj, jlong value) {
43 Java_JavaCallbackLong_invoke(env, obj, value);
44 }
45
46 static ScopedJavaLocalRef<jobject> create(JNIEnv* env, jint callbackPtr) {
47 return Java_NativeCallbackLong_create(env, callbackPtr);
48 }
49 };
50
51 template<>
52 struct JNISelector<bool> {
53 static void Invoke(JNIEnv* env, jobject obj, jboolean value) {
54 Java_JavaCallbackBoolean_invoke(env, obj, value);
55 }
56
57 static ScopedJavaLocalRef<jobject> create(JNIEnv* env, jint callbackPtr) {
58 return Java_NativeCallbackBoolean_create(env, callbackPtr);
59 }
60 };
61
62 template<>
63 struct JNISelector<ScopedJavaLocalRef<jobject> > {
64 static void Invoke(JNIEnv* env,
65 jobject obj,
66 const ScopedJavaLocalRef<jobject>& value) {
67 Java_JavaCallback_invoke(env, obj, value.obj());
68 }
69
70 static ScopedJavaLocalRef<jobject> create(JNIEnv* env, jint callbackPtr) {
71 return Java_NativeCallback_create(env, callbackPtr);
72 }
73 };
74
75 // This wraps a Java-side ValueCallback instance.
76 template<typename T>
77 class JavaCallback {
78 public:
79 JavaCallback(JNIEnv* env,
80 const ScopedJavaLocalRef<jobject>& jvalue_callback) {
81 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
82 }
83
84 void onReceiveValue(T value) {
85 DCHECK(!jvalue_callback_.is_null());
86 DCHECK(thread_checker_.CalledOnValidThread());
87
88 if (!jvalue_callback_.is_null()) {
89 JNIEnv* env = AttachCurrentThread();
90 JNISelector<T>::Invoke(env, jvalue_callback_.obj(), value);
91 jvalue_callback_.Reset();
92 }
93 }
94
95 private:
96 ScopedJavaGlobalRef<jobject> jvalue_callback_;
97 base::ThreadChecker thread_checker_;
98 };
99
100 template <typename T>
101 static Callback<void(T)> FromJavaCallbackTemplate(
102 JNIEnv* env,
103 const ScopedJavaLocalRef<jobject>& jvalue_callback) {
104 JavaCallback<T>* value_callback = new JavaCallback<T>(env, jvalue_callback);
105 return base::Bind(&JavaCallback<T>::onReceiveValue,
106 base::Owned(value_callback));
107 }
108
109 } // namespace
110
111 Callback<void(int)> CallbackJNIBridge::FromJavaCallbackInt(
112 JNIEnv* env,
113 const ScopedJavaLocalRef<jobject>& jvalue_callback) {
114 return FromJavaCallbackTemplate<int>(env, jvalue_callback);
115 }
116
117 Callback<void(long)> CallbackJNIBridge::FromJavaCallbackLong(
118 JNIEnv* env,
119 const ScopedJavaLocalRef<jobject>& jvalue_callback) {
120 return FromJavaCallbackTemplate<long>(env, jvalue_callback);
121 }
122
123 Callback<void(bool)> CallbackJNIBridge::FromJavaCallbackBool(
124 JNIEnv* env,
125 const ScopedJavaLocalRef<jobject>& jvalue_callback) {
126 return FromJavaCallbackTemplate<bool>(env, jvalue_callback);
127 }
128
129 base::Callback<void(ScopedJavaLocalRef<jobject>)>
130 CallbackJNIBridge::FromJavaCallbackObj(
131 JNIEnv* env,
132 const ScopedJavaLocalRef<jobject>& jvalue_callback) {
133 return FromJavaCallbackTemplate<ScopedJavaLocalRef<jobject> >(
134 env, jvalue_callback);
135 }
136
137 namespace {
138
139 template <typename T>
140 ScopedJavaLocalRef<jobject> ToJavaCallbackTemplate(
141 JNIEnv* env,
142 const base::Callback<void(T)>& callback) {
143 Callback<void(T)>* native_callback = new Callback<void(T)>(callback);
144 ScopedJavaLocalRef<jobject> jvalue_callback = Java_NativeCallbackInt_create(
145 env, reinterpret_cast<int>(native_callback));
146
147 return jvalue_callback;
148 }
149
150 } // namespace
151
152 ScopedJavaLocalRef<jobject> CallbackJNIBridge::ToJavaCallbackInt(
153 JNIEnv* env,
154 const Callback<void(int)>& callback) {
155 return ToJavaCallbackTemplate(env, callback);
156 }
157
158 ScopedJavaLocalRef<jobject> CallbackJNIBridge::ToJavaCallbackLong(
159 JNIEnv* env,
160 const Callback<void(long)>& callback) {
161 return ToJavaCallbackTemplate(env, callback);
162 }
163
164 ScopedJavaLocalRef<jobject> CallbackJNIBridge::ToJavaCallbackBool(
165 JNIEnv* env,
166 const Callback<void(bool)>& callback) {
167 return ToJavaCallbackTemplate(env, callback);
168 }
169
170 ScopedJavaLocalRef<jobject> CallbackJNIBridge::ToJavaCallbackObj(
171 JNIEnv* env,
172 const base::Callback<void(ScopedJavaLocalRef<jobject>)>& callback) {
173 Callback<void(ScopedJavaLocalRef<jobject>)>* native_callback =
174 new Callback<void(ScopedJavaLocalRef<jobject>)>(callback);
175 ScopedJavaLocalRef<jobject> jvalue_callback =
176 Java_NativeCallback_create(
177 env, reinterpret_cast<int>(native_callback));
178
179 return jvalue_callback;
180 }
181
182 // static methods -------------------------------------------------------------
183 namespace {
184
185 template <typename T>
186 void DestroyTemplate(JNIEnv* env, jclass clazz, jint callbackPtr) {
187 Callback<void(T)>* native_callback =
188 reinterpret_cast<Callback<void(T)>*>(callbackPtr);
189 delete native_callback;
190 }
191
192 template <typename T, typename JT>
193 static void InvokeTemplate(JNIEnv* env,
194 jclass clazz,
195 jint callbackPtr,
196 JT value) {
197 Callback<void(T)>* native_callback =
198 reinterpret_cast<Callback<void(T)>*>(callbackPtr);
199 native_callback->Run(value);
200 }
201
202 } // namespace
203
204 static void DestroyInt(JNIEnv* env, jclass clazz, jint callbackPtr) {
205 DestroyTemplate<int>(env, clazz, callbackPtr);
206 }
207
208 static void InvokeInt(JNIEnv* env, jclass clazz, jint callbackPtr, jint value) {
209 InvokeTemplate<int, jint>(env, clazz, callbackPtr, value);
210 }
211
212 static void DestroyLong(JNIEnv* env, jclass clazz, jint callbackPtr) {
213 DestroyTemplate<long>(env, clazz, callbackPtr);
214 }
215
216 static void InvokeLong(JNIEnv* env,
217 jclass clazz,
218 jint callbackPtr,
219 jlong value) {
220 InvokeTemplate<long, jlong>(env, clazz, callbackPtr, value);
221 }
222
223 static void DestroyBoolean(JNIEnv* env, jclass clazz, jint callbackPtr) {
224 DestroyTemplate<bool>(env, clazz, callbackPtr);
225 }
226
227 static void InvokeBoolean(JNIEnv* env,
228 jclass clazz,
229 jint callbackPtr,
230 jboolean value) {
231 InvokeTemplate<bool, jboolean>(env, clazz, callbackPtr, value);
232 }
233
234 static void DestroyObj(JNIEnv* env, jclass clazz, jint callbackPtr) {
235 DestroyTemplate<ScopedJavaLocalRef<jobject> >(env, clazz, callbackPtr);
236 }
237
238 static void InvokeObj(JNIEnv* env,
239 jclass clazz,
240 jint callbackPtr,
241 jobject value) {
242 ScopedJavaLocalRef<jobject> jvalue(env, value);
243 InvokeTemplate<ScopedJavaLocalRef<jobject>,
244 const ScopedJavaLocalRef<jobject>&>(env,
245 clazz,
246 callbackPtr,
247 jvalue);
248 }
249
250 bool RegisterCallbackJNIBridge(JNIEnv* env) {
251 return RegisterNativesImpl(env);
252 }
253
254 } // namespace android_webview
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698