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:
parent
407ce5c0af
commit
4e60681c87
@ -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
|
||||
)
|
||||
|
133
src/corelib/doc/snippets/jni/src_qjniobject.cpp
Normal file
133
src/corelib/doc/snippets/jni/src_qjniobject.cpp
Normal 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]
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
283
src/corelib/kernel/qjnienvironment.cpp
Normal file
283
src/corelib/kernel/qjnienvironment.cpp
Normal 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
|
85
src/corelib/kernel/qjnienvironment.h
Normal file
85
src/corelib/kernel/qjnienvironment.h
Normal 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
|
@ -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)
|
||||
|
@ -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);
|
||||
|
1872
src/corelib/kernel/qjniobject.cpp
Normal file
1872
src/corelib/kernel/qjniobject.cpp
Normal file
File diff suppressed because it is too large
Load Diff
207
src/corelib/kernel/qjniobject.h
Normal file
207
src/corelib/kernel/qjniobject.h
Normal 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
|
@ -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";
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 ¶
|
||||
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 ¶
|
||||
| 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 ¶
|
||||
|
||||
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);
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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()
|
||||
|
8
tests/auto/corelib/kernel/qjnienvironment/CMakeLists.txt
Normal file
8
tests/auto/corelib/kernel/qjnienvironment/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
||||
#####################################################################
|
||||
## tst_qjnienvironment Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qjnienvironment
|
||||
SOURCES
|
||||
tst_qjnienvironment.cpp
|
||||
)
|
@ -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"
|
16
tests/auto/corelib/kernel/qjniobject/CMakeLists.txt
Normal file
16
tests/auto/corelib/kernel/qjniobject/CMakeLists.txt
Normal 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()
|
@ -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(); }
|
||||
}
|
||||
|
1054
tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp
Normal file
1054
tests/auto/corelib/kernel/qjniobject/tst_qjniobject.cpp
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user