1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #include "qjni_p.h"
41 #include "qjnihelpers_p.h"
42 #include <QtCore/qthreadstorage.h>
43 #include <QtCore/qhash.h>
44 #include <QtCore/qstring.h>
45 #include <QtCore/QThread>
46 #include <QtCore/QReadWriteLock>
47 
48 QT_BEGIN_NAMESPACE
49 
keyBase()50 static inline QLatin1String keyBase()
51 {
52     return QLatin1String("%1%2:%3");
53 }
54 
qt_convertJString(jstring string)55 static QString qt_convertJString(jstring string)
56 {
57     QJNIEnvironmentPrivate env;
58     int strLength = env->GetStringLength(string);
59     QString res(strLength, Qt::Uninitialized);
60     env->GetStringRegion(string, 0, strLength, reinterpret_cast<jchar *>(res.data()));
61     return res;
62 }
63 
exceptionCheckAndClear(JNIEnv * env)64 static inline bool exceptionCheckAndClear(JNIEnv *env)
65 {
66     if (Q_UNLIKELY(env->ExceptionCheck())) {
67         env->ExceptionDescribe();
68         env->ExceptionClear();
69         return true;
70     }
71 
72     return false;
73 }
74 
75 typedef QHash<QString, jclass> JClassHash;
Q_GLOBAL_STATIC(JClassHash,cachedClasses)76 Q_GLOBAL_STATIC(JClassHash, cachedClasses)
77 Q_GLOBAL_STATIC(QReadWriteLock, cachedClassesLock)
78 
79 static QByteArray toBinaryEncClassName(const QByteArray &className)
80 {
81     return QByteArray(className).replace('/', '.');
82 }
83 
getCachedClass(const QByteArray & classBinEnc,bool * isCached=0)84 static jclass getCachedClass(const QByteArray &classBinEnc, bool *isCached = 0)
85 {
86     QReadLocker locker(cachedClassesLock);
87     const QHash<QString, jclass>::const_iterator &it = cachedClasses->constFind(QString::fromLatin1(classBinEnc));
88     const bool found = (it != cachedClasses->constEnd());
89 
90     if (isCached != 0)
91         *isCached = found;
92 
93     return found ? it.value() : 0;
94 }
95 
loadClass(const QByteArray & className,JNIEnv * env,bool binEncoded=false)96 inline static jclass loadClass(const QByteArray &className, JNIEnv *env, bool binEncoded = false)
97 {
98     const QByteArray &binEncClassName = binEncoded ? className : toBinaryEncClassName(className);
99 
100     bool isCached = false;
101     jclass clazz = getCachedClass(binEncClassName, &isCached);
102     if (clazz != 0 || isCached)
103         return clazz;
104 
105     QJNIObjectPrivate classLoader(QtAndroidPrivate::classLoader());
106     if (!classLoader.isValid())
107         return 0;
108 
109     QWriteLocker locker(cachedClassesLock);
110     // did we lose the race?
111     const QLatin1String key(binEncClassName);
112     const QHash<QString, jclass>::const_iterator &it = cachedClasses->constFind(key);
113     if (it != cachedClasses->constEnd())
114         return it.value();
115 
116     QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(key);
117     QJNIObjectPrivate classObject = classLoader.callObjectMethod("loadClass",
118                                                                  "(Ljava/lang/String;)Ljava/lang/Class;",
119                                                                  stringName.object());
120 
121     if (!exceptionCheckAndClear(env) && classObject.isValid())
122         clazz = static_cast<jclass>(env->NewGlobalRef(classObject.object()));
123 
124     cachedClasses->insert(key, clazz);
125     return clazz;
126 }
127 
128 typedef QHash<QString, jmethodID> JMethodIDHash;
Q_GLOBAL_STATIC(JMethodIDHash,cachedMethodID)129 Q_GLOBAL_STATIC(JMethodIDHash, cachedMethodID)
130 Q_GLOBAL_STATIC(QReadWriteLock, cachedMethodIDLock)
131 
132 static inline jmethodID getMethodID(JNIEnv *env,
133                                     jclass clazz,
134                                     const char *name,
135                                     const char *sig,
136                                     bool isStatic = false)
137 {
138     jmethodID id = isStatic ? env->GetStaticMethodID(clazz, name, sig)
139                             : env->GetMethodID(clazz, name, sig);
140 
141     if (exceptionCheckAndClear(env))
142         return 0;
143 
144     return id;
145 }
146 
getCachedMethodID(JNIEnv * env,jclass clazz,const QByteArray & className,const char * name,const char * sig,bool isStatic=false)147 static jmethodID getCachedMethodID(JNIEnv *env,
148                                    jclass clazz,
149                                    const QByteArray &className,
150                                    const char *name,
151                                    const char *sig,
152                                    bool isStatic = false)
153 {
154     if (className.isEmpty())
155         return getMethodID(env, clazz, name, sig, isStatic);
156 
157     const QString key = keyBase().arg(QLatin1String(className), QLatin1String(name), QLatin1String(sig));
158     QHash<QString, jmethodID>::const_iterator it;
159 
160     {
161         QReadLocker locker(cachedMethodIDLock);
162         it = cachedMethodID->constFind(key);
163         if (it != cachedMethodID->constEnd())
164             return it.value();
165     }
166 
167     {
168         QWriteLocker locker(cachedMethodIDLock);
169         it = cachedMethodID->constFind(key);
170         if (it != cachedMethodID->constEnd())
171             return it.value();
172 
173         jmethodID id = getMethodID(env, clazz, name, sig, isStatic);
174 
175         cachedMethodID->insert(key, id);
176         return id;
177     }
178 }
179 
180 typedef QHash<QString, jfieldID> JFieldIDHash;
Q_GLOBAL_STATIC(JFieldIDHash,cachedFieldID)181 Q_GLOBAL_STATIC(JFieldIDHash, cachedFieldID)
182 Q_GLOBAL_STATIC(QReadWriteLock, cachedFieldIDLock)
183 
184 static inline jfieldID getFieldID(JNIEnv *env,
185                                   jclass clazz,
186                                   const char *name,
187                                   const char *sig,
188                                   bool isStatic = false)
189 {
190     jfieldID id = isStatic ? env->GetStaticFieldID(clazz, name, sig)
191                            : env->GetFieldID(clazz, name, sig);
192 
193     if (exceptionCheckAndClear(env))
194         return 0;
195 
196     return id;
197 }
198 
getCachedFieldID(JNIEnv * env,jclass clazz,const QByteArray & className,const char * name,const char * sig,bool isStatic=false)199 static jfieldID getCachedFieldID(JNIEnv *env,
200                                  jclass clazz,
201                                  const QByteArray &className,
202                                  const char *name,
203                                  const char *sig,
204                                  bool isStatic = false)
205 {
206     if (className.isNull())
207         return getFieldID(env, clazz, name, sig, isStatic);
208 
209     const QString key = keyBase().arg(QLatin1String(className), QLatin1String(name), QLatin1String(sig));
210     QHash<QString, jfieldID>::const_iterator it;
211 
212     {
213         QReadLocker locker(cachedFieldIDLock);
214         it = cachedFieldID->constFind(key);
215         if (it != cachedFieldID->constEnd())
216             return it.value();
217     }
218 
219     {
220         QWriteLocker locker(cachedFieldIDLock);
221         it = cachedFieldID->constFind(key);
222         if (it != cachedFieldID->constEnd())
223             return it.value();
224 
225         jfieldID id = getFieldID(env, clazz, name, sig, isStatic);
226 
227         cachedFieldID->insert(key, id);
228         return id;
229     }
230 }
231 
cleanup(jobject obj)232 void QJNILocalRefDeleter::cleanup(jobject obj)
233 {
234     if (obj == 0)
235         return;
236 
237     QJNIEnvironmentPrivate env;
238     env->DeleteLocalRef(obj);
239 }
240 
241 class QJNIEnvironmentPrivateTLS
242 {
243 public:
~QJNIEnvironmentPrivateTLS()244     inline ~QJNIEnvironmentPrivateTLS()
245     {
246         QtAndroidPrivate::javaVM()->DetachCurrentThread();
247     }
248 };
249 
250 Q_GLOBAL_STATIC(QThreadStorage<QJNIEnvironmentPrivateTLS *>, jniEnvTLS)
251 
252 static const char qJniThreadName[] = "QtThread";
253 
QJNIEnvironmentPrivate()254 QJNIEnvironmentPrivate::QJNIEnvironmentPrivate()
255     : jniEnv(0)
256 {
257     JavaVM *vm = QtAndroidPrivate::javaVM();
258     const jint ret = vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6);
259     if (ret == JNI_OK) // Already attached
260         return;
261 
262     if (ret == JNI_EDETACHED) { // We need to (re-)attach
263         JavaVMAttachArgs args = { JNI_VERSION_1_6, qJniThreadName, nullptr };
264         if (vm->AttachCurrentThread(&jniEnv, &args) != JNI_OK)
265             return;
266 
267         if (!jniEnvTLS->hasLocalData()) // If we attached the thread we own it.
268             jniEnvTLS->setLocalData(new QJNIEnvironmentPrivateTLS);
269     }
270 }
271 
operator ->()272 JNIEnv *QJNIEnvironmentPrivate::operator->()
273 {
274     return jniEnv;
275 }
276 
findClass(const char * className,JNIEnv * env)277 jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env)
278 {
279     const QByteArray &classDotEnc = toBinaryEncClassName(className);
280     bool isCached = false;
281     jclass clazz = getCachedClass(classDotEnc, &isCached);
282 
283     const bool found = (clazz != 0) || (clazz == 0 && isCached);
284 
285     if (found)
286         return clazz;
287 
288     const QLatin1String key(classDotEnc);
289     if (env != 0) { // We got an env. pointer (We expect this to be the right env. and call FindClass())
290         QWriteLocker locker(cachedClassesLock);
291         const QHash<QString, jclass>::const_iterator &it = cachedClasses->constFind(key);
292         // Did we lose the race?
293         if (it != cachedClasses->constEnd())
294             return it.value();
295 
296         jclass fclazz = env->FindClass(className);
297         if (!exceptionCheckAndClear(env)) {
298             clazz = static_cast<jclass>(env->NewGlobalRef(fclazz));
299             env->DeleteLocalRef(fclazz);
300         }
301 
302         if (clazz != 0)
303             cachedClasses->insert(key, clazz);
304     }
305 
306     if (clazz == 0) // We didn't get an env. pointer or we got one with the WRONG class loader...
307         clazz = loadClass(classDotEnc, QJNIEnvironmentPrivate(), true);
308 
309     return clazz;
310 }
311 
operator JNIEnv*() const312 QJNIEnvironmentPrivate::operator JNIEnv* () const
313 {
314     return jniEnv;
315 }
316 
~QJNIEnvironmentPrivate()317 QJNIEnvironmentPrivate::~QJNIEnvironmentPrivate()
318 {
319 }
320 
QJNIObjectData()321 QJNIObjectData::QJNIObjectData()
322     : m_jobject(0),
323       m_jclass(0),
324       m_own_jclass(true)
325 {
326 
327 }
328 
~QJNIObjectData()329 QJNIObjectData::~QJNIObjectData()
330 {
331     QJNIEnvironmentPrivate env;
332     if (m_jobject)
333         env->DeleteGlobalRef(m_jobject);
334     if (m_jclass && m_own_jclass)
335         env->DeleteGlobalRef(m_jclass);
336 }
337 
QJNIObjectPrivate()338 QJNIObjectPrivate::QJNIObjectPrivate()
339     : d(new QJNIObjectData())
340 {
341 
342 }
343 
QJNIObjectPrivate(const char * className)344 QJNIObjectPrivate::QJNIObjectPrivate(const char *className)
345     : d(new QJNIObjectData())
346 {
347     QJNIEnvironmentPrivate env;
348     d->m_className = toBinaryEncClassName(className);
349     d->m_jclass = loadClass(d->m_className, env, true);
350     d->m_own_jclass = false;
351     if (d->m_jclass) {
352         // get default constructor
353         jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "<init>", "()V");
354         if (constructorId) {
355             jobject obj = env->NewObject(d->m_jclass, constructorId);
356             if (obj) {
357                 d->m_jobject = env->NewGlobalRef(obj);
358                 env->DeleteLocalRef(obj);
359             }
360         }
361     }
362 }
363 
QJNIObjectPrivate(const char * className,const char * sig,...)364 QJNIObjectPrivate::QJNIObjectPrivate(const char *className, const char *sig, ...)
365     : d(new QJNIObjectData())
366 {
367     QJNIEnvironmentPrivate env;
368     d->m_className = toBinaryEncClassName(className);
369     d->m_jclass = loadClass(d->m_className, env, true);
370     d->m_own_jclass = false;
371     if (d->m_jclass) {
372         jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "<init>", sig);
373         if (constructorId) {
374             va_list args;
375             va_start(args, sig);
376             jobject obj = env->NewObjectV(d->m_jclass, constructorId, args);
377             va_end(args);
378             if (obj) {
379                 d->m_jobject = env->NewGlobalRef(obj);
380                 env->DeleteLocalRef(obj);
381             }
382         }
383     }
384 }
385 
QJNIObjectPrivate(const char * className,const char * sig,const QVaListPrivate & args)386 QJNIObjectPrivate::QJNIObjectPrivate(const char *className, const char *sig, const QVaListPrivate &args)
387     : d(new QJNIObjectData())
388 {
389     QJNIEnvironmentPrivate env;
390     d->m_className = toBinaryEncClassName(className);
391     d->m_jclass = loadClass(d->m_className, env, true);
392     d->m_own_jclass = false;
393     if (d->m_jclass) {
394         jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "<init>", sig);
395         if (constructorId) {
396             jobject obj = env->NewObjectV(d->m_jclass, constructorId, args);
397             if (obj) {
398                 d->m_jobject = env->NewGlobalRef(obj);
399                 env->DeleteLocalRef(obj);
400             }
401         }
402     }
403 }
404 
QJNIObjectPrivate(jclass clazz)405 QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz)
406     : d(new QJNIObjectData())
407 {
408     QJNIEnvironmentPrivate env;
409     d->m_jclass = static_cast<jclass>(env->NewGlobalRef(clazz));
410     if (d->m_jclass) {
411         // get default constructor
412         jmethodID constructorId = getMethodID(env, d->m_jclass, "<init>", "()V");
413         if (constructorId) {
414             jobject obj = env->NewObject(d->m_jclass, constructorId);
415             if (obj) {
416                 d->m_jobject = env->NewGlobalRef(obj);
417                 env->DeleteLocalRef(obj);
418             }
419         }
420     }
421 }
422 
QJNIObjectPrivate(jclass clazz,const char * sig,...)423 QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz, const char *sig, ...)
424     : d(new QJNIObjectData())
425 {
426     QJNIEnvironmentPrivate env;
427     if (clazz) {
428         d->m_jclass = static_cast<jclass>(env->NewGlobalRef(clazz));
429         if (d->m_jclass) {
430             jmethodID constructorId = getMethodID(env, d->m_jclass, "<init>", sig);
431             if (constructorId) {
432                 va_list args;
433                 va_start(args, sig);
434                 jobject obj = env->NewObjectV(d->m_jclass, constructorId, args);
435                 va_end(args);
436                 if (obj) {
437                     d->m_jobject = env->NewGlobalRef(obj);
438                     env->DeleteLocalRef(obj);
439                 }
440             }
441         }
442     }
443 }
444 
QJNIObjectPrivate(jclass clazz,const char * sig,const QVaListPrivate & args)445 QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz, const char *sig, const QVaListPrivate &args)
446     : d(new QJNIObjectData())
447 {
448     QJNIEnvironmentPrivate env;
449     if (clazz) {
450         d->m_jclass = static_cast<jclass>(env->NewGlobalRef(clazz));
451         if (d->m_jclass) {
452             jmethodID constructorId = getMethodID(env, d->m_jclass, "<init>", sig);
453             if (constructorId) {
454                 jobject obj = env->NewObjectV(d->m_jclass, constructorId, args);
455                 if (obj) {
456                     d->m_jobject = env->NewGlobalRef(obj);
457                     env->DeleteLocalRef(obj);
458                 }
459             }
460         }
461     }
462 }
463 
QJNIObjectPrivate(jobject obj)464 QJNIObjectPrivate::QJNIObjectPrivate(jobject obj)
465     : d(new QJNIObjectData())
466 {
467     if (!obj)
468         return;
469 
470     QJNIEnvironmentPrivate env;
471     d->m_jobject = env->NewGlobalRef(obj);
472     jclass cls = env->GetObjectClass(obj);
473     d->m_jclass = static_cast<jclass>(env->NewGlobalRef(cls));
474     env->DeleteLocalRef(cls);
475 }
476 template <>
callMethodV(const char * methodName,const char * sig,va_list args) const477 Q_CORE_EXPORT void QJNIObjectPrivate::callMethodV<void>(const char *methodName, const char *sig, va_list args) const
478 {
479     QJNIEnvironmentPrivate env;
480     jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
481     if (id) {
482         env->CallVoidMethodV(d->m_jobject, id, args);
483     }
484 }
485 
486 template <>
callMethod(const char * methodName,const char * sig,...) const487 Q_CORE_EXPORT void QJNIObjectPrivate::callMethod<void>(const char *methodName, const char *sig, ...) const
488 {
489     va_list args;
490     va_start(args, sig);
491     callMethodV<void>(methodName, sig, args);
492     va_end(args);
493 }
494 
495 template <>
callMethodV(const char * methodName,const char * sig,va_list args) const496 Q_CORE_EXPORT jboolean QJNIObjectPrivate::callMethodV<jboolean>(const char *methodName, const char *sig, va_list args) const
497 {
498     QJNIEnvironmentPrivate env;
499     jboolean res = 0;
500     jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
501     if (id) {
502         res = env->CallBooleanMethodV(d->m_jobject, id, args);
503     }
504     return res;
505 }
506 
507 template <>
callMethod(const char * methodName,const char * sig,...) const508 Q_CORE_EXPORT jboolean QJNIObjectPrivate::callMethod<jboolean>(const char *methodName, const char *sig, ...) const
509 {
510     va_list args;
511     va_start(args, sig);
512     jboolean res = callMethodV<jboolean>(methodName, sig, args);
513     va_end(args);
514     return res;
515 }
516 
517 template <>
callMethodV(const char * methodName,const char * sig,va_list args) const518 Q_CORE_EXPORT jbyte QJNIObjectPrivate::callMethodV<jbyte>(const char *methodName, const char *sig, va_list args) const
519 {
520     QJNIEnvironmentPrivate env;
521     jbyte res = 0;
522     jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
523     if (id) {
524         res = env->CallByteMethodV(d->m_jobject, id, args);
525     }
526     return res;
527 }
528 
529 template <>
callMethod(const char * methodName,const char * sig,...) const530 Q_CORE_EXPORT jbyte QJNIObjectPrivate::callMethod<jbyte>(const char *methodName, const char *sig, ...) const
531 {
532     va_list args;
533     va_start(args, sig);
534     jbyte res = callMethodV<jbyte>(methodName, sig, args);
535     va_end(args);
536     return res;
537 }
538 
539 template <>
callMethodV(const char * methodName,const char * sig,va_list args) const540 Q_CORE_EXPORT jchar QJNIObjectPrivate::callMethodV<jchar>(const char *methodName, const char *sig, va_list args) const
541 {
542     QJNIEnvironmentPrivate env;
543     jchar res = 0;
544     jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
545     if (id) {
546         res = env->CallCharMethodV(d->m_jobject, id, args);
547     }
548     return res;
549 }
550 
551 template <>
callMethod(const char * methodName,const char * sig,...) const552 Q_CORE_EXPORT jchar QJNIObjectPrivate::callMethod<jchar>(const char *methodName, const char *sig, ...) const
553 {
554     va_list args;
555     va_start(args, sig);
556     jchar res = callMethodV<jchar>(methodName, sig, args);
557     va_end(args);
558     return res;
559 }
560 
561 template <>
callMethodV(const char * methodName,const char * sig,va_list args) const562 Q_CORE_EXPORT jshort QJNIObjectPrivate::callMethodV<jshort>(const char *methodName, const char *sig, va_list args) const
563 {
564     QJNIEnvironmentPrivate env;
565     jshort res = 0;
566     jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
567     if (id) {
568         res = env->CallShortMethodV(d->m_jobject, id, args);
569     }
570     return res;
571 }
572 
573 template <>
callMethod(const char * methodName,const char * sig,...) const574 Q_CORE_EXPORT jshort QJNIObjectPrivate::callMethod<jshort>(const char *methodName, const char *sig, ...) const
575 {
576     va_list args;
577     va_start(args, sig);
578     jshort res = callMethodV<jshort>(methodName, sig, args);
579     va_end(args);
580     return res;
581 }
582 
583 template <>
callMethodV(const char * methodName,const char * sig,va_list args) const584 Q_CORE_EXPORT jint QJNIObjectPrivate::callMethodV<jint>(const char *methodName, const char *sig, va_list args) const
585 {
586     QJNIEnvironmentPrivate env;
587     jint res = 0;
588     jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
589     if (id) {
590         res = env->CallIntMethodV(d->m_jobject, id, args);
591     }
592     return res;
593 }
594 
595 template <>
callMethod(const char * methodName,const char * sig,...) const596 Q_CORE_EXPORT jint QJNIObjectPrivate::callMethod<jint>(const char *methodName, const char *sig, ...) const
597 {
598     va_list args;
599     va_start(args, sig);
600     jint res = callMethodV<jint>(methodName, sig, args);
601     va_end(args);
602     return res;
603 }
604 
605 template <>
callMethodV(const char * methodName,const char * sig,va_list args) const606 Q_CORE_EXPORT jlong QJNIObjectPrivate::callMethodV<jlong>(const char *methodName, const char *sig, va_list args) const
607 {
608     QJNIEnvironmentPrivate env;
609     jlong res = 0;
610     jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
611     if (id) {
612         res = env->CallLongMethodV(d->m_jobject, id, args);
613     }
614     return res;
615 }
616 
617 template <>
callMethod(const char * methodName,const char * sig,...) const618 Q_CORE_EXPORT jlong QJNIObjectPrivate::callMethod<jlong>(const char *methodName, const char *sig, ...) const
619 {
620     va_list args;
621     va_start(args, sig);
622     jlong res = callMethodV<jlong>(methodName, sig, args);
623     va_end(args);
624     return res;
625 }
626 
627 template <>
callMethodV(const char * methodName,const char * sig,va_list args) const628 Q_CORE_EXPORT jfloat QJNIObjectPrivate::callMethodV<jfloat>(const char *methodName, const char *sig, va_list args) const
629 {
630     QJNIEnvironmentPrivate env;
631     jfloat res = 0.f;
632     jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
633     if (id) {
634         res = env->CallFloatMethodV(d->m_jobject, id, args);
635     }
636     return res;
637 }
638 
639 template <>
callMethod(const char * methodName,const char * sig,...) const640 Q_CORE_EXPORT jfloat QJNIObjectPrivate::callMethod<jfloat>(const char *methodName, const char *sig, ...) const
641 {
642     va_list args;
643     va_start(args, sig);
644     jfloat res = callMethodV<jfloat>(methodName, sig, args);
645     va_end(args);
646     return res;
647 }
648 
649 template <>
callMethodV(const char * methodName,const char * sig,va_list args) const650 Q_CORE_EXPORT jdouble QJNIObjectPrivate::callMethodV<jdouble>(const char *methodName, const char *sig, va_list args) const
651 {
652     QJNIEnvironmentPrivate env;
653     jdouble res = 0.;
654     jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
655     if (id) {
656         res = env->CallDoubleMethodV(d->m_jobject, id, args);
657     }
658     return res;
659 }
660 
661 template <>
callMethod(const char * methodName,const char * sig,...) const662 Q_CORE_EXPORT jdouble QJNIObjectPrivate::callMethod<jdouble>(const char *methodName, const char *sig, ...) const
663 {
664     va_list args;
665     va_start(args, sig);
666     jdouble res = callMethodV<jdouble>(methodName, sig, args);
667     va_end(args);
668     return res;
669 }
670 
671 template <>
callMethod(const char * methodName) const672 Q_CORE_EXPORT void QJNIObjectPrivate::callMethod<void>(const char *methodName) const
673 {
674     callMethod<void>(methodName, "()V");
675 }
676 
677 template <>
callMethod(const char * methodName) const678 Q_CORE_EXPORT jboolean QJNIObjectPrivate::callMethod<jboolean>(const char *methodName) const
679 {
680     return callMethod<jboolean>(methodName, "()Z");
681 }
682 
683 template <>
callMethod(const char * methodName) const684 Q_CORE_EXPORT jbyte QJNIObjectPrivate::callMethod<jbyte>(const char *methodName) const
685 {
686     return callMethod<jbyte>(methodName, "()B");
687 }
688 
689 template <>
callMethod(const char * methodName) const690 Q_CORE_EXPORT jchar QJNIObjectPrivate::callMethod<jchar>(const char *methodName) const
691 {
692     return callMethod<jchar>(methodName, "()C");
693 }
694 
695 template <>
callMethod(const char * methodName) const696 Q_CORE_EXPORT jshort QJNIObjectPrivate::callMethod<jshort>(const char *methodName) const
697 {
698     return callMethod<jshort>(methodName, "()S");
699 }
700 
701 template <>
callMethod(const char * methodName) const702 Q_CORE_EXPORT jint QJNIObjectPrivate::callMethod<jint>(const char *methodName) const
703 {
704     return callMethod<jint>(methodName, "()I");
705 }
706 
707 template <>
callMethod(const char * methodName) const708 Q_CORE_EXPORT jlong QJNIObjectPrivate::callMethod<jlong>(const char *methodName) const
709 {
710     return callMethod<jlong>(methodName, "()J");
711 }
712 
713 template <>
callMethod(const char * methodName) const714 Q_CORE_EXPORT jfloat QJNIObjectPrivate::callMethod<jfloat>(const char *methodName) const
715 {
716     return callMethod<jfloat>(methodName, "()F");
717 }
718 
719 template <>
callMethod(const char * methodName) const720 Q_CORE_EXPORT jdouble QJNIObjectPrivate::callMethod<jdouble>(const char *methodName) const
721 {
722     return callMethod<jdouble>(methodName, "()D");
723 }
724 
725 template <>
callStaticMethodV(const char * className,const char * methodName,const char * sig,va_list args)726 Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethodV<void>(const char *className,
727                                                 const char *methodName,
728                                                 const char *sig,
729                                                 va_list args)
730 {
731     QJNIEnvironmentPrivate env;
732     jclass clazz = loadClass(className, env);
733     if (clazz) {
734         jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true);
735         if (id) {
736             env->CallStaticVoidMethodV(clazz, id, args);
737         }
738     }
739 }
740 
741 template <>
callStaticMethod(const char * className,const char * methodName,const char * sig,...)742 Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethod<void>(const char *className,
743                                                const char *methodName,
744                                                const char *sig,
745                                                ...)
746 {
747     va_list args;
748     va_start(args, sig);
749     callStaticMethodV<void>(className, methodName, sig, args);
750     va_end(args);
751 }
752 
753 template <>
callStaticMethodV(jclass clazz,const char * methodName,const char * sig,va_list args)754 Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethodV<void>(jclass clazz,
755                                                 const char *methodName,
756                                                 const char *sig,
757                                                 va_list args)
758 {
759     QJNIEnvironmentPrivate env;
760     jmethodID id = getMethodID(env, clazz, methodName, sig, true);
761     if (id) {
762         env->CallStaticVoidMethodV(clazz, id, args);
763     }
764 }
765 
766 template <>
callStaticMethod(jclass clazz,const char * methodName,const char * sig,...)767 Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethod<void>(jclass clazz,
768                                                const char *methodName,
769                                                const char *sig,
770                                                ...)
771 {
772     va_list args;
773     va_start(args, sig);
774     callStaticMethodV<void>(clazz, methodName, sig, args);
775     va_end(args);
776 }
777 
778 template <>
callStaticMethodV(const char * className,const char * methodName,const char * sig,va_list args)779 Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethodV<jboolean>(const char *className,
780                                                         const char *methodName,
781                                                         const char *sig,
782                                                         va_list args)
783 {
784     QJNIEnvironmentPrivate env;
785     jboolean res = 0;
786     jclass clazz = loadClass(className, env);
787     if (clazz) {
788         jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true);
789         if (id) {
790             res = env->CallStaticBooleanMethodV(clazz, id, args);
791         }
792     }
793 
794     return res;
795 }
796 
797 template <>
callStaticMethod(const char * className,const char * methodName,const char * sig,...)798 Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(const char *className,
799                                                        const char *methodName,
800                                                        const char *sig,
801                                                        ...)
802 {
803     va_list args;
804     va_start(args, sig);
805     jboolean res = callStaticMethodV<jboolean>(className, methodName, sig, args);
806     va_end(args);
807     return res;
808 }
809 
810 template <>
callStaticMethodV(jclass clazz,const char * methodName,const char * sig,va_list args)811 Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethodV<jboolean>(jclass clazz,
812                                                         const char *methodName,
813                                                         const char *sig,
814                                                         va_list args)
815 {
816     QJNIEnvironmentPrivate env;
817     jboolean res = 0;
818     jmethodID id = getMethodID(env, clazz, methodName, sig, true);
819     if (id) {
820         res = env->CallStaticBooleanMethodV(clazz, id, args);
821     }
822 
823     return res;
824 }
825 
826 template <>
callStaticMethod(jclass clazz,const char * methodName,const char * sig,...)827 Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(jclass clazz,
828                                                        const char *methodName,
829                                                        const char *sig,
830                                                        ...)
831 {
832     va_list args;
833     va_start(args, sig);
834     jboolean res = callStaticMethodV<jboolean>(clazz, methodName, sig, args);
835     va_end(args);
836     return res;
837 }
838 
839 template <>
callStaticMethodV(const char * className,const char * methodName,const char * sig,va_list args)840 Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethodV<jbyte>(const char *className,
841                                                   const char *methodName,
842                                                   const char *sig,
843                                                   va_list args)
844 {
845     QJNIEnvironmentPrivate env;
846     jbyte res = 0;
847     jclass clazz = loadClass(className, env);
848     if (clazz) {
849         jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true);
850         if (id) {
851             res = env->CallStaticByteMethodV(clazz, id, args);
852         }
853     }
854 
855     return res;
856 }
857 
858 template <>
callStaticMethod(const char * className,const char * methodName,const char * sig,...)859 Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(const char *className,
860                                                  const char *methodName,
861                                                  const char *sig,
862                                                  ...)
863 {
864     va_list args;
865     va_start(args, sig);
866     jbyte res = callStaticMethodV<jbyte>(className, methodName, sig, args);
867     va_end(args);
868     return res;
869 }
870 
871 template <>
callStaticMethodV(jclass clazz,const char * methodName,const char * sig,va_list args)872 Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethodV<jbyte>(jclass clazz,
873                                                   const char *methodName,
874                                                   const char *sig,
875                                                   va_list args)
876 {
877     QJNIEnvironmentPrivate env;
878     jbyte res = 0;
879     jmethodID id = getMethodID(env, clazz, methodName, sig, true);
880     if (id) {
881         res = env->CallStaticByteMethodV(clazz, id, args);
882     }
883 
884     return res;
885 }
886 
887 template <>
callStaticMethod(jclass clazz,const char * methodName,const char * sig,...)888 Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(jclass clazz,
889                                                  const char *methodName,
890                                                  const char *sig,
891                                                  ...)
892 {
893     va_list args;
894     va_start(args, sig);
895     jbyte res = callStaticMethodV<jbyte>(clazz, methodName, sig, args);
896     va_end(args);
897     return res;
898 }
899 
900 template <>
callStaticMethodV(const char * className,const char * methodName,const char * sig,va_list args)901 Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethodV<jchar>(const char *className,
902                                                   const char *methodName,
903                                                   const char *sig,
904                                                   va_list args)
905 {
906     QJNIEnvironmentPrivate env;
907     jchar res = 0;
908     jclass clazz = loadClass(className, env);
909     if (clazz) {
910         jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true);
911         if (id) {
912             res = env->CallStaticCharMethodV(clazz, id, args);
913         }
914     }
915 
916     return res;
917 }
918 
919 template <>
callStaticMethod(const char * className,const char * methodName,const char * sig,...)920 Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethod<jchar>(const char *className,
921                                                  const char *methodName,
922                                                  const char *sig,
923                                                  ...)
924 {
925     va_list args;
926     va_start(args, sig);
927     jchar res = callStaticMethodV<jchar>(className, methodName, sig, args);
928     va_end(args);
929     return res;
930 }
931 
932 template <>
callStaticMethodV(jclass clazz,const char * methodName,const char * sig,va_list args)933 Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethodV<jchar>(jclass clazz,
934                                                   const char *methodName,
935                                                   const char *sig,
936                                                   va_list args)
937 {
938     QJNIEnvironmentPrivate env;
939     jchar res = 0;
940     jmethodID id = getMethodID(env, clazz, methodName, sig, true);
941     if (id) {
942         res = env->CallStaticCharMethodV(clazz, id, args);
943     }
944 
945     return res;
946 }
947 
948 template <>
callStaticMethod(jclass clazz,const char * methodName,const char * sig,...)949 Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethod<jchar>(jclass clazz,
950                                                  const char *methodName,
951                                                  const char *sig,
952                                                  ...)
953 {
954     va_list args;
955     va_start(args, sig);
956     jchar res = callStaticMethodV<jchar>(clazz, methodName, sig, args);
957     va_end(args);
958     return res;
959 }
960 
961 template <>
callStaticMethodV(const char * className,const char * methodName,const char * sig,va_list args)962 Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethodV<jshort>(const char *className,
963                                                     const char *methodName,
964                                                     const char *sig,
965                                                     va_list args)
966 {
967     QJNIEnvironmentPrivate env;
968     jshort res = 0;
969     jclass clazz = loadClass(className, env);
970     if (clazz) {
971         jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true);
972         if (id) {
973             res = env->CallStaticShortMethodV(clazz, id, args);
974         }
975     }
976 
977     return res;
978 }
979 
980 template <>
callStaticMethod(const char * className,const char * methodName,const char * sig,...)981 Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethod<jshort>(const char *className,
982                                                    const char *methodName,
983                                                    const char *sig,
984                                                    ...)
985 {
986     va_list args;
987     va_start(args, sig);
988     jshort res = callStaticMethodV<jshort>(className, methodName, sig, args);
989     va_end(args);
990     return res;
991 }
992 
993 template <>
callStaticMethodV(jclass clazz,const char * methodName,const char * sig,va_list args)994 Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethodV<jshort>(jclass clazz,
995                                                     const char *methodName,
996                                                     const char *sig,
997                                                     va_list args)
998 {
999     QJNIEnvironmentPrivate env;
1000     jshort res = 0;
1001     jmethodID id = getMethodID(env, clazz, methodName, sig, true);
1002     if (id) {
1003         res = env->CallStaticShortMethodV(clazz, id, args);
1004     }
1005 
1006     return res;
1007 }
1008 
1009 template <>
callStaticMethod(jclass clazz,const char * methodName,const char * sig,...)1010 Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethod<jshort>(jclass clazz,
1011                                                    const char *methodName,
1012                                                    const char *sig,
1013                                                    ...)
1014 {
1015     va_list args;
1016     va_start(args, sig);
1017     jshort res = callStaticMethodV<jshort>(clazz, methodName, sig, args);
1018     va_end(args);
1019     return res;
1020 }
1021 
1022 template <>
callStaticMethodV(const char * className,const char * methodName,const char * sig,va_list args)1023 Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethodV<jint>(const char *className,
1024                                                 const char *methodName,
1025                                                 const char *sig,
1026                                                 va_list args)
1027 {
1028     QJNIEnvironmentPrivate env;
1029     jint res = 0;
1030     jclass clazz = loadClass(className, env);
1031     if (clazz) {
1032         jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true);
1033         if (id) {
1034             res = env->CallStaticIntMethodV(clazz, id, args);
1035         }
1036     }
1037 
1038     return res;
1039 }
1040 
1041 template <>
callStaticMethod(const char * className,const char * methodName,const char * sig,...)1042 Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethod<jint>(const char *className,
1043                                                const char *methodName,
1044                                                const char *sig,
1045                                                ...)
1046 {
1047     va_list args;
1048     va_start(args, sig);
1049     jint res = callStaticMethodV<jint>(className, methodName, sig, args);
1050     va_end(args);
1051     return res;
1052 }
1053 
1054 template <>
callStaticMethodV(jclass clazz,const char * methodName,const char * sig,va_list args)1055 Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethodV<jint>(jclass clazz,
1056                                                 const char *methodName,
1057                                                 const char *sig,
1058                                                 va_list args)
1059 {
1060     QJNIEnvironmentPrivate env;
1061     jint res = 0;
1062     jmethodID id = getMethodID(env, clazz, methodName, sig, true);
1063     if (id) {
1064         res = env->CallStaticIntMethodV(clazz, id, args);
1065     }
1066 
1067     return res;
1068 }
1069 
1070 template <>
callStaticMethod(jclass clazz,const char * methodName,const char * sig,...)1071 Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethod<jint>(jclass clazz,
1072                                                const char *methodName,
1073                                                const char *sig,
1074                                                ...)
1075 {
1076     va_list args;
1077     va_start(args, sig);
1078     jint res = callStaticMethodV<jint>(clazz, methodName, sig, args);
1079     va_end(args);
1080     return res;
1081 }
1082 
1083 template <>
callStaticMethodV(const char * className,const char * methodName,const char * sig,va_list args)1084 Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethodV<jlong>(const char *className,
1085                                                   const char *methodName,
1086                                                   const char *sig,
1087                                                   va_list args)
1088 {
1089     QJNIEnvironmentPrivate env;
1090     jlong res = 0;
1091     jclass clazz = loadClass(className, env);
1092     if (clazz) {
1093         jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true);
1094         if (id) {
1095             res = env->CallStaticLongMethodV(clazz, id, args);
1096         }
1097     }
1098 
1099     return res;
1100 }
1101 
1102 template <>
callStaticMethod(const char * className,const char * methodName,const char * sig,...)1103 Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethod<jlong>(const char *className,
1104                                                  const char *methodName,
1105                                                  const char *sig,
1106                                                  ...)
1107 {
1108     va_list args;
1109     va_start(args, sig);
1110     jlong res = callStaticMethodV<jlong>(className, methodName, sig, args);
1111     va_end(args);
1112     return res;
1113 }
1114 
1115 template <>
callStaticMethodV(jclass clazz,const char * methodName,const char * sig,va_list args)1116 Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethodV<jlong>(jclass clazz,
1117                                                   const char *methodName,
1118                                                   const char *sig,
1119                                                   va_list args)
1120 {
1121     QJNIEnvironmentPrivate env;
1122     jlong res = 0;
1123     jmethodID id = getMethodID(env, clazz, methodName, sig, true);
1124     if (id) {
1125         res = env->CallStaticLongMethodV(clazz, id, args);
1126     }
1127 
1128     return res;
1129 }
1130 
1131 template <>
callStaticMethod(jclass clazz,const char * methodName,const char * sig,...)1132 Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethod<jlong>(jclass clazz,
1133                                                  const char *methodName,
1134                                                  const char *sig,
1135                                                  ...)
1136 {
1137     va_list args;
1138     va_start(args, sig);
1139     jlong res = callStaticMethodV<jlong>(clazz, methodName, sig, args);
1140     va_end(args);
1141     return res;
1142 }
1143 
1144 template <>
callStaticMethodV(const char * className,const char * methodName,const char * sig,va_list args)1145 Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethodV<jfloat>(const char *className,
1146                                                     const char *methodName,
1147                                                     const char *sig,
1148                                                     va_list args)
1149 {
1150     QJNIEnvironmentPrivate env;
1151     jfloat res = 0.f;
1152     jclass clazz = loadClass(className, env);
1153     if (clazz) {
1154         jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true);
1155         if (id) {
1156             res = env->CallStaticFloatMethodV(clazz, id, args);
1157         }
1158     }
1159 
1160     return res;
1161 }
1162 
1163 template <>
callStaticMethod(const char * className,const char * methodName,const char * sig,...)1164 Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(const char *className,
1165                                                    const char *methodName,
1166                                                    const char *sig,
1167                                                    ...)
1168 {
1169     va_list args;
1170     va_start(args, sig);
1171     jfloat res = callStaticMethodV<jfloat>(className, methodName, sig, args);
1172     va_end(args);
1173     return res;
1174 }
1175 
1176 template <>
callStaticMethodV(jclass clazz,const char * methodName,const char * sig,va_list args)1177 Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethodV<jfloat>(jclass clazz,
1178                                                     const char *methodName,
1179                                                     const char *sig,
1180                                                     va_list args)
1181 {
1182     QJNIEnvironmentPrivate env;
1183     jfloat res = 0.f;
1184     jmethodID id = getMethodID(env, clazz, methodName, sig, true);
1185     if (id) {
1186         res = env->CallStaticFloatMethodV(clazz, id, args);
1187     }
1188 
1189     return res;
1190 }
1191 
1192 template <>
callStaticMethod(jclass clazz,const char * methodName,const char * sig,...)1193 Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(jclass clazz,
1194                                                    const char *methodName,
1195                                                    const char *sig,
1196                                                    ...)
1197 {
1198     va_list args;
1199     va_start(args, sig);
1200     jfloat res = callStaticMethodV<jfloat>(clazz, methodName, sig, args);
1201     va_end(args);
1202     return res;
1203 }
1204 
1205 template <>
callStaticMethodV(const char * className,const char * methodName,const char * sig,va_list args)1206 Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethodV<jdouble>(const char *className,
1207                                                       const char *methodName,
1208                                                       const char *sig,
1209                                                       va_list args)
1210 {
1211     QJNIEnvironmentPrivate env;
1212     jdouble res = 0.;
1213     jclass clazz = loadClass(className, env);
1214     if (clazz) {
1215         jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true);
1216         if (id) {
1217             res = env->CallStaticDoubleMethodV(clazz, id, args);
1218         }
1219     }
1220 
1221     return res;
1222 }
1223 
1224 template <>
callStaticMethod(const char * className,const char * methodName,const char * sig,...)1225 Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(const char *className,
1226                                                      const char *methodName,
1227                                                      const char *sig,
1228                                                      ...)
1229 {
1230     va_list args;
1231     va_start(args, sig);
1232     jdouble res = callStaticMethodV<jdouble>(className, methodName, sig, args);
1233     va_end(args);
1234     return res;
1235 }
1236 
1237 template <>
callStaticMethodV(jclass clazz,const char * methodName,const char * sig,va_list args)1238 Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethodV<jdouble>(jclass clazz,
1239                                                       const char *methodName,
1240                                                       const char *sig,
1241                                                       va_list args)
1242 {
1243     QJNIEnvironmentPrivate env;
1244     jdouble res = 0.;
1245     jmethodID id = getMethodID(env, clazz, methodName, sig, true);
1246     if (id) {
1247         res = env->CallStaticDoubleMethodV(clazz, id, args);
1248     }
1249 
1250     return res;
1251 }
1252 
1253 template <>
callStaticMethod(jclass clazz,const char * methodName,const char * sig,...)1254 Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(jclass clazz,
1255                                                      const char *methodName,
1256                                                      const char *sig,
1257                                                      ...)
1258 {
1259     va_list args;
1260     va_start(args, sig);
1261     jdouble res = callStaticMethodV<jdouble>(clazz, methodName, sig, args);
1262     va_end(args);
1263     return res;
1264 }
1265 
1266 template <>
callStaticMethod(const char * className,const char * methodName)1267 Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethod<void>(const char *className, const char *methodName)
1268 {
1269     callStaticMethod<void>(className, methodName, "()V");
1270 }
1271 
1272 template <>
callStaticMethod(jclass clazz,const char * methodName)1273 Q_CORE_EXPORT void QJNIObjectPrivate::callStaticMethod<void>(jclass clazz, const char *methodName)
1274 {
1275     callStaticMethod<void>(clazz, methodName, "()V");
1276 }
1277 
1278 template <>
callStaticMethod(const char * className,const char * methodName)1279 Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(const char *className, const char *methodName)
1280 {
1281     return callStaticMethod<jboolean>(className, methodName, "()Z");
1282 }
1283 
1284 template <>
callStaticMethod(jclass clazz,const char * methodName)1285 Q_CORE_EXPORT jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(jclass clazz, const char *methodName)
1286 {
1287     return callStaticMethod<jboolean>(clazz, methodName, "()Z");
1288 }
1289 
1290 template <>
callStaticMethod(const char * className,const char * methodName)1291 Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(const char *className, const char *methodName)
1292 {
1293     return callStaticMethod<jbyte>(className, methodName, "()B");
1294 }
1295 
1296 template <>
callStaticMethod(jclass clazz,const char * methodName)1297 Q_CORE_EXPORT jbyte QJNIObjectPrivate::callStaticMethod<jbyte>(jclass clazz, const char *methodName)
1298 {
1299     return callStaticMethod<jbyte>(clazz, methodName, "()B");
1300 }
1301 
1302 template <>
callStaticMethod(const char * className,const char * methodName)1303 Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethod<jchar>(const char *className, const char *methodName)
1304 {
1305     return callStaticMethod<jchar>(className, methodName, "()C");
1306 }
1307 
1308 template <>
callStaticMethod(jclass clazz,const char * methodName)1309 Q_CORE_EXPORT jchar QJNIObjectPrivate::callStaticMethod<jchar>(jclass clazz, const char *methodName)
1310 {
1311     return callStaticMethod<jchar>(clazz, methodName, "()C");
1312 }
1313 
1314 template <>
callStaticMethod(const char * className,const char * methodName)1315 Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethod<jshort>(const char *className, const char *methodName)
1316 {
1317     return callStaticMethod<jshort>(className, methodName, "()S");
1318 }
1319 
1320 template <>
callStaticMethod(jclass clazz,const char * methodName)1321 Q_CORE_EXPORT jshort QJNIObjectPrivate::callStaticMethod<jshort>(jclass clazz, const char *methodName)
1322 {
1323     return callStaticMethod<jshort>(clazz, methodName, "()S");
1324 }
1325 
1326 template <>
callStaticMethod(const char * className,const char * methodName)1327 Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethod<jint>(const char *className, const char *methodName)
1328 {
1329     return callStaticMethod<jint>(className, methodName, "()I");
1330 }
1331 
1332 template <>
callStaticMethod(jclass clazz,const char * methodName)1333 Q_CORE_EXPORT jint QJNIObjectPrivate::callStaticMethod<jint>(jclass clazz, const char *methodName)
1334 {
1335     return callStaticMethod<jint>(clazz, methodName, "()I");
1336 }
1337 
1338 template <>
callStaticMethod(const char * className,const char * methodName)1339 Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethod<jlong>(const char *className, const char *methodName)
1340 {
1341     return callStaticMethod<jlong>(className, methodName, "()J");
1342 }
1343 
1344 template <>
callStaticMethod(jclass clazz,const char * methodName)1345 Q_CORE_EXPORT jlong QJNIObjectPrivate::callStaticMethod<jlong>(jclass clazz, const char *methodName)
1346 {
1347     return callStaticMethod<jlong>(clazz, methodName, "()J");
1348 }
1349 
1350 template <>
callStaticMethod(const char * className,const char * methodName)1351 Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(const char *className, const char *methodName)
1352 {
1353     return callStaticMethod<jfloat>(className, methodName, "()F");
1354 }
1355 
1356 template <>
callStaticMethod(jclass clazz,const char * methodName)1357 Q_CORE_EXPORT jfloat QJNIObjectPrivate::callStaticMethod<jfloat>(jclass clazz, const char *methodName)
1358 {
1359     return callStaticMethod<jfloat>(clazz, methodName, "()F");
1360 }
1361 
1362 template <>
callStaticMethod(const char * className,const char * methodName)1363 Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(const char *className, const char *methodName)
1364 {
1365     return callStaticMethod<jdouble>(className, methodName, "()D");
1366 }
1367 
1368 template <>
callStaticMethod(jclass clazz,const char * methodName)1369 Q_CORE_EXPORT jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(jclass clazz, const char *methodName)
1370 {
1371     return callStaticMethod<jdouble>(clazz, methodName, "()D");
1372 }
1373 
callObjectMethodV(const char * methodName,const char * sig,va_list args) const1374 QJNIObjectPrivate QJNIObjectPrivate::callObjectMethodV(const char *methodName,
1375                                                        const char *sig,
1376                                                        va_list args) const
1377 {
1378     QJNIEnvironmentPrivate env;
1379     jobject res = 0;
1380     jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig);
1381     if (id) {
1382         res = env->CallObjectMethodV(d->m_jobject, id, args);
1383         if (res && env->ExceptionCheck())
1384             res = 0;
1385     }
1386 
1387     QJNIObjectPrivate obj(res);
1388     env->DeleteLocalRef(res);
1389     return obj;
1390 }
1391 
callObjectMethod(const char * methodName,const char * sig,...) const1392 QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName,
1393                                                       const char *sig,
1394                                                       ...) const
1395 {
1396     va_list args;
1397     va_start(args, sig);
1398     QJNIObjectPrivate res = callObjectMethodV(methodName, sig, args);
1399     va_end(args);
1400     return res;
1401 }
1402 
1403 template <>
callObjectMethod(const char * methodName) const1404 Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jstring>(const char *methodName) const
1405 {
1406     return callObjectMethod(methodName, "()Ljava/lang/String;");
1407 }
1408 
1409 template <>
callObjectMethod(const char * methodName) const1410 Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jbooleanArray>(const char *methodName) const
1411 {
1412     return callObjectMethod(methodName, "()[Z");
1413 }
1414 
1415 template <>
callObjectMethod(const char * methodName) const1416 Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jbyteArray>(const char *methodName) const
1417 {
1418     return callObjectMethod(methodName, "()[B");
1419 }
1420 
1421 template <>
callObjectMethod(const char * methodName) const1422 Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jshortArray>(const char *methodName) const
1423 {
1424     return callObjectMethod(methodName, "()[S");
1425 }
1426 
1427 template <>
callObjectMethod(const char * methodName) const1428 Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jintArray>(const char *methodName) const
1429 {
1430     return callObjectMethod(methodName, "()[I");
1431 }
1432 
1433 template <>
callObjectMethod(const char * methodName) const1434 Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jlongArray>(const char *methodName) const
1435 {
1436     return callObjectMethod(methodName, "()[J");
1437 }
1438 
1439 template <>
callObjectMethod(const char * methodName) const1440 Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jfloatArray>(const char *methodName) const
1441 {
1442     return callObjectMethod(methodName, "()[F");
1443 }
1444 
1445 template <>
callObjectMethod(const char * methodName) const1446 Q_CORE_EXPORT QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod<jdoubleArray>(const char *methodName) const
1447 {
1448     return callObjectMethod(methodName, "()[D");
1449 }
1450 
callStaticObjectMethodV(const char * className,const char * methodName,const char * sig,va_list args)1451 QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethodV(const char *className,
1452                                                              const char *methodName,
1453                                                              const char *sig,
1454                                                              va_list args)
1455 {
1456     QJNIEnvironmentPrivate env;
1457     jobject res = 0;
1458     jclass clazz = loadClass(className, env);
1459     if (clazz) {
1460         jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true);
1461         if (id) {
1462             res = env->CallStaticObjectMethodV(clazz, id, args);
1463             if (res && env->ExceptionCheck())
1464                 res = 0;
1465         }
1466     }
1467 
1468     QJNIObjectPrivate obj(res);
1469     env->DeleteLocalRef(res);
1470     return obj;
1471 }
1472 
callStaticObjectMethod(const char * className,const char * methodName,const char * sig,...)1473 QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(const char *className,
1474                                                             const char *methodName,
1475                                                             const char *sig,
1476                                                             ...)
1477 {
1478     va_list args;
1479     va_start(args, sig);
1480     QJNIObjectPrivate res = callStaticObjectMethodV(className, methodName, sig, args);
1481     va_end(args);
1482     return res;
1483 }
1484 
callStaticObjectMethodV(jclass clazz,const char * methodName,const char * sig,va_list args)1485 QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethodV(jclass clazz,
1486                                                              const char *methodName,
1487                                                              const char *sig,
1488                                                              va_list args)
1489 {
1490     QJNIEnvironmentPrivate env;
1491     jobject res = 0;
1492     jmethodID id = getMethodID(env, clazz, methodName, sig, true);
1493     if (id) {
1494         res = env->CallStaticObjectMethodV(clazz, id, args);
1495         if (res && env->ExceptionCheck())
1496             res = 0;
1497     }
1498 
1499     QJNIObjectPrivate obj(res);
1500     env->DeleteLocalRef(res);
1501     return obj;
1502 }
1503 
callStaticObjectMethod(jclass clazz,const char * methodName,const char * sig,...)1504 QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(jclass clazz,
1505                                                             const char *methodName,
1506                                                             const char *sig,
1507                                                             ...)
1508 {
1509     va_list args;
1510     va_start(args, sig);
1511     QJNIObjectPrivate res = callStaticObjectMethodV(clazz, methodName, sig, args);
1512     va_end(args);
1513     return res;
1514 }
1515 
1516 template <>
getField(const char * fieldName) const1517 Q_CORE_EXPORT jboolean QJNIObjectPrivate::getField<jboolean>(const char *fieldName) const
1518 {
1519     QJNIEnvironmentPrivate env;
1520     jboolean res = 0;
1521     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Z");
1522     if (id)
1523         res = env->GetBooleanField(d->m_jobject, id);
1524 
1525     return res;
1526 }
1527 
1528 template <>
getField(const char * fieldName) const1529 Q_CORE_EXPORT jbyte QJNIObjectPrivate::getField<jbyte>(const char *fieldName) const
1530 {
1531     QJNIEnvironmentPrivate env;
1532     jbyte res = 0;
1533     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "B");
1534     if (id)
1535         res = env->GetByteField(d->m_jobject, id);
1536 
1537     return res;
1538 }
1539 
1540 template <>
getField(const char * fieldName) const1541 Q_CORE_EXPORT jchar QJNIObjectPrivate::getField<jchar>(const char *fieldName) const
1542 {
1543     QJNIEnvironmentPrivate env;
1544     jchar res = 0;
1545     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "C");
1546     if (id)
1547         res = env->GetCharField(d->m_jobject, id);
1548 
1549     return res;
1550 }
1551 
1552 template <>
getField(const char * fieldName) const1553 Q_CORE_EXPORT jshort QJNIObjectPrivate::getField<jshort>(const char *fieldName) const
1554 {
1555     QJNIEnvironmentPrivate env;
1556     jshort res = 0;
1557     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "S");
1558     if (id)
1559         res = env->GetShortField(d->m_jobject, id);
1560 
1561     return res;
1562 }
1563 
1564 template <>
getField(const char * fieldName) const1565 Q_CORE_EXPORT jint QJNIObjectPrivate::getField<jint>(const char *fieldName) const
1566 {
1567     QJNIEnvironmentPrivate env;
1568     jint res = 0;
1569     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "I");
1570     if (id)
1571         res = env->GetIntField(d->m_jobject, id);
1572 
1573     return res;
1574 }
1575 
1576 template <>
getField(const char * fieldName) const1577 Q_CORE_EXPORT jlong QJNIObjectPrivate::getField<jlong>(const char *fieldName) const
1578 {
1579     QJNIEnvironmentPrivate env;
1580     jlong res = 0;
1581     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "J");
1582     if (id)
1583         res = env->GetLongField(d->m_jobject, id);
1584 
1585     return res;
1586 }
1587 
1588 template <>
getField(const char * fieldName) const1589 Q_CORE_EXPORT jfloat QJNIObjectPrivate::getField<jfloat>(const char *fieldName) const
1590 {
1591     QJNIEnvironmentPrivate env;
1592     jfloat res = 0.f;
1593     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "F");
1594     if (id)
1595         res = env->GetFloatField(d->m_jobject, id);
1596 
1597     return res;
1598 }
1599 
1600 template <>
getField(const char * fieldName) const1601 Q_CORE_EXPORT jdouble QJNIObjectPrivate::getField<jdouble>(const char *fieldName) const
1602 {
1603     QJNIEnvironmentPrivate env;
1604     jdouble res = 0.;
1605     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "D");
1606     if (id)
1607         res = env->GetDoubleField(d->m_jobject, id);
1608 
1609     return res;
1610 }
1611 
1612 template <>
getStaticField(jclass clazz,const char * fieldName)1613 Q_CORE_EXPORT jboolean QJNIObjectPrivate::getStaticField<jboolean>(jclass clazz, const char *fieldName)
1614 {
1615     QJNIEnvironmentPrivate env;
1616     jboolean res = 0;
1617     jfieldID id = getFieldID(env, clazz, fieldName, "Z", true);
1618     if (id)
1619         res = env->GetStaticBooleanField(clazz, id);
1620 
1621     return res;
1622 }
1623 
1624 template <>
getStaticField(const char * className,const char * fieldName)1625 Q_CORE_EXPORT jboolean QJNIObjectPrivate::getStaticField<jboolean>(const char *className, const char *fieldName)
1626 {
1627     QJNIEnvironmentPrivate env;
1628     jclass clazz = loadClass(className, env);
1629     if (clazz == 0)
1630         return 0;
1631 
1632     jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "Z", true);
1633     if (id == 0)
1634         return 0;
1635 
1636     return env->GetStaticBooleanField(clazz, id);
1637 }
1638 
1639 template <>
getStaticField(jclass clazz,const char * fieldName)1640 Q_CORE_EXPORT jbyte QJNIObjectPrivate::getStaticField<jbyte>(jclass clazz, const char *fieldName)
1641 {
1642     QJNIEnvironmentPrivate env;
1643     jbyte res = 0;
1644     jfieldID id = getFieldID(env, clazz, fieldName, "B", true);
1645     if (id)
1646         res = env->GetStaticByteField(clazz, id);
1647 
1648     return res;
1649 }
1650 
1651 template <>
getStaticField(const char * className,const char * fieldName)1652 Q_CORE_EXPORT jbyte QJNIObjectPrivate::getStaticField<jbyte>(const char *className, const char *fieldName)
1653 {
1654     QJNIEnvironmentPrivate env;
1655     jclass clazz = loadClass(className, env);
1656     if (clazz == 0)
1657         return 0;
1658 
1659     jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "B", true);
1660     if (id == 0)
1661         return 0;
1662 
1663     return env->GetStaticByteField(clazz, id);
1664 }
1665 
1666 template <>
getStaticField(jclass clazz,const char * fieldName)1667 Q_CORE_EXPORT jchar QJNIObjectPrivate::getStaticField<jchar>(jclass clazz, const char *fieldName)
1668 {
1669     QJNIEnvironmentPrivate env;
1670     jchar res = 0;
1671     jfieldID id = getFieldID(env, clazz, fieldName, "C", true);
1672     if (id)
1673         res = env->GetStaticCharField(clazz, id);
1674 
1675     return res;
1676 }
1677 
1678 template <>
getStaticField(const char * className,const char * fieldName)1679 Q_CORE_EXPORT jchar QJNIObjectPrivate::getStaticField<jchar>(const char *className, const char *fieldName)
1680 {
1681     QJNIEnvironmentPrivate env;
1682     jclass clazz = loadClass(className, env);
1683     if (clazz == 0)
1684         return 0;
1685 
1686     jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "C", true);
1687     if (id == 0)
1688         return 0;
1689 
1690     return env->GetStaticCharField(clazz, id);
1691 }
1692 
1693 template <>
getStaticField(jclass clazz,const char * fieldName)1694 Q_CORE_EXPORT jshort QJNIObjectPrivate::getStaticField<jshort>(jclass clazz, const char *fieldName)
1695 {
1696     QJNIEnvironmentPrivate env;
1697     jshort res = 0;
1698     jfieldID id = getFieldID(env, clazz, fieldName, "S", true);
1699     if (id)
1700         res = env->GetStaticShortField(clazz, id);
1701 
1702     return res;
1703 }
1704 
1705 template <>
getStaticField(const char * className,const char * fieldName)1706 Q_CORE_EXPORT jshort QJNIObjectPrivate::getStaticField<jshort>(const char *className, const char *fieldName)
1707 {
1708     QJNIEnvironmentPrivate env;
1709     jclass clazz = loadClass(className, env);
1710     if (clazz == 0)
1711         return 0;
1712 
1713     jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "S", true);
1714     if (id == 0)
1715         return 0;
1716 
1717     return env->GetStaticShortField(clazz, id);
1718 }
1719 
1720 template <>
getStaticField(jclass clazz,const char * fieldName)1721 Q_CORE_EXPORT jint QJNIObjectPrivate::getStaticField<jint>(jclass clazz, const char *fieldName)
1722 {
1723     QJNIEnvironmentPrivate env;
1724     jint res = 0;
1725     jfieldID id = getFieldID(env, clazz, fieldName, "I", true);
1726     if (id)
1727         res = env->GetStaticIntField(clazz, id);
1728 
1729     return res;
1730 }
1731 
1732 template <>
getStaticField(const char * className,const char * fieldName)1733 Q_CORE_EXPORT jint QJNIObjectPrivate::getStaticField<jint>(const char *className, const char *fieldName)
1734 {
1735     QJNIEnvironmentPrivate env;
1736     jclass clazz = loadClass(className, env);
1737     if (clazz == 0)
1738         return 0;
1739 
1740     jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "I", true);
1741     if (id == 0)
1742         return 0;
1743 
1744     return env->GetStaticIntField(clazz, id);
1745 }
1746 
1747 template <>
getStaticField(jclass clazz,const char * fieldName)1748 Q_CORE_EXPORT jlong QJNIObjectPrivate::getStaticField<jlong>(jclass clazz, const char *fieldName)
1749 {
1750     QJNIEnvironmentPrivate env;
1751     jlong res = 0;
1752     jfieldID id = getFieldID(env, clazz, fieldName, "J", true);
1753     if (id)
1754         res = env->GetStaticLongField(clazz, id);
1755 
1756     return res;
1757 }
1758 
1759 template <>
getStaticField(const char * className,const char * fieldName)1760 Q_CORE_EXPORT jlong QJNIObjectPrivate::getStaticField<jlong>(const char *className, const char *fieldName)
1761 {
1762     QJNIEnvironmentPrivate env;
1763     jclass clazz = loadClass(className, env);
1764     if (clazz == 0)
1765         return 0;
1766 
1767     jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "J", true);
1768     if (id == 0)
1769         return 0;
1770 
1771     return env->GetStaticLongField(clazz, id);
1772 }
1773 
1774 template <>
getStaticField(jclass clazz,const char * fieldName)1775 Q_CORE_EXPORT jfloat QJNIObjectPrivate::getStaticField<jfloat>(jclass clazz, const char *fieldName)
1776 {
1777     QJNIEnvironmentPrivate env;
1778     jfloat res = 0.f;
1779     jfieldID id = getFieldID(env, clazz, fieldName, "F", true);
1780     if (id)
1781         res = env->GetStaticFloatField(clazz, id);
1782 
1783     return res;
1784 }
1785 
1786 template <>
getStaticField(const char * className,const char * fieldName)1787 Q_CORE_EXPORT jfloat QJNIObjectPrivate::getStaticField<jfloat>(const char *className, const char *fieldName)
1788 {
1789     QJNIEnvironmentPrivate env;
1790     jclass clazz = loadClass(className, env);
1791     if (clazz == 0)
1792         return 0.f;
1793 
1794     jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "F", true);
1795     if (id == 0)
1796         return 0.f;
1797 
1798     return env->GetStaticFloatField(clazz, id);
1799 }
1800 
1801 template <>
getStaticField(jclass clazz,const char * fieldName)1802 Q_CORE_EXPORT jdouble QJNIObjectPrivate::getStaticField<jdouble>(jclass clazz, const char *fieldName)
1803 {
1804     QJNIEnvironmentPrivate env;
1805     jdouble res = 0.;
1806     jfieldID id = getFieldID(env, clazz, fieldName, "D", true);
1807     if (id)
1808         res = env->GetStaticDoubleField(clazz, id);
1809 
1810     return res;
1811 }
1812 
1813 template <>
getStaticField(const char * className,const char * fieldName)1814 Q_CORE_EXPORT jdouble QJNIObjectPrivate::getStaticField<jdouble>(const char *className, const char *fieldName)
1815 {
1816     QJNIEnvironmentPrivate env;
1817     jclass clazz = loadClass(className, env);
1818     if (clazz == 0)
1819         return 0.;
1820 
1821     jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "D", true);
1822     if (id == 0)
1823         return 0.;
1824 
1825     return env->GetStaticDoubleField(clazz, id);
1826 }
1827 
getObjectField(const char * fieldName,const char * sig) const1828 QJNIObjectPrivate QJNIObjectPrivate::getObjectField(const char *fieldName,
1829                                                     const char *sig) const
1830 {
1831     QJNIEnvironmentPrivate env;
1832     jobject res = 0;
1833     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig);
1834     if (id) {
1835         res = env->GetObjectField(d->m_jobject, id);
1836         if (res && env->ExceptionCheck())
1837             res = 0;
1838     }
1839 
1840     QJNIObjectPrivate obj(res);
1841     env->DeleteLocalRef(res);
1842     return obj;
1843 }
1844 
getStaticObjectField(const char * className,const char * fieldName,const char * sig)1845 QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(const char *className,
1846                                                           const char *fieldName,
1847                                                           const char *sig)
1848 {
1849     QJNIEnvironmentPrivate env;
1850     jclass clazz = loadClass(className, env);
1851     if (clazz == 0)
1852         return QJNIObjectPrivate();
1853 
1854     jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, sig, true);
1855     if (id == 0)
1856         return QJNIObjectPrivate();
1857 
1858     jobject res = env->GetStaticObjectField(clazz, id);
1859     if (res && env->ExceptionCheck())
1860         res = 0;
1861 
1862     QJNIObjectPrivate obj(res);
1863     env->DeleteLocalRef(res);
1864     return obj;
1865 }
1866 
getStaticObjectField(jclass clazz,const char * fieldName,const char * sig)1867 QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz,
1868                                                           const char *fieldName,
1869                                                           const char *sig)
1870 {
1871     QJNIEnvironmentPrivate env;
1872     jobject res = 0;
1873     jfieldID id = getFieldID(env, clazz, fieldName, sig, true);
1874     if (id) {
1875         res = env->GetStaticObjectField(clazz, id);
1876         if (res && env->ExceptionCheck())
1877             res = 0;
1878     }
1879 
1880     QJNIObjectPrivate obj(res);
1881     env->DeleteLocalRef(res);
1882     return obj;
1883 }
1884 
1885 template <>
setField(const char * fieldName,jboolean value)1886 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jboolean>(const char *fieldName, jboolean value)
1887 {
1888     QJNIEnvironmentPrivate env;
1889     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Z");
1890     if (id)
1891         env->SetBooleanField(d->m_jobject, id, value);
1892 
1893 }
1894 
1895 template <>
setField(const char * fieldName,jbyte value)1896 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jbyte>(const char *fieldName, jbyte value)
1897 {
1898     QJNIEnvironmentPrivate env;
1899     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "B");
1900     if (id)
1901         env->SetByteField(d->m_jobject, id, value);
1902 
1903 }
1904 
1905 template <>
setField(const char * fieldName,jchar value)1906 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jchar>(const char *fieldName, jchar value)
1907 {
1908     QJNIEnvironmentPrivate env;
1909     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "C");
1910     if (id)
1911         env->SetCharField(d->m_jobject, id, value);
1912 
1913 }
1914 
1915 template <>
setField(const char * fieldName,jshort value)1916 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jshort>(const char *fieldName, jshort value)
1917 {
1918     QJNIEnvironmentPrivate env;
1919     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "S");
1920     if (id)
1921         env->SetShortField(d->m_jobject, id, value);
1922 
1923 }
1924 
1925 template <>
setField(const char * fieldName,jint value)1926 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jint>(const char *fieldName, jint value)
1927 {
1928     QJNIEnvironmentPrivate env;
1929     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "I");
1930     if (id)
1931         env->SetIntField(d->m_jobject, id, value);
1932 
1933 }
1934 
1935 template <>
setField(const char * fieldName,jlong value)1936 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jlong>(const char *fieldName, jlong value)
1937 {
1938     QJNIEnvironmentPrivate env;
1939     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "J");
1940     if (id)
1941         env->SetLongField(d->m_jobject, id, value);
1942 
1943 }
1944 
1945 template <>
setField(const char * fieldName,jfloat value)1946 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jfloat>(const char *fieldName, jfloat value)
1947 {
1948     QJNIEnvironmentPrivate env;
1949     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "F");
1950     if (id)
1951         env->SetFloatField(d->m_jobject, id, value);
1952 
1953 }
1954 
1955 template <>
setField(const char * fieldName,jdouble value)1956 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jdouble>(const char *fieldName, jdouble value)
1957 {
1958     QJNIEnvironmentPrivate env;
1959     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "D");
1960     if (id)
1961         env->SetDoubleField(d->m_jobject, id, value);
1962 
1963 }
1964 
1965 template <>
setField(const char * fieldName,jbooleanArray value)1966 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jbooleanArray>(const char *fieldName, jbooleanArray value)
1967 {
1968     QJNIEnvironmentPrivate env;
1969     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[Z");
1970     if (id)
1971         env->SetObjectField(d->m_jobject, id, value);
1972 
1973 }
1974 
1975 template <>
setField(const char * fieldName,jbyteArray value)1976 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jbyteArray>(const char *fieldName, jbyteArray value)
1977 {
1978     QJNIEnvironmentPrivate env;
1979     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[B");
1980     if (id)
1981         env->SetObjectField(d->m_jobject, id, value);
1982 
1983 }
1984 
1985 template <>
setField(const char * fieldName,jcharArray value)1986 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jcharArray>(const char *fieldName, jcharArray value)
1987 {
1988     QJNIEnvironmentPrivate env;
1989     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[C");
1990     if (id)
1991         env->SetObjectField(d->m_jobject, id, value);
1992 
1993 }
1994 
1995 template <>
setField(const char * fieldName,jshortArray value)1996 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jshortArray>(const char *fieldName, jshortArray value)
1997 {
1998     QJNIEnvironmentPrivate env;
1999     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[S");
2000     if (id)
2001         env->SetObjectField(d->m_jobject, id, value);
2002 
2003 }
2004 
2005 template <>
setField(const char * fieldName,jintArray value)2006 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jintArray>(const char *fieldName, jintArray value)
2007 {
2008     QJNIEnvironmentPrivate env;
2009     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[I");
2010     if (id)
2011         env->SetObjectField(d->m_jobject, id, value);
2012 
2013 }
2014 
2015 template <>
setField(const char * fieldName,jlongArray value)2016 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jlongArray>(const char *fieldName, jlongArray value)
2017 {
2018     QJNIEnvironmentPrivate env;
2019     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[J");
2020     if (id)
2021         env->SetObjectField(d->m_jobject, id, value);
2022 
2023 }
2024 
2025 template <>
setField(const char * fieldName,jfloatArray value)2026 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jfloatArray>(const char *fieldName, jfloatArray value)
2027 {
2028     QJNIEnvironmentPrivate env;
2029     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[F");
2030     if (id)
2031         env->SetObjectField(d->m_jobject, id, value);
2032 
2033 }
2034 
2035 template <>
setField(const char * fieldName,jdoubleArray value)2036 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jdoubleArray>(const char *fieldName, jdoubleArray value)
2037 {
2038     QJNIEnvironmentPrivate env;
2039     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[D");
2040     if (id)
2041         env->SetObjectField(d->m_jobject, id, value);
2042 
2043 }
2044 
2045 template <>
setField(const char * fieldName,jstring value)2046 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jstring>(const char *fieldName, jstring value)
2047 {
2048     QJNIEnvironmentPrivate env;
2049     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Ljava/lang/String;");
2050     if (id)
2051         env->SetObjectField(d->m_jobject, id, value);
2052 
2053 }
2054 
2055 template <>
setField(const char * fieldName,const char * sig,jobject value)2056 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jobject>(const char *fieldName,
2057                                           const char *sig,
2058                                           jobject value)
2059 {
2060     QJNIEnvironmentPrivate env;
2061     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig);
2062     if (id)
2063         env->SetObjectField(d->m_jobject, id, value);
2064 
2065 }
2066 
2067 template <>
setField(const char * fieldName,const char * sig,jobjectArray value)2068 Q_CORE_EXPORT void QJNIObjectPrivate::setField<jobjectArray>(const char *fieldName,
2069                                                const char *sig,
2070                                                jobjectArray value)
2071 {
2072     QJNIEnvironmentPrivate env;
2073     jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig);
2074     if (id)
2075         env->SetObjectField(d->m_jobject, id, value);
2076 
2077 }
2078 
2079 template <>
setStaticField(jclass clazz,const char * fieldName,jboolean value)2080 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jboolean>(jclass clazz,
2081                                                  const char *fieldName,
2082                                                  jboolean value)
2083 {
2084     QJNIEnvironmentPrivate env;
2085     jfieldID id = getFieldID(env, clazz, fieldName, "Z", true);
2086     if (id)
2087         env->SetStaticBooleanField(clazz, id, value);
2088 }
2089 
2090 template <>
setStaticField(const char * className,const char * fieldName,jboolean value)2091 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jboolean>(const char *className,
2092                                                  const char *fieldName,
2093                                                  jboolean value)
2094 {
2095     QJNIEnvironmentPrivate env;
2096     jclass clazz = loadClass(className, env);
2097     if (clazz == 0)
2098         return;
2099 
2100     jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "Z", true);
2101     if (id == 0)
2102         return;
2103 
2104     env->SetStaticBooleanField(clazz, id, value);
2105 }
2106 
2107 template <>
setStaticField(jclass clazz,const char * fieldName,jbyte value)2108 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jbyte>(jclass clazz,
2109                                               const char *fieldName,
2110                                               jbyte value)
2111 {
2112     QJNIEnvironmentPrivate env;
2113     jfieldID id = getFieldID(env, clazz, fieldName, "B", true);
2114     if (id)
2115         env->SetStaticByteField(clazz, id, value);
2116 }
2117 
2118 template <>
setStaticField(const char * className,const char * fieldName,jbyte value)2119 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jbyte>(const char *className,
2120                                               const char *fieldName,
2121                                               jbyte value)
2122 {
2123     QJNIEnvironmentPrivate env;
2124     jclass clazz = loadClass(className, env);
2125     if (clazz == 0)
2126         return;
2127 
2128     jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "B", true);
2129     if (id == 0)
2130         return;
2131 
2132     env->SetStaticByteField(clazz, id, value);
2133 }
2134 
2135 template <>
setStaticField(jclass clazz,const char * fieldName,jchar value)2136 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jchar>(jclass clazz,
2137                                               const char *fieldName,
2138                                               jchar value)
2139 {
2140     QJNIEnvironmentPrivate env;
2141     jfieldID id = getFieldID(env, clazz, fieldName, "C", true);
2142     if (id)
2143         env->SetStaticCharField(clazz, id, value);
2144 }
2145 
2146 template <>
setStaticField(const char * className,const char * fieldName,jchar value)2147 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jchar>(const char *className,
2148                                               const char *fieldName,
2149                                               jchar value)
2150 {
2151     QJNIEnvironmentPrivate env;
2152     jclass clazz = loadClass(className, env);
2153     if (clazz == 0)
2154         return;
2155 
2156     jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "C", true);
2157     if (id == 0)
2158         return;
2159 
2160     env->SetStaticCharField(clazz, id, value);
2161 }
2162 
2163 template <>
setStaticField(jclass clazz,const char * fieldName,jshort value)2164 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jshort>(jclass clazz,
2165                                                const char *fieldName,
2166                                                jshort value)
2167 {
2168     QJNIEnvironmentPrivate env;
2169     jfieldID id = getFieldID(env, clazz, fieldName, "S", true);
2170     if (id)
2171         env->SetStaticShortField(clazz, id, value);
2172 }
2173 
2174 template <>
setStaticField(const char * className,const char * fieldName,jshort value)2175 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jshort>(const char *className,
2176                                                const char *fieldName,
2177                                                jshort value)
2178 {
2179     QJNIEnvironmentPrivate env;
2180     jclass clazz = loadClass(className, env);
2181     if (clazz == 0)
2182         return;
2183 
2184     jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "S", true);
2185     if (id == 0)
2186         return;
2187 
2188     env->SetStaticShortField(clazz, id, value);
2189 }
2190 
2191 template <>
setStaticField(jclass clazz,const char * fieldName,jint value)2192 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jint>(jclass clazz,
2193                                              const char *fieldName,
2194                                              jint value)
2195 {
2196     QJNIEnvironmentPrivate env;
2197     jfieldID id = getFieldID(env, clazz, fieldName, "I", true);
2198     if (id)
2199         env->SetStaticIntField(clazz, id, value);
2200 }
2201 
2202 template <>
setStaticField(const char * className,const char * fieldName,jint value)2203 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jint>(const char *className,
2204                                              const char *fieldName,
2205                                              jint value)
2206 {
2207     QJNIEnvironmentPrivate env;
2208     jclass clazz = loadClass(className, env);
2209     if (clazz == 0)
2210         return;
2211 
2212     jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "I", true);
2213     if (id == 0)
2214         return;
2215 
2216     env->SetStaticIntField(clazz, id, value);
2217 }
2218 
2219 template <>
setStaticField(jclass clazz,const char * fieldName,jlong value)2220 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jlong>(jclass clazz,
2221                                               const char *fieldName,
2222                                               jlong value)
2223 {
2224     QJNIEnvironmentPrivate env;
2225     jfieldID id = getFieldID(env, clazz, fieldName, "J", true);
2226     if (id)
2227         env->SetStaticLongField(clazz, id, value);
2228 }
2229 
2230 template <>
setStaticField(const char * className,const char * fieldName,jlong value)2231 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jlong>(const char *className,
2232                                               const char *fieldName,
2233                                               jlong value)
2234 {
2235     QJNIEnvironmentPrivate env;
2236     jclass clazz = loadClass(className, env);
2237     if (clazz == 0)
2238         return;
2239 
2240     jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "J", true);
2241     if (id == 0)
2242         return;
2243 
2244     env->SetStaticLongField(clazz, id, value);
2245 }
2246 
2247 template <>
setStaticField(jclass clazz,const char * fieldName,jfloat value)2248 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jfloat>(jclass clazz,
2249                                                const char *fieldName,
2250                                                jfloat value)
2251 {
2252     QJNIEnvironmentPrivate env;
2253     jfieldID id = getFieldID(env, clazz, fieldName, "F", true);
2254     if (id)
2255         env->SetStaticFloatField(clazz, id, value);
2256 }
2257 
2258 template <>
setStaticField(const char * className,const char * fieldName,jfloat value)2259 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jfloat>(const char *className,
2260                                                const char *fieldName,
2261                                                jfloat value)
2262 {
2263     QJNIEnvironmentPrivate env;
2264     jclass clazz = loadClass(className, env);
2265     if (clazz == 0)
2266         return;
2267 
2268     jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "F", true);
2269     if (id == 0)
2270         return;
2271 
2272     env->SetStaticFloatField(clazz, id, value);
2273 }
2274 
2275 template <>
setStaticField(jclass clazz,const char * fieldName,jdouble value)2276 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jdouble>(jclass clazz,
2277                                                 const char *fieldName,
2278                                                 jdouble value)
2279 {
2280     QJNIEnvironmentPrivate env;
2281     jfieldID id = getFieldID(env, clazz, fieldName, "D", true);
2282     if (id)
2283         env->SetStaticDoubleField(clazz, id, value);
2284 }
2285 
2286 template <>
setStaticField(const char * className,const char * fieldName,jdouble value)2287 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jdouble>(const char *className,
2288                                                 const char *fieldName,
2289                                                 jdouble value)
2290 {
2291     QJNIEnvironmentPrivate env;
2292     jclass clazz = loadClass(className, env);
2293     if (clazz == 0)
2294         return;
2295 
2296     jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "D", true);
2297     if (id == 0)
2298         return;
2299 
2300     env->SetStaticDoubleField(clazz, id, value);
2301 }
2302 
2303 template <>
setStaticField(jclass clazz,const char * fieldName,const char * sig,jobject value)2304 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jobject>(jclass clazz,
2305                                                 const char *fieldName,
2306                                                 const char *sig,
2307                                                 jobject value)
2308 {
2309     QJNIEnvironmentPrivate env;
2310     jfieldID id = getFieldID(env, clazz, fieldName, sig, true);
2311     if (id)
2312         env->SetStaticObjectField(clazz, id, value);
2313 }
2314 
2315 template <>
setStaticField(const char * className,const char * fieldName,const char * sig,jobject value)2316 Q_CORE_EXPORT void QJNIObjectPrivate::setStaticField<jobject>(const char *className,
2317                                                 const char *fieldName,
2318                                                 const char *sig,
2319                                                 jobject value)
2320 {
2321     QJNIEnvironmentPrivate env;
2322     jclass clazz = loadClass(className, env);
2323     if (clazz == 0)
2324         return;
2325 
2326     jfieldID id = getCachedFieldID(env, clazz, className, fieldName, sig, true);
2327     if (id == 0)
2328         return;
2329 
2330     env->SetStaticObjectField(clazz, id, value);
2331 }
2332 
fromString(const QString & string)2333 QJNIObjectPrivate QJNIObjectPrivate::fromString(const QString &string)
2334 {
2335     QJNIEnvironmentPrivate env;
2336     jstring res = env->NewString(reinterpret_cast<const jchar*>(string.constData()),
2337                                         string.length());
2338     QJNIObjectPrivate obj(res);
2339     env->DeleteLocalRef(res);
2340     return obj;
2341 }
2342 
toString() const2343 QString QJNIObjectPrivate::toString() const
2344 {
2345     if (!isValid())
2346         return QString();
2347 
2348     QJNIObjectPrivate string = callObjectMethod<jstring>("toString");
2349     return qt_convertJString(static_cast<jstring>(string.object()));
2350 }
2351 
isClassAvailable(const char * className)2352 bool QJNIObjectPrivate::isClassAvailable(const char *className)
2353 {
2354     QJNIEnvironmentPrivate env;
2355 
2356     if (!env)
2357         return false;
2358 
2359     jclass clazz = loadClass(className, env);
2360     return (clazz != 0);
2361 }
2362 
isValid() const2363 bool QJNIObjectPrivate::isValid() const
2364 {
2365     return d->m_jobject;
2366 }
2367 
fromLocalRef(jobject lref)2368 QJNIObjectPrivate QJNIObjectPrivate::fromLocalRef(jobject lref)
2369 {
2370     QJNIObjectPrivate o(lref);
2371     QJNIEnvironmentPrivate()->DeleteLocalRef(lref);
2372     return o;
2373 }
2374 
isSameObject(jobject obj) const2375 bool QJNIObjectPrivate::isSameObject(jobject obj) const
2376 {
2377     QJNIEnvironmentPrivate env;
2378     return env->IsSameObject(d->m_jobject, obj);
2379 }
2380 
isSameObject(const QJNIObjectPrivate & other) const2381 bool QJNIObjectPrivate::isSameObject(const QJNIObjectPrivate &other) const
2382 {
2383     return isSameObject(other.d->m_jobject);
2384 }
2385 
2386 QT_END_NAMESPACE
2387