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 // 41 // W A R N I N G 42 // ------------- 43 // 44 // This file is not part of the Qt API. It exists purely as an 45 // implementation detail. This header file may change from version to 46 // version without notice, or even be removed. 47 // 48 // We mean it. 49 // 50 51 #ifndef QJNI_P_H 52 #define QJNI_P_H 53 54 #include <jni.h> 55 #include <QtCore/private/qglobal_p.h> 56 #include <QtCore/qsharedpointer.h> 57 58 QT_BEGIN_NAMESPACE 59 60 struct Q_CORE_EXPORT QJNILocalRefDeleter 61 { 62 static void cleanup(jobject obj); 63 }; 64 65 // To simplify this we only define it for jobjects. 66 typedef QScopedPointer<_jobject, QJNILocalRefDeleter> QJNIScopedLocalRef; 67 68 class Q_CORE_EXPORT QJNIEnvironmentPrivate 69 { 70 public: 71 QJNIEnvironmentPrivate(); 72 ~QJNIEnvironmentPrivate(); 73 JNIEnv *operator->(); 74 operator JNIEnv*() const; 75 static jclass findClass(const char *className, JNIEnv *env = 0); 76 77 private: 78 friend class QAndroidJniEnvironment; 79 Q_DISABLE_COPY_MOVE(QJNIEnvironmentPrivate) 80 JNIEnv *jniEnv; 81 }; 82 83 class Q_CORE_EXPORT QJNIObjectData 84 { 85 public: 86 QJNIObjectData(); 87 ~QJNIObjectData(); 88 jobject m_jobject; 89 jclass m_jclass; 90 bool m_own_jclass; 91 QByteArray m_className; 92 }; 93 94 class Q_CORE_EXPORT QJNIObjectPrivate 95 { 96 public: 97 QJNIObjectPrivate(); 98 explicit QJNIObjectPrivate(const char *className); 99 QJNIObjectPrivate(const char *className, const char *sig, ...); 100 explicit QJNIObjectPrivate(jclass clazz); 101 QJNIObjectPrivate(jclass clazz, const char *sig, ...); 102 // In most cases you should never call this function with a local ref. unless you intend 103 // to manage the local ref. yourself. 104 // NOTE: see fromLocalRef() for converting a local ref. to QJNIObjectPrivate. 105 explicit QJNIObjectPrivate(jobject globalRef); 106 107 template <typename T> 108 T callMethod(const char *methodName, 109 const char *sig, 110 ...) const; 111 template <typename T> 112 T callMethod(const char *methodName) const; 113 template <typename T> 114 QJNIObjectPrivate callObjectMethod(const char *methodName) const; 115 QJNIObjectPrivate callObjectMethod(const char *methodName, 116 const char *sig, 117 ...) const; 118 template <typename T> 119 static T callStaticMethod(const char *className, 120 const char *methodName, 121 const char *sig, ...); 122 template <typename T> 123 static T callStaticMethod(const char *className, 124 const char *methodName); 125 template <typename T> 126 static T callStaticMethod(jclass clazz, 127 const char *methodName, 128 const char *sig, ...); 129 template <typename T> 130 static T callStaticMethod(jclass clazz, 131 const char *methodName); 132 static QJNIObjectPrivate callStaticObjectMethod(const char *className, 133 const char *methodName, 134 const char *sig, ...); 135 136 static QJNIObjectPrivate callStaticObjectMethod(jclass clazz, 137 const char *methodName, 138 const char *sig, ...); 139 140 template <typename T> 141 T getField(const char *fieldName) const; 142 template <typename T> 143 static T getStaticField(const char *className, const char *fieldName); 144 template <typename T> 145 static T getStaticField(jclass clazz, const char *fieldName); 146 147 QJNIObjectPrivate getObjectField(const char *fieldName, const char *sig) const; 148 static QJNIObjectPrivate getStaticObjectField(const char *className, 149 const char *fieldName, 150 const char *sig); 151 static QJNIObjectPrivate getStaticObjectField(jclass clazz, 152 const char *fieldName, 153 const char *sig); 154 155 template <typename T> 156 void setField(const char *fieldName, T value); 157 template <typename T> 158 void setField(const char *fieldName, const char *sig, T value); 159 template <typename T> 160 static void setStaticField(const char *className, 161 const char *fieldName, 162 T value); 163 template <typename T> 164 static void setStaticField(const char *className, 165 const char *fieldName, 166 const char *sig, 167 T value); 168 template <typename T> 169 static void setStaticField(jclass clazz, 170 const char *fieldName, 171 const char *sig, 172 T value); 173 174 template <typename T> 175 static void setStaticField(jclass clazz, 176 const char *fieldName, 177 T value); 178 179 static QJNIObjectPrivate fromString(const QString &string); 180 QString toString() const; 181 182 static bool isClassAvailable(const char *className); 183 bool isValid() const; 184 jobject object() const { return d->m_jobject; } 185 186 template <typename T> 187 inline QJNIObjectPrivate &operator=(T o) 188 { 189 jobject jobj = static_cast<jobject>(o); 190 if (!isSameObject(jobj)) { 191 d = QSharedPointer<QJNIObjectData>::create(); 192 if (jobj) { 193 QJNIEnvironmentPrivate env; 194 d->m_jobject = env->NewGlobalRef(jobj); 195 jclass objectClass = env->GetObjectClass(jobj); 196 d->m_jclass = static_cast<jclass>(env->NewGlobalRef(objectClass)); 197 env->DeleteLocalRef(objectClass); 198 } 199 } 200 201 return *this; 202 } 203 204 // This function takes ownership of the jobject and releases the local ref. before returning. 205 static QJNIObjectPrivate fromLocalRef(jobject lref); 206 207 private: 208 friend class QAndroidJniObject; 209 210 struct QVaListPrivate { operator va_list &() const { return m_args; } va_list &m_args; }; 211 212 QJNIObjectPrivate(const char *className, const char *sig, const QVaListPrivate &args); 213 QJNIObjectPrivate(jclass clazz, const char *sig, const QVaListPrivate &args); 214 215 template <typename T> 216 T callMethodV(const char *methodName, 217 const char *sig, 218 va_list args) const; 219 QJNIObjectPrivate callObjectMethodV(const char *methodName, 220 const char *sig, 221 va_list args) const; 222 template <typename T> 223 static T callStaticMethodV(const char *className, 224 const char *methodName, 225 const char *sig, 226 va_list args); 227 template <typename T> 228 static T callStaticMethodV(jclass clazz, 229 const char *methodName, 230 const char *sig, 231 va_list args); 232 static QJNIObjectPrivate callStaticObjectMethodV(const char *className, 233 const char *methodName, 234 const char *sig, 235 va_list args); 236 237 static QJNIObjectPrivate callStaticObjectMethodV(jclass clazz, 238 const char *methodName, 239 const char *sig, 240 va_list args); 241 242 bool isSameObject(jobject obj) const; 243 bool isSameObject(const QJNIObjectPrivate &other) const; 244 245 friend bool operator==(const QJNIObjectPrivate &, const QJNIObjectPrivate &); 246 friend bool operator!=(const QJNIObjectPrivate&, const QJNIObjectPrivate&); 247 template <typename T> friend bool operator!=(const QJNIObjectPrivate&, T); 248 template <typename T> friend bool operator==(const QJNIObjectPrivate&, T); 249 template <typename T> friend bool operator!=(T, const QJNIObjectPrivate&); 250 template <typename T> friend bool operator==(T, const QJNIObjectPrivate&); 251 252 QSharedPointer<QJNIObjectData> d; 253 }; 254 255 inline bool operator==(const QJNIObjectPrivate&obj1, const QJNIObjectPrivate&obj2) 256 { 257 return obj1.isSameObject(obj2); 258 } 259 260 inline bool operator!=(const QJNIObjectPrivate&obj1, const QJNIObjectPrivate&obj2) 261 { 262 return !obj1.isSameObject(obj2); 263 } 264 265 template <typename T> 266 inline bool operator==(const QJNIObjectPrivate &obj1, T obj2) 267 { 268 return obj1.isSameObject(static_cast<jobject>(obj2)); 269 } 270 271 template <typename T> 272 inline bool operator==(T obj1, const QJNIObjectPrivate &obj2) 273 { 274 return obj2.isSameObject(static_cast<jobject>(obj1)); 275 } 276 277 template <typename T> 278 inline bool operator!=(const QJNIObjectPrivate &obj1, T obj2) 279 { 280 return !obj1.isSameObject(obj2); 281 } 282 283 template <typename T> 284 inline bool operator!=(T obj1, const QJNIObjectPrivate &obj2) 285 { 286 return !obj2.isSameObject(obj1); 287 } 288 289 QT_END_NAMESPACE 290 291 #endif // QJNI_P_H 292