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

Side by Side Diff: base/android/jni_android.cc

Issue 9358028: Upstream Android JNI code, allowing us to use more ScopedJava references. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 10 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 "base/android/jni_android.h" 5 #include "base/android/jni_android.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/atomicops.h" 9 #include "base/atomicops.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/threading/platform_thread.h" 12 #include "base/threading/platform_thread.h"
13 13
14 namespace { 14 namespace {
15 JavaVM* g_jvm = 0; 15
16 jobject g_application_context = NULL; 16 JavaVM* g_jvm = NULL;
17
18 base::LazyInstance<base::android::ScopedJavaGlobalRef<jobject> >
19 g_application_context = LAZY_INSTANCE_INITIALIZER;
17 20
18 struct MethodIdentifier { 21 struct MethodIdentifier {
19 const char* class_name; 22 const char* class_name;
20 const char* method; 23 const char* method;
21 const char* jni_signature; 24 const char* jni_signature;
22 25
23 bool operator<(const MethodIdentifier& other) const { 26 bool operator<(const MethodIdentifier& other) const {
24 int r = strcmp(class_name, other.class_name); 27 int r = strcmp(class_name, other.class_name);
25 if (r < 0) { 28 if (r < 0) {
26 return true; 29 return true;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 if (g_jvm) 69 if (g_jvm)
67 g_jvm->DetachCurrentThread(); 70 g_jvm->DetachCurrentThread();
68 } 71 }
69 72
70 void InitVM(JavaVM* vm) { 73 void InitVM(JavaVM* vm) {
71 DCHECK(!g_jvm); 74 DCHECK(!g_jvm);
72 g_jvm = vm; 75 g_jvm = vm;
73 } 76 }
74 77
75 void InitApplicationContext(const JavaRef<jobject>& context) { 78 void InitApplicationContext(const JavaRef<jobject>& context) {
76 DCHECK(!g_application_context); 79 DCHECK(g_application_context.Get().is_null());
77 g_application_context = context.env()->NewGlobalRef(context.obj()); 80 g_application_context.Get().Reset(context);
78 } 81 }
79 82
80 jobject GetApplicationContext() { 83 const jobject GetApplicationContext() {
81 DCHECK(g_application_context); 84 DCHECK(!g_application_context.Get().is_null());
82 return g_application_context; 85 return g_application_context.Get().obj();
86 }
87
88 ScopedJavaLocalRef<jclass> GetClass(JNIEnv* env, const char* class_name) {
89 jclass clazz = env->FindClass(class_name);
90 CHECK(clazz && !ClearException(env)) << "Failed to find class " << class_name;
91 return ScopedJavaLocalRef<jclass>(env, clazz);
92 }
93
94 bool HasClass(JNIEnv* env, const char* class_name) {
95 ScopedJavaLocalRef<jclass> clazz(env, env->FindClass(class_name));
96 if (!clazz.obj()) {
97 ClearException(env);
98 return false;
99 }
100 bool error = ClearException(env);
101 DCHECK(!error);
102 return true;
103 }
104
105 jmethodID GetMethodID(JNIEnv* env,
106 const JavaRef<jclass>& clazz,
107 const char* method_name,
108 const char* jni_signature) {
109 jmethodID method_id =
110 env->GetMethodID(clazz.obj(), method_name, jni_signature);
111 CHECK(method_id && !ClearException(env)) << "Failed to find method " <<
112 method_name << " " << jni_signature;
113 return method_id;
114 }
115
116 jmethodID GetStaticMethodID(JNIEnv* env,
117 const JavaRef<jclass>& clazz,
118 const char* method_name,
119 const char* jni_signature) {
120 jmethodID method_id =
121 env->GetStaticMethodID(clazz.obj(), method_name, jni_signature);
122 CHECK(method_id && !ClearException(env)) << "Failed to find static method " <<
123 method_name << " " << jni_signature;
124 return method_id;
125 }
126
127 bool HasMethod(JNIEnv* env,
128 const JavaRef<jclass>& clazz,
129 const char* method_name,
130 const char* jni_signature) {
131 jmethodID method_id =
132 env->GetMethodID(clazz.obj(), method_name, jni_signature);
133 if (!method_id) {
134 ClearException(env);
135 return false;
136 }
137 bool error = ClearException(env);
138 DCHECK(!error);
139 return true;
140 }
141
142 jfieldID GetFieldID(JNIEnv* env,
143 const JavaRef<jclass>& clazz,
144 const char* field_name,
145 const char* jni_signature) {
146 jfieldID field_id = env->GetFieldID(clazz.obj(), field_name, jni_signature);
147 CHECK(field_id && !ClearException(env)) << "Failed to find field " <<
148 field_name << " " << jni_signature;
149 bool error = ClearException(env);
150 DCHECK(!error);
151 return field_id;
152 }
153
154 bool HasField(JNIEnv* env,
155 const JavaRef<jclass>& clazz,
156 const char* field_name,
157 const char* jni_signature) {
158 jfieldID field_id = env->GetFieldID(clazz.obj(), field_name, jni_signature);
159 if (!field_id) {
160 ClearException(env);
161 return false;
162 }
163 bool error = ClearException(env);
164 DCHECK(!error);
165 return true;
166 }
167
168 jfieldID GetStaticFieldID(JNIEnv* env,
169 const JavaRef<jclass>& clazz,
170 const char* field_name,
171 const char* jni_signature) {
172 jfieldID field_id =
173 env->GetStaticFieldID(clazz.obj(), field_name, jni_signature);
174 CHECK(field_id && !ClearException(env)) << "Failed to find static field " <<
175 field_name << " " << jni_signature;
176 bool error = ClearException(env);
177 DCHECK(!error);
178 return field_id;
83 } 179 }
84 180
85 jmethodID GetMethodIDFromClassName(JNIEnv* env, 181 jmethodID GetMethodIDFromClassName(JNIEnv* env,
86 const char* class_name, 182 const char* class_name,
87 const char* method, 183 const char* method,
88 const char* jni_signature) { 184 const char* jni_signature) {
89 MethodIdentifier key; 185 MethodIdentifier key;
90 key.class_name = class_name; 186 key.class_name = class_name;
91 key.method = method; 187 key.method = method;
92 key.jni_signature = jni_signature; 188 key.jni_signature = jni_signature;
(...skipping 11 matching lines...) Expand all
104 found = true; 200 found = true;
105 } 201 }
106 base::subtle::Release_Store(&g_method_id_map_lock, kUnlocked); 202 base::subtle::Release_Store(&g_method_id_map_lock, kUnlocked);
107 203
108 // Addition to the map does not invalidate this iterator. 204 // Addition to the map does not invalidate this iterator.
109 if (found) { 205 if (found) {
110 return iter->second; 206 return iter->second;
111 } 207 }
112 208
113 ScopedJavaLocalRef<jclass> clazz(env, env->FindClass(class_name)); 209 ScopedJavaLocalRef<jclass> clazz(env, env->FindClass(class_name));
114 jmethodID id = GetMethodID(env, clazz.obj(), method, jni_signature); 210 jmethodID id = GetMethodID(env, clazz, method, jni_signature);
115 211
116 while (base::subtle::Acquire_CompareAndSwap(&g_method_id_map_lock, 212 while (base::subtle::Acquire_CompareAndSwap(&g_method_id_map_lock,
117 kUnlocked, 213 kUnlocked,
118 kLocked) != kUnlocked) { 214 kLocked) != kUnlocked) {
119 base::PlatformThread::YieldCurrentThread(); 215 base::PlatformThread::YieldCurrentThread();
120 } 216 }
121 // Another thread may have populated the map already. 217 // Another thread may have populated the map already.
122 std::pair<MethodIDMap::const_iterator, bool> result = 218 std::pair<MethodIDMap::const_iterator, bool> result =
123 map->insert(std::make_pair(key, id)); 219 map->insert(std::make_pair(key, id));
124 DCHECK_EQ(id, result.first->second); 220 DCHECK_EQ(id, result.first->second);
125 base::subtle::Release_Store(&g_method_id_map_lock, kUnlocked); 221 base::subtle::Release_Store(&g_method_id_map_lock, kUnlocked);
126 222
127 return id; 223 return id;
128 } 224 }
129 225
130 jmethodID GetMethodID(JNIEnv* env, 226 bool HasException(JNIEnv* env) {
131 jclass clazz, 227 return env->ExceptionCheck() != JNI_FALSE;
132 const char* const method,
133 const char* const jni_signature) {
134 jmethodID id = env->GetMethodID(clazz, method, jni_signature);
135 DCHECK(id) << method;
136 CheckException(env);
137 return id;
138 } 228 }
139 229
140 jmethodID GetStaticMethodID(JNIEnv* env, 230 bool ClearException(JNIEnv* env) {
141 jclass clazz, 231 if (!HasException(env))
142 const char* const method,
143 const char* const jni_signature) {
144 jmethodID id = env->GetStaticMethodID(clazz, method, jni_signature);
145 DCHECK(id) << method;
146 CheckException(env);
147 return id;
148 }
149
150 jfieldID GetFieldID(JNIEnv* env,
151 jclass clazz,
152 const char* field,
153 const char* jni_signature) {
154 jfieldID id = env->GetFieldID(clazz, field, jni_signature);
155 DCHECK(id) << field;
156 CheckException(env);
157 return id;
158 }
159
160 bool CheckException(JNIEnv* env) {
161 if (env->ExceptionCheck() == JNI_FALSE)
162 return false; 232 return false;
163 env->ExceptionDescribe();
164 env->ExceptionClear(); 233 env->ExceptionClear();
165 return true; 234 return true;
166 } 235 }
167 236
237 void CheckException(JNIEnv* env) {
238 if (HasException(env)) {
239 env->ExceptionDescribe();
240 CHECK(false);
241 }
242 }
243
168 } // namespace android 244 } // namespace android
169 } // namespace base 245 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698