Chromium Code Reviews| 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/memory/singleton.h" | 9 #include "base/memory/singleton.h" |
| 10 #include "base/string_util.h" // For ReplaceSubstringsAfterOffset | 10 #include "base/string_util.h" // For ReplaceSubstringsAfterOffset |
| 11 | 11 |
| 12 using base::android::AttachCurrentThread; | 12 using base::android::AttachCurrentThread; |
| 13 using base::android::ConvertJavaStringToUTF8; | 13 using base::android::ConvertJavaStringToUTF8; |
| 14 using base::android::GetMethodID; | |
| 15 using base::android::GetStaticMethodID; | |
| 14 using base::android::MethodID; | 16 using base::android::MethodID; |
| 15 using base::android::ScopedJavaLocalRef; | 17 using base::android::ScopedJavaLocalRef; |
| 16 | 18 |
| 17 namespace { | 19 namespace { |
| 18 | 20 |
| 19 // Java's reflection API represents types as a string using an extended 'binary | 21 // Java's reflection API represents types as a string using an extended 'binary |
| 20 // name'. This converts to an enum which we store in place of the binary name | 22 // name'. This converts to an enum which we store in place of the binary name |
| 21 // for simplicity. | 23 // for simplicity. |
| 22 JavaType::Type BinaryNameToType(const std::string& binary_name) { | 24 JavaType::Type BinaryNameToType(const std::string& binary_name) { |
| 23 if (binary_name == "boolean") { | 25 if (binary_name == "boolean") { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 case JavaType::TypeArray: | 74 case JavaType::TypeArray: |
| 73 return "["; | 75 return "["; |
| 74 default: | 76 default: |
| 75 DCHECK (*type == JavaType::TypeString || *type == JavaType::TypeObject); | 77 DCHECK (*type == JavaType::TypeString || *type == JavaType::TypeObject); |
| 76 std::string jni_name = "L" + binary_name + ";"; | 78 std::string jni_name = "L" + binary_name + ";"; |
| 77 ReplaceSubstringsAfterOffset(&jni_name, 0, ".", "/"); | 79 ReplaceSubstringsAfterOffset(&jni_name, 0, ".", "/"); |
| 78 return jni_name; | 80 return jni_name; |
| 79 } | 81 } |
| 80 } | 82 } |
| 81 | 83 |
| 82 class MethodGetParameterTypesID : public MethodID { | 84 class MethodGetParameterTypesID : public MethodID { |
|
joth
2011/11/29 11:24:36
aside: I never noticed MethodID get added in the l
Steve Block
2011/11/29 16:54:00
Personally I prefer a simple static too, but I thi
| |
| 83 public: | 85 public: |
| 84 static MethodGetParameterTypesID* GetInstance() { | 86 static MethodGetParameterTypesID* GetInstance() { |
| 85 return Singleton<MethodGetParameterTypesID>::get(); | 87 return Singleton<MethodGetParameterTypesID>::get(); |
| 86 } | 88 } |
| 87 private: | 89 private: |
| 88 friend struct DefaultSingletonTraits<MethodGetParameterTypesID>; | 90 friend struct DefaultSingletonTraits<MethodGetParameterTypesID>; |
| 89 MethodGetParameterTypesID() | 91 MethodGetParameterTypesID() |
| 90 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method", | 92 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method", |
| 91 "getParameterTypes", "()[Ljava/lang/Class;") { | 93 "getParameterTypes", "()[Ljava/lang/Class;") { |
| 92 } | 94 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 128 } | 130 } |
| 129 private: | 131 private: |
| 130 friend struct DefaultSingletonTraits<MethodGetDeclaringClassID>; | 132 friend struct DefaultSingletonTraits<MethodGetDeclaringClassID>; |
| 131 MethodGetDeclaringClassID() | 133 MethodGetDeclaringClassID() |
| 132 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method", | 134 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method", |
| 133 "getDeclaringClass", "()Ljava/lang/Class;") { | 135 "getDeclaringClass", "()Ljava/lang/Class;") { |
| 134 } | 136 } |
| 135 DISALLOW_COPY_AND_ASSIGN(MethodGetDeclaringClassID); | 137 DISALLOW_COPY_AND_ASSIGN(MethodGetDeclaringClassID); |
| 136 }; | 138 }; |
| 137 | 139 |
| 140 class MethodGetModifiersID : public MethodID { | |
|
joth
2011/11/29 11:24:36
nit: I'd find all these easier to read if named li
Steve Block
2011/11/29 16:54:00
All of these are named <class><method>ID. I don't
| |
| 141 public: | |
| 142 static MethodGetModifiersID* GetInstance() { | |
| 143 return Singleton<MethodGetModifiersID>::get(); | |
| 144 } | |
| 145 private: | |
|
joth
2011/11/29 11:24:36
nit: we normally have a blank line before private:
Steve Block
2011/11/29 16:54:00
Done.
| |
| 146 friend struct DefaultSingletonTraits<MethodGetModifiersID>; | |
| 147 MethodGetModifiersID() | |
| 148 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method", | |
| 149 "getModifiers", "()I") { | |
| 150 } | |
| 151 DISALLOW_COPY_AND_ASSIGN(MethodGetModifiersID); | |
| 152 }; | |
| 153 | |
| 138 class ClassGetNameID : public MethodID { | 154 class ClassGetNameID : public MethodID { |
|
joth
2011/11/29 11:24:36
add 'Method' in the name for consistency with the
Steve Block
2011/11/29 16:54:00
See above
| |
| 139 public: | 155 public: |
| 140 static ClassGetNameID* GetInstance() { | 156 static ClassGetNameID* GetInstance() { |
| 141 return Singleton<ClassGetNameID>::get(); | 157 return Singleton<ClassGetNameID>::get(); |
| 142 } | 158 } |
| 143 private: | 159 private: |
| 144 friend struct DefaultSingletonTraits<ClassGetNameID>; | 160 friend struct DefaultSingletonTraits<ClassGetNameID>; |
| 145 ClassGetNameID() | 161 ClassGetNameID() |
| 146 : MethodID(AttachCurrentThread(), "java/lang/Class", "getName", | 162 : MethodID(AttachCurrentThread(), "java/lang/Class", "getName", |
| 147 "()Ljava/lang/String;") { | 163 "()Ljava/lang/String;") { |
| 148 } | 164 } |
| 149 DISALLOW_COPY_AND_ASSIGN(ClassGetNameID); | 165 DISALLOW_COPY_AND_ASSIGN(ClassGetNameID); |
| 150 }; | 166 }; |
| 151 | 167 |
| 168 class ModifierIsStaticID { | |
| 169 public: | |
| 170 static ModifierIsStaticID* GetInstance() { | |
| 171 return Singleton<ModifierIsStaticID>::get(); | |
| 172 } | |
| 173 jclass clazz() { return clazz_.obj(); } | |
| 174 jmethodID id() { return id_; } | |
| 175 private: | |
| 176 friend struct DefaultSingletonTraits<ModifierIsStaticID>; | |
| 177 ModifierIsStaticID() { | |
| 178 JNIEnv* env = AttachCurrentThread(); | |
| 179 clazz_.Reset(env, env->FindClass("java/lang/reflect/Modifier")); | |
| 180 id_ = GetStaticMethodID(env, clazz_.obj(), "isStatic", "(I)Z"); | |
| 181 } | |
| 182 base::android::ScopedJavaGlobalRef<jclass> clazz_; | |
| 183 jmethodID id_; | |
| 184 DISALLOW_COPY_AND_ASSIGN(ModifierIsStaticID); | |
| 185 }; | |
| 186 | |
| 152 } // namespace | 187 } // namespace |
| 153 | 188 |
| 154 JavaMethod::JavaMethod(const base::android::JavaRef<jobject>& method) | 189 JavaMethod::JavaMethod(const base::android::JavaRef<jobject>& method) |
| 155 : java_method_(method), | 190 : java_method_(method), |
| 156 have_calculated_num_parameters_(false), | 191 have_calculated_num_parameters_(false), |
| 157 id_(NULL) { | 192 id_(NULL) { |
| 158 JNIEnv* env = java_method_.env(); | 193 JNIEnv* env = java_method_.env(); |
| 159 // On construction, we do nothing except get the name. Everything else is | 194 // On construction, we do nothing except get the name. Everything else is |
| 160 // done lazily. | 195 // done lazily. |
| 161 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( | 196 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 240 | 275 |
| 241 // Get the return type | 276 // Get the return type |
| 242 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>( | 277 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>( |
| 243 env->CallObjectMethod(java_method_.obj(), | 278 env->CallObjectMethod(java_method_.obj(), |
| 244 MethodGetReturnTypeID::GetInstance()->id()))); | 279 MethodGetReturnTypeID::GetInstance()->id()))); |
| 245 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( | 280 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( |
| 246 env->CallObjectMethod(clazz.obj(), ClassGetNameID::GetInstance()->id()))); | 281 env->CallObjectMethod(clazz.obj(), ClassGetNameID::GetInstance()->id()))); |
| 247 signature += BinaryNameToJNIName(ConvertJavaStringToUTF8(env, name.obj()), | 282 signature += BinaryNameToJNIName(ConvertJavaStringToUTF8(env, name.obj()), |
| 248 &return_type_); | 283 &return_type_); |
| 249 | 284 |
| 285 // Determine whether the method is static. | |
| 286 jint modifiers = env->CallIntMethod( | |
| 287 java_method_.obj(), | |
| 288 MethodGetModifiersID::GetInstance()->id()); | |
| 289 bool is_static = env->CallStaticBooleanMethod( | |
| 290 ModifierIsStaticID::GetInstance()->clazz(), | |
| 291 ModifierIsStaticID::GetInstance()->id(), | |
| 292 modifiers); | |
| 293 | |
| 250 // Get the ID for this method. | 294 // Get the ID for this method. |
| 251 ScopedJavaLocalRef<jclass> declaring_class(env, static_cast<jclass>( | 295 ScopedJavaLocalRef<jclass> declaring_class(env, static_cast<jclass>( |
| 252 env->CallObjectMethod(java_method_.obj(), | 296 env->CallObjectMethod(java_method_.obj(), |
| 253 MethodGetDeclaringClassID::GetInstance()->id()))); | 297 MethodGetDeclaringClassID::GetInstance()->id()))); |
| 254 id_ = base::android::GetMethodID(env, declaring_class.obj(), name_.c_str(), | 298 id_ = is_static ? |
| 255 signature.c_str()); | 299 GetStaticMethodID(env, declaring_class.obj(), name_.c_str(), |
| 300 signature.c_str()) : | |
| 301 GetMethodID(env, declaring_class.obj(), name_.c_str(), | |
| 302 signature.c_str()); | |
| 256 | 303 |
| 257 java_method_.Reset(); | 304 java_method_.Reset(); |
| 258 } | 305 } |
| OLD | NEW |