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

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

Powered by Google App Engine
This is Rietveld 408576698