OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/renderer_host/java/java_method.h" | 5 #include "content/browser/renderer_host/java/java_method.h" |
6 | 6 |
7 #include "base/android/jni_android.h" | 7 #include "base/android/jni_android.h" |
8 #include "base/android/jni_string.h" | 8 #include "base/android/jni_string.h" |
9 #include "base/lazy_instance.h" | |
9 #include "base/memory/singleton.h" | 10 #include "base/memory/singleton.h" |
10 #include "base/string_util.h" // For ReplaceSubstringsAfterOffset | 11 #include "base/string_util.h" // For ReplaceSubstringsAfterOffset |
11 | 12 |
12 using base::android::AttachCurrentThread; | 13 using base::android::AttachCurrentThread; |
13 using base::android::ConvertJavaStringToUTF8; | 14 using base::android::ConvertJavaStringToUTF8; |
15 using base::android::GetMethodID; | |
14 using base::android::GetMethodIDFromClassName; | 16 using base::android::GetMethodIDFromClassName; |
17 using base::android::GetStaticMethodID; | |
18 using base::android::ScopedJavaGlobalRef; | |
15 using base::android::ScopedJavaLocalRef; | 19 using base::android::ScopedJavaLocalRef; |
16 | 20 |
17 namespace { | 21 namespace { |
18 | 22 |
19 const char kGetName[] = "getName"; | 23 const char kGetName[] = "getName"; |
20 const char kGetDeclaringClass[] = "getDeclaringClass"; | 24 const char kGetDeclaringClass[] = "getDeclaringClass"; |
25 const char kGetModifiers[] = "getModifiers"; | |
21 const char kGetParameterTypes[] = "getParameterTypes"; | 26 const char kGetParameterTypes[] = "getParameterTypes"; |
22 const char kGetReturnType[] = "getReturnType"; | 27 const char kGetReturnType[] = "getReturnType"; |
28 const char kIntegerReturningBoolean[] = "(I)Z"; | |
29 const char kIsStatic[] = "isStatic"; | |
23 const char kJavaLangClass[] = "java/lang/Class"; | 30 const char kJavaLangClass[] = "java/lang/Class"; |
24 const char kJavaLangReflectMethod[] = "java/lang/reflect/Method"; | 31 const char kJavaLangReflectMethod[] = "java/lang/reflect/Method"; |
32 const char kJavaLangReflectModifier[] = "java/lang/reflect/Modifier"; | |
33 const char kReturningInteger[] = "()I"; | |
25 const char kReturningJavaLangClass[] = "()Ljava/lang/Class;"; | 34 const char kReturningJavaLangClass[] = "()Ljava/lang/Class;"; |
26 const char kReturningJavaLangClassArray[] = "()[Ljava/lang/Class;"; | 35 const char kReturningJavaLangClassArray[] = "()[Ljava/lang/Class;"; |
27 const char kReturningJavaLangString[] = "()Ljava/lang/String;"; | 36 const char kReturningJavaLangString[] = "()Ljava/lang/String;"; |
28 | 37 |
38 struct ModifierClassTraits : | |
39 public base::DefaultLazyInstanceTraits<ScopedJavaGlobalRef<jclass> > { | |
40 static ScopedJavaGlobalRef<jclass>* New(void* instance) { | |
41 JNIEnv* env = AttachCurrentThread(); | |
42 // Use placement new to initialize our instance in our preallocated space. | |
43 // The parenthesis is very important here to force POD type initialization. | |
joth
2011/12/05 15:53:23
this sentence not needed here. (we already know Sc
| |
44 return new (instance) ScopedJavaGlobalRef<jclass>( | |
45 ScopedJavaLocalRef<jclass>( | |
46 env, | |
47 static_cast<jclass>(env->FindClass(kJavaLangReflectModifier)))); | |
48 } | |
49 }; | |
50 | |
51 base::LazyInstance<ScopedJavaGlobalRef<jclass>, ModifierClassTraits> | |
52 g_java_lang_reflect_modifier_class = LAZY_INSTANCE_INITIALIZER; | |
53 | |
29 std::string BinaryNameToJNIName(const std::string& binary_name, | 54 std::string BinaryNameToJNIName(const std::string& binary_name, |
30 JavaType* type) { | 55 JavaType* type) { |
31 DCHECK(type); | 56 DCHECK(type); |
32 *type = JavaType::CreateFromBinaryName(binary_name); | 57 *type = JavaType::CreateFromBinaryName(binary_name); |
33 switch (type->type) { | 58 switch (type->type) { |
34 case JavaType::TypeBoolean: | 59 case JavaType::TypeBoolean: |
35 return "Z"; | 60 return "Z"; |
36 case JavaType::TypeByte: | 61 case JavaType::TypeByte: |
37 return "B"; | 62 return "B"; |
38 case JavaType::TypeChar: | 63 case JavaType::TypeChar: |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
170 kReturningJavaLangClass)))); | 195 kReturningJavaLangClass)))); |
171 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( | 196 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( |
172 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName( | 197 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName( |
173 env, | 198 env, |
174 kJavaLangClass, | 199 kJavaLangClass, |
175 kGetName, | 200 kGetName, |
176 kReturningJavaLangString)))); | 201 kReturningJavaLangString)))); |
177 signature += BinaryNameToJNIName(ConvertJavaStringToUTF8(env, name.obj()), | 202 signature += BinaryNameToJNIName(ConvertJavaStringToUTF8(env, name.obj()), |
178 &return_type_); | 203 &return_type_); |
179 | 204 |
205 // Determine whether the method is static. | |
206 jint modifiers = env->CallIntMethod( | |
207 java_method_.obj(), GetMethodIDFromClassName(env, | |
208 kJavaLangReflectMethod, | |
209 kGetModifiers, | |
210 kReturningInteger)); | |
211 bool is_static = env->CallStaticBooleanMethod( | |
212 g_java_lang_reflect_modifier_class.Pointer()->obj(), | |
joth
2011/12/05 15:53:23
nit: g_java_lang_reflect_modifier_class.Get().obj(
| |
213 GetMethodIDFromClassName(env, | |
214 kJavaLangReflectModifier, | |
215 kIsStatic, | |
216 kIntegerReturningBoolean), | |
217 modifiers); | |
218 | |
180 // Get the ID for this method. | 219 // Get the ID for this method. |
181 ScopedJavaLocalRef<jclass> declaring_class(env, static_cast<jclass>( | 220 ScopedJavaLocalRef<jclass> declaring_class(env, static_cast<jclass>( |
182 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName( | 221 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName( |
183 env, | 222 env, |
184 kJavaLangReflectMethod, | 223 kJavaLangReflectMethod, |
185 kGetDeclaringClass, | 224 kGetDeclaringClass, |
186 kReturningJavaLangClass)))); | 225 kReturningJavaLangClass)))); |
187 id_ = base::android::GetMethodID(env, declaring_class.obj(), name_.c_str(), | 226 id_ = is_static ? |
188 signature.c_str()); | 227 GetStaticMethodID(env, declaring_class.obj(), name_.c_str(), |
228 signature.c_str()) : | |
229 GetMethodID(env, declaring_class.obj(), name_.c_str(), | |
230 signature.c_str()); | |
189 | 231 |
190 java_method_.Reset(); | 232 java_method_.Reset(); |
191 } | 233 } |
OLD | NEW |