Make QJniObject and QJniEnvironment public API

As part of Qt 6 restructring for the extras modules, this change exposes
the Jni APIs which are very important for Android platform. This patch
adds the APIs QJniObject, QJniEnvironment, QJniExceptionCleaner based
from private QtCore and QtAndroidExtras.

The Jni interface is cross-platform which justifies the name, but
currently, this API is used mainly for Android, and the naming comes
generic without Android keyword to avoid any future limitation on
supporting other platforms.

[ChangeLog][QtCore] Add new QJniObject, QJniEnvironment and
QJniExceptionCleaner APIs.

Task-number: QTBUG-89482
Fixes: QTBUG-89633
Change-Id: I4382dd53a225375759b9d042f6035a4a9810572b
Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
This commit is contained in:
Assam Boudjelthia 2021-01-14 12:38:04 +02:00
parent 407ce5c0af
commit 4e60681c87
48 changed files with 4386 additions and 413 deletions

View File

@ -979,6 +979,8 @@ qt_internal_extend_target(Core CONDITION ANDROID AND NOT ANDROID_EMBEDDED
io/qstandardpaths_android.cpp
io/qstorageinfo_unix.cpp
kernel/qjni.cpp kernel/qjni_p.h
kernel/qjnienvironment.cpp kernel/qjnienvironment.h
kernel/qjniobject.cpp kernel/qjniobject.h
kernel/qjnihelpers.cpp kernel/qjnihelpers_p.h
kernel/qjnionload.cpp
)

View File

