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 return new (instance) ScopedJavaGlobalRef<jclass>( |
| 44 ScopedJavaLocalRef<jclass>( |
| 45 env, |
| 46 static_cast<jclass>(env->FindClass(kJavaLangReflectModifier)))); |
| 47 } |
| 48 }; |
| 49 |
| 50 base::LazyInstance<ScopedJavaGlobalRef<jclass>, ModifierClassTraits> |
| 51 g_java_lang_reflect_modifier_class = LAZY_INSTANCE_INITIALIZER; |
| 52 |
29 std::string BinaryNameToJNIName(const std::string& binary_name, | 53 std::string BinaryNameToJNIName(const std::string& binary_name, |
30 JavaType* type) { | 54 JavaType* type) { |
31 DCHECK(type); | 55 DCHECK(type); |
32 *type = JavaType::CreateFromBinaryName(binary_name); | 56 *type = JavaType::CreateFromBinaryName(binary_name); |
33 switch (type->type) { | 57 switch (type->type) { |
34 case JavaType::TypeBoolean: | 58 case JavaType::TypeBoolean: |
35 return "Z"; | 59 return "Z"; |
36 case JavaType::TypeByte: | 60 case JavaType::TypeByte: |
37 return "B"; | 61 return "B"; |
38 case JavaType::TypeChar: | 62 case JavaType::TypeChar: |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 kReturningJavaLangClass)))); | 194 kReturningJavaLangClass)))); |
171 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( | 195 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( |
172 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName( | 196 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName( |
173 env, | 197 env, |
174 kJavaLangClass, | 198 kJavaLangClass, |
175 kGetName, | 199 kGetName, |
176 kReturningJavaLangString)))); | 200 kReturningJavaLangString)))); |
177 signature += BinaryNameToJNIName(ConvertJavaStringToUTF8(env, name.obj()), | 201 signature += BinaryNameToJNIName(ConvertJavaStringToUTF8(env, name.obj()), |
178 &return_type_); | 202 &return_type_); |
179 | 203 |
| 204 // Determine whether the method is static. |
| 205 jint modifiers = env->CallIntMethod( |
| 206 java_method_.obj(), GetMethodIDFromClassName(env, |
| 207 kJavaLangReflectMethod, |
| 208 kGetModifiers, |
| 209 kReturningInteger)); |
| 210 bool is_static = env->CallStaticBooleanMethod( |
| 211 g_java_lang_reflect_modifier_class.Get().obj(), |
| 212 GetMethodIDFromClassName(env, |
| 213 kJavaLangReflectModifier, |
| 214 kIsStatic, |
| 215 kIntegerReturningBoolean), |
| 216 modifiers); |
| 217 |
180 // Get the ID for this method. | 218 // Get the ID for this method. |
181 ScopedJavaLocalRef<jclass> declaring_class(env, static_cast<jclass>( | 219 ScopedJavaLocalRef<jclass> declaring_class(env, static_cast<jclass>( |
182 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName( | 220 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName( |
183 env, | 221 env, |
184 kJavaLangReflectMethod, | 222 kJavaLangReflectMethod, |
185 kGetDeclaringClass, | 223 kGetDeclaringClass, |
186 kReturningJavaLangClass)))); | 224 kReturningJavaLangClass)))); |
187 id_ = base::android::GetMethodID(env, declaring_class.obj(), name_.c_str(), | 225 id_ = is_static ? |
188 signature.c_str()); | 226 GetStaticMethodID(env, declaring_class.obj(), name_.c_str(), |
| 227 signature.c_str()) : |
| 228 GetMethodID(env, declaring_class.obj(), name_.c_str(), |
| 229 signature.c_str()); |
189 | 230 |
190 java_method_.Reset(); | 231 java_method_.Reset(); |
191 } | 232 } |
OLD | NEW |