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

Side by Side Diff: content/browser/renderer_host/java/gin_java_bound_object.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 2014 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/gin_java_bound_object.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/android/scoped_java_ref.h"
10 #include "base/strings/utf_string_conversions.h"
11 #include "content/browser/renderer_host/java/jni_helper.h"
12
13 using base::android::AttachCurrentThread;
14 using base::android::ScopedJavaLocalRef;
15
16 namespace content {
17
18 namespace {
19
20 const char kJavaLangClass[] = "java/lang/Class";
21 const char kJavaLangObject[] = "java/lang/Object";
22 const char kJavaLangReflectMethod[] = "java/lang/reflect/Method";
23 const char kGetClass[] = "getClass";
24 const char kGetMethods[] = "getMethods";
25 const char kIsAnnotationPresent[] = "isAnnotationPresent";
26 const char kReturningJavaLangClass[] = "()Ljava/lang/Class;";
27 const char kReturningJavaLangReflectMethodArray[] =
28 "()[Ljava/lang/reflect/Method;";
29 const char kTakesJavaLangClassReturningBoolean[] = "(Ljava/lang/Class;)Z";
30
31 } // namespace
32
33
34 // static
35 GinJavaBoundObject* GinJavaBoundObject::CreateNamed(
36 const JavaObjectWeakGlobalRef& ref,
37 const base::android::JavaRef<jclass>& safe_annotation_clazz) {
38 return new GinJavaBoundObject(ref, safe_annotation_clazz);
39 }
40
41 // static
42 GinJavaBoundObject* GinJavaBoundObject::CreateTransient(
43 const JavaObjectWeakGlobalRef& ref,
44 const base::android::JavaRef<jclass>& safe_annotation_clazz,
45 RenderFrameHost* holder) {
46 std::set<RenderFrameHost*> holders;
47 holders.insert(holder);
48 return new GinJavaBoundObject(ref, safe_annotation_clazz, holders);
49 }
50
51 GinJavaBoundObject::GinJavaBoundObject(
52 const JavaObjectWeakGlobalRef& ref,
53 const base::android::JavaRef<jclass>& safe_annotation_clazz)
54 : ref_(ref),
55 names_count_(1),
56 object_get_class_method_id_(NULL),
57 are_methods_set_up_(false),
58 safe_annotation_clazz_(safe_annotation_clazz) {
59 }
60
61 GinJavaBoundObject::GinJavaBoundObject(
62 const JavaObjectWeakGlobalRef& ref,
63 const base::android::JavaRef<jclass>& safe_annotation_clazz,
64 const std::set<RenderFrameHost*> holders)
65 : ref_(ref),
66 names_count_(0),
67 holders_(holders),
68 object_get_class_method_id_(NULL),
69 are_methods_set_up_(false),
70 safe_annotation_clazz_(safe_annotation_clazz) {
71 }
72
73 GinJavaBoundObject::~GinJavaBoundObject() {
74 }
75
76 std::set<std::string> GinJavaBoundObject::GetMethodNames() {
77 EnsureMethodsAreSetUp();
78 std::set<std::string> result;
79 for (JavaMethodMap::const_iterator it = methods_.begin();
80 it != methods_.end();
81 ++it) {
82 result.insert(it->first);
83 }
84 return result;
85 }
86
87 bool GinJavaBoundObject::HasMethod(const std::string& method_name) {
88 EnsureMethodsAreSetUp();
89 return methods_.find(method_name) != methods_.end();
90 }
91
92 const JavaMethod* GinJavaBoundObject::FindMethod(
93 const std::string& method_name,
94 size_t num_parameters) {
95 EnsureMethodsAreSetUp();
96
97 // Get all methods with the correct name.
98 std::pair<JavaMethodMap::const_iterator, JavaMethodMap::const_iterator>
99 iters = methods_.equal_range(method_name);
100 if (iters.first == iters.second) {
101 return NULL;
102 }
103
104 // LIVECONNECT_COMPLIANCE: We just take the first method with the correct
105 // number of arguments, while the spec proposes using cost-based algorithm:
106 // https://jdk6.java.net/plugin2/liveconnect/#OVERLOADED_METHODS
107 for (JavaMethodMap::const_iterator iter = iters.first; iter != iters.second;
108 ++iter) {
109 if (iter->second->num_parameters() == num_parameters) {
110 return iter->second.get();
111 }
112 }
113
114 return NULL;
115 }
116
117 bool GinJavaBoundObject::IsObjectGetClassMethod(const JavaMethod* method) {
118 EnsureMethodsAreSetUp();
119 // As java.lang.Object.getClass is declared to be final, it is sufficient to
120 // compare methodIDs.
121 return method->id() == object_get_class_method_id_;
122 }
123
124 const base::android::JavaRef<jclass>&
125 GinJavaBoundObject::GetSafeAnnotationClass() {
126 return safe_annotation_clazz_;
127 }
128
129 base::android::ScopedJavaLocalRef<jclass> GinJavaBoundObject::GetLocalClassRef(
130 JNIEnv* env) {
131 if (!object_get_class_method_id_) {
132 object_get_class_method_id_ = GetMethodIDFromClassName(
133 env, kJavaLangObject, kGetClass, kReturningJavaLangClass);
134 }
135 ScopedJavaLocalRef<jobject> obj = GetLocalRef(env);
136 if (obj.obj()) {
137 return base::android::ScopedJavaLocalRef<jclass>(
138 env,
139 static_cast<jclass>(
140 env->CallObjectMethod(obj.obj(), object_get_class_method_id_)));
141 } else {
142 return base::android::ScopedJavaLocalRef<jclass>();
143 }
144 }
145
146 void GinJavaBoundObject::EnsureMethodsAreSetUp() {
147 if (are_methods_set_up_)
148 return;
149 are_methods_set_up_ = true;
150
151 JNIEnv* env = AttachCurrentThread();
152
153 ScopedJavaLocalRef<jclass> clazz = GetLocalClassRef(env);
154 if (clazz.is_null()) {
155 return;
156 }
157
158 ScopedJavaLocalRef<jobjectArray> methods(env, static_cast<jobjectArray>(
159 env->CallObjectMethod(clazz.obj(), GetMethodIDFromClassName(
160 env,
161 kJavaLangClass,
162 kGetMethods,
163 kReturningJavaLangReflectMethodArray))));
164
165 size_t num_methods = env->GetArrayLength(methods.obj());
166 // Java objects always have public methods.
167 DCHECK(num_methods);
168
169 for (size_t i = 0; i < num_methods; ++i) {
170 ScopedJavaLocalRef<jobject> java_method(
171 env,
172 env->GetObjectArrayElement(methods.obj(), i));
173
174 if (!safe_annotation_clazz_.is_null()) {
175 jboolean safe = env->CallBooleanMethod(java_method.obj(),
176 GetMethodIDFromClassName(
177 env,
178 kJavaLangReflectMethod,
179 kIsAnnotationPresent,
180 kTakesJavaLangClassReturningBoolean),
181 safe_annotation_clazz_.obj());
182
183 if (!safe)
184 continue;
185 }
186
187 JavaMethod* method = new JavaMethod(java_method);
188 methods_.insert(std::make_pair(method->name(), method));
189 }
190 }
191
192 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698