@ -0,0 +1,133 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
//! [Working with lists]
QStringList getTrackTitles(const QJniObject &album) {
QStringList stringList;
QJniObject list = album.callObjectMethod("getTitles",
"()Ljava/util/List;");
if (list.isValid()) {
const int size = list.callMethod<jint>("size");
for (int i = 0; i < size; ++i) {
QJniObject title = list.callObjectMethod("get", "(I)Ljava/lang/Object;", i);
stringList.append(title.toString());
}
}
return stringList;
}
//! [Working with lists]
//! [QJniObject scope]
void functionScope()
{
QString helloString("Hello");
jstring myJString = 0;
{
QJniObject string = QJniObject::fromString(helloString);
myJString = string.object<jstring>();
}
// Ops! myJString is no longer valid.
}
//! [QJniObject scope]
//! [Registering native methods]
static void fromJavaOne(JNIEnv *env, jobject thiz, jint x)
{
Q_UNUSED(env);
Q_UNUSED(thiz);
qDebug() << x << "< 100";
}
static void fromJavaTwo(JNIEnv *env, jobject thiz, jint x)
{
Q_UNUSED(env);
Q_UNUSED(thiz);
qDebug() << x << ">= 100";
}
void registerNativeMethods() {
JNINativeMethod methods[] {{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)},
{"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}};
QJniObject javaClass("my/java/project/FooJavaClass");
QJniEnvironment env;
jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());
env->RegisterNatives(objectClass,
methods,
sizeof(methods) / sizeof(methods[0]));
env->DeleteLocalRef(objectClass);
}
void foo()
{
QJniObject::callStaticMethod<void>("my/java/project/FooJavaClass", "foo", "(I)V", 10); // Output: 10 < 100
QJniObject::callStaticMethod<void>("my/java/project/FooJavaClass", "foo", "(I)V", 100); // Output: 100 >= 100
}
//! [Registering native methods]
//! [Java native methods]
class FooJavaClass
{
public static void foo(int x)
{
if (x < 100)
callNativeOne(x);
else
callNativeTwo(x);
}
private static native void callNativeOne(int x);
private static native void callNativeTwo(int x);
}
//! [Java native methods]

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2017 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@ -78,7 +78,7 @@
#endif
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#include <private/qjni_p.h>
#include <qjniobject.h>
#endif
#if defined(Q_OS_SOLARIS)
@ -2296,7 +2296,7 @@ Oreo
// https://source.android.com/source/build-numbers.html
// https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels
const int sdk_int = QJNIObjectPrivate::getStaticField<jint>("android/os/Build$VERSION", "SDK_INT");
const int sdk_int = QJniObject::getStaticField<jint>("android/os/Build$VERSION", "SDK_INT");
return &versions_string[versions_indices[qBound(0, sdk_int, versions_count - 1)]];
}
#endif

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@ -50,7 +50,7 @@
#include <qdebug.h>
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#include <private/qjni_p.h>
#include <QJniObject>
#endif
QT_BEGIN_NAMESPACE
@ -157,7 +157,7 @@ QOperatingSystemVersion QOperatingSystemVersion::current()
version.m_os = currentType();
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#ifndef QT_BOOTSTRAPPED
const QVersionNumber v = QVersionNumber::fromString(QJNIObjectPrivate::getStaticObjectField(
const QVersionNumber v = QVersionNumber::fromString(QJniObject::getStaticObjectField(
"android/os/Build$VERSION", "RELEASE", "Ljava/lang/String;").toString());
if (!v.isNull()) {
version.m_major = v.majorVersion();
@ -207,7 +207,7 @@ QOperatingSystemVersion QOperatingSystemVersion::current()
};
// This will give us at least the first 2 version components
const size_t versionIdx = size_t(QJNIObjectPrivate::getStaticField<jint>(
const size_t versionIdx = size_t(QJniObject::getStaticField<jint>(
"android/os/Build$VERSION", "SDK_INT")) - 1;
if (versionIdx < sizeof(versions) / sizeof(versions[0])) {
version.m_major = versions[versionIdx].major;

View File

@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2020 Intel Corporation.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@ -72,10 +73,6 @@ DECLSPEC_IMPORT BOOLEAN WINAPI SystemFunction036(PVOID RandomBuffer, ULONG Rando
}
#endif
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
# include <private/qjni_p.h>
#endif
// This file is too low-level for regular Q_ASSERT (the logging framework may
// recurse back), so use regular assert()
#undef NDEBUG

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@ -41,7 +41,7 @@
#ifndef QT_NO_STANDARDPATHS
#include <QtCore/private/qjni_p.h>
#include <QJniObject>
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/qmap.h>
#include <QDir>
@ -57,13 +57,13 @@ static QString testDir()
: QLatin1String("");
}
static QJNIObjectPrivate applicationContext()
static QJniObject applicationContext()
{
static QJNIObjectPrivate appCtx;
static QJniObject appCtx;
if (appCtx.isValid())
return appCtx;
QJNIObjectPrivate context(QtAndroidPrivate::activity());
QJniObject context(QtAndroidPrivate::activity());
if (!context.isValid()) {
context = QtAndroidPrivate::service();
if (!context.isValid())
@ -75,10 +75,10 @@ static QJNIObjectPrivate applicationContext()
return appCtx;
}
static inline QString getAbsolutePath(const QJNIObjectPrivate &file)
static inline QString getAbsolutePath(const QJniObject &file)
{
QJNIObjectPrivate path = file.callObjectMethod("getAbsolutePath",
"()Ljava/lang/String;");
QJniObject path = file.callObjectMethod("getAbsolutePath",
"()Ljava/lang/String;");
if (!path.isValid())
return QString();
@ -95,22 +95,22 @@ static QString getExternalFilesDir(const char *directoryField = nullptr)
if (!path.isEmpty())
return path;
QJNIObjectPrivate appCtx = applicationContext();
QJniObject appCtx = applicationContext();
if (!appCtx.isValid())
return QString();
QJNIObjectPrivate dirField = QJNIObjectPrivate::fromString(QLatin1String(""));
QJniObject dirField = QJniObject::fromString(QLatin1String(""));
if (directoryField && strlen(directoryField) > 0) {
dirField = QJNIObjectPrivate::getStaticObjectField("android/os/Environment",
directoryField,
"Ljava/lang/String;");
dirField = QJniObject::getStaticObjectField("android/os/Environment",
directoryField,
"Ljava/lang/String;");
if (!dirField.isValid())
return QString();
}
QJNIObjectPrivate file = appCtx.callObjectMethod("getExternalFilesDir",
"(Ljava/lang/String;)Ljava/io/File;",
dirField.object());
QJniObject file = appCtx.callObjectMethod("getExternalFilesDir",
"(Ljava/lang/String;)Ljava/io/File;",
dirField.object());
if (!file.isValid())
return QString();
@ -128,12 +128,12 @@ static QString getExternalCacheDir()
if (!path.isEmpty())
return path;
QJNIObjectPrivate appCtx = applicationContext();
QJniObject appCtx = applicationContext();
if (!appCtx.isValid())
return QString();
QJNIObjectPrivate file = appCtx.callObjectMethod("getExternalCacheDir",
"()Ljava/io/File;");
QJniObject file = appCtx.callObjectMethod("getExternalCacheDir",
"()Ljava/io/File;");
if (!file.isValid())
return QString();
@ -150,12 +150,12 @@ static QString getCacheDir()
if (!path.isEmpty())
return path;
QJNIObjectPrivate appCtx = applicationContext();
QJniObject appCtx = applicationContext();
if (!appCtx.isValid())
return QString();
QJNIObjectPrivate file = appCtx.callObjectMethod("getCacheDir",
"()Ljava/io/File;");
QJniObject file = appCtx.callObjectMethod("getCacheDir",
"()Ljava/io/File;");
if (!file.isValid())
return QString();
@ -172,12 +172,12 @@ static QString getFilesDir()
if (!path.isEmpty())
return path;
QJNIObjectPrivate appCtx = applicationContext();
QJniObject appCtx = applicationContext();
if (!appCtx.isValid())
return QString();
QJNIObjectPrivate file = appCtx.callObjectMethod("getFilesDir",
"()Ljava/io/File;");
QJniObject file = appCtx.callObjectMethod("getFilesDir",
"()Ljava/io/File;");
if (!file.isValid())
return QString();

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
@ -91,8 +91,8 @@
#endif // QT_NO_QOBJECT
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
# include <private/qjni_p.h>
# include <private/qjnihelpers_p.h>
#include <QJniObject>
#include <private/qjnihelpers_p.h>
#endif
#ifdef Q_OS_MAC
@ -170,17 +170,17 @@ QString QCoreApplicationPrivate::appVersion() const
# ifdef Q_OS_DARWIN
applicationVersion = infoDictionaryStringProperty(QStringLiteral("CFBundleVersion"));
# elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
QJNIObjectPrivate context(QtAndroidPrivate::context());
QJniObject context(QtAndroidPrivate::context());
if (context.isValid()) {
QJNIObjectPrivate pm = context.callObjectMethod(
QJniObject pm = context.callObjectMethod(
"getPackageManager", "()Landroid/content/pm/PackageManager;");
QJNIObjectPrivate pn = context.callObjectMethod<jstring>("getPackageName");
QJniObject pn = context.callObjectMethod<jstring>("getPackageName");
if (pm.isValid() && pn.isValid()) {
QJNIObjectPrivate packageInfo = pm.callObjectMethod(
QJniObject packageInfo = pm.callObjectMethod(
"getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;",
pn.object(), 0);
if (packageInfo.isValid()) {
QJNIObjectPrivate versionName = packageInfo.getObjectField(
QJniObject versionName = packageInfo.getObjectField(
"versionName", "Ljava/lang/String;");
if (versionName.isValid())
return versionName.toString();

View File

@ -47,6 +47,7 @@
//
// We mean it.
//
// FIXME: Remove this once the JNI API is used by other modules.
#ifndef QJNI_P_H
#define QJNI_P_H

View File

@ -0,0 +1,283 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qjnienvironment.h"
#include "qjniobject.h"
#include "qjnihelpers_p.h"
#include <QtCore/QThread>
#include <QtCore/QThreadStorage>
QT_BEGIN_NAMESPACE
/*!
\class QJniEnvironment
\inmodule QtCore
\brief The QJniEnvironment provides access to the JNI Environment.
\since 6.1
\note This API has been tested and meant to be mainly used for Android and it hasn't been tested
for other platforms.
*/
static const char qJniThreadName[] = "QtThread";
class QJniEnvironmentPrivate
{
public:
JNIEnv *jniEnv = nullptr;
};
class QJniEnvironmentPrivateTLS
{
public:
inline ~QJniEnvironmentPrivateTLS()
{
QtAndroidPrivate::javaVM()->DetachCurrentThread();
}
};
struct QJniLocalRefDeleterPrivate
{
static void cleanup(jobject obj)
{
if (!obj)
return;
QJniEnvironment env;
env->DeleteLocalRef(obj);
}
};
// To simplify this we only define it for jobjects.
typedef QScopedPointer<_jobject, QJniLocalRefDeleterPrivate> QJniScopedLocalRefPrivate;
Q_GLOBAL_STATIC(QThreadStorage<QJniEnvironmentPrivateTLS *>, jniEnvTLS)
/*!
\fn QJniEnvironment::QJniEnvironment()
Constructs a new QJniEnvironment object and attaches the current thread to the Java VM.
*/
QJniEnvironment::QJniEnvironment()
: d(new QJniEnvironmentPrivate{})
{
JavaVM *vm = QtAndroidPrivate::javaVM();
const jint ret = vm->GetEnv((void**)&d->jniEnv, JNI_VERSION_1_6);
if (ret == JNI_OK) // Already attached
return;
if (ret == JNI_EDETACHED) { // We need to (re-)attach
JavaVMAttachArgs args = { JNI_VERSION_1_6, qJniThreadName, nullptr };
if (vm->AttachCurrentThread(&d->jniEnv, &args) != JNI_OK)
return;
if (!jniEnvTLS->hasLocalData()) // If we attached the thread we own it.
jniEnvTLS->setLocalData(new QJniEnvironmentPrivateTLS);
}
}
/*!
\fn QJniEnvironment::~QJniEnvironment()
Detaches the current thread from the Java VM and destroys the QJniEnvironment object.
*/
QJniEnvironment::~QJniEnvironment()
{
exceptionCheckAndClear();
}
/*!
\fn JNIEnv *QJniEnvironment::operator->()
Provides access to the QJniEnvironment's JNIEnv pointer.
*/
JNIEnv *QJniEnvironment::operator->()
{
return d->jniEnv;
}
/*!
\fn QJniEnvironment::operator JNIEnv *() const
Returns the JNI Environment pointer.
*/
QJniEnvironment::operator JNIEnv* () const
{
return d->jniEnv;
}
/*!
\fn jclass QJniEnvironment::findClass(const char *className)
Searches for \a className using all available class loaders. Qt on Android
uses a custom class loader to load all the .jar files and it must be used
to find any classes that are created by that class loader because these
classes are not visible in the default class loader.
Returns the class pointer or null if is not found.
A use case for this function is searching for a custom class then calling
its memeber method. The following code snippet create an instance of the
class \c CustomClass and then calls \c printFromJava() method:
\code
QJniEnvironment env;
jclass javaClass = env.findClass("org/qtproject/example/android/CustomClass");
QJniObject classObject(javaClass);
QJniObject javaMessage = QJniObject::fromString("findClass example");
classObject.callMethod<void>("printFromJava",
"(Ljava/lang/String;)V",
javaMessage.object<jstring>());
\endcode
\since Qt 6.1
*/
jclass QJniEnvironment::findClass(const char *className)
{
return QtAndroidPrivate::findClass(className, d->jniEnv);
}
/*!
\fn JavaVM *QJniEnvironment::javaVM()
Returns the Java VM interface.
\since Qt 6.1
*/
JavaVM *QJniEnvironment::javaVM()
{
return QtAndroidPrivate::javaVM();
}
/*!
\fn bool QJniEnvironment::registerNativeMethods(const char *className, JNINativeMethod methods[])
Registers the Java methods \a methods that can call native C++ functions from class \a
className. These methods must be registered before any attempt to call them.
Returns True if the registration is successful, otherwise False.
Each element in the methods array consists of:
\list
\li The Java method name
\li Method signature
\li The C++ functions that will be executed
\endlist
\code
JNINativeMethod methods[] {{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)},
{"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}};
QJniEnvironment env;
env.registerNativeMethods("org/qtproject/android/TestJavaClass", methods);
\endcode
\since Qt 6.1
*/
bool QJniEnvironment::registerNativeMethods(const char *className, JNINativeMethod methods[], int size)
{
jclass clazz = findClass(className);
if (!clazz)
return false;
jclass gClazz = static_cast<jclass>(d->jniEnv->NewGlobalRef(clazz));
if (d->jniEnv->RegisterNatives(gClazz, methods, size / sizeof(methods[0])) < 0) {
exceptionCheckAndClear();
return false;
}
d->jniEnv->DeleteLocalRef(gClazz);
return true;
}
/*!
\enum QJniExceptionCleaner::OutputMode
\value Silent the exceptions are cleaned silently
\value Verbose describes the exceptions before cleaning them
*/
/*!
\fn QJniEnvironment::exceptionCheckAndClear(OutputMode outputMode = OutputMode::Silent)
Cleans any pending exceptions either silently or with descriptions, depending on the \a outputMode.
\since 6.1
*/
bool QJniEnvironment::exceptionCheckAndClear(QJniEnvironment::OutputMode outputMode)
{
if (Q_UNLIKELY(d->jniEnv->ExceptionCheck())) {
if (outputMode != OutputMode::Silent)
d->jniEnv->ExceptionDescribe();
d->jniEnv->ExceptionClear();
return true;
}
return false;
}
/*!
\fn QJniEnvironment::exceptionCheckAndClear(JNIEnv *env, OutputMode outputMode = OutputMode::Silent)
Cleans any pending exceptions for \a env, either silently or with descriptions, depending on the \a outputMode.
\since 6.1
*/
bool QJniEnvironment::exceptionCheckAndClear(JNIEnv *env, QJniEnvironment::OutputMode outputMode)
{
if (Q_UNLIKELY(env->ExceptionCheck())) {
if (outputMode != OutputMode::Silent)
env->ExceptionDescribe();
env->ExceptionClear();
return true;
}
return false;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,85 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QJNI_ENVIRONMENT_H
#define QJNI_ENVIRONMENT_H
#include <QScopedPointer>
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#include <jni.h>
#else
class JNIEnv;
class JNINativeMethod;
class JavaVM;
class jclass;
#endif
QT_BEGIN_NAMESPACE
class QJniEnvironmentPrivate;
class Q_CORE_EXPORT QJniEnvironment
{
public:
QJniEnvironment();
~QJniEnvironment();
JNIEnv *operator->();
operator JNIEnv *() const;
jclass findClass(const char *className);
static JavaVM *javaVM();
bool registerNativeMethods(const char *className, JNINativeMethod methods[], int size);
enum class OutputMode {
Silent,
Verbose
};
bool exceptionCheckAndClear(OutputMode outputMode = OutputMode::Verbose);
static bool exceptionCheckAndClear(JNIEnv *env, OutputMode outputMode = OutputMode::Verbose);
private:
Q_DISABLE_COPY_MOVE(QJniEnvironment)
QScopedPointer<QJniEnvironmentPrivate> d;
};
QT_END_NAMESPACE
#endif // QJNI_ENVIRONMENT_H

View File

@ -37,14 +37,16 @@
**
****************************************************************************/
#include "qcoreapplication.h"
#include "qjnienvironment.h"
#include "qjnihelpers_p.h"
#include "qjni_p.h"
#include "qmutex.h"
#include "qjniobject.h"
#include "qlist.h"
#include "qmutex.h"
#include "qsemaphore.h"
#include "qsharedpointer.h"
#include "qthread.h"
#include "qcoreapplication.h"
#include <QtCore/qrunnable.h>
#include <deque>
@ -146,7 +148,7 @@ static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requ
std::unique_ptr<jint[]> results(new jint[size]);
env->GetIntArrayRegion(grantResults, 0, size, results.get());
for (int i = 0 ; i < size; ++i) {
const auto &permission = QJNIObjectPrivate(env->GetObjectArrayElement(permissions, i)).toString();
const auto &permission = QJniObject(env->GetObjectArrayElement(permissions, i)).toString();
auto value = results[i] == PERMISSION_GRANTED ?
QtAndroidPrivate::PermissionsResult::Granted :
QtAndroidPrivate::PermissionsResult::Denied;
@ -286,27 +288,14 @@ void QtAndroidPrivate::handleResume()
listeners.at(i)->handleResume();
}
static inline bool exceptionCheck(JNIEnv *env)
{
if (env->ExceptionCheck()) {
#ifdef QT_DEBUG
env->ExceptionDescribe();
#endif // QT_DEBUG
env->ExceptionClear();
return true;
}
return false;
}
static void setAndroidSdkVersion(JNIEnv *env)
{
jclass androidVersionClass = env->FindClass("android/os/Build$VERSION");
if (exceptionCheck(env))
if (QJniEnvironment::exceptionCheckAndClear(env))
return;
jfieldID androidSDKFieldID = env->GetStaticFieldID(androidVersionClass, "SDK_INT", "I");
if (exceptionCheck(env))
if (QJniEnvironment::exceptionCheckAndClear(env))
return;
g_androidSdkVersion = env->GetStaticIntField(androidVersionClass, androidSDKFieldID);
@ -342,42 +331,42 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
{
jclass jQtNative = env->FindClass("org/qtproject/qt/android/QtNative");
if (exceptionCheck(env))
if (QJniEnvironment::exceptionCheckAndClear(env))
return JNI_ERR;
jmethodID activityMethodID = env->GetStaticMethodID(jQtNative,
"activity",
"()Landroid/app/Activity;");
if (exceptionCheck(env))
if (QJniEnvironment::exceptionCheckAndClear(env))
return JNI_ERR;
jobject activity = env->CallStaticObjectMethod(jQtNative, activityMethodID);
if (exceptionCheck(env))
if (QJniEnvironment::exceptionCheckAndClear(env))
return JNI_ERR;
jmethodID serviceMethodID = env->GetStaticMethodID(jQtNative,
"service",
"()Landroid/app/Service;");
if (exceptionCheck(env))
if (QJniEnvironment::exceptionCheckAndClear(env))
return JNI_ERR;
jobject service = env->CallStaticObjectMethod(jQtNative, serviceMethodID);
if (exceptionCheck(env))
if (QJniEnvironment::exceptionCheckAndClear(env))
return JNI_ERR;
jmethodID classLoaderMethodID = env->GetStaticMethodID(jQtNative,
"classLoader",
"()Ljava/lang/ClassLoader;");
if (exceptionCheck(env))
if (QJniEnvironment::exceptionCheckAndClear(env))
return JNI_ERR;
jobject classLoader = env->CallStaticObjectMethod(jQtNative, classLoaderMethodID);
if (exceptionCheck(env))
if (QJniEnvironment::exceptionCheckAndClear(env))
return JNI_ERR;
setAndroidSdkVersion(env);
@ -405,7 +394,7 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
const bool regOk = (env->RegisterNatives(jQtNative, methods, sizeof(methods) / sizeof(methods[0])) == JNI_OK);
if (!regOk && exceptionCheck(env))
if (!regOk && QJniEnvironment::exceptionCheckAndClear(env))
return JNI_ERR;
g_runPendingCppRunnablesMethodID = env->GetStaticMethodID(jQtNative,
@ -495,7 +484,10 @@ void QtAndroidPrivate::runOnAndroidThreadSync(const QtAndroidPrivate::Runnable &
waitForSemaphore(timeoutMs, sem);
}
void QtAndroidPrivate::requestPermissions(JNIEnv *env, const QStringList &permissions, const QtAndroidPrivate::PermissionsResultFunc &callbackFunc, bool directCall)
void QtAndroidPrivate::requestPermissions(JNIEnv *env,
const QStringList &permissions,
const QtAndroidPrivate::PermissionsResultFunc &callbackFunc,
bool directCall)
{
if (androidSdkVersion() < 23 || !activity()) {
QHash<QString, QtAndroidPrivate::PermissionsResult> res;
@ -517,12 +509,17 @@ void QtAndroidPrivate::requestPermissions(JNIEnv *env, const QStringList &permis
(*g_pendingPermissionRequests)[requestCode] = new PermissionsResultClass(callbackFunc);
}
QJNIEnvironmentPrivate env;
auto array = env->NewObjectArray(permissions.size(), env->FindClass("java/lang/String"), nullptr);
QJniEnvironment env;
jclass clazz = env->FindClass("java/lang/String");
if (env.exceptionCheckAndClear())
return;
auto array = env->NewObjectArray(permissions.size(), clazz, nullptr);
int index = 0;
for (const auto &perm : permissions)
env->SetObjectArrayElement(array, index++, QJNIObjectPrivate::fromString(perm).object());
QJNIObjectPrivate(activity()).callMethod<void>("requestPermissions", "([Ljava/lang/String;I)V", array, requestCode);
env->SetObjectArrayElement(array, index++, QJniObject::fromString(perm).object());
QJniObject(activity()).callMethod<void>("requestPermissions", "([Ljava/lang/String;I)V", array, requestCode);
env->DeleteLocalRef(array);
}, env);
}
@ -543,10 +540,10 @@ QtAndroidPrivate::PermissionsHash QtAndroidPrivate::requestPermissionsSync(JNIEn
QtAndroidPrivate::PermissionsResult QtAndroidPrivate::checkPermission(const QString &permission)
{
const auto res = QJNIObjectPrivate::callStaticMethod<jint>("org/qtproject/qt/android/QtNative",
"checkSelfPermission",
"(Ljava/lang/String;)I",
QJNIObjectPrivate::fromString(permission).object());
const auto res = QJniObject::callStaticMethod<jint>("org/qtproject/qt/android/QtNative",
"checkSelfPermission",
"(Ljava/lang/String;)I",
QJniObject::fromString(permission).object());
return res == PERMISSION_GRANTED ? PermissionsResult::Granted : PermissionsResult::Denied;
}
@ -555,8 +552,9 @@ bool QtAndroidPrivate::shouldShowRequestPermissionRationale(const QString &permi
if (androidSdkVersion() < 23 || !activity())
return false;
return QJNIObjectPrivate(activity()).callMethod<jboolean>("shouldShowRequestPermissionRationale", "(Ljava/lang/String;)Z",
QJNIObjectPrivate::fromString(permission).object());
return QJniObject(activity()).callMethod<jboolean>("shouldShowRequestPermissionRationale",
"(Ljava/lang/String;)Z",
QJniObject::fromString(permission).object());
}
void QtAndroidPrivate::registerGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)

View File

@ -119,6 +119,7 @@ namespace QtAndroidPrivate
Q_CORE_EXPORT jobject context();
Q_CORE_EXPORT JavaVM *javaVM();
Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env);
Q_CORE_EXPORT jclass findClass(const char *className, JNIEnv *env);
jobject classLoader();
Q_CORE_EXPORT jint androidSdkVersion();
Q_CORE_EXPORT void runOnAndroidThread(const Runnable &runnable, JNIEnv *env);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,207 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QJNIOBJECT_H
#define QJNIOBJECT_H
#include <QtCore/QSharedPointer>
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#include <jni.h>
#else
class jclass;
class jobject;
#endif
QT_BEGIN_NAMESPACE
class QJniObjectPrivate;
class Q_CORE_EXPORT QJniObject
{
public:
QJniObject();
explicit QJniObject(const char *className);
explicit QJniObject(const char *className, const char *sig, ...);
explicit QJniObject(jclass clazz);
explicit QJniObject(jclass clazz, const char *sig, ...);
QJniObject(jobject globalRef);
~QJniObject();
template <typename T>
T object() const;
jobject object() const;
template <typename T>
T callMethod(const char *methodName, const char *sig, ...) const;
template <typename T>
T callMethod(const char *methodName) const;
template <typename T>
QJniObject callObjectMethod(const char *methodName) const;
QJniObject callObjectMethod(const char *methodName, const char *sig, ...) const;
template <typename T>
static T callStaticMethod(const char *className, const char *methodName, const char *sig, ...);
template <typename T>
static T callStaticMethod(const char *className, const char *methodName);
template <typename T>
static T callStaticMethod(jclass clazz, const char *methodName, const char *sig, ...);
template <typename T>
static T callStaticMethod(jclass clazz, const char *methodName);
template <typename T>
static QJniObject callStaticObjectMethod(const char *className, const char *methodName);
static QJniObject callStaticObjectMethod(const char *className,
const char *methodName,
const char *sig, ...);
template <typename T>
static QJniObject callStaticObjectMethod(jclass clazz, const char *methodName);
static QJniObject callStaticObjectMethod(jclass clazz,
const char *methodName,
const char *sig, ...);
template <typename T>
T getField(const char *fieldName) const;
template <typename T>
static T getStaticField(const char *className, const char *fieldName);
template <typename T>
static T getStaticField(jclass clazz, const char *fieldName);
template <typename T>
QJniObject getObjectField(const char *fieldName) const;
QJniObject getObjectField(const char *fieldName, const char *sig) const;
template <typename T>
static QJniObject getStaticObjectField(const char *className, const char *fieldName);
static QJniObject getStaticObjectField(const char *className,
const char *fieldName,
const char *sig);
template <typename T>
static QJniObject getStaticObjectField(const char *className,
const char *fieldName,
const char *sig);
template <typename T>
static QJniObject getStaticObjectField(jclass clazz, const char *fieldName);
static QJniObject getStaticObjectField(jclass clazz, const char *fieldName, const char *sig);
template <typename T>
static QJniObject getStaticObjectField(jclass clazz, const char *fieldName, const char *sig);
template <typename T>
void setField(const char *fieldName, T value);
template <typename T>
void setField(const char *fieldName, const char *sig, T value);
template <typename T>
static void setStaticField(const char *className, const char *fieldName, T value);
template <typename T>
static void setStaticField(const char *className, const char *fieldName,
const char *sig, T value);
template <typename T>
static void setStaticField(jclass clazz, const char *fieldName, const char *sig, T value);
template <typename T>
static void setStaticField(jclass clazz, const char *fieldName, T value);
static QJniObject fromString(const QString &string);
QString toString() const;
static bool isClassAvailable(const char *className);
bool isValid() const;
// This function takes ownership of the jobject and releases the local ref. before returning.
static QJniObject fromLocalRef(jobject lref);
template <typename T> QJniObject &operator=(T obj);
private:
struct QVaListPrivate { operator va_list &() const { return m_args; } va_list &m_args; };
QJniObject(const char *className, const char *sig, const QVaListPrivate &args);
QJniObject(jclass clazz, const char *sig, const QVaListPrivate &args);
template <typename T>
T callMethodV(const char *methodName, const char *sig, va_list args) const;
QJniObject callObjectMethodV(const char *methodName, const char *sig, va_list args) const;
template <typename T>
static T callStaticMethodV(const char *className,
const char *methodName,
const char *sig,
va_list args);
template <typename T>
static T callStaticMethodV(jclass clazz,
const char *methodName,
const char *sig,
va_list args);
static QJniObject callStaticObjectMethodV(const char *className,
const char *methodName,
const char *sig,
va_list args);
static QJniObject callStaticObjectMethodV(jclass clazz,
const char *methodName,
const char *sig,
va_list args);
bool isSameObject(jobject obj) const;
bool isSameObject(const QJniObject &other) const;
void assign(jobject obj);
jobject javaObject() const;
friend bool operator==(const QJniObject &, const QJniObject &);
friend bool operator!=(const QJniObject&, const QJniObject&);
QSharedPointer<QJniObjectPrivate> d;
};
inline bool operator==(const QJniObject &obj1, const QJniObject &obj2)
{
return obj1.isSameObject(obj2);
}
inline bool operator!=(const QJniObject &obj1, const QJniObject &obj2)
{
return !obj1.isSameObject(obj2);
}
QT_END_NAMESPACE
#endif // QJNIOBJECT_H

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@ -37,8 +37,9 @@
**
****************************************************************************/
#include <jni.h>
#include "qjnihelpers_p.h"
#include <jni.h>
#include <android/log.h>
static const char logTag[] = "QtCore";

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Copyright (C) 2014 Drew Parsons <dparsons@emerall.com>
** Contact: https://www.qt.io/licensing/
**
@ -38,10 +38,12 @@
**
****************************************************************************/
#include <QtCore/QSet>
#include "qtimezone.h"
#include "qtimezoneprivate_p.h"
#include <QtCore/QJniEnvironment>
#include <QtCore/QSet>
QT_BEGIN_NAMESPACE
/*
@ -49,7 +51,7 @@ QT_BEGIN_NAMESPACE
Android implementation
Note that a QJNIObjectPrivate manages a global reference, so it serves as an
Note that a QJniObject manages a global reference, so it serves as an
owning smart-pointer, ensuring an object doesn't get garbage-collected
before we're done with it.
*/
@ -59,9 +61,9 @@ QAndroidTimeZonePrivate::QAndroidTimeZonePrivate()
: QTimeZonePrivate()
{
// Keep in sync with systemTimeZoneId():
androidTimeZone = QJNIObjectPrivate::callStaticObjectMethod(
androidTimeZone = QJniObject::callStaticObjectMethod(
"java.util.TimeZone", "getDefault", "()Ljava/util/TimeZone;");
const QJNIObjectPrivate id = androidTimeZone.callObjectMethod("getID", "()Ljava/lang/String;");
const QJniObject id = androidTimeZone.callObjectMethod("getID", "()Ljava/lang/String;");
m_id = id.toString().toUtf8();
}
@ -83,16 +85,16 @@ QAndroidTimeZonePrivate::~QAndroidTimeZonePrivate()
{
}
static QJNIObjectPrivate getDisplayName(QJNIObjectPrivate zone, jint style, jboolean dst,
static QJniObject getDisplayName(QJniObject zone, jint style, jboolean dst,
const QLocale &locale)
{
QJNIObjectPrivate jlanguage
= QJNIObjectPrivate::fromString(QLocale::languageToString(locale.language()));
QJNIObjectPrivate jcountry
= QJNIObjectPrivate::fromString(QLocale::countryToString(locale.country()));
QJNIObjectPrivate
jvariant = QJNIObjectPrivate::fromString(QLocale::scriptToString(locale.script()));
QJNIObjectPrivate jlocale("java.util.Locale",
QJniObject jlanguage
= QJniObject::fromString(QLocale::languageToString(locale.language()));
QJniObject jcountry
= QJniObject::fromString(QLocale::countryToString(locale.country()));
QJniObject
jvariant = QJniObject::fromString(QLocale::scriptToString(locale.script()));
QJniObject jlocale("java.util.Locale",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
static_cast<jstring>(jlanguage.object()),
static_cast<jstring>(jcountry.object()),
@ -106,12 +108,12 @@ static QJNIObjectPrivate getDisplayName(QJNIObjectPrivate zone, jint style, jboo
void QAndroidTimeZonePrivate::init(const QByteArray &ianaId)
{
const QString iana = QString::fromUtf8(ianaId);
androidTimeZone = QJNIObjectPrivate::callStaticObjectMethod(
androidTimeZone = QJniObject::callStaticObjectMethod(
"java.util.TimeZone", "getTimeZone", "(Ljava/lang/String;)Ljava/util/TimeZone;",
static_cast<jstring>(QJNIObjectPrivate::fromString(iana).object()));
static_cast<jstring>(QJniObject::fromString(iana).object()));
// The ID or display name of the zone we've got, if it looks like what we asked for:
const auto match = [iana](const QJNIObjectPrivate &jname) -> QByteArray {
const auto match = [iana](const QJniObject &jname) -> QByteArray {
const QString name = jname.toString();
if (iana.compare(name, Qt::CaseInsensitive) == 0)
return name.toUtf8();
@ -205,7 +207,7 @@ bool QAndroidTimeZonePrivate::hasDaylightTime() const
bool QAndroidTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
{
if ( androidTimeZone.isValid() ) {
QJNIObjectPrivate jDate( "java/util/Date", "(J)V", static_cast<jlong>(atMSecsSinceEpoch) );
QJniObject jDate( "java/util/Date", "(J)V", static_cast<jlong>(atMSecsSinceEpoch) );
return androidTimeZone.callMethod<jboolean>("inDaylightTime", "(Ljava/util/Date;)Z", jDate.object() );
}
else
@ -250,24 +252,24 @@ QTimeZonePrivate::Data QAndroidTimeZonePrivate::previousTransition(qint64 before
QByteArray QAndroidTimeZonePrivate::systemTimeZoneId() const
{
// Keep in sync with default constructor:
QJNIObjectPrivate androidSystemTimeZone = QJNIObjectPrivate::callStaticObjectMethod(
QJniObject androidSystemTimeZone = QJniObject::callStaticObjectMethod(
"java.util.TimeZone", "getDefault", "()Ljava/util/TimeZone;");
const QJNIObjectPrivate id = androidSystemTimeZone.callObjectMethod<jstring>("getID");
const QJniObject id = androidSystemTimeZone.callObjectMethod<jstring>("getID");
return id.toString().toUtf8();
}
QList<QByteArray> QAndroidTimeZonePrivate::availableTimeZoneIds() const
{
QList<QByteArray> availableTimeZoneIdList;
QJNIObjectPrivate androidAvailableIdList = QJNIObjectPrivate::callStaticObjectMethod("java.util.TimeZone", "getAvailableIDs", "()[Ljava/lang/String;");
QJniObject androidAvailableIdList = QJniObject::callStaticObjectMethod("java.util.TimeZone", "getAvailableIDs", "()[Ljava/lang/String;");
QJNIEnvironmentPrivate jniEnv;
QJniEnvironment jniEnv;
int androidTZcount = jniEnv->GetArrayLength( static_cast<jarray>(androidAvailableIdList.object()) );
// need separate jobject and QAndroidJniObject here so that we can delete (DeleteLocalRef) the reference to the jobject
// need separate jobject and QJniObject here so that we can delete (DeleteLocalRef) the reference to the jobject
// (or else the JNI reference table fills after 512 entries from GetObjectArrayElement)
jobject androidTZobject;
QJNIObjectPrivate androidTZ;
QJniObject androidTZ;
for (int i=0; i<androidTZcount; i++ ) {
androidTZobject = jniEnv->GetObjectArrayElement( static_cast<jobjectArray>( androidAvailableIdList.object() ), i );
androidTZ = androidTZobject;

View File

@ -70,7 +70,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(NSTimeZone);
#endif // Q_OS_WIN
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
#include <QtCore/private/qjni_p.h>
#include <QJniObject>
#endif
QT_BEGIN_NAMESPACE
@ -496,7 +496,7 @@ public:
private:
void init(const QByteArray &zoneId);
QJNIObjectPrivate androidTimeZone;
QJniObject androidTimeZone;
};
#endif // Q_OS_ANDROID

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@ -38,7 +38,9 @@
****************************************************************************/
#include "qnetworkproxy.h"
#include <QtCore/private/qjni_p.h>
#include <QtCore/QJniEnvironment>
#include <QtCore/QJniObject>
#include <QtCore/private/qjnihelpers_p.h>
#ifndef QT_NO_NETWORKPROXY
@ -58,18 +60,18 @@ static const char networkClass[] = "org/qtproject/qt/android/network/QtNetwork";
ProxyInfoObject::ProxyInfoObject()
{
QJNIObjectPrivate::callStaticMethod<void>(networkClass,
"registerReceiver",
"(Landroid/content/Context;)V",
QtAndroidPrivate::context());
QJniObject::callStaticMethod<void>(networkClass,
"registerReceiver",
"(Landroid/content/Context;)V",
QtAndroidPrivate::context());
}
ProxyInfoObject::~ProxyInfoObject()
{
QJNIObjectPrivate::callStaticMethod<void>(networkClass,
"unregisterReceiver",
"(Landroid/content/Context;)V",
QtAndroidPrivate::context());
QJniObject::callStaticMethod<void>(networkClass,
"unregisterReceiver",
"(Landroid/content/Context;)V",
QtAndroidPrivate::context());
}
QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkProxyQuery &query)
@ -78,18 +80,18 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
if (!proxyInfoInstance)
return proxyList;
QJNIObjectPrivate proxyInfo = QJNIObjectPrivate::callStaticObjectMethod(networkClass,
QJniObject proxyInfo = QJniObject::callStaticObjectMethod(networkClass,
"getProxyInfo",
"(Landroid/content/Context;)Landroid/net/ProxyInfo;",
QtAndroidPrivate::context());
if (proxyInfo.isValid()) {
QJNIObjectPrivate exclusionList = proxyInfo.callObjectMethod("getExclusionList",
"()[Ljava/lang/String;");
QJniObject exclusionList = proxyInfo.callObjectMethod("getExclusionList",
"()[Ljava/lang/String;");
bool exclude = false;
if (exclusionList.isValid()) {
jobjectArray listObject = static_cast<jobjectArray>(exclusionList.object());
QJNIEnvironmentPrivate env;
QJNIObjectPrivate entry;
QJniEnvironment env;
QJniObject entry;
const int size = env->GetArrayLength(listObject);
QUrl host = QUrl(query.url().host());
for (int i = 0; i < size; ++i) {
@ -101,7 +103,7 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
}
}
if (!exclude) {
QJNIObjectPrivate hostName = proxyInfo.callObjectMethod<jstring>("getHost");
QJniObject hostName = proxyInfo.callObjectMethod<jstring>("getHost");
const int port = proxyInfo.callMethod<jint>("getPort");
QNetworkProxy proxy(QNetworkProxy::HttpProxy, hostName.toString(), port);
proxyList << proxy;

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@ -53,7 +53,8 @@
****************************************************************************/
#include "qsslsocket_openssl_p.h"
#include <QtCore/private/qjni_p.h>
#include <QtCore/QJniEnvironment>
#include <QtCore/QJniObject>
QT_BEGIN_NAMESPACE
@ -61,13 +62,13 @@ QList<QByteArray> QSslSocketPrivate::fetchSslCertificateData()
{
QList<QByteArray> certificateData;
QJNIObjectPrivate certificates = QJNIObjectPrivate::callStaticObjectMethod("org/qtproject/qt/android/QtNative",
"getSSLCertificates",
"()[[B");
QJniObject certificates = QJniObject::callStaticObjectMethod("org/qtproject/qt/android/QtNative",
"getSSLCertificates",
"()[[B");
if (!certificates.isValid())
return certificateData;
QJNIEnvironmentPrivate env;
QJniEnvironment env;
jobjectArray jcertificates = static_cast<jobjectArray>(certificates.object());
const jint nCertificates = env->GetArrayLength(jcertificates);
certificateData.reserve(static_cast<int>(nCertificates));

View File

@ -39,7 +39,8 @@
#include "androidcontentfileengine.h"
#include <private/qjni_p.h>
#include <QtCore/QJniEnvironment>
#include <QtCore/QJniObject>
#include <private/qjnihelpers_p.h>
#include <QDebug>
@ -65,12 +66,12 @@ bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
openModeStr += QLatin1Char('a');
}
const auto fd = QJNIObjectPrivate::callStaticMethod<jint>("org/qtproject/qt/android/QtNative",
const auto fd = QJniObject::callStaticMethod<jint>("org/qtproject/qt/android/QtNative",
"openFdForContentUrl",
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I",
QtAndroidPrivate::context(),
QJNIObjectPrivate::fromString(fileName(DefaultName)).object(),
QJNIObjectPrivate::fromString(openModeStr).object());
QJniObject::fromString(fileName(DefaultName)).object(),
QJniObject::fromString(openModeStr).object());
if (fd < 0) {
return false;
@ -81,10 +82,10 @@ bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
qint64 AndroidContentFileEngine::size() const
{
const jlong size = QJNIObjectPrivate::callStaticMethod<jlong>(
const jlong size = QJniObject::callStaticMethod<jlong>(
"org/qtproject/qt/android/QtNative", "getSize",
"(Landroid/content/Context;Ljava/lang/String;)J", QtAndroidPrivate::context(),
QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
QJniObject::fromString(fileName(DefaultName)).object());
return (qint64)size;
}
@ -92,25 +93,25 @@ AndroidContentFileEngine::FileFlags AndroidContentFileEngine::fileFlags(FileFlag
{
FileFlags commonFlags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag);
FileFlags flags;
const bool isDir = QJNIObjectPrivate::callStaticMethod<jboolean>(
const bool isDir = QJniObject::callStaticMethod<jboolean>(
"org/qtproject/qt/android/QtNative", "checkIfDir",
"(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
QJniObject::fromString(fileName(DefaultName)).object());
// If it is a directory then we know it exists so there is no reason to explicitly check
const bool exists = isDir ? true : QJNIObjectPrivate::callStaticMethod<jboolean>(
const bool exists = isDir ? true : QJniObject::callStaticMethod<jboolean>(
"org/qtproject/qt/android/QtNative", "checkFileExists",
"(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
QJniObject::fromString(fileName(DefaultName)).object());
if (!exists && !isDir)
return flags;
if (isDir) {
flags = DirectoryType | commonFlags;
} else {
flags = FileType | commonFlags;
const bool writable = QJNIObjectPrivate::callStaticMethod<jboolean>(
const bool writable = QJniObject::callStaticMethod<jboolean>(
"org/qtproject/qt/android/QtNative", "checkIfWritable",
"(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
QJniObject::fromString(fileName(DefaultName)).object());
if (writable)
flags |= WriteOwnerPerm|WriteUserPerm|WriteGroupPerm|WriteOtherPerm;
}
@ -182,22 +183,22 @@ bool AndroidContentFileEngineIterator::hasNext() const
if (m_index == -1) {
if (path().isEmpty())
return false;
const bool isDir = QJNIObjectPrivate::callStaticMethod<jboolean>(
const bool isDir = QJniObject::callStaticMethod<jboolean>(
"org/qtproject/qt/android/QtNative", "checkIfDir",
"(Landroid/content/Context;Ljava/lang/String;)Z",
QtAndroidPrivate::context(),
QJNIObjectPrivate::fromString(path()).object());
QJniObject::fromString(path()).object());
if (isDir) {
QJNIObjectPrivate objArray = QJNIObjectPrivate::callStaticObjectMethod("org/qtproject/qt/android/QtNative",
QJniObject objArray = QJniObject::callStaticObjectMethod("org/qtproject/qt/android/QtNative",
"listContentsFromTreeUri",
"(Landroid/content/Context;Ljava/lang/String;)[Ljava/lang/String;",
QtAndroidPrivate::context(),
QJNIObjectPrivate::fromString(path()).object());
QJniObject::fromString(path()).object());
if (objArray.isValid()) {
QJNIEnvironmentPrivate env;
QJniEnvironment env;
const jsize length = env->GetArrayLength(static_cast<jarray>(objArray.object()));
for (int i = 0; i != length; ++i) {
m_entries << QJNIObjectPrivate(env->GetObjectArrayElement(
m_entries << QJniObject(env->GetObjectArrayElement(
static_cast<jobjectArray>(objArray.object()), i)).toString();
}
}

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -48,11 +48,9 @@
#include "QtGui/qaccessible.h"
#include <QtCore/qmath.h>
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/private/qjni_p.h>
#include <QtCore/QJniObject>
#include <QtGui/private/qhighdpiscaling_p.h>
#include "qdebug.h"
static const char m_qtTag[] = "Qt A11Y";
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
@ -77,8 +75,8 @@ namespace QtAndroidAccessibility
void initialize()
{
QJNIObjectPrivate::callStaticMethod<void>(QtAndroid::applicationClass(),
"initializeAccessibility");
QJniObject::callStaticMethod<void>(QtAndroid::applicationClass(),
"initializeAccessibility");
}
bool isActive()

View File

@ -39,7 +39,8 @@
#include "androidjniclipboard.h"
#include <QtCore/QUrl>
#include <QtCore/private/qjni_p.h>
#include <QtCore/QJniObject>
#include <QtCore/QJniEnvironment>
QT_BEGIN_NAMESPACE
@ -55,9 +56,9 @@ namespace QtAndroidClipboard
void setClipboardManager(QAndroidPlatformClipboard *manager)
{
m_manager = manager;
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "registerClipboardManager");
QJniObject::callStaticMethod<void>(applicationClass(), "registerClipboardManager");
jclass appClass = QtAndroid::applicationClass();
QJNIEnvironmentPrivate env;
QJniEnvironment env;
if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
__android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
return;
@ -65,29 +66,30 @@ namespace QtAndroidClipboard
}
void clearClipboardData()
{
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "clearClipData");
QJniObject::callStaticMethod<void>(applicationClass(), "clearClipData");
}
void setClipboardMimeData(QMimeData *data)
{
clearClipboardData();
if (data->hasText()) {
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
"setClipboardText", "(Ljava/lang/String;)V",
QJNIObjectPrivate::fromString(data->text()).object());
QJniObject::callStaticMethod<void>(applicationClass(),
"setClipboardText", "(Ljava/lang/String;)V",
QJniObject::fromString(data->text()).object());
}
if (data->hasHtml()) {
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
"setClipboardHtml",
"(Ljava/lang/String;Ljava/lang/String;)V",
QJNIObjectPrivate::fromString(data->text()).object(),
QJNIObjectPrivate::fromString(data->html()).object());
QJniObject::callStaticMethod<void>(applicationClass(),
"setClipboardHtml",
"(Ljava/lang/String;Ljava/lang/String;)V",
QJniObject::fromString(data->text()).object(),
QJniObject::fromString(data->html()).object());
}
if (data->hasUrls()) {
QList<QUrl> urls = data->urls();
for (const auto &u : qAsConst(urls)) {
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "setClipboardUri",
"(Ljava/lang/String;)V",
QJNIObjectPrivate::fromString(u.toEncoded()).object());
QJniObject::callStaticMethod<void>(applicationClass(),
"setClipboardUri",
"(Ljava/lang/String;)V",
QJniObject::fromString(u.toEncoded()).object());
}
}
}
@ -95,28 +97,28 @@ namespace QtAndroidClipboard
QMimeData *getClipboardMimeData()
{
QMimeData *data = new QMimeData;
if (QJNIObjectPrivate::callStaticMethod<jboolean>(applicationClass(), "hasClipboardText")) {
data->setText(QJNIObjectPrivate::callStaticObjectMethod(applicationClass(),
"getClipboardText",
"()Ljava/lang/String;").toString());
if (QJniObject::callStaticMethod<jboolean>(applicationClass(), "hasClipboardText")) {
data->setText(QJniObject::callStaticObjectMethod(applicationClass(),
"getClipboardText",
"()Ljava/lang/String;").toString());
}
if (QJNIObjectPrivate::callStaticMethod<jboolean>(applicationClass(), "hasClipboardHtml")) {
data->setHtml(QJNIObjectPrivate::callStaticObjectMethod(applicationClass(),
"getClipboardHtml",
"()Ljava/lang/String;").toString());
if (QJniObject::callStaticMethod<jboolean>(applicationClass(), "hasClipboardHtml")) {
data->setHtml(QJniObject::callStaticObjectMethod(applicationClass(),
"getClipboardHtml",
"()Ljava/lang/String;").toString());
}
if (QJNIObjectPrivate::callStaticMethod<jboolean>(applicationClass(), "hasClipboardUri")) {
QJNIObjectPrivate uris = QJNIObjectPrivate::callStaticObjectMethod(applicationClass(),
"getClipboardUris",
"()[Ljava/lang/String;");
if (QJniObject::callStaticMethod<jboolean>(applicationClass(), "hasClipboardUri")) {
QJniObject uris = QJniObject::callStaticObjectMethod(applicationClass(),
"getClipboardUris",
"()[Ljava/lang/String;");
if (uris.isValid()) {
QList<QUrl> urls;
QJNIEnvironmentPrivate env;
QJniEnvironment env;
jobjectArray juris = static_cast<jobjectArray>(uris.object());
const jint nUris = env->GetArrayLength(juris);
urls.reserve(static_cast<int>(nUris));
for (int i = 0; i < nUris; ++i)
urls << QUrl(QJNIObjectPrivate(env->GetObjectArrayElement(juris, i)).toString());
urls << QUrl(QJniObject(env->GetObjectArrayElement(juris, i)).toString());
data->setUrls(urls);
}
}

View File

@ -49,7 +49,6 @@
#include <QPointer>
#include <QGuiApplication>
#include <QDebug>
#include <QtMath>
QT_BEGIN_NAMESPACE
@ -71,27 +70,26 @@ namespace QtAndroidInput
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << ">>> UPDATESELECTION" << selStart << selEnd << candidatesStart << candidatesEnd;
#endif
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
"updateSelection",
"(IIII)V",
selStart,
selEnd,
candidatesStart,
candidatesEnd);
QJniObject::callStaticMethod<void>(applicationClass(),
"updateSelection",
"(IIII)V",
selStart,
selEnd,
candidatesStart,
candidatesEnd);
}
void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints, int enterKeyType)
{
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
"showSoftwareKeyboard",
"(IIIIII)V",
left,
top,
width,
height,
inputHints,
enterKeyType
);
QJniObject::callStaticMethod<void>(applicationClass(),
"showSoftwareKeyboard",
"(IIIIII)V",
left,
top,
width,
height,
inputHints,
enterKeyType);
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints << enterKeyType;
#endif
@ -99,7 +97,7 @@ namespace QtAndroidInput
void resetSoftwareKeyboard()
{
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "resetSoftwareKeyboard");
QJniObject::callStaticMethod<void>(applicationClass(), "resetSoftwareKeyboard");
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@ RESETSOFTWAREKEYBOARD");
#endif
@ -107,7 +105,7 @@ namespace QtAndroidInput
void hideSoftwareKeyboard()
{
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "hideSoftwareKeyboard");
QJniObject::callStaticMethod<void>(applicationClass(), "hideSoftwareKeyboard");
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
qDebug("@@@ HIDESOFTWAREKEYBOARD");
#endif
@ -125,10 +123,10 @@ namespace QtAndroidInput
void updateHandles(int mode, QPoint editMenuPos, uint32_t editButtons, QPoint cursor, QPoint anchor, bool rtl)
{
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "updateHandles", "(IIIIIIIIZ)V",
mode, editMenuPos.x(), editMenuPos.y(), editButtons,
cursor.x(), cursor.y(),
anchor.x(), anchor.y(), rtl);
QJniObject::callStaticMethod<void>(applicationClass(), "updateHandles", "(IIIIIIIIZ)V",
mode, editMenuPos.x(), editMenuPos.y(), editButtons,
cursor.x(), cursor.y(),
anchor.x(), anchor.y(), rtl);
}
static void mouseDown(JNIEnv */*env*/, jobject /*thiz*/, jint /*winId*/, jint x, jint y)

View File

@ -1,7 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -40,30 +40,30 @@
#include <dlfcn.h>
#include <pthread.h>
#include <semaphore.h>
#include <qplugin.h>
#include <qdebug.h>
#include <semaphore.h>
#include "androidjnimain.h"
#include "androidjniaccessibility.h"
#include "androidjniinput.h"
#include "androidjniclipboard.h"
#include "androidjnimenu.h"
#include "androidcontentfileengine.h"
#include "androiddeadlockprotector.h"
#include "androidjniaccessibility.h"
#include "androidjniclipboard.h"
#include "androidjniinput.h"
#include "androidjnimain.h"
#include "androidjnimenu.h"
#include "qandroidassetsfileenginehandler.h"
#include "qandroideventdispatcher.h"
#include "qandroidplatformdialoghelpers.h"
#include "qandroidplatformintegration.h"
#include "qandroidassetsfileenginehandler.h"
#include <android/bitmap.h>
#include <android/asset_manager_jni.h>
#include "qandroideventdispatcher.h"
#include <android/api-level.h>
#include <android/asset_manager_jni.h>
#include <android/bitmap.h>
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/qjnienvironment.h>
#include <QtCore/qjniobject.h>
#include <QtCore/qresource.h>
#include <QtCore/qthread.h>
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/private/qjni_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qhighdpiscaling_p.h>
@ -205,22 +205,22 @@ namespace QtAndroid
void setSystemUiVisibility(SystemUiVisibility uiVisibility)
{
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "setSystemUiVisibility", "(I)V", jint(uiVisibility));
QJniObject::callStaticMethod<void>(m_applicationClass, "setSystemUiVisibility", "(I)V", jint(uiVisibility));
}
void notifyAccessibilityLocationChange()
{
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "notifyAccessibilityLocationChange");
QJniObject::callStaticMethod<void>(m_applicationClass, "notifyAccessibilityLocationChange");
}
void notifyObjectHide(uint accessibilityObjectId)
{
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "notifyObjectHide","(I)V", accessibilityObjectId);
QJniObject::callStaticMethod<void>(m_applicationClass, "notifyObjectHide","(I)V", accessibilityObjectId);
}
void notifyObjectFocus(uint accessibilityObjectId)
{
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "notifyObjectFocus","(I)V", accessibilityObjectId);
QJniObject::callStaticMethod<void>(m_applicationClass, "notifyObjectFocus","(I)V", accessibilityObjectId);
}
jobject createBitmap(QImage img, JNIEnv *env)
@ -311,15 +311,15 @@ namespace QtAndroid
QString deviceName()
{
QString manufacturer = QJNIObjectPrivate::getStaticObjectField("android/os/Build", "MANUFACTURER", "Ljava/lang/String;").toString();
QString model = QJNIObjectPrivate::getStaticObjectField("android/os/Build", "MODEL", "Ljava/lang/String;").toString();
QString manufacturer = QJniObject::getStaticObjectField("android/os/Build", "MANUFACTURER", "Ljava/lang/String;").toString();
QString model = QJniObject::getStaticObjectField("android/os/Build", "MODEL", "Ljava/lang/String;").toString();
return manufacturer + QLatin1Char(' ') + model;
}
int createSurface(AndroidSurfaceClient *client, const QRect &geometry, bool onTop, int imageDepth)
{
QJNIEnvironmentPrivate env;
QJniEnvironment env;
if (!env)
return -1;
@ -355,26 +355,26 @@ namespace QtAndroid
if (!geometry.isNull())
geometry.getRect(&x, &y, &w, &h);
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass,
"insertNativeView",
"(ILandroid/view/View;IIII)V",
surfaceId,
view,
x,
y,
qMax(w, 1),
qMax(h, 1));
QJniObject::callStaticMethod<void>(m_applicationClass,
"insertNativeView",
"(ILandroid/view/View;IIII)V",
surfaceId,
view,
x,
y,
qMax(w, 1),
qMax(h, 1));
return surfaceId;
}
void setViewVisibility(jobject view, bool visible)
{
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass,
"setViewVisibility",
"(Landroid/view/View;Z)V",
view,
visible);
QJniObject::callStaticMethod<void>(m_applicationClass,
"setViewVisibility",
"(Landroid/view/View;Z)V",
view,
visible);
}
void setSurfaceGeometry(int surfaceId, const QRect &geometry)
@ -382,7 +382,7 @@ namespace QtAndroid
if (surfaceId == -1)
return;
QJNIEnvironmentPrivate env;
QJniEnvironment env;
if (!env)
return;
jint x = 0, y = 0, w = -1, h = -1;
@ -393,9 +393,9 @@ namespace QtAndroid
h = geometry.height();
}
env->CallStaticVoidMethod(m_applicationClass,
m_setSurfaceGeometryMethodID,
surfaceId,
x, y, w, h);
m_setSurfaceGeometryMethodID,
surfaceId,
x, y, w, h);
}
@ -411,11 +411,11 @@ namespace QtAndroid
m_surfaces.erase(it);
}
QJNIEnvironmentPrivate env;
QJniEnvironment env;
if (env)
env->CallStaticVoidMethod(m_applicationClass,
m_destroySurfaceMethodID,
surfaceId);
m_destroySurfaceMethodID,
surfaceId);
}
void bringChildToFront(int surfaceId)
@ -423,10 +423,10 @@ namespace QtAndroid
if (surfaceId == -1)
return;
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass,
"bringChildToFront",
"(I)V",
surfaceId);
QJniObject::callStaticMethod<void>(m_applicationClass,
"bringChildToFront",
"(I)V",
surfaceId);
}
void bringChildToBack(int surfaceId)
@ -434,10 +434,10 @@ namespace QtAndroid
if (surfaceId == -1)
return;
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass,
"bringChildToBack",
"(I)V",
surfaceId);
QJniObject::callStaticMethod<void>(m_applicationClass,
"bringChildToBack",
"(I)V",
surfaceId);
}
bool blockEventLoopsWhenSuspended()
@ -550,7 +550,7 @@ static jboolean startQtApplication(JNIEnv */*env*/, jclass /*clazz*/)
if (m_applicationClass) {
qWarning("exit app 0");
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "quitApp", "()V");
QJniObject::callStaticMethod<void>(m_applicationClass, "quitApp", "()V");
}
sem_post(&m_terminateSemaphore);

View File

@ -37,10 +37,10 @@
**
****************************************************************************/
#include "androidjnimenu.h"
#include "androidjnimain.h"
#include "qandroidplatformmenubar.h"
#include "androidjnimenu.h"
#include "qandroidplatformmenu.h"
#include "qandroidplatformmenubar.h"
#include "qandroidplatformmenuitem.h"
#include <QMutex>
@ -50,7 +50,7 @@
#include <QSet>
#include <QWindow>
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/private/qjni_p.h>
#include <QtCore/QJniObject>
QT_BEGIN_NAMESPACE
@ -82,12 +82,12 @@ namespace QtAndroidMenu
void resetMenuBar()
{
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "resetOptionsMenu");
QJniObject::callStaticMethod<void>(applicationClass(), "resetOptionsMenu");
}
void openOptionsMenu()
{
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "openOptionsMenu");
QJniObject::callStaticMethod<void>(applicationClass(), "openOptionsMenu");
}
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env)
@ -104,13 +104,14 @@ namespace QtAndroidMenu
{
QMutexLocker lock(&visibleMenuMutex);
if (visibleMenu == menu) {
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "closeContextMenu");
QJniObject::callStaticMethod<void>(applicationClass(), "closeContextMenu");
pendingContextMenus.clear();
} else {
pendingContextMenus.removeOne(menu);
}
}
// FIXME
void syncMenu(QAndroidPlatformMenu */*menu*/)
{
// QMutexLocker lock(&visibleMenuMutex);

View File

@ -39,10 +39,12 @@
#include <jni.h>
#include <QtCore/QJniEnvironment>
#include <alloca.h>
#include <android/log.h>
#include <extract.h>
#include <alloca.h>
#include <jni.h>
#include <stdlib.h>
#define LOG_TAG "extractSyleInfo"
@ -133,12 +135,15 @@ Java_org_qtproject_qt_android_ExtractStyle_extractChunkInfo20(JNIEnv *env, jobje
env->GetByteArrayRegion(chunkObj, 0, chunkSize,
reinterpret_cast<jbyte*>(storage));
if (!env->ExceptionCheck())
return Java_org_qtproject_qt_android_ExtractStyle_extractNativeChunkInfo20(env, obj,
long(storage));
else
env->ExceptionClear();
return 0;
if (QJniEnvironment::exceptionCheckAndClear(env))
return 0;
jintArray res = Java_org_qtproject_qt_android_ExtractStyle_extractNativeChunkInfo20(env, obj,
long(storage));
if (QJniEnvironment::exceptionCheckAndClear(env))
res = nullptr;
return res;
}
static inline void fill9patchOffsets(Res_png_9patch20* patch) {

View File

@ -37,13 +37,15 @@
**
****************************************************************************/
#include "qandroidassetsfileenginehandler.h"
#include "androidjnimain.h"
#include "qandroidassetsfileenginehandler.h"
#include <optional>
#include <QCoreApplication>
#include <QList>
#include <QtCore/private/qjni_p.h>
#include <QtCore/QJniEnvironment>
#include <QtCore/QJniObject>
QT_BEGIN_NAMESPACE
@ -139,16 +141,16 @@ public:
FolderIterator(const QString &path)
: m_path(path)
{
QJNIObjectPrivate files = QJNIObjectPrivate::callStaticObjectMethod(QtAndroid::applicationClass(),
QJniObject files = QJniObject::callStaticObjectMethod(QtAndroid::applicationClass(),
"listAssetContent",
"(Landroid/content/res/AssetManager;Ljava/lang/String;)[Ljava/lang/String;",
QtAndroid::assets(), QJNIObjectPrivate::fromString(path).object());
QtAndroid::assets(), QJniObject::fromString(path).object());
if (files.isValid()) {
QJNIEnvironmentPrivate env;
QJniEnvironment env;
jobjectArray jFiles = static_cast<jobjectArray>(files.object());
const jint nFiles = env->GetArrayLength(jFiles);
for (int i = 0; i < nFiles; ++i) {
AssetItem item{QJNIObjectPrivate::fromLocalRef(env->GetObjectArrayElement(jFiles, i)).toString()};
AssetItem item{QJniObject::fromLocalRef(env->GetObjectArrayElement(jFiles, i)).toString()};
insert(std::upper_bound(begin(), end(), item, [](const auto &a, const auto &b){
return a.name < b.name;
}), item);

View File

@ -41,26 +41,24 @@
#include <android/log.h>
#include "qandroidinputcontext.h"
#include "androidjnimain.h"
#include "androidjniinput.h"
#include "qandroideventdispatcher.h"
#include "androiddeadlockprotector.h"
#include "androidjniinput.h"
#include "androidjnimain.h"
#include "qandroideventdispatcher.h"
#include "qandroidinputcontext.h"
#include "qandroidplatformintegration.h"
#include <QDebug>
#include <QTextBoundaryFinder>
#include <QTextCharFormat>
#include <QtCore/QJniEnvironment>
#include <QtCore/QJniObject>
#include <private/qhighdpiscaling_p.h>
#include <qevent.h>
#include <qguiapplication.h>
#include <qinputmethod.h>
#include <qsharedpointer.h>
#include <qthread.h>
#include <qinputmethod.h>
#include <qwindow.h>
#include <QtCore/private/qjni_p.h>
#include <private/qhighdpiscaling_p.h>
#include <QTextCharFormat>
#include <QTextBoundaryFinder>
#include <QDebug>
QT_BEGIN_NAMESPACE
@ -434,7 +432,8 @@ QAndroidInputContext::QAndroidInputContext()
, m_batchEditNestingLevel(0)
, m_focusObject(0)
{
jclass clazz = QJNIEnvironmentPrivate::findClass(QtNativeInputConnectionClassName);
QJniEnvironment env;
jclass clazz = env.findClass(QtNativeInputConnectionClassName);
if (Q_UNLIKELY(!clazz)) {
qCritical() << "Native registration unable to find class '"
<< QtNativeInputConnectionClassName
@ -442,7 +441,6 @@ QAndroidInputContext::QAndroidInputContext()
return;
}
QJNIEnvironmentPrivate env;
if (Q_UNLIKELY(env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0)) {
qCritical() << "RegisterNatives failed for '"
<< QtNativeInputConnectionClassName
@ -450,7 +448,7 @@ QAndroidInputContext::QAndroidInputContext()
return;
}
clazz = QJNIEnvironmentPrivate::findClass(QtExtractedTextClassName);
clazz = env.findClass(QtExtractedTextClassName);
if (Q_UNLIKELY(!clazz)) {
qCritical() << "Native registration unable to find class '"
<< QtExtractedTextClassName

View File

@ -90,19 +90,19 @@ bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
QString str = htmlText(opt->windowTitle());
if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setTile", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
m_javaMessageDialog.callMethod<void>("setTile", "(Ljava/lang/String;)V", QJniObject::fromString(str).object());
str = htmlText(opt->text());
if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
m_javaMessageDialog.callMethod<void>("setText", "(Ljava/lang/String;)V", QJniObject::fromString(str).object());
str = htmlText(opt->informativeText());
if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setInformativeText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
m_javaMessageDialog.callMethod<void>("setInformativeText", "(Ljava/lang/String;)V", QJniObject::fromString(str).object());
str = htmlText(opt->detailedText());
if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setDetailedText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
m_javaMessageDialog.callMethod<void>("setDetailedText", "(Ljava/lang/String;)V", QJniObject::fromString(str).object());
const int * currentLayout = buttonLayout(Qt::Horizontal, AndroidLayout);
while (*currentLayout != QPlatformDialogHelper::EOL) {
@ -123,7 +123,7 @@ void QAndroidPlatformMessageDialogHelper::addButtons(QSharedPointer<QMessageDial
QString label = b.label;
label.remove(QChar('&'));
m_javaMessageDialog.callMethod<void>("addButton", "(ILjava/lang/String;)V", b.id,
QJNIObjectPrivate::fromString(label).object());
QJniObject::fromString(label).object());
}
}
@ -131,7 +131,7 @@ void QAndroidPlatformMessageDialogHelper::addButtons(QSharedPointer<QMessageDial
StandardButton b = static_cast<StandardButton>(i);
if (buttonRole(b) == role && (opt->standardButtons() & i)) {
const QString text = QGuiApplicationPrivate::platformTheme()->standardButtonText(b);
m_javaMessageDialog.callMethod<void>("addButton", "(ILjava/lang/String;)V", i, QJNIObjectPrivate::fromString(text).object());
m_javaMessageDialog.callMethod<void>("addButton", "(ILjava/lang/String;)V", i, QJniObject::fromString(text).object());
}
}
}
@ -183,7 +183,8 @@ static JNINativeMethod methods[] = {
bool registerNatives(JNIEnv *env)
{
jclass clazz = QJNIEnvironmentPrivate::findClass(QtMessageHandlerHelperClassName, env);
QJniEnvironment qenv;
jclass clazz = qenv.findClass(QtMessageHandlerHelperClassName);
if (!clazz) {
__android_log_print(ANDROID_LOG_FATAL, QtAndroid::qtTagText(), QtAndroid::classErrorMsgFmt()
, QtMessageHandlerHelperClassName);

View File

@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -39,10 +40,13 @@
#ifndef QANDROIDPLATFORMDIALOGHELPERS_H
#define QANDROIDPLATFORMDIALOGHELPERS_H
#include <jni.h>
#include <qpa/qplatformdialoghelper.h>
#include <QEventLoop>
#include <private/qjni_p.h>
#include <QtCore/QJniEnvironment>
#include <QtCore/QJniObject>
#include <qpa/qplatformdialoghelper.h>
QT_BEGIN_NAMESPACE
@ -68,7 +72,7 @@ private:
private:
int m_buttonId;
QEventLoop m_loop;
QJNIObjectPrivate m_javaMessageDialog;
QJniObject m_javaMessageDialog;
bool m_shown;
};

View File

@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB)
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -40,10 +41,10 @@
#include "qandroidplatformfiledialoghelper.h"
#include <androidjnimain.h>
#include <jni.h>
#include <QtCore/QJniObject>
#include <QMimeType>
#include <QMimeDatabase>
#include <QMimeType>
#include <QRegularExpression>
QT_BEGIN_NAMESPACE
@ -71,9 +72,9 @@ bool QAndroidPlatformFileDialogHelper::handleActivityResult(jint requestCode, ji
return true;
}
const QJNIObjectPrivate intent = QJNIObjectPrivate::fromLocalRef(data);
const QJniObject intent = QJniObject::fromLocalRef(data);
const QJNIObjectPrivate uri = intent.callObjectMethod("getData", "()Landroid/net/Uri;");
const QJniObject uri = intent.callObjectMethod("getData", "()Landroid/net/Uri;");
if (uri.isValid()) {
takePersistableUriPermission(uri);
m_selectedFile.append(QUrl(uri.toString()));
@ -83,15 +84,15 @@ bool QAndroidPlatformFileDialogHelper::handleActivityResult(jint requestCode, ji
return true;
}
const QJNIObjectPrivate uriClipData =
const QJniObject uriClipData =
intent.callObjectMethod("getClipData", "()Landroid/content/ClipData;");
if (uriClipData.isValid()) {
const int size = uriClipData.callMethod<jint>("getItemCount");
for (int i = 0; i < size; ++i) {
QJNIObjectPrivate item = uriClipData.callObjectMethod(
QJniObject item = uriClipData.callObjectMethod(
"getItemAt", "(I)Landroid/content/ClipData$Item;", i);
QJNIObjectPrivate itemUri = item.callObjectMethod("getUri", "()Landroid/net/Uri;");
QJniObject itemUri = item.callObjectMethod("getUri", "()Landroid/net/Uri;");
takePersistableUriPermission(itemUri);
m_selectedFile.append(itemUri.toString());
}
@ -102,17 +103,17 @@ bool QAndroidPlatformFileDialogHelper::handleActivityResult(jint requestCode, ji
return true;
}
void QAndroidPlatformFileDialogHelper::takePersistableUriPermission(const QJNIObjectPrivate &uri)
void QAndroidPlatformFileDialogHelper::takePersistableUriPermission(const QJniObject &uri)
{
int modeFlags = QJNIObjectPrivate::getStaticField<jint>(
int modeFlags = QJniObject::getStaticField<jint>(
JniIntentClass, "FLAG_GRANT_READ_URI_PERMISSION");
if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
modeFlags |= QJNIObjectPrivate::getStaticField<jint>(
modeFlags |= QJniObject::getStaticField<jint>(
JniIntentClass, "FLAG_GRANT_WRITE_URI_PERMISSION");
}
QJNIObjectPrivate contentResolver = m_activity.callObjectMethod(
QJniObject contentResolver = m_activity.callObjectMethod(
"getContentResolver", "()Landroid/content/ContentResolver;");
contentResolver.callMethod<void>("takePersistableUriPermission", "(Landroid/net/Uri;I)V",
uri.object(), modeFlags);
@ -120,16 +121,16 @@ void QAndroidPlatformFileDialogHelper::takePersistableUriPermission(const QJNIOb
void QAndroidPlatformFileDialogHelper::setIntentTitle(const QString &title)
{
const QJNIObjectPrivate extraTitle = QJNIObjectPrivate::getStaticObjectField(
const QJniObject extraTitle = QJniObject::getStaticObjectField(
JniIntentClass, "EXTRA_TITLE", "Ljava/lang/String;");
m_intent.callObjectMethod("putExtra",
"(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
extraTitle.object(), QJNIObjectPrivate::fromString(title).object());
extraTitle.object(), QJniObject::fromString(title).object());
}
void QAndroidPlatformFileDialogHelper::setOpenableCategory()
{
const QJNIObjectPrivate CATEGORY_OPENABLE = QJNIObjectPrivate::getStaticObjectField(
const QJniObject CATEGORY_OPENABLE = QJniObject::getStaticObjectField(
JniIntentClass, "CATEGORY_OPENABLE", "Ljava/lang/String;");
m_intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;",
CATEGORY_OPENABLE.object());
@ -137,7 +138,7 @@ void QAndroidPlatformFileDialogHelper::setOpenableCategory()
void QAndroidPlatformFileDialogHelper::setAllowMultipleSelections(bool allowMultiple)
{
const QJNIObjectPrivate allowMultipleSelections = QJNIObjectPrivate::getStaticObjectField(
const QJniObject allowMultipleSelections = QJniObject::getStaticObjectField(
JniIntentClass, "EXTRA_ALLOW_MULTIPLE", "Ljava/lang/String;");
m_intent.callObjectMethod("putExtra", "(Ljava/lang/String;Z)Landroid/content/Intent;",
allowMultipleSelections.object(), allowMultiple);
@ -169,17 +170,17 @@ void QAndroidPlatformFileDialogHelper::setMimeTypes()
QString type = !mimeTypes.isEmpty() ? mimeTypes.at(0) : QLatin1String("*/*");
m_intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;",
QJNIObjectPrivate::fromString(type).object());
QJniObject::fromString(type).object());
if (!mimeTypes.isEmpty()) {
const QJNIObjectPrivate extraMimeType = QJNIObjectPrivate::getStaticObjectField(
const QJniObject extraMimeType = QJniObject::getStaticObjectField(
JniIntentClass, "EXTRA_MIME_TYPES", "Ljava/lang/String;");
QJNIObjectPrivate mimeTypesArray = QJNIObjectPrivate::callStaticObjectMethod(
QJniObject mimeTypesArray = QJniObject::callStaticObjectMethod(
"org/qtproject/qt/android/QtNative",
"getStringArray",
"(Ljava/lang/String;)[Ljava/lang/String;",
QJNIObjectPrivate::fromString(mimeTypes.join(",")).object());
QJniObject::fromString(mimeTypes.join(",")).object());
m_intent.callObjectMethod(
"putExtra", "(Ljava/lang/String;[Ljava/lang/String;)Landroid/content/Intent;",
@ -187,11 +188,11 @@ void QAndroidPlatformFileDialogHelper::setMimeTypes()
}
}
QJNIObjectPrivate QAndroidPlatformFileDialogHelper::getFileDialogIntent(const QString &intentType)
QJniObject QAndroidPlatformFileDialogHelper::getFileDialogIntent(const QString &intentType)
{
const QJNIObjectPrivate ACTION_OPEN_DOCUMENT = QJNIObjectPrivate::getStaticObjectField(
const QJniObject ACTION_OPEN_DOCUMENT = QJniObject::getStaticObjectField(
JniIntentClass, intentType.toLatin1(), "Ljava/lang/String;");
return QJNIObjectPrivate(JniIntentClass, "(Ljava/lang/String;)V",
return QJniObject(JniIntentClass, "(Ljava/lang/String;)V",
ACTION_OPEN_DOCUMENT.object());
}

View File

@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB)
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -41,11 +42,11 @@
#define QANDROIDPLATFORMFILEDIALOGHELPER_H
#include <jni.h>
#include <QEventLoop>
#include <qpa/qplatformdialoghelper.h>
#include <QtCore/QJniObject>
#include <QtCore/private/qjnihelpers_p.h>
#include <private/qjni_p.h>
#include <QEventLoop>
#include <qpa/qplatformdialoghelper.h>
QT_BEGIN_NAMESPACE
@ -73,8 +74,8 @@ public:
bool handleActivityResult(jint requestCode, jint resultCode, jobject data) override;
private:
QJNIObjectPrivate getFileDialogIntent(const QString &intentType);
void takePersistableUriPermission(const QJNIObjectPrivate &uri);
QJniObject getFileDialogIntent(const QString &intentType);
void takePersistableUriPermission(const QJniObject &uri);
void setIntentTitle(const QString &title);
void setOpenableCategory();
void setAllowMultipleSelections(bool allowMultiple);
@ -82,8 +83,8 @@ private:
QEventLoop m_eventLoop;
QList<QUrl> m_selectedFile;
QJNIObjectPrivate m_intent;
const QJNIObjectPrivate m_activity;
QJniObject m_intent;
const QJniObject m_activity;
};
}

View File

@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -42,7 +42,8 @@
#include "androidsurfaceclient.h"
#include "qandroidplatformwindow.h"
#include <QtCore/private/qjni_p.h>
#include <QtCore/QJniObject>
QT_BEGIN_NAMESPACE
@ -61,7 +62,7 @@ public:
private:
int m_surfaceId;
QJNIObjectPrivate m_view;
QJniObject m_view;
};
QT_END_NAMESPACE

View File

@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -39,35 +40,34 @@
#include "qandroidplatformintegration.h"
#include <QtCore/private/qjni_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QGuiApplication>
#include <QOpenGLContext>
#include <QOffscreenSurface>
#include <QtGui/private/qoffscreensurface_p.h>
#include <QThread>
#include <QtGui/private/qeglpbuffer_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qplatformoffscreensurface.h>
#include "androidjnimain.h"
#include "androidjniaccessibility.h"
#include "androidjnimain.h"
#include "qabstracteventdispatcher.h"
#include "qandroideventdispatcher.h"
#include "qandroidplatformbackingstore.h"
#include "qandroidplatformaccessibility.h"
#include "qandroidplatformbackingstore.h"
#include "qandroidplatformclipboard.h"
#include "qandroidplatformforeignwindow.h"
#include "qandroidplatformfontdatabase.h"
#include "qandroidplatformforeignwindow.h"
#include "qandroidplatformoffscreensurface.h"
#include "qandroidplatformopenglcontext.h"
#include "qandroidplatformopenglwindow.h"
#include "qandroidplatformscreen.h"
#include "qandroidplatformservices.h"
#include "qandroidplatformtheme.h"
#include "qandroidsystemlocale.h"
#include "qandroidplatformoffscreensurface.h"
#include <QGuiApplication>
#include <QOffscreenSurface>
#include <QOpenGLContext>
#include <QThread>
#include <QtCore/QJniObject>
#include <QtGui/private/qeglpbuffer_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtGui/private/qoffscreensurface_p.h>
#include <qpa/qplatformoffscreensurface.h>
#include <qpa/qplatformwindow.h>
#include <qpa/qwindowsysteminterface.h>
#include <jni.h>
@ -200,17 +200,17 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
m_accessibility = new QAndroidPlatformAccessibility();
#endif // QT_NO_ACCESSIBILITY
QJNIObjectPrivate javaActivity(QtAndroid::activity());
QJniObject javaActivity(QtAndroid::activity());
if (!javaActivity.isValid())
javaActivity = QtAndroid::service();
if (javaActivity.isValid()) {
QJNIObjectPrivate resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
QJNIObjectPrivate configuration = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;");
QJniObject resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
QJniObject configuration = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;");
int touchScreen = configuration.getField<jint>("touchscreen");
if (touchScreen == QJNIObjectPrivate::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_FINGER")
|| touchScreen == QJNIObjectPrivate::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_STYLUS"))
if (touchScreen == QJniObject::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_FINGER")
|| touchScreen == QJniObject::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_STYLUS"))
{
m_touchDevice = new QPointingDevice;
m_touchDevice->setType(QInputDevice::DeviceType::TouchScreen);
@ -219,16 +219,16 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
| QPointingDevice::Capability::Pressure
| QPointingDevice::Capability::NormalizedPosition);
QJNIObjectPrivate pm = javaActivity.callObjectMethod("getPackageManager", "()Landroid/content/pm/PackageManager;");
QJniObject pm = javaActivity.callObjectMethod("getPackageManager", "()Landroid/content/pm/PackageManager;");
Q_ASSERT(pm.isValid());
if (pm.callMethod<jboolean>("hasSystemFeature","(Ljava/lang/String;)Z",
QJNIObjectPrivate::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND", "Ljava/lang/String;").object())) {
QJniObject::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND", "Ljava/lang/String;").object())) {
m_touchDevice->setMaximumTouchPoints(10);
} else if (pm.callMethod<jboolean>("hasSystemFeature","(Ljava/lang/String;)Z",
QJNIObjectPrivate::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT", "Ljava/lang/String;").object())) {
QJniObject::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT", "Ljava/lang/String;").object())) {
m_touchDevice->setMaximumTouchPoints(4);
} else if (pm.callMethod<jboolean>("hasSystemFeature","(Ljava/lang/String;)Z",
QJNIObjectPrivate::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH", "Ljava/lang/String;").object())) {
QJniObject::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH", "Ljava/lang/String;").object())) {
m_touchDevice->setMaximumTouchPoints(2);
}
QWindowSystemInterface::registerInputDevice(m_touchDevice);
@ -236,11 +236,14 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
auto contentResolver = javaActivity.callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;");
Q_ASSERT(contentResolver.isValid());
QJNIObjectPrivate txtShowPassValue = QJNIObjectPrivate::callStaticObjectMethod("android/provider/Settings$System",
"getString",
"(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;",
contentResolver.object(),
QJNIObjectPrivate::getStaticObjectField("android/provider/Settings$System", "TEXT_SHOW_PASSWORD", "Ljava/lang/String;").object());
QJniObject txtShowPassValue = QJniObject::callStaticObjectMethod(
"android/provider/Settings$System",
"getString",
"(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;",
contentResolver.object(),
QJniObject::getStaticObjectField("android/provider/Settings$System",
"TEXT_SHOW_PASSWORD",
"Ljava/lang/String;").object());
if (txtShowPassValue.isValid()) {
bool ok = false;
const int txtShowPass = txtShowPassValue.toString().toInt(&ok);

View File

@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the plugins of the Qt Toolkit.
@ -37,10 +38,12 @@
**
****************************************************************************/
#include "androidjnimenu.h"
#include "qandroidplatformmenu.h"
#include "qandroidplatformmenuitem.h"
#include "androidjnimenu.h"
#include <QtCore/private/qjni_p.h>
#include <QtCore/qjnienvironment.h>
#include <QtCore/qjniobject.h>
QT_BEGIN_NAMESPACE
@ -152,7 +155,7 @@ void QAndroidPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &t
Q_UNUSED(parentWindow);
Q_UNUSED(item);
setVisible(true);
QtAndroidMenu::showContextMenu(this, targetRect, QJNIEnvironmentPrivate());
QtAndroidMenu::showContextMenu(this, targetRect, QJniEnvironment());
}
QPlatformMenuItem *QAndroidPlatformMenu::menuItemForTag(quintptr tag) const

View File

@ -40,20 +40,20 @@
#include "qandroidplatformopenglwindow.h"
#include "qandroidplatformscreen.h"
#include "androiddeadlockprotector.h"
#include "androidjnimain.h"
#include "qandroideventdispatcher.h"
#include "androiddeadlockprotector.h"
#include "qandroidplatformscreen.h"
#include <QSurfaceFormat>
#include <QtGui/private/qwindow_p.h>
#include <QtGui/qguiapplication.h>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformscreen.h>
#include <QtGui/private/qeglconvenience_p.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
#include <qpa/qplatformscreen.h>
#include <qpa/qwindowsysteminterface.h>
QT_BEGIN_NAMESPACE
@ -175,9 +175,9 @@ void QAndroidPlatformOpenGLWindow::applicationStateChanged(Qt::ApplicationState
void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
{
clearEgl();
QJNIEnvironmentPrivate env;
QJniEnvironment env;
m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object());
m_androidSurfaceObject = QJNIObjectPrivate();
m_androidSurfaceObject = QJniObject();
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_nativeWindow, NULL);
m_format = q_glFormatFromConfig(m_eglDisplay, config, window()->requestedFormat());
if (Q_UNLIKELY(m_eglSurface == EGL_NO_SURFACE)) {

View File

@ -41,13 +41,15 @@
#ifndef QANDROIDPLATFORMOPENGLWINDOW_H
#define QANDROIDPLATFORMOPENGLWINDOW_H
#include <EGL/egl.h>
#include <QWaitCondition>
#include <QtCore/private/qjni_p.h>
#include "androidsurfaceclient.h"
#include "qandroidplatformwindow.h"
#include <QWaitCondition>
#include <QtCore/qjnienvironment.h>
#include <QtCore/qjniobject.h>
#include <EGL/egl.h>
QT_BEGIN_NAMESPACE
class QAndroidPlatformOpenGLWindow : public QAndroidPlatformWindow, public AndroidSurfaceClient
@ -77,7 +79,7 @@ private:
EGLNativeWindowType m_nativeWindow = nullptr;
int m_nativeSurfaceId = -1;
QJNIObjectPrivate m_androidSurfaceObject;
QJniObject m_androidSurfaceObject;
QWaitCondition m_surfaceWaitCondition;
QSurfaceFormat m_format;
QRect m_oldGeometry;

View File

@ -41,14 +41,14 @@
#ifndef QANDROIDPLATFORMSCREEN_H
#define QANDROIDPLATFORMSCREEN_H
#include <qpa/qplatformscreen.h>
#include "androidsurfaceclient.h"
#include <QList>
#include <QPainter>
#include <QTimer>
#include <QWaitCondition>
#include <QtCore/private/qjni_p.h>
#include "androidsurfaceclient.h"
#include <QtCore/QJniObject>
#include <qpa/qplatformscreen.h>
#include <android/native_window.h>

View File

@ -38,11 +38,12 @@
****************************************************************************/
#include "qandroidplatformservices.h"
#include <QUrl>
#include <QFile>
#include <QDebug>
#include <QFile>
#include <QMimeDatabase>
#include <QtCore/private/qjni_p.h>
#include <QUrl>
#include <QtCore/QJniObject>
#include <private/qjnihelpers_p.h>
QT_BEGIN_NAMESPACE
@ -66,9 +67,9 @@ bool QAndroidPlatformServices::openUrl(const QUrl &theUrl)
mime = mimeDb.mimeTypeForUrl(url).name();
}
QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString());
QJNIObjectPrivate mimeString = QJNIObjectPrivate::fromString(mime);
return QJNIObjectPrivate::callStaticMethod<jboolean>(
QJniObject urlString = QJniObject::fromString(url.toString());
QJniObject mimeString = QJniObject::fromString(mime);
return QJniObject::callStaticMethod<jboolean>(
QtAndroid::applicationClass(), "openURL",
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Z",
QtAndroidPrivate::context(), urlString.object(), mimeString.object());

View File

@ -37,15 +37,15 @@
**
****************************************************************************/
#include "qandroidplatformvulkanwindow.h"
#include "qandroidplatformscreen.h"
#include "androiddeadlockprotector.h"
#include "androidjnimain.h"
#include "qandroideventdispatcher.h"
#include "androiddeadlockprotector.h"
#include "qandroidplatformscreen.h"
#include "qandroidplatformvulkanwindow.h"
#include <QSurfaceFormat>
#include <qpa/qwindowsysteminterface.h>
#include <qpa/qplatformscreen.h>
#include <qpa/qwindowsysteminterface.h>
#include <android/native_window.h>
#include <android/native_window_jni.h>
@ -172,7 +172,7 @@ VkSurfaceKHR *QAndroidPlatformVulkanWindow::vkSurface()
if (m_nativeSurfaceId == -1 || !m_androidSurfaceObject.isValid())
return &m_vkSurface;
QJNIEnvironmentPrivate env;
QJniEnvironment env;
m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object());
VkAndroidSurfaceCreateInfoKHR surfaceInfo;

View File

@ -46,13 +46,13 @@
#define VK_USE_PLATFORM_ANDROID_KHR
#include <QWaitCondition>
#include <QtCore/private/qjni_p.h>
#include "androidsurfaceclient.h"
#include "qandroidplatformvulkaninstance.h"
#include "qandroidplatformwindow.h"
#include "qandroidplatformvulkaninstance.h"
#include <QWaitCondition>
#include <QtCore/QJniEnvironment>
#include <QtCore/QJniObject>
QT_BEGIN_NAMESPACE
@ -77,7 +77,7 @@ private:
int m_nativeSurfaceId;
ANativeWindow *m_nativeWindow;
QJNIObjectPrivate m_androidSurfaceObject;
QJniObject m_androidSurfaceObject;
QWaitCondition m_surfaceWaitCondition;
QSurfaceFormat m_format;
QRect m_oldGeometry;

View File

@ -37,14 +37,15 @@
**
****************************************************************************/
#include "qandroidsystemlocale.h"
#include "androidjnimain.h"
#include <QtCore/private/qjni_p.h>
#include <QtCore/private/qjnihelpers_p.h>
#include "qandroidsystemlocale.h"
#include "qdatetime.h"
#include "qstringlist.h"
#include "qvariant.h"
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/QJniObject>
QT_BEGIN_NAMESPACE
QAndroidSystemLocale::QAndroidSystemLocale() : m_locale(QLocale::C)
@ -55,17 +56,17 @@ void QAndroidSystemLocale::getLocaleFromJava() const
{
QWriteLocker locker(&m_lock);
QJNIObjectPrivate javaLocaleObject;
QJNIObjectPrivate javaActivity(QtAndroid::activity());
QJniObject javaLocaleObject;
QJniObject javaActivity(QtAndroid::activity());
if (!javaActivity.isValid())
javaActivity = QtAndroid::service();
if (javaActivity.isValid()) {
QJNIObjectPrivate resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
QJNIObjectPrivate configuration = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;");
QJniObject resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
QJniObject configuration = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;");
javaLocaleObject = configuration.getObjectField("locale", "Ljava/util/Locale;");
} else {
javaLocaleObject = QJNIObjectPrivate::callStaticObjectMethod("java/util/Locale", "getDefault", "()Ljava/util/Locale;");
javaLocaleObject = QJniObject::callStaticObjectMethod("java/util/Locale", "getDefault", "()Ljava/util/Locale;");
}
QString languageCode = javaLocaleObject.callObjectMethod("getLanguage", "()Ljava/lang/String;").toString();
@ -165,9 +166,9 @@ QVariant QAndroidSystemLocale::query(QueryType type, QVariant in) const
Q_ASSERT_X(false, Q_FUNC_INFO, "This can't happen.");
case UILanguages: {
if (QtAndroidPrivate::androidSdkVersion() >= 24) {
QJNIObjectPrivate localeListObject =
QJNIObjectPrivate::callStaticObjectMethod("android/os/LocaleList", "getDefault",
"()Landroid/os/LocaleList;");
QJniObject localeListObject =
QJniObject::callStaticObjectMethod("android/os/LocaleList", "getDefault",
"()Landroid/os/LocaleList;");
if (localeListObject.isValid()) {
QString lang = localeListObject.callObjectMethod("toLanguageTags",
"()Ljava/lang/String;").toString();

View File

@ -45,3 +45,7 @@ endif()
if(QT_FEATURE_private_tests)
add_subdirectory(qproperty)
endif()
if(ANDROID AND NOT ANDROID_EMBEDDED)
add_subdirectory(qjnienvironment)
add_subdirectory(qjniobject)
endif()

View File

@ -0,0 +1,8 @@
#####################################################################
## tst_qjnienvironment Test:
#####################################################################
qt_internal_add_test(tst_qjnienvironment
SOURCES
tst_qjnienvironment.cpp
)

View File

@ -0,0 +1,106 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtCore/QJniEnvironment>
#include <QtTest/QtTest>
class tst_QJniEnvironment : public QObject
{
Q_OBJECT
private slots:
void jniEnv();
void javaVM();
};
void tst_QJniEnvironment::jniEnv()
{
QJniEnvironment env;
JavaVM *javaVM = env.javaVM();
QVERIFY(javaVM);
{
// JNI environment should now be attached to the current thread
JNIEnv *jni = 0;
QCOMPARE(javaVM->GetEnv((void**)&jni, JNI_VERSION_1_6), JNI_OK);
JNIEnv *e = env;
QVERIFY(e);
QCOMPARE(env->GetVersion(), JNI_VERSION_1_6);
// try to find an existing class
QVERIFY(env->FindClass("java/lang/Object"));
QVERIFY(!env->ExceptionCheck());
// try to find a nonexistent class
QVERIFY(!env->FindClass("this/doesnt/Exist"));
QVERIFY(env->ExceptionCheck());
env->ExceptionClear();
QVERIFY(env->FindClass("java/lang/Object"));
QVERIFY(!QJniEnvironment::exceptionCheckAndClear(env));
// try to find a nonexistent class
QVERIFY(!env->FindClass("this/doesnt/Exist"));
QVERIFY(QJniEnvironment::exceptionCheckAndClear(env));
// try to find an existing class with QJniEnvironment
QJniEnvironment env;
QVERIFY(env.findClass("java/lang/Object"));
// try to find a nonexistent class
QVERIFY(!env.findClass("this/doesnt/Exist"));
// clear exception with member function
QVERIFY(!env->FindClass("this/doesnt/Exist"));
QVERIFY(env.exceptionCheckAndClear());
}
// The env does not detach automatically, even if it goes out of scope. The only way it can
// be detached is if it's done explicitly, or if the thread we attached to gets killed (TLS clean-up).
JNIEnv *jni = nullptr;
QCOMPARE(javaVM->GetEnv((void**)&jni, JNI_VERSION_1_6), JNI_OK);
}
void tst_QJniEnvironment::javaVM()
{
QJniEnvironment env;
JavaVM *javaVM = env.javaVM();
QVERIFY(javaVM);
QCOMPARE(env.javaVM(), javaVM);
JavaVM *vm = 0;
QCOMPARE(env->GetJavaVM(&vm), JNI_OK);
QCOMPARE(env.javaVM(), vm);
}
QTEST_MAIN(tst_QJniEnvironment)
#include "tst_qjnienvironment.moc"

View File

@ -0,0 +1,16 @@
#####################################################################
## tst_qjniobject Test:
#####################################################################
qt_internal_add_test(tst_qjniobject
SOURCES
tst_qjniobject.cpp
)
if(ANDROID)
set_property(TARGET tst_qjniobject APPEND PROPERTY QT_ANDROID_PACKAGE_SOURCE_DIR
${CMAKE_CURRENT_SOURCE_DIR}/testdata
)
# QTBUG-88840 # special case
qt_android_generate_deployment_settings(tst_qjniobject) # special case
endif()

View File

@ -0,0 +1,177 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
package org.qtproject.qt.android.testdatapackage;
public class QtJniObjectTestClass
{
static final byte A_BYTE_VALUE = 127;
static final short A_SHORT_VALUE = 32767;
static final int A_INT_VALUE = 060701;
static final long A_LONG_VALUE = 060701;
static final float A_FLOAT_VALUE = 1.0f;
static final double A_DOUBLE_VALUE = 1.0;
static final boolean A_BOOLEAN_VALUE = true;
static final char A_CHAR_VALUE = 'Q';
static final String A_STRING_OBJECT = "TEST_DATA_STRING";
static final Class A_CLASS_OBJECT = QtJniObjectTestClass.class;
static final Object A_OBJECT_OBJECT = new QtJniObjectTestClass();
static final Throwable A_THROWABLE_OBJECT = new Throwable(A_STRING_OBJECT);
// --------------------------------------------------------------------------------------------
public static void staticVoidMethod() { return; }
public static void staticVoidMethodWithArgs(int a, boolean b, char c) { return; }
public void voidMethod() { return; }
public void voidMethodWithArgs(int a, boolean b, char c) { return; }
// --------------------------------------------------------------------------------------------
public static boolean staticBooleanMethod() { return A_BOOLEAN_VALUE; }
public static boolean staticBooleanMethodWithArgs(boolean a, boolean b, boolean c)
{ return staticBooleanMethod(); }
public boolean booleanMethod() { return staticBooleanMethod(); }
public boolean booleanMethodWithArgs(boolean a, boolean b, boolean c)
{ return staticBooleanMethodWithArgs(a, b, c); }
// --------------------------------------------------------------------------------------------
public static byte staticByteMethod() { return A_BYTE_VALUE; }
public static byte staticByteMethodWithArgs(byte a, byte b, byte c) { return staticByteMethod(); }
public byte byteMethod() { return staticByteMethod(); }
public byte byteMethodWithArgs(byte a, byte b, byte c)
{ return staticByteMethodWithArgs(a, b, c); }
// --------------------------------------------------------------------------------------------
public static char staticCharMethod() { return A_CHAR_VALUE; }
public static char staticCharMethodWithArgs(char a, char b, char c) { return staticCharMethod(); }
public char charMethod() { return staticCharMethod(); }
public char charMethodWithArgs(char a, char b, char c)
{ return staticCharMethodWithArgs(a, b, c); }
// --------------------------------------------------------------------------------------------
public static short staticShortMethod() { return A_SHORT_VALUE; }
public static short staticShortMethodWithArgs(short a, short b, short c) { return staticShortMethod(); }
public short shortMethod() { return staticShortMethod(); }
public short shortMethodWithArgs(short a, short b, short c)
{ return staticShortMethodWithArgs(a, b, c); }
// --------------------------------------------------------------------------------------------
public static int staticIntMethod() { return A_INT_VALUE; }
public static int staticIntMethodWithArgs(int a, int b, int c) { return staticIntMethod(); }
public int intMethod() { return staticIntMethod(); }
public int intMethodWithArgs(int a, int b, int c) { return staticIntMethodWithArgs(a, b, c); }
// --------------------------------------------------------------------------------------------
public static long staticLongMethod() { return A_LONG_VALUE; }
public static long staticLongMethodWithArgs(long a, long b, long c) { return staticLongMethod(); }
public long longMethod() { return staticLongMethod(); }
public long longMethodWithArgs(long a, long b, long c)
{ return staticLongMethodWithArgs(a, b, c); }
// --------------------------------------------------------------------------------------------
public static float staticFloatMethod() { return A_FLOAT_VALUE; }
public static float staticFloatMethodWithArgs(float a, float b, float c) { return staticFloatMethod(); }
public float floatMethod() { return staticFloatMethod(); }
public float floatMethodWithArgs(float a, float b, float c)
{ return staticFloatMethodWithArgs(a, b, c); }
// --------------------------------------------------------------------------------------------
public static double staticDoubleMethod() { return A_DOUBLE_VALUE; }
public static double staticDoubleMethodWithArgs(double a, double b, double c)
{ return staticDoubleMethod(); }
public double doubleMethod() { return staticDoubleMethod(); }
public double doubleMethodWithArgs(double a, double b, double c)
{ return staticDoubleMethodWithArgs(a, b, c); }
// --------------------------------------------------------------------------------------------
public static Object staticObjectMethod() { return A_OBJECT_OBJECT; }
public Object objectMethod() { return staticObjectMethod(); }
// --------------------------------------------------------------------------------------------
public static Class staticClassMethod() { return A_CLASS_OBJECT; }
public Class classMethod() { return staticClassMethod(); }
// --------------------------------------------------------------------------------------------
public static String staticStringMethod() { return A_STRING_OBJECT; }
public String stringMethod() { return staticStringMethod(); }
// --------------------------------------------------------------------------------------------
public static Throwable staticThrowableMethod() { return A_THROWABLE_OBJECT; }
public Throwable throwableMethod() { return staticThrowableMethod(); }
// --------------------------------------------------------------------------------------------
public static Object[] staticObjectArrayMethod()
{ Object[] array = { new Object(), new Object(), new Object() }; return array; }
public Object[] objectArrayMethod() { return staticObjectArrayMethod(); }
// --------------------------------------------------------------------------------------------
public static boolean[] staticBooleanArrayMethod()
{ boolean[] array = { true, true, true }; return array; }
public boolean[] booleanArrayMethod() { return staticBooleanArrayMethod(); }
// --------------------------------------------------------------------------------------------
public static byte[] staticByteArrayMethod()
{ byte[] array = { 'a', 'b', 'c' }; return array; }
public byte[] byteArrayMethod() { return staticByteArrayMethod(); }
// --------------------------------------------------------------------------------------------
public static char[] staticCharArrayMethod()
{ char[] array = { 'a', 'b', 'c' }; return array; }
public char[] charArrayMethod() { return staticCharArrayMethod(); }
// --------------------------------------------------------------------------------------------
public static short[] staticShortArrayMethod() { short[] array = { 3, 2, 1 }; return array; }
public short[] shortArrayMethod() { return staticShortArrayMethod(); }
// --------------------------------------------------------------------------------------------
public static int[] staticIntArrayMethod() { int[] array = { 3, 2, 1 }; return array; }
public int[] intArrayMethod() { return staticIntArrayMethod(); }
// --------------------------------------------------------------------------------------------
public static long[] staticLongArrayMethod()
{ long[] array = { 3, 2, 1 }; return array; }
public long[] longArrayMethod() { return staticLongArrayMethod(); }
// --------------------------------------------------------------------------------------------
public static float[] staticFloatArrayMethod()
{ float[] array = { 1.0f, 2.0f, 3.0f }; return array; }
public float[] floatArrayMethod() { return staticFloatArrayMethod(); }
// --------------------------------------------------------------------------------------------
public static double[] staticDoubleArrayMethod()
{ double[] array = { 3.0, 2.0, 1.0 }; return array; }
public double[] doubleArrayMethod() { return staticDoubleArrayMethod(); }
}

File diff suppressed because it is too large Load Diff