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

Side by Side Diff: content/browser/renderer_host/java/java_method.cc

Issue 336313018: [Android] Move content/browser/{renderer_host => android}/java/* (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updated paths for unit tests, rebased Created 6 years, 5 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 (c) 2012 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 "content/browser/renderer_host/java/java_method.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/lazy_instance.h"
10 #include "base/memory/singleton.h"
11 #include "base/strings/string_util.h" // For ReplaceSubstringsAfterOffset
12 #include "content/browser/renderer_host/java/jni_helper.h"
13
14 using base::android::AttachCurrentThread;
15 using base::android::ConvertJavaStringToUTF8;
16 using base::android::GetClass;
17 using base::android::MethodID;
18 using base::android::ScopedJavaGlobalRef;
19 using base::android::ScopedJavaLocalRef;
20
21 namespace content {
22 namespace {
23
24 const char kGetName[] = "getName";
25 const char kGetDeclaringClass[] = "getDeclaringClass";
26 const char kGetModifiers[] = "getModifiers";
27 const char kGetParameterTypes[] = "getParameterTypes";
28 const char kGetReturnType[] = "getReturnType";
29 const char kIntegerReturningBoolean[] = "(I)Z";
30 const char kIsStatic[] = "isStatic";
31 const char kJavaLangClass[] = "java/lang/Class";
32 const char kJavaLangReflectMethod[] = "java/lang/reflect/Method";
33 const char kJavaLangReflectModifier[] = "java/lang/reflect/Modifier";
34 const char kReturningInteger[] = "()I";
35 const char kReturningJavaLangClass[] = "()Ljava/lang/Class;";
36 const char kReturningJavaLangClassArray[] = "()[Ljava/lang/Class;";
37 const char kReturningJavaLangString[] = "()Ljava/lang/String;";
38
39 struct ModifierClassTraits :
40 public base::internal::LeakyLazyInstanceTraits<ScopedJavaGlobalRef<
41 jclass> > {
42 static ScopedJavaGlobalRef<jclass>* New(void* instance) {
43 JNIEnv* env = AttachCurrentThread();
44 // Use placement new to initialize our instance in our preallocated space.
45 return new (instance) ScopedJavaGlobalRef<jclass>(
46 GetClass(env, kJavaLangReflectModifier));
47 }
48 };
49
50 base::LazyInstance<ScopedJavaGlobalRef<jclass>, ModifierClassTraits>
51 g_java_lang_reflect_modifier_class = LAZY_INSTANCE_INITIALIZER;
52
53 std::string BinaryNameToJNIName(const std::string& binary_name,
54 JavaType* type) {
55 DCHECK(type);
56 *type = JavaType::CreateFromBinaryName(binary_name);
57 switch (type->type) {
58 case JavaType::TypeBoolean:
59 return "Z";
60 case JavaType::TypeByte:
61 return "B";
62 case JavaType::TypeChar:
63 return "C";
64 case JavaType::TypeShort:
65 return "S";
66 case JavaType::TypeInt:
67 return "I";
68 case JavaType::TypeLong:
69 return "J";
70 case JavaType::TypeFloat:
71 return "F";
72 case JavaType::TypeDouble:
73 return "D";
74 case JavaType::TypeVoid:
75 return "V";
76 case JavaType::TypeArray: {
77 // For array types, the binary name uses the JNI name encodings.
78 std::string jni_name = binary_name;
79 ReplaceSubstringsAfterOffset(&jni_name, 0, ".", "/");
80 return jni_name;
81 }
82 case JavaType::TypeString:
83 case JavaType::TypeObject:
84 std::string jni_name = "L" + binary_name + ";";
85 ReplaceSubstringsAfterOffset(&jni_name, 0, ".", "/");
86 return jni_name;
87 }
88 NOTREACHED();
89 return std::string();
90 }
91
92 } // namespace
93
94 JavaMethod::JavaMethod(const base::android::JavaRef<jobject>& method)
95 : java_method_(method),
96 have_calculated_num_parameters_(false),
97 id_(NULL) {
98 JNIEnv* env = AttachCurrentThread();
99 // On construction, we do nothing except get the name. Everything else is
100 // done lazily.
101 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>(
102 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
103 env,
104 kJavaLangReflectMethod,
105 kGetName,
106 kReturningJavaLangString))));
107 name_ = ConvertJavaStringToUTF8(name);
108 }
109
110 JavaMethod::~JavaMethod() {
111 }
112
113 size_t JavaMethod::num_parameters() const {
114 EnsureNumParametersIsSetUp();
115 return num_parameters_;
116 }
117
118 bool JavaMethod::is_static() const {
119 EnsureTypesAndIDAreSetUp();
120 return is_static_;
121 }
122
123 const JavaType& JavaMethod::parameter_type(size_t index) const {
124 EnsureTypesAndIDAreSetUp();
125 return parameter_types_[index];
126 }
127
128 const JavaType& JavaMethod::return_type() const {
129 EnsureTypesAndIDAreSetUp();
130 return return_type_;
131 }
132
133 jmethodID JavaMethod::id() const {
134 EnsureTypesAndIDAreSetUp();
135 return id_;
136 }
137
138 void JavaMethod::EnsureNumParametersIsSetUp() const {
139 if (have_calculated_num_parameters_) {
140 return;
141 }
142 have_calculated_num_parameters_ = true;
143
144 // The number of parameters will be used frequently when determining
145 // whether to call this method. We don't get the ID etc until actually
146 // required.
147 JNIEnv* env = AttachCurrentThread();
148 ScopedJavaLocalRef<jarray> parameters(env, static_cast<jarray>(
149 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
150 env,
151 kJavaLangReflectMethod,
152 kGetParameterTypes,
153 kReturningJavaLangClassArray))));
154 num_parameters_ = env->GetArrayLength(parameters.obj());
155 }
156
157 void JavaMethod::EnsureTypesAndIDAreSetUp() const {
158 if (id_) {
159 return;
160 }
161
162 // Get the parameters
163 JNIEnv* env = AttachCurrentThread();
164 ScopedJavaLocalRef<jobjectArray> parameters(env, static_cast<jobjectArray>(
165 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
166 env,
167 kJavaLangReflectMethod,
168 kGetParameterTypes,
169 kReturningJavaLangClassArray))));
170 // Usually, this will already have been called.
171 EnsureNumParametersIsSetUp();
172 DCHECK_EQ(num_parameters_,
173 static_cast<size_t>(env->GetArrayLength(parameters.obj())));
174
175 // Java gives us the argument type using an extended version of the 'binary
176 // name'. See
177 // http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Class.html#getNa me().
178 // If we build the signature now, there's no need to store the binary name
179 // of the arguments. We just store the simple type.
180 std::string signature("(");
181
182 // Form the signature and record the parameter types.
183 parameter_types_.resize(num_parameters_);
184 for (size_t i = 0; i < num_parameters_; ++i) {
185 ScopedJavaLocalRef<jobject> parameter(env, env->GetObjectArrayElement(
186 parameters.obj(), i));
187 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>(
188 env->CallObjectMethod(parameter.obj(), GetMethodIDFromClassName(
189 env,
190 kJavaLangClass,
191 kGetName,
192 kReturningJavaLangString))));
193 std::string name_utf8 = ConvertJavaStringToUTF8(name);
194 signature += BinaryNameToJNIName(name_utf8, &parameter_types_[i]);
195 }
196 signature += ")";
197
198 // Get the return type
199 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>(
200 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
201 env,
202 kJavaLangReflectMethod,
203 kGetReturnType,
204 kReturningJavaLangClass))));
205 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>(
206 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName(
207 env,
208 kJavaLangClass,
209 kGetName,
210 kReturningJavaLangString))));
211 signature += BinaryNameToJNIName(ConvertJavaStringToUTF8(name),
212 &return_type_);
213
214 // Determine whether the method is static.
215 jint modifiers = env->CallIntMethod(
216 java_method_.obj(), GetMethodIDFromClassName(env,
217 kJavaLangReflectMethod,
218 kGetModifiers,
219 kReturningInteger));
220 is_static_ = env->CallStaticBooleanMethod(
221 g_java_lang_reflect_modifier_class.Get().obj(),
222 MethodID::Get<MethodID::TYPE_STATIC>(
223 env, g_java_lang_reflect_modifier_class.Get().obj(), kIsStatic,
224 kIntegerReturningBoolean),
225 modifiers);
226
227 // Get the ID for this method.
228 ScopedJavaLocalRef<jclass> declaring_class(env, static_cast<jclass>(
229 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
230 env,
231 kJavaLangReflectMethod,
232 kGetDeclaringClass,
233 kReturningJavaLangClass))));
234 id_ = is_static_ ?
235 MethodID::Get<MethodID::TYPE_STATIC>(
236 env, declaring_class.obj(), name_.c_str(), signature.c_str()) :
237 MethodID::Get<MethodID::TYPE_INSTANCE>(
238 env, declaring_class.obj(), name_.c_str(), signature.c_str());
239 java_method_.Reset();
240 }
241
242 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/java/java_method.h ('k') | content/browser/renderer_host/java/java_type.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698