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

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

Issue 8769005: Don't use Singleton to cache JNI method IDs in Java Bridge (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rename test file, fix comments Created 9 years 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
« no previous file with comments | « content/browser/renderer_host/java/java_bound_object.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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::MethodID; 14 using base::android::GetMethodIDFromClassName;
15 using base::android::ScopedJavaLocalRef; 15 using base::android::ScopedJavaLocalRef;
16 16
17 namespace { 17 namespace {
18 18
19 const char kGetName[] = "getName";
20 const char kGetDeclaringClass[] = "getDeclaringClass";
21 const char kGetParameterTypes[] = "getParameterTypes";
22 const char kGetReturnType[] = "getReturnType";
23 const char kJavaLangClass[] = "java/lang/Class";
24 const char kJavaLangReflectMethod[] = "java/lang/reflect/Method";
25 const char kReturningJavaLangClass[] = "()Ljava/lang/Class;";
26 const char kReturningJavaLangClassArray[] = "()[Ljava/lang/Class;";
27 const char kReturningJavaLangString[] = "()Ljava/lang/String;";
28
19 std::string BinaryNameToJNIName(const std::string& binary_name, 29 std::string BinaryNameToJNIName(const std::string& binary_name,
20 JavaType* type) { 30 JavaType* type) {
21 DCHECK(type); 31 DCHECK(type);
22 *type = JavaType::CreateFromBinaryName(binary_name); 32 *type = JavaType::CreateFromBinaryName(binary_name);
23 switch (type->type) { 33 switch (type->type) {
24 case JavaType::TypeBoolean: 34 case JavaType::TypeBoolean:
25 return "Z"; 35 return "Z";
26 case JavaType::TypeByte: 36 case JavaType::TypeByte:
27 return "B"; 37 return "B";
28 case JavaType::TypeChar: 38 case JavaType::TypeChar:
(...skipping 14 matching lines...) Expand all
43 return "["; 53 return "[";
44 default: 54 default:
45 DCHECK(type->type == JavaType::TypeString || 55 DCHECK(type->type == JavaType::TypeString ||
46 type->type == JavaType::TypeObject); 56 type->type == JavaType::TypeObject);
47 std::string jni_name = "L" + binary_name + ";"; 57 std::string jni_name = "L" + binary_name + ";";
48 ReplaceSubstringsAfterOffset(&jni_name, 0, ".", "/"); 58 ReplaceSubstringsAfterOffset(&jni_name, 0, ".", "/");
49 return jni_name; 59 return jni_name;
50 } 60 }
51 } 61 }
52 62
53 class MethodGetParameterTypesID : public MethodID {
54 public:
55 static MethodGetParameterTypesID* GetInstance() {
56 return Singleton<MethodGetParameterTypesID>::get();
57 }
58 private:
59 friend struct DefaultSingletonTraits<MethodGetParameterTypesID>;
60 MethodGetParameterTypesID()
61 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method",
62 "getParameterTypes", "()[Ljava/lang/Class;") {
63 }
64 DISALLOW_COPY_AND_ASSIGN(MethodGetParameterTypesID);
65 };
66
67 class MethodGetNameID : public MethodID {
68 public:
69 static MethodGetNameID* GetInstance() {
70 return Singleton<MethodGetNameID>::get();
71 }
72 private:
73 friend struct DefaultSingletonTraits<MethodGetNameID>;
74 MethodGetNameID()
75 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method",
76 "getName", "()Ljava/lang/String;") {
77 }
78 DISALLOW_COPY_AND_ASSIGN(MethodGetNameID);
79 };
80
81 class MethodGetReturnTypeID : public MethodID {
82 public:
83 static MethodGetReturnTypeID* GetInstance() {
84 return Singleton<MethodGetReturnTypeID>::get();
85 }
86 private:
87 friend struct DefaultSingletonTraits<MethodGetReturnTypeID>;
88 MethodGetReturnTypeID()
89 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method",
90 "getReturnType", "()Ljava/lang/Class;") {
91 }
92 DISALLOW_COPY_AND_ASSIGN(MethodGetReturnTypeID);
93 };
94
95 class MethodGetDeclaringClassID : public MethodID {
96 public:
97 static MethodGetDeclaringClassID* GetInstance() {
98 return Singleton<MethodGetDeclaringClassID>::get();
99 }
100 private:
101 friend struct DefaultSingletonTraits<MethodGetDeclaringClassID>;
102 MethodGetDeclaringClassID()
103 : MethodID(AttachCurrentThread(), "java/lang/reflect/Method",
104 "getDeclaringClass", "()Ljava/lang/Class;") {
105 }
106 DISALLOW_COPY_AND_ASSIGN(MethodGetDeclaringClassID);
107 };
108
109 class ClassGetNameID : public MethodID {
110 public:
111 static ClassGetNameID* GetInstance() {
112 return Singleton<ClassGetNameID>::get();
113 }
114 private:
115 friend struct DefaultSingletonTraits<ClassGetNameID>;
116 ClassGetNameID()
117 : MethodID(AttachCurrentThread(), "java/lang/Class", "getName",
118 "()Ljava/lang/String;") {
119 }
120 DISALLOW_COPY_AND_ASSIGN(ClassGetNameID);
121 };
122
123 } // namespace 63 } // namespace
124 64
125 JavaMethod::JavaMethod(const base::android::JavaRef<jobject>& method) 65 JavaMethod::JavaMethod(const base::android::JavaRef<jobject>& method)
126 : java_method_(method), 66 : java_method_(method),
127 have_calculated_num_parameters_(false), 67 have_calculated_num_parameters_(false),
128 id_(NULL) { 68 id_(NULL) {
129 JNIEnv* env = java_method_.env(); 69 JNIEnv* env = java_method_.env();
130 // On construction, we do nothing except get the name. Everything else is 70 // On construction, we do nothing except get the name. Everything else is
131 // done lazily. 71 // done lazily.
132 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( 72 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>(
133 env->CallObjectMethod(java_method_.obj(), 73 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
134 MethodGetNameID::GetInstance()->id()))); 74 env,
75 kJavaLangReflectMethod,
76 kGetName,
77 kReturningJavaLangString))));
135 name_ = ConvertJavaStringToUTF8(env, name.obj()); 78 name_ = ConvertJavaStringToUTF8(env, name.obj());
136 } 79 }
137 80
138 JavaMethod::~JavaMethod() { 81 JavaMethod::~JavaMethod() {
139 } 82 }
140 83
141 size_t JavaMethod::num_parameters() const { 84 size_t JavaMethod::num_parameters() const {
142 EnsureNumParametersIsSetUp(); 85 EnsureNumParametersIsSetUp();
143 return num_parameters_; 86 return num_parameters_;
144 } 87 }
(...skipping 17 matching lines...) Expand all
162 if (have_calculated_num_parameters_) { 105 if (have_calculated_num_parameters_) {
163 return; 106 return;
164 } 107 }
165 have_calculated_num_parameters_ = true; 108 have_calculated_num_parameters_ = true;
166 109
167 // The number of parameters will be used frequently when determining 110 // The number of parameters will be used frequently when determining
168 // whether to call this method. We don't get the ID etc until actually 111 // whether to call this method. We don't get the ID etc until actually
169 // required. 112 // required.
170 JNIEnv* env = java_method_.env(); 113 JNIEnv* env = java_method_.env();
171 ScopedJavaLocalRef<jarray> parameters(env, static_cast<jarray>( 114 ScopedJavaLocalRef<jarray> parameters(env, static_cast<jarray>(
172 env->CallObjectMethod(java_method_.obj(), 115 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
173 MethodGetParameterTypesID::GetInstance()->id()))); 116 env,
117 kJavaLangReflectMethod,
118 kGetParameterTypes,
119 kReturningJavaLangClassArray))));
174 num_parameters_ = env->GetArrayLength(parameters.obj()); 120 num_parameters_ = env->GetArrayLength(parameters.obj());
175 } 121 }
176 122
177 void JavaMethod::EnsureTypesAndIDAreSetUp() const { 123 void JavaMethod::EnsureTypesAndIDAreSetUp() const {
178 if (id_) { 124 if (id_) {
179 return; 125 return;
180 } 126 }
181 127
182 // Get the parameters 128 // Get the parameters
183 JNIEnv* env = java_method_.env(); 129 JNIEnv* env = java_method_.env();
184 ScopedJavaLocalRef<jobjectArray> parameters(env, static_cast<jobjectArray>( 130 ScopedJavaLocalRef<jobjectArray> parameters(env, static_cast<jobjectArray>(
185 env->CallObjectMethod(java_method_.obj(), 131 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
186 MethodGetParameterTypesID::GetInstance()->id()))); 132 env,
133 kJavaLangReflectMethod,
134 kGetParameterTypes,
135 kReturningJavaLangClassArray))));
187 // Usually, this will already have been called. 136 // Usually, this will already have been called.
188 EnsureNumParametersIsSetUp(); 137 EnsureNumParametersIsSetUp();
189 DCHECK_EQ(num_parameters_, 138 DCHECK_EQ(num_parameters_,
190 static_cast<size_t>(env->GetArrayLength(parameters.obj()))); 139 static_cast<size_t>(env->GetArrayLength(parameters.obj())));
191 140
192 // Java gives us the argument type using an extended version of the 'binary 141 // Java gives us the argument type using an extended version of the 'binary
193 // name'. See 142 // name'. See
194 // http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Class.html#getNa me(). 143 // http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Class.html#getNa me().
195 // If we build the signature now, there's no need to store the binary name 144 // If we build the signature now, there's no need to store the binary name
196 // of the arguments. We just store the simple type. 145 // of the arguments. We just store the simple type.
197 std::string signature("("); 146 std::string signature("(");
198 147
199 // Form the signature and record the parameter types. 148 // Form the signature and record the parameter types.
200 parameter_types_.resize(num_parameters_); 149 parameter_types_.resize(num_parameters_);
201 for (size_t i = 0; i < num_parameters_; ++i) { 150 for (size_t i = 0; i < num_parameters_; ++i) {
202 ScopedJavaLocalRef<jobject> parameter(env, env->GetObjectArrayElement( 151 ScopedJavaLocalRef<jobject> parameter(env, env->GetObjectArrayElement(
203 parameters.obj(), i)); 152 parameters.obj(), i));
204 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( 153 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>(
205 env->CallObjectMethod(parameter.obj(), 154 env->CallObjectMethod(parameter.obj(), GetMethodIDFromClassName(
206 ClassGetNameID::GetInstance()->id()))); 155 env,
156 kJavaLangClass,
157 kGetName,
158 kReturningJavaLangString))));
207 std::string name_utf8 = ConvertJavaStringToUTF8(env, name.obj()); 159 std::string name_utf8 = ConvertJavaStringToUTF8(env, name.obj());
208 signature += BinaryNameToJNIName(name_utf8, &parameter_types_[i]); 160 signature += BinaryNameToJNIName(name_utf8, &parameter_types_[i]);
209 } 161 }
210 signature += ")"; 162 signature += ")";
211 163
212 // Get the return type 164 // Get the return type
213 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>( 165 ScopedJavaLocalRef<jclass> clazz(env, static_cast<jclass>(
214 env->CallObjectMethod(java_method_.obj(), 166 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
215 MethodGetReturnTypeID::GetInstance()->id()))); 167 env,
168 kJavaLangReflectMethod,
169 kGetReturnType,
170 kReturningJavaLangClass))));
216 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>( 171 ScopedJavaLocalRef<jstring> name(env, static_cast<jstring>(
217 env->CallObjectMethod(clazz.obj(), ClassGetNameID::GetInstance()->id()))); 172 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName(
173 env,
174 kJavaLangClass,
175 kGetName,
176 kReturningJavaLangString))));
218 signature += BinaryNameToJNIName(ConvertJavaStringToUTF8(env, name.obj()), 177 signature += BinaryNameToJNIName(ConvertJavaStringToUTF8(env, name.obj()),
219 &return_type_); 178 &return_type_);
220 179
221 // Get the ID for this method. 180 // Get the ID for this method.
222 ScopedJavaLocalRef<jclass> declaring_class(env, static_cast<jclass>( 181 ScopedJavaLocalRef<jclass> declaring_class(env, static_cast<jclass>(
223 env->CallObjectMethod(java_method_.obj(), 182 env->CallObjectMethod(java_method_.obj(), GetMethodIDFromClassName(
224 MethodGetDeclaringClassID::GetInstance()->id()))); 183 env,
184 kJavaLangReflectMethod,
185 kGetDeclaringClass,
186 kReturningJavaLangClass))));
225 id_ = base::android::GetMethodID(env, declaring_class.obj(), name_.c_str(), 187 id_ = base::android::GetMethodID(env, declaring_class.obj(), name_.c_str(),
226 signature.c_str()); 188 signature.c_str());
227 189
228 java_method_.Reset(); 190 java_method_.Reset();
229 } 191 }
OLDNEW
« no previous file with comments | « content/browser/renderer_host/java/java_bound_object.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698