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/qstandardpaths_android.cpp
|
||||||
io/qstorageinfo_unix.cpp
|
io/qstorageinfo_unix.cpp
|
||||||
kernel/qjni.cpp kernel/qjni_p.h
|
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/qjnihelpers.cpp kernel/qjnihelpers_p.h
|
||||||
kernel/qjnionload.cpp
|
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.
|
** Copyright (C) 2017 Intel Corporation.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -78,7 +78,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|
||||||
#include <private/qjni_p.h>
|
#include <qjniobject.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_SOLARIS)
|
#if defined(Q_OS_SOLARIS)
|
||||||
@ -2296,7 +2296,7 @@ Oreo
|
|||||||
|
|
||||||
// https://source.android.com/source/build-numbers.html
|
// https://source.android.com/source/build-numbers.html
|
||||||
// https://developer.android.com/guide/topics/manifest/uses-sdk-element.html#ApiLevels
|
// 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)]];
|
return &versions_string[versions_indices[qBound(0, sdk_int, versions_count - 1)]];
|
||||||
}
|
}
|
||||||
#endif
|
#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/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtCore module of the Qt Toolkit.
|
** This file is part of the QtCore module of the Qt Toolkit.
|
||||||
@ -50,7 +50,7 @@
|
|||||||
#include <qdebug.h>
|
#include <qdebug.h>
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|
||||||
#include <private/qjni_p.h>
|
#include <QJniObject>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -157,7 +157,7 @@ QOperatingSystemVersion QOperatingSystemVersion::current()
|
|||||||
version.m_os = currentType();
|
version.m_os = currentType();
|
||||||
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|
||||||
#ifndef QT_BOOTSTRAPPED
|
#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());
|
"android/os/Build$VERSION", "RELEASE", "Ljava/lang/String;").toString());
|
||||||
if (!v.isNull()) {
|
if (!v.isNull()) {
|
||||||
version.m_major = v.majorVersion();
|
version.m_major = v.majorVersion();
|
||||||
@ -207,7 +207,7 @@ QOperatingSystemVersion QOperatingSystemVersion::current()
|
|||||||
};
|
};
|
||||||
|
|
||||||
// This will give us at least the first 2 version components
|
// 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;
|
"android/os/Build$VERSION", "SDK_INT")) - 1;
|
||||||
if (versionIdx < sizeof(versions) / sizeof(versions[0])) {
|
if (versionIdx < sizeof(versions) / sizeof(versions[0])) {
|
||||||
version.m_major = versions[versionIdx].major;
|
version.m_major = versions[versionIdx].major;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2020 Intel Corporation.
|
** Copyright (C) 2020 Intel Corporation.
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtCore module of the Qt Toolkit.
|
** 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
|
#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
|
// This file is too low-level for regular Q_ASSERT (the logging framework may
|
||||||
// recurse back), so use regular assert()
|
// recurse back), so use regular assert()
|
||||||
#undef NDEBUG
|
#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/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtCore module of the Qt Toolkit.
|
** This file is part of the QtCore module of the Qt Toolkit.
|
||||||
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
#ifndef QT_NO_STANDARDPATHS
|
#ifndef QT_NO_STANDARDPATHS
|
||||||
|
|
||||||
#include <QtCore/private/qjni_p.h>
|
#include <QJniObject>
|
||||||
#include <QtCore/private/qjnihelpers_p.h>
|
#include <QtCore/private/qjnihelpers_p.h>
|
||||||
#include <QtCore/qmap.h>
|
#include <QtCore/qmap.h>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@ -57,13 +57,13 @@ static QString testDir()
|
|||||||
: QLatin1String("");
|
: QLatin1String("");
|
||||||
}
|
}
|
||||||
|
|
||||||
static QJNIObjectPrivate applicationContext()
|
static QJniObject applicationContext()
|
||||||
{
|
{
|
||||||
static QJNIObjectPrivate appCtx;
|
static QJniObject appCtx;
|
||||||
if (appCtx.isValid())
|
if (appCtx.isValid())
|
||||||
return appCtx;
|
return appCtx;
|
||||||
|
|
||||||
QJNIObjectPrivate context(QtAndroidPrivate::activity());
|
QJniObject context(QtAndroidPrivate::activity());
|
||||||
if (!context.isValid()) {
|
if (!context.isValid()) {
|
||||||
context = QtAndroidPrivate::service();
|
context = QtAndroidPrivate::service();
|
||||||
if (!context.isValid())
|
if (!context.isValid())
|
||||||
@ -75,9 +75,9 @@ static QJNIObjectPrivate applicationContext()
|
|||||||
return appCtx;
|
return appCtx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline QString getAbsolutePath(const QJNIObjectPrivate &file)
|
static inline QString getAbsolutePath(const QJniObject &file)
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate path = file.callObjectMethod("getAbsolutePath",
|
QJniObject path = file.callObjectMethod("getAbsolutePath",
|
||||||
"()Ljava/lang/String;");
|
"()Ljava/lang/String;");
|
||||||
if (!path.isValid())
|
if (!path.isValid())
|
||||||
return QString();
|
return QString();
|
||||||
@ -95,20 +95,20 @@ static QString getExternalFilesDir(const char *directoryField = nullptr)
|
|||||||
if (!path.isEmpty())
|
if (!path.isEmpty())
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
QJNIObjectPrivate appCtx = applicationContext();
|
QJniObject appCtx = applicationContext();
|
||||||
if (!appCtx.isValid())
|
if (!appCtx.isValid())
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
QJNIObjectPrivate dirField = QJNIObjectPrivate::fromString(QLatin1String(""));
|
QJniObject dirField = QJniObject::fromString(QLatin1String(""));
|
||||||
if (directoryField && strlen(directoryField) > 0) {
|
if (directoryField && strlen(directoryField) > 0) {
|
||||||
dirField = QJNIObjectPrivate::getStaticObjectField("android/os/Environment",
|
dirField = QJniObject::getStaticObjectField("android/os/Environment",
|
||||||
directoryField,
|
directoryField,
|
||||||
"Ljava/lang/String;");
|
"Ljava/lang/String;");
|
||||||
if (!dirField.isValid())
|
if (!dirField.isValid())
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
QJNIObjectPrivate file = appCtx.callObjectMethod("getExternalFilesDir",
|
QJniObject file = appCtx.callObjectMethod("getExternalFilesDir",
|
||||||
"(Ljava/lang/String;)Ljava/io/File;",
|
"(Ljava/lang/String;)Ljava/io/File;",
|
||||||
dirField.object());
|
dirField.object());
|
||||||
|
|
||||||
@ -128,11 +128,11 @@ static QString getExternalCacheDir()
|
|||||||
if (!path.isEmpty())
|
if (!path.isEmpty())
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
QJNIObjectPrivate appCtx = applicationContext();
|
QJniObject appCtx = applicationContext();
|
||||||
if (!appCtx.isValid())
|
if (!appCtx.isValid())
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
QJNIObjectPrivate file = appCtx.callObjectMethod("getExternalCacheDir",
|
QJniObject file = appCtx.callObjectMethod("getExternalCacheDir",
|
||||||
"()Ljava/io/File;");
|
"()Ljava/io/File;");
|
||||||
|
|
||||||
if (!file.isValid())
|
if (!file.isValid())
|
||||||
@ -150,11 +150,11 @@ static QString getCacheDir()
|
|||||||
if (!path.isEmpty())
|
if (!path.isEmpty())
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
QJNIObjectPrivate appCtx = applicationContext();
|
QJniObject appCtx = applicationContext();
|
||||||
if (!appCtx.isValid())
|
if (!appCtx.isValid())
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
QJNIObjectPrivate file = appCtx.callObjectMethod("getCacheDir",
|
QJniObject file = appCtx.callObjectMethod("getCacheDir",
|
||||||
"()Ljava/io/File;");
|
"()Ljava/io/File;");
|
||||||
if (!file.isValid())
|
if (!file.isValid())
|
||||||
return QString();
|
return QString();
|
||||||
@ -172,11 +172,11 @@ static QString getFilesDir()
|
|||||||
if (!path.isEmpty())
|
if (!path.isEmpty())
|
||||||
return path;
|
return path;
|
||||||
|
|
||||||
QJNIObjectPrivate appCtx = applicationContext();
|
QJniObject appCtx = applicationContext();
|
||||||
if (!appCtx.isValid())
|
if (!appCtx.isValid())
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
QJNIObjectPrivate file = appCtx.callObjectMethod("getFilesDir",
|
QJniObject file = appCtx.callObjectMethod("getFilesDir",
|
||||||
"()Ljava/io/File;");
|
"()Ljava/io/File;");
|
||||||
if (!file.isValid())
|
if (!file.isValid())
|
||||||
return QString();
|
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.
|
** Copyright (C) 2016 Intel Corporation.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -91,7 +91,7 @@
|
|||||||
#endif // QT_NO_QOBJECT
|
#endif // QT_NO_QOBJECT
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|
||||||
# include <private/qjni_p.h>
|
#include <QJniObject>
|
||||||
#include <private/qjnihelpers_p.h>
|
#include <private/qjnihelpers_p.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -170,17 +170,17 @@ QString QCoreApplicationPrivate::appVersion() const
|
|||||||
# ifdef Q_OS_DARWIN
|
# ifdef Q_OS_DARWIN
|
||||||
applicationVersion = infoDictionaryStringProperty(QStringLiteral("CFBundleVersion"));
|
applicationVersion = infoDictionaryStringProperty(QStringLiteral("CFBundleVersion"));
|
||||||
# elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|
# elif defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|
||||||
QJNIObjectPrivate context(QtAndroidPrivate::context());
|
QJniObject context(QtAndroidPrivate::context());
|
||||||
if (context.isValid()) {
|
if (context.isValid()) {
|
||||||
QJNIObjectPrivate pm = context.callObjectMethod(
|
QJniObject pm = context.callObjectMethod(
|
||||||
"getPackageManager", "()Landroid/content/pm/PackageManager;");
|
"getPackageManager", "()Landroid/content/pm/PackageManager;");
|
||||||
QJNIObjectPrivate pn = context.callObjectMethod<jstring>("getPackageName");
|
QJniObject pn = context.callObjectMethod<jstring>("getPackageName");
|
||||||
if (pm.isValid() && pn.isValid()) {
|
if (pm.isValid() && pn.isValid()) {
|
||||||
QJNIObjectPrivate packageInfo = pm.callObjectMethod(
|
QJniObject packageInfo = pm.callObjectMethod(
|
||||||
"getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;",
|
"getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;",
|
||||||
pn.object(), 0);
|
pn.object(), 0);
|
||||||
if (packageInfo.isValid()) {
|
if (packageInfo.isValid()) {
|
||||||
QJNIObjectPrivate versionName = packageInfo.getObjectField(
|
QJniObject versionName = packageInfo.getObjectField(
|
||||||
"versionName", "Ljava/lang/String;");
|
"versionName", "Ljava/lang/String;");
|
||||||
if (versionName.isValid())
|
if (versionName.isValid())
|
||||||
return versionName.toString();
|
return versionName.toString();
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
//
|
//
|
||||||
// We mean it.
|
// We mean it.
|
||||||
//
|
//
|
||||||
|
// FIXME: Remove this once the JNI API is used by other modules.
|
||||||
|
|
||||||
#ifndef QJNI_P_H
|
#ifndef QJNI_P_H
|
||||||
#define 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 "qjnihelpers_p.h"
|
||||||
#include "qjni_p.h"
|
#include "qjniobject.h"
|
||||||
#include "qmutex.h"
|
|
||||||
#include "qlist.h"
|
#include "qlist.h"
|
||||||
|
#include "qmutex.h"
|
||||||
#include "qsemaphore.h"
|
#include "qsemaphore.h"
|
||||||
#include "qsharedpointer.h"
|
#include "qsharedpointer.h"
|
||||||
#include "qthread.h"
|
#include "qthread.h"
|
||||||
#include "qcoreapplication.h"
|
|
||||||
#include <QtCore/qrunnable.h>
|
#include <QtCore/qrunnable.h>
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
@ -146,7 +148,7 @@ static void sendRequestPermissionsResult(JNIEnv *env, jobject /*obj*/, jint requ
|
|||||||
std::unique_ptr<jint[]> results(new jint[size]);
|
std::unique_ptr<jint[]> results(new jint[size]);
|
||||||
env->GetIntArrayRegion(grantResults, 0, size, results.get());
|
env->GetIntArrayRegion(grantResults, 0, size, results.get());
|
||||||
for (int i = 0 ; i < size; ++i) {
|
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 ?
|
auto value = results[i] == PERMISSION_GRANTED ?
|
||||||
QtAndroidPrivate::PermissionsResult::Granted :
|
QtAndroidPrivate::PermissionsResult::Granted :
|
||||||
QtAndroidPrivate::PermissionsResult::Denied;
|
QtAndroidPrivate::PermissionsResult::Denied;
|
||||||
@ -286,27 +288,14 @@ void QtAndroidPrivate::handleResume()
|
|||||||
listeners.at(i)->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)
|
static void setAndroidSdkVersion(JNIEnv *env)
|
||||||
{
|
{
|
||||||
jclass androidVersionClass = env->FindClass("android/os/Build$VERSION");
|
jclass androidVersionClass = env->FindClass("android/os/Build$VERSION");
|
||||||
if (exceptionCheck(env))
|
if (QJniEnvironment::exceptionCheckAndClear(env))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
jfieldID androidSDKFieldID = env->GetStaticFieldID(androidVersionClass, "SDK_INT", "I");
|
jfieldID androidSDKFieldID = env->GetStaticFieldID(androidVersionClass, "SDK_INT", "I");
|
||||||
if (exceptionCheck(env))
|
if (QJniEnvironment::exceptionCheckAndClear(env))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_androidSdkVersion = env->GetStaticIntField(androidVersionClass, androidSDKFieldID);
|
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");
|
jclass jQtNative = env->FindClass("org/qtproject/qt/android/QtNative");
|
||||||
|
|
||||||
if (exceptionCheck(env))
|
if (QJniEnvironment::exceptionCheckAndClear(env))
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
|
|
||||||
jmethodID activityMethodID = env->GetStaticMethodID(jQtNative,
|
jmethodID activityMethodID = env->GetStaticMethodID(jQtNative,
|
||||||
"activity",
|
"activity",
|
||||||
"()Landroid/app/Activity;");
|
"()Landroid/app/Activity;");
|
||||||
|
|
||||||
if (exceptionCheck(env))
|
if (QJniEnvironment::exceptionCheckAndClear(env))
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
|
|
||||||
jobject activity = env->CallStaticObjectMethod(jQtNative, activityMethodID);
|
jobject activity = env->CallStaticObjectMethod(jQtNative, activityMethodID);
|
||||||
|
|
||||||
if (exceptionCheck(env))
|
if (QJniEnvironment::exceptionCheckAndClear(env))
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
|
|
||||||
jmethodID serviceMethodID = env->GetStaticMethodID(jQtNative,
|
jmethodID serviceMethodID = env->GetStaticMethodID(jQtNative,
|
||||||
"service",
|
"service",
|
||||||
"()Landroid/app/Service;");
|
"()Landroid/app/Service;");
|
||||||
|
|
||||||
if (exceptionCheck(env))
|
if (QJniEnvironment::exceptionCheckAndClear(env))
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
|
|
||||||
jobject service = env->CallStaticObjectMethod(jQtNative, serviceMethodID);
|
jobject service = env->CallStaticObjectMethod(jQtNative, serviceMethodID);
|
||||||
|
|
||||||
if (exceptionCheck(env))
|
if (QJniEnvironment::exceptionCheckAndClear(env))
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
|
|
||||||
jmethodID classLoaderMethodID = env->GetStaticMethodID(jQtNative,
|
jmethodID classLoaderMethodID = env->GetStaticMethodID(jQtNative,
|
||||||
"classLoader",
|
"classLoader",
|
||||||
"()Ljava/lang/ClassLoader;");
|
"()Ljava/lang/ClassLoader;");
|
||||||
|
|
||||||
if (exceptionCheck(env))
|
if (QJniEnvironment::exceptionCheckAndClear(env))
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
|
|
||||||
jobject classLoader = env->CallStaticObjectMethod(jQtNative, classLoaderMethodID);
|
jobject classLoader = env->CallStaticObjectMethod(jQtNative, classLoaderMethodID);
|
||||||
if (exceptionCheck(env))
|
if (QJniEnvironment::exceptionCheckAndClear(env))
|
||||||
return JNI_ERR;
|
return JNI_ERR;
|
||||||
|
|
||||||
setAndroidSdkVersion(env);
|
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);
|
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;
|
return JNI_ERR;
|
||||||
|
|
||||||
g_runPendingCppRunnablesMethodID = env->GetStaticMethodID(jQtNative,
|
g_runPendingCppRunnablesMethodID = env->GetStaticMethodID(jQtNative,
|
||||||
@ -495,7 +484,10 @@ void QtAndroidPrivate::runOnAndroidThreadSync(const QtAndroidPrivate::Runnable &
|
|||||||
waitForSemaphore(timeoutMs, sem);
|
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()) {
|
if (androidSdkVersion() < 23 || !activity()) {
|
||||||
QHash<QString, QtAndroidPrivate::PermissionsResult> res;
|
QHash<QString, QtAndroidPrivate::PermissionsResult> res;
|
||||||
@ -517,12 +509,17 @@ void QtAndroidPrivate::requestPermissions(JNIEnv *env, const QStringList &permis
|
|||||||
(*g_pendingPermissionRequests)[requestCode] = new PermissionsResultClass(callbackFunc);
|
(*g_pendingPermissionRequests)[requestCode] = new PermissionsResultClass(callbackFunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJNIEnvironmentPrivate env;
|
QJniEnvironment env;
|
||||||
auto array = env->NewObjectArray(permissions.size(), env->FindClass("java/lang/String"), nullptr);
|
jclass clazz = env->FindClass("java/lang/String");
|
||||||
|
|
||||||
|
if (env.exceptionCheckAndClear())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto array = env->NewObjectArray(permissions.size(), clazz, nullptr);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (const auto &perm : permissions)
|
for (const auto &perm : permissions)
|
||||||
env->SetObjectArrayElement(array, index++, QJNIObjectPrivate::fromString(perm).object());
|
env->SetObjectArrayElement(array, index++, QJniObject::fromString(perm).object());
|
||||||
QJNIObjectPrivate(activity()).callMethod<void>("requestPermissions", "([Ljava/lang/String;I)V", array, requestCode);
|
QJniObject(activity()).callMethod<void>("requestPermissions", "([Ljava/lang/String;I)V", array, requestCode);
|
||||||
env->DeleteLocalRef(array);
|
env->DeleteLocalRef(array);
|
||||||
}, env);
|
}, env);
|
||||||
}
|
}
|
||||||
@ -543,10 +540,10 @@ QtAndroidPrivate::PermissionsHash QtAndroidPrivate::requestPermissionsSync(JNIEn
|
|||||||
|
|
||||||
QtAndroidPrivate::PermissionsResult QtAndroidPrivate::checkPermission(const QString &permission)
|
QtAndroidPrivate::PermissionsResult QtAndroidPrivate::checkPermission(const QString &permission)
|
||||||
{
|
{
|
||||||
const auto res = QJNIObjectPrivate::callStaticMethod<jint>("org/qtproject/qt/android/QtNative",
|
const auto res = QJniObject::callStaticMethod<jint>("org/qtproject/qt/android/QtNative",
|
||||||
"checkSelfPermission",
|
"checkSelfPermission",
|
||||||
"(Ljava/lang/String;)I",
|
"(Ljava/lang/String;)I",
|
||||||
QJNIObjectPrivate::fromString(permission).object());
|
QJniObject::fromString(permission).object());
|
||||||
return res == PERMISSION_GRANTED ? PermissionsResult::Granted : PermissionsResult::Denied;
|
return res == PERMISSION_GRANTED ? PermissionsResult::Granted : PermissionsResult::Denied;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -555,8 +552,9 @@ bool QtAndroidPrivate::shouldShowRequestPermissionRationale(const QString &permi
|
|||||||
if (androidSdkVersion() < 23 || !activity())
|
if (androidSdkVersion() < 23 || !activity())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return QJNIObjectPrivate(activity()).callMethod<jboolean>("shouldShowRequestPermissionRationale", "(Ljava/lang/String;)Z",
|
return QJniObject(activity()).callMethod<jboolean>("shouldShowRequestPermissionRationale",
|
||||||
QJNIObjectPrivate::fromString(permission).object());
|
"(Ljava/lang/String;)Z",
|
||||||
|
QJniObject::fromString(permission).object());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtAndroidPrivate::registerGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)
|
void QtAndroidPrivate::registerGenericMotionEventListener(QtAndroidPrivate::GenericMotionEventListener *listener)
|
||||||
|
@ -119,6 +119,7 @@ namespace QtAndroidPrivate
|
|||||||
Q_CORE_EXPORT jobject context();
|
Q_CORE_EXPORT jobject context();
|
||||||
Q_CORE_EXPORT JavaVM *javaVM();
|
Q_CORE_EXPORT JavaVM *javaVM();
|
||||||
Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env);
|
Q_CORE_EXPORT jint initJNI(JavaVM *vm, JNIEnv *env);
|
||||||
|
Q_CORE_EXPORT jclass findClass(const char *className, JNIEnv *env);
|
||||||
jobject classLoader();
|
jobject classLoader();
|
||||||
Q_CORE_EXPORT jint androidSdkVersion();
|
Q_CORE_EXPORT jint androidSdkVersion();
|
||||||
Q_CORE_EXPORT void runOnAndroidThread(const Runnable &runnable, JNIEnv *env);
|
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/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtCore module of the Qt Toolkit.
|
** This file is part of the QtCore module of the Qt Toolkit.
|
||||||
@ -37,8 +37,9 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
#include "qjnihelpers_p.h"
|
#include "qjnihelpers_p.h"
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
|
|
||||||
static const char logTag[] = "QtCore";
|
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>
|
** Copyright (C) 2014 Drew Parsons <dparsons@emerall.com>
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
@ -38,10 +38,12 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <QtCore/QSet>
|
|
||||||
#include "qtimezone.h"
|
#include "qtimezone.h"
|
||||||
#include "qtimezoneprivate_p.h"
|
#include "qtimezoneprivate_p.h"
|
||||||
|
|
||||||
|
#include <QtCore/QJniEnvironment>
|
||||||
|
#include <QtCore/QSet>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -49,7 +51,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
|
|
||||||
Android implementation
|
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
|
owning smart-pointer, ensuring an object doesn't get garbage-collected
|
||||||
before we're done with it.
|
before we're done with it.
|
||||||
*/
|
*/
|
||||||
@ -59,9 +61,9 @@ QAndroidTimeZonePrivate::QAndroidTimeZonePrivate()
|
|||||||
: QTimeZonePrivate()
|
: QTimeZonePrivate()
|
||||||
{
|
{
|
||||||
// Keep in sync with systemTimeZoneId():
|
// Keep in sync with systemTimeZoneId():
|
||||||
androidTimeZone = QJNIObjectPrivate::callStaticObjectMethod(
|
androidTimeZone = QJniObject::callStaticObjectMethod(
|
||||||
"java.util.TimeZone", "getDefault", "()Ljava/util/TimeZone;");
|
"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();
|
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)
|
const QLocale &locale)
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate jlanguage
|
QJniObject jlanguage
|
||||||
= QJNIObjectPrivate::fromString(QLocale::languageToString(locale.language()));
|
= QJniObject::fromString(QLocale::languageToString(locale.language()));
|
||||||
QJNIObjectPrivate jcountry
|
QJniObject jcountry
|
||||||
= QJNIObjectPrivate::fromString(QLocale::countryToString(locale.country()));
|
= QJniObject::fromString(QLocale::countryToString(locale.country()));
|
||||||
QJNIObjectPrivate
|
QJniObject
|
||||||
jvariant = QJNIObjectPrivate::fromString(QLocale::scriptToString(locale.script()));
|
jvariant = QJniObject::fromString(QLocale::scriptToString(locale.script()));
|
||||||
QJNIObjectPrivate jlocale("java.util.Locale",
|
QJniObject jlocale("java.util.Locale",
|
||||||
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
|
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
|
||||||
static_cast<jstring>(jlanguage.object()),
|
static_cast<jstring>(jlanguage.object()),
|
||||||
static_cast<jstring>(jcountry.object()),
|
static_cast<jstring>(jcountry.object()),
|
||||||
@ -106,12 +108,12 @@ static QJNIObjectPrivate getDisplayName(QJNIObjectPrivate zone, jint style, jboo
|
|||||||
void QAndroidTimeZonePrivate::init(const QByteArray &ianaId)
|
void QAndroidTimeZonePrivate::init(const QByteArray &ianaId)
|
||||||
{
|
{
|
||||||
const QString iana = QString::fromUtf8(ianaId);
|
const QString iana = QString::fromUtf8(ianaId);
|
||||||
androidTimeZone = QJNIObjectPrivate::callStaticObjectMethod(
|
androidTimeZone = QJniObject::callStaticObjectMethod(
|
||||||
"java.util.TimeZone", "getTimeZone", "(Ljava/lang/String;)Ljava/util/TimeZone;",
|
"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:
|
// 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();
|
const QString name = jname.toString();
|
||||||
if (iana.compare(name, Qt::CaseInsensitive) == 0)
|
if (iana.compare(name, Qt::CaseInsensitive) == 0)
|
||||||
return name.toUtf8();
|
return name.toUtf8();
|
||||||
@ -205,7 +207,7 @@ bool QAndroidTimeZonePrivate::hasDaylightTime() const
|
|||||||
bool QAndroidTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
|
bool QAndroidTimeZonePrivate::isDaylightTime(qint64 atMSecsSinceEpoch) const
|
||||||
{
|
{
|
||||||
if ( androidTimeZone.isValid() ) {
|
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() );
|
return androidTimeZone.callMethod<jboolean>("inDaylightTime", "(Ljava/util/Date;)Z", jDate.object() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -250,24 +252,24 @@ QTimeZonePrivate::Data QAndroidTimeZonePrivate::previousTransition(qint64 before
|
|||||||
QByteArray QAndroidTimeZonePrivate::systemTimeZoneId() const
|
QByteArray QAndroidTimeZonePrivate::systemTimeZoneId() const
|
||||||
{
|
{
|
||||||
// Keep in sync with default constructor:
|
// Keep in sync with default constructor:
|
||||||
QJNIObjectPrivate androidSystemTimeZone = QJNIObjectPrivate::callStaticObjectMethod(
|
QJniObject androidSystemTimeZone = QJniObject::callStaticObjectMethod(
|
||||||
"java.util.TimeZone", "getDefault", "()Ljava/util/TimeZone;");
|
"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();
|
return id.toString().toUtf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<QByteArray> QAndroidTimeZonePrivate::availableTimeZoneIds() const
|
QList<QByteArray> QAndroidTimeZonePrivate::availableTimeZoneIds() const
|
||||||
{
|
{
|
||||||
QList<QByteArray> availableTimeZoneIdList;
|
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()) );
|
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)
|
// (or else the JNI reference table fills after 512 entries from GetObjectArrayElement)
|
||||||
jobject androidTZobject;
|
jobject androidTZobject;
|
||||||
QJNIObjectPrivate androidTZ;
|
QJniObject androidTZ;
|
||||||
for (int i=0; i<androidTZcount; i++ ) {
|
for (int i=0; i<androidTZcount; i++ ) {
|
||||||
androidTZobject = jniEnv->GetObjectArrayElement( static_cast<jobjectArray>( androidAvailableIdList.object() ), i );
|
androidTZobject = jniEnv->GetObjectArrayElement( static_cast<jobjectArray>( androidAvailableIdList.object() ), i );
|
||||||
androidTZ = androidTZobject;
|
androidTZ = androidTZobject;
|
||||||
|
@ -70,7 +70,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(NSTimeZone);
|
|||||||
#endif // Q_OS_WIN
|
#endif // Q_OS_WIN
|
||||||
|
|
||||||
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|
#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED)
|
||||||
#include <QtCore/private/qjni_p.h>
|
#include <QJniObject>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -496,7 +496,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void init(const QByteArray &zoneId);
|
void init(const QByteArray &zoneId);
|
||||||
|
|
||||||
QJNIObjectPrivate androidTimeZone;
|
QJniObject androidTimeZone;
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif // Q_OS_ANDROID
|
#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/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtNetwork module of the Qt Toolkit.
|
** This file is part of the QtNetwork module of the Qt Toolkit.
|
||||||
@ -38,7 +38,9 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qnetworkproxy.h"
|
#include "qnetworkproxy.h"
|
||||||
#include <QtCore/private/qjni_p.h>
|
|
||||||
|
#include <QtCore/QJniEnvironment>
|
||||||
|
#include <QtCore/QJniObject>
|
||||||
#include <QtCore/private/qjnihelpers_p.h>
|
#include <QtCore/private/qjnihelpers_p.h>
|
||||||
|
|
||||||
#ifndef QT_NO_NETWORKPROXY
|
#ifndef QT_NO_NETWORKPROXY
|
||||||
@ -58,7 +60,7 @@ static const char networkClass[] = "org/qtproject/qt/android/network/QtNetwork";
|
|||||||
|
|
||||||
ProxyInfoObject::ProxyInfoObject()
|
ProxyInfoObject::ProxyInfoObject()
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(networkClass,
|
QJniObject::callStaticMethod<void>(networkClass,
|
||||||
"registerReceiver",
|
"registerReceiver",
|
||||||
"(Landroid/content/Context;)V",
|
"(Landroid/content/Context;)V",
|
||||||
QtAndroidPrivate::context());
|
QtAndroidPrivate::context());
|
||||||
@ -66,7 +68,7 @@ ProxyInfoObject::ProxyInfoObject()
|
|||||||
|
|
||||||
ProxyInfoObject::~ProxyInfoObject()
|
ProxyInfoObject::~ProxyInfoObject()
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(networkClass,
|
QJniObject::callStaticMethod<void>(networkClass,
|
||||||
"unregisterReceiver",
|
"unregisterReceiver",
|
||||||
"(Landroid/content/Context;)V",
|
"(Landroid/content/Context;)V",
|
||||||
QtAndroidPrivate::context());
|
QtAndroidPrivate::context());
|
||||||
@ -78,18 +80,18 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
|
|||||||
if (!proxyInfoInstance)
|
if (!proxyInfoInstance)
|
||||||
return proxyList;
|
return proxyList;
|
||||||
|
|
||||||
QJNIObjectPrivate proxyInfo = QJNIObjectPrivate::callStaticObjectMethod(networkClass,
|
QJniObject proxyInfo = QJniObject::callStaticObjectMethod(networkClass,
|
||||||
"getProxyInfo",
|
"getProxyInfo",
|
||||||
"(Landroid/content/Context;)Landroid/net/ProxyInfo;",
|
"(Landroid/content/Context;)Landroid/net/ProxyInfo;",
|
||||||
QtAndroidPrivate::context());
|
QtAndroidPrivate::context());
|
||||||
if (proxyInfo.isValid()) {
|
if (proxyInfo.isValid()) {
|
||||||
QJNIObjectPrivate exclusionList = proxyInfo.callObjectMethod("getExclusionList",
|
QJniObject exclusionList = proxyInfo.callObjectMethod("getExclusionList",
|
||||||
"()[Ljava/lang/String;");
|
"()[Ljava/lang/String;");
|
||||||
bool exclude = false;
|
bool exclude = false;
|
||||||
if (exclusionList.isValid()) {
|
if (exclusionList.isValid()) {
|
||||||
jobjectArray listObject = static_cast<jobjectArray>(exclusionList.object());
|
jobjectArray listObject = static_cast<jobjectArray>(exclusionList.object());
|
||||||
QJNIEnvironmentPrivate env;
|
QJniEnvironment env;
|
||||||
QJNIObjectPrivate entry;
|
QJniObject entry;
|
||||||
const int size = env->GetArrayLength(listObject);
|
const int size = env->GetArrayLength(listObject);
|
||||||
QUrl host = QUrl(query.url().host());
|
QUrl host = QUrl(query.url().host());
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
@ -101,7 +103,7 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!exclude) {
|
if (!exclude) {
|
||||||
QJNIObjectPrivate hostName = proxyInfo.callObjectMethod<jstring>("getHost");
|
QJniObject hostName = proxyInfo.callObjectMethod<jstring>("getHost");
|
||||||
const int port = proxyInfo.callMethod<jint>("getPort");
|
const int port = proxyInfo.callMethod<jint>("getPort");
|
||||||
QNetworkProxy proxy(QNetworkProxy::HttpProxy, hostName.toString(), port);
|
QNetworkProxy proxy(QNetworkProxy::HttpProxy, hostName.toString(), port);
|
||||||
proxyList << proxy;
|
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/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the QtNetwork module of the Qt Toolkit.
|
** This file is part of the QtNetwork module of the Qt Toolkit.
|
||||||
@ -53,7 +53,8 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qsslsocket_openssl_p.h"
|
#include "qsslsocket_openssl_p.h"
|
||||||
#include <QtCore/private/qjni_p.h>
|
#include <QtCore/QJniEnvironment>
|
||||||
|
#include <QtCore/QJniObject>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -61,13 +62,13 @@ QList<QByteArray> QSslSocketPrivate::fetchSslCertificateData()
|
|||||||
{
|
{
|
||||||
QList<QByteArray> certificateData;
|
QList<QByteArray> certificateData;
|
||||||
|
|
||||||
QJNIObjectPrivate certificates = QJNIObjectPrivate::callStaticObjectMethod("org/qtproject/qt/android/QtNative",
|
QJniObject certificates = QJniObject::callStaticObjectMethod("org/qtproject/qt/android/QtNative",
|
||||||
"getSSLCertificates",
|
"getSSLCertificates",
|
||||||
"()[[B");
|
"()[[B");
|
||||||
if (!certificates.isValid())
|
if (!certificates.isValid())
|
||||||
return certificateData;
|
return certificateData;
|
||||||
|
|
||||||
QJNIEnvironmentPrivate env;
|
QJniEnvironment env;
|
||||||
jobjectArray jcertificates = static_cast<jobjectArray>(certificates.object());
|
jobjectArray jcertificates = static_cast<jobjectArray>(certificates.object());
|
||||||
const jint nCertificates = env->GetArrayLength(jcertificates);
|
const jint nCertificates = env->GetArrayLength(jcertificates);
|
||||||
certificateData.reserve(static_cast<int>(nCertificates));
|
certificateData.reserve(static_cast<int>(nCertificates));
|
||||||
|
@ -39,7 +39,8 @@
|
|||||||
|
|
||||||
#include "androidcontentfileengine.h"
|
#include "androidcontentfileengine.h"
|
||||||
|
|
||||||
#include <private/qjni_p.h>
|
#include <QtCore/QJniEnvironment>
|
||||||
|
#include <QtCore/QJniObject>
|
||||||
#include <private/qjnihelpers_p.h>
|
#include <private/qjnihelpers_p.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@ -65,12 +66,12 @@ bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
|
|||||||
openModeStr += QLatin1Char('a');
|
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",
|
"openFdForContentUrl",
|
||||||
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I",
|
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I",
|
||||||
QtAndroidPrivate::context(),
|
QtAndroidPrivate::context(),
|
||||||
QJNIObjectPrivate::fromString(fileName(DefaultName)).object(),
|
QJniObject::fromString(fileName(DefaultName)).object(),
|
||||||
QJNIObjectPrivate::fromString(openModeStr).object());
|
QJniObject::fromString(openModeStr).object());
|
||||||
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
return false;
|
return false;
|
||||||
@ -81,10 +82,10 @@ bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
|
|||||||
|
|
||||||
qint64 AndroidContentFileEngine::size() const
|
qint64 AndroidContentFileEngine::size() const
|
||||||
{
|
{
|
||||||
const jlong size = QJNIObjectPrivate::callStaticMethod<jlong>(
|
const jlong size = QJniObject::callStaticMethod<jlong>(
|
||||||
"org/qtproject/qt/android/QtNative", "getSize",
|
"org/qtproject/qt/android/QtNative", "getSize",
|
||||||
"(Landroid/content/Context;Ljava/lang/String;)J", QtAndroidPrivate::context(),
|
"(Landroid/content/Context;Ljava/lang/String;)J", QtAndroidPrivate::context(),
|
||||||
QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
|
QJniObject::fromString(fileName(DefaultName)).object());
|
||||||
return (qint64)size;
|
return (qint64)size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,25 +93,25 @@ AndroidContentFileEngine::FileFlags AndroidContentFileEngine::fileFlags(FileFlag
|
|||||||
{
|
{
|
||||||
FileFlags commonFlags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag);
|
FileFlags commonFlags(ReadOwnerPerm|ReadUserPerm|ReadGroupPerm|ReadOtherPerm|ExistsFlag);
|
||||||
FileFlags flags;
|
FileFlags flags;
|
||||||
const bool isDir = QJNIObjectPrivate::callStaticMethod<jboolean>(
|
const bool isDir = QJniObject::callStaticMethod<jboolean>(
|
||||||
"org/qtproject/qt/android/QtNative", "checkIfDir",
|
"org/qtproject/qt/android/QtNative", "checkIfDir",
|
||||||
"(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
|
"(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
|
// 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",
|
"org/qtproject/qt/android/QtNative", "checkFileExists",
|
||||||
"(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
|
"(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
|
||||||
QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
|
QJniObject::fromString(fileName(DefaultName)).object());
|
||||||
if (!exists && !isDir)
|
if (!exists && !isDir)
|
||||||
return flags;
|
return flags;
|
||||||
if (isDir) {
|
if (isDir) {
|
||||||
flags = DirectoryType | commonFlags;
|
flags = DirectoryType | commonFlags;
|
||||||
} else {
|
} else {
|
||||||
flags = FileType | commonFlags;
|
flags = FileType | commonFlags;
|
||||||
const bool writable = QJNIObjectPrivate::callStaticMethod<jboolean>(
|
const bool writable = QJniObject::callStaticMethod<jboolean>(
|
||||||
"org/qtproject/qt/android/QtNative", "checkIfWritable",
|
"org/qtproject/qt/android/QtNative", "checkIfWritable",
|
||||||
"(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
|
"(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
|
||||||
QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
|
QJniObject::fromString(fileName(DefaultName)).object());
|
||||||
if (writable)
|
if (writable)
|
||||||
flags |= WriteOwnerPerm|WriteUserPerm|WriteGroupPerm|WriteOtherPerm;
|
flags |= WriteOwnerPerm|WriteUserPerm|WriteGroupPerm|WriteOtherPerm;
|
||||||
}
|
}
|
||||||
@ -182,22 +183,22 @@ bool AndroidContentFileEngineIterator::hasNext() const
|
|||||||
if (m_index == -1) {
|
if (m_index == -1) {
|
||||||
if (path().isEmpty())
|
if (path().isEmpty())
|
||||||
return false;
|
return false;
|
||||||
const bool isDir = QJNIObjectPrivate::callStaticMethod<jboolean>(
|
const bool isDir = QJniObject::callStaticMethod<jboolean>(
|
||||||
"org/qtproject/qt/android/QtNative", "checkIfDir",
|
"org/qtproject/qt/android/QtNative", "checkIfDir",
|
||||||
"(Landroid/content/Context;Ljava/lang/String;)Z",
|
"(Landroid/content/Context;Ljava/lang/String;)Z",
|
||||||
QtAndroidPrivate::context(),
|
QtAndroidPrivate::context(),
|
||||||
QJNIObjectPrivate::fromString(path()).object());
|
QJniObject::fromString(path()).object());
|
||||||
if (isDir) {
|
if (isDir) {
|
||||||
QJNIObjectPrivate objArray = QJNIObjectPrivate::callStaticObjectMethod("org/qtproject/qt/android/QtNative",
|
QJniObject objArray = QJniObject::callStaticObjectMethod("org/qtproject/qt/android/QtNative",
|
||||||
"listContentsFromTreeUri",
|
"listContentsFromTreeUri",
|
||||||
"(Landroid/content/Context;Ljava/lang/String;)[Ljava/lang/String;",
|
"(Landroid/content/Context;Ljava/lang/String;)[Ljava/lang/String;",
|
||||||
QtAndroidPrivate::context(),
|
QtAndroidPrivate::context(),
|
||||||
QJNIObjectPrivate::fromString(path()).object());
|
QJniObject::fromString(path()).object());
|
||||||
if (objArray.isValid()) {
|
if (objArray.isValid()) {
|
||||||
QJNIEnvironmentPrivate env;
|
QJniEnvironment env;
|
||||||
const jsize length = env->GetArrayLength(static_cast<jarray>(objArray.object()));
|
const jsize length = env->GetArrayLength(static_cast<jarray>(objArray.object()));
|
||||||
for (int i = 0; i != length; ++i) {
|
for (int i = 0; i != length; ++i) {
|
||||||
m_entries << QJNIObjectPrivate(env->GetObjectArrayElement(
|
m_entries << QJniObject(env->GetObjectArrayElement(
|
||||||
static_cast<jobjectArray>(objArray.object()), i)).toString();
|
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/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the plugins of the Qt Toolkit.
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
@ -48,11 +48,9 @@
|
|||||||
#include "QtGui/qaccessible.h"
|
#include "QtGui/qaccessible.h"
|
||||||
#include <QtCore/qmath.h>
|
#include <QtCore/qmath.h>
|
||||||
#include <QtCore/private/qjnihelpers_p.h>
|
#include <QtCore/private/qjnihelpers_p.h>
|
||||||
#include <QtCore/private/qjni_p.h>
|
#include <QtCore/QJniObject>
|
||||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||||
|
|
||||||
#include "qdebug.h"
|
|
||||||
|
|
||||||
static const char m_qtTag[] = "Qt A11Y";
|
static const char m_qtTag[] = "Qt A11Y";
|
||||||
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
|
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
|
||||||
|
|
||||||
@ -77,7 +75,7 @@ namespace QtAndroidAccessibility
|
|||||||
|
|
||||||
void initialize()
|
void initialize()
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(QtAndroid::applicationClass(),
|
QJniObject::callStaticMethod<void>(QtAndroid::applicationClass(),
|
||||||
"initializeAccessibility");
|
"initializeAccessibility");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,8 @@
|
|||||||
|
|
||||||
#include "androidjniclipboard.h"
|
#include "androidjniclipboard.h"
|
||||||
#include <QtCore/QUrl>
|
#include <QtCore/QUrl>
|
||||||
#include <QtCore/private/qjni_p.h>
|
#include <QtCore/QJniObject>
|
||||||
|
#include <QtCore/QJniEnvironment>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -55,9 +56,9 @@ namespace QtAndroidClipboard
|
|||||||
void setClipboardManager(QAndroidPlatformClipboard *manager)
|
void setClipboardManager(QAndroidPlatformClipboard *manager)
|
||||||
{
|
{
|
||||||
m_manager = manager;
|
m_manager = manager;
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "registerClipboardManager");
|
QJniObject::callStaticMethod<void>(applicationClass(), "registerClipboardManager");
|
||||||
jclass appClass = QtAndroid::applicationClass();
|
jclass appClass = QtAndroid::applicationClass();
|
||||||
QJNIEnvironmentPrivate env;
|
QJniEnvironment env;
|
||||||
if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
|
if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
|
||||||
__android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
|
__android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
|
||||||
return;
|
return;
|
||||||
@ -65,29 +66,30 @@ namespace QtAndroidClipboard
|
|||||||
}
|
}
|
||||||
void clearClipboardData()
|
void clearClipboardData()
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "clearClipData");
|
QJniObject::callStaticMethod<void>(applicationClass(), "clearClipData");
|
||||||
}
|
}
|
||||||
void setClipboardMimeData(QMimeData *data)
|
void setClipboardMimeData(QMimeData *data)
|
||||||
{
|
{
|
||||||
clearClipboardData();
|
clearClipboardData();
|
||||||
if (data->hasText()) {
|
if (data->hasText()) {
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
|
QJniObject::callStaticMethod<void>(applicationClass(),
|
||||||
"setClipboardText", "(Ljava/lang/String;)V",
|
"setClipboardText", "(Ljava/lang/String;)V",
|
||||||
QJNIObjectPrivate::fromString(data->text()).object());
|
QJniObject::fromString(data->text()).object());
|
||||||
}
|
}
|
||||||
if (data->hasHtml()) {
|
if (data->hasHtml()) {
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
|
QJniObject::callStaticMethod<void>(applicationClass(),
|
||||||
"setClipboardHtml",
|
"setClipboardHtml",
|
||||||
"(Ljava/lang/String;Ljava/lang/String;)V",
|
"(Ljava/lang/String;Ljava/lang/String;)V",
|
||||||
QJNIObjectPrivate::fromString(data->text()).object(),
|
QJniObject::fromString(data->text()).object(),
|
||||||
QJNIObjectPrivate::fromString(data->html()).object());
|
QJniObject::fromString(data->html()).object());
|
||||||
}
|
}
|
||||||
if (data->hasUrls()) {
|
if (data->hasUrls()) {
|
||||||
QList<QUrl> urls = data->urls();
|
QList<QUrl> urls = data->urls();
|
||||||
for (const auto &u : qAsConst(urls)) {
|
for (const auto &u : qAsConst(urls)) {
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "setClipboardUri",
|
QJniObject::callStaticMethod<void>(applicationClass(),
|
||||||
|
"setClipboardUri",
|
||||||
"(Ljava/lang/String;)V",
|
"(Ljava/lang/String;)V",
|
||||||
QJNIObjectPrivate::fromString(u.toEncoded()).object());
|
QJniObject::fromString(u.toEncoded()).object());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,28 +97,28 @@ namespace QtAndroidClipboard
|
|||||||
QMimeData *getClipboardMimeData()
|
QMimeData *getClipboardMimeData()
|
||||||
{
|
{
|
||||||
QMimeData *data = new QMimeData;
|
QMimeData *data = new QMimeData;
|
||||||
if (QJNIObjectPrivate::callStaticMethod<jboolean>(applicationClass(), "hasClipboardText")) {
|
if (QJniObject::callStaticMethod<jboolean>(applicationClass(), "hasClipboardText")) {
|
||||||
data->setText(QJNIObjectPrivate::callStaticObjectMethod(applicationClass(),
|
data->setText(QJniObject::callStaticObjectMethod(applicationClass(),
|
||||||
"getClipboardText",
|
"getClipboardText",
|
||||||
"()Ljava/lang/String;").toString());
|
"()Ljava/lang/String;").toString());
|
||||||
}
|
}
|
||||||
if (QJNIObjectPrivate::callStaticMethod<jboolean>(applicationClass(), "hasClipboardHtml")) {
|
if (QJniObject::callStaticMethod<jboolean>(applicationClass(), "hasClipboardHtml")) {
|
||||||
data->setHtml(QJNIObjectPrivate::callStaticObjectMethod(applicationClass(),
|
data->setHtml(QJniObject::callStaticObjectMethod(applicationClass(),
|
||||||
"getClipboardHtml",
|
"getClipboardHtml",
|
||||||
"()Ljava/lang/String;").toString());
|
"()Ljava/lang/String;").toString());
|
||||||
}
|
}
|
||||||
if (QJNIObjectPrivate::callStaticMethod<jboolean>(applicationClass(), "hasClipboardUri")) {
|
if (QJniObject::callStaticMethod<jboolean>(applicationClass(), "hasClipboardUri")) {
|
||||||
QJNIObjectPrivate uris = QJNIObjectPrivate::callStaticObjectMethod(applicationClass(),
|
QJniObject uris = QJniObject::callStaticObjectMethod(applicationClass(),
|
||||||
"getClipboardUris",
|
"getClipboardUris",
|
||||||
"()[Ljava/lang/String;");
|
"()[Ljava/lang/String;");
|
||||||
if (uris.isValid()) {
|
if (uris.isValid()) {
|
||||||
QList<QUrl> urls;
|
QList<QUrl> urls;
|
||||||
QJNIEnvironmentPrivate env;
|
QJniEnvironment env;
|
||||||
jobjectArray juris = static_cast<jobjectArray>(uris.object());
|
jobjectArray juris = static_cast<jobjectArray>(uris.object());
|
||||||
const jint nUris = env->GetArrayLength(juris);
|
const jint nUris = env->GetArrayLength(juris);
|
||||||
urls.reserve(static_cast<int>(nUris));
|
urls.reserve(static_cast<int>(nUris));
|
||||||
for (int i = 0; i < nUris; ++i)
|
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);
|
data->setUrls(urls);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QDebug>
|
|
||||||
#include <QtMath>
|
#include <QtMath>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -71,7 +70,7 @@ namespace QtAndroidInput
|
|||||||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||||
qDebug() << ">>> UPDATESELECTION" << selStart << selEnd << candidatesStart << candidatesEnd;
|
qDebug() << ">>> UPDATESELECTION" << selStart << selEnd << candidatesStart << candidatesEnd;
|
||||||
#endif
|
#endif
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
|
QJniObject::callStaticMethod<void>(applicationClass(),
|
||||||
"updateSelection",
|
"updateSelection",
|
||||||
"(IIII)V",
|
"(IIII)V",
|
||||||
selStart,
|
selStart,
|
||||||
@ -82,7 +81,7 @@ namespace QtAndroidInput
|
|||||||
|
|
||||||
void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints, int enterKeyType)
|
void showSoftwareKeyboard(int left, int top, int width, int height, int inputHints, int enterKeyType)
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(),
|
QJniObject::callStaticMethod<void>(applicationClass(),
|
||||||
"showSoftwareKeyboard",
|
"showSoftwareKeyboard",
|
||||||
"(IIIIII)V",
|
"(IIIIII)V",
|
||||||
left,
|
left,
|
||||||
@ -90,8 +89,7 @@ namespace QtAndroidInput
|
|||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
inputHints,
|
inputHints,
|
||||||
enterKeyType
|
enterKeyType);
|
||||||
);
|
|
||||||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||||
qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints << enterKeyType;
|
qDebug() << "@@@ SHOWSOFTWAREKEYBOARD" << left << top << width << height << inputHints << enterKeyType;
|
||||||
#endif
|
#endif
|
||||||
@ -99,7 +97,7 @@ namespace QtAndroidInput
|
|||||||
|
|
||||||
void resetSoftwareKeyboard()
|
void resetSoftwareKeyboard()
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "resetSoftwareKeyboard");
|
QJniObject::callStaticMethod<void>(applicationClass(), "resetSoftwareKeyboard");
|
||||||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||||
qDebug("@@@ RESETSOFTWAREKEYBOARD");
|
qDebug("@@@ RESETSOFTWAREKEYBOARD");
|
||||||
#endif
|
#endif
|
||||||
@ -107,7 +105,7 @@ namespace QtAndroidInput
|
|||||||
|
|
||||||
void hideSoftwareKeyboard()
|
void hideSoftwareKeyboard()
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "hideSoftwareKeyboard");
|
QJniObject::callStaticMethod<void>(applicationClass(), "hideSoftwareKeyboard");
|
||||||
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
|
||||||
qDebug("@@@ HIDESOFTWAREKEYBOARD");
|
qDebug("@@@ HIDESOFTWAREKEYBOARD");
|
||||||
#endif
|
#endif
|
||||||
@ -125,7 +123,7 @@ namespace QtAndroidInput
|
|||||||
|
|
||||||
void updateHandles(int mode, QPoint editMenuPos, uint32_t editButtons, QPoint cursor, QPoint anchor, bool rtl)
|
void updateHandles(int mode, QPoint editMenuPos, uint32_t editButtons, QPoint cursor, QPoint anchor, bool rtl)
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "updateHandles", "(IIIIIIIIZ)V",
|
QJniObject::callStaticMethod<void>(applicationClass(), "updateHandles", "(IIIIIIIIZ)V",
|
||||||
mode, editMenuPos.x(), editMenuPos.y(), editButtons,
|
mode, editMenuPos.x(), editMenuPos.y(), editButtons,
|
||||||
cursor.x(), cursor.y(),
|
cursor.x(), cursor.y(),
|
||||||
anchor.x(), anchor.y(), rtl);
|
anchor.x(), anchor.y(), rtl);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2014 BogDan Vatra <bogdan@kde.org>
|
** 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/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the plugins of the Qt Toolkit.
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
@ -40,30 +40,30 @@
|
|||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <semaphore.h>
|
|
||||||
#include <qplugin.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 "androidcontentfileengine.h"
|
||||||
#include "androiddeadlockprotector.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 "qandroidplatformdialoghelpers.h"
|
||||||
#include "qandroidplatformintegration.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/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/qresource.h>
|
||||||
#include <QtCore/qthread.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/qguiapplication_p.h>
|
||||||
#include <QtGui/private/qhighdpiscaling_p.h>
|
#include <QtGui/private/qhighdpiscaling_p.h>
|
||||||
|
|
||||||
@ -205,22 +205,22 @@ namespace QtAndroid
|
|||||||
|
|
||||||
void setSystemUiVisibility(SystemUiVisibility uiVisibility)
|
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()
|
void notifyAccessibilityLocationChange()
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "notifyAccessibilityLocationChange");
|
QJniObject::callStaticMethod<void>(m_applicationClass, "notifyAccessibilityLocationChange");
|
||||||
}
|
}
|
||||||
|
|
||||||
void notifyObjectHide(uint accessibilityObjectId)
|
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)
|
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)
|
jobject createBitmap(QImage img, JNIEnv *env)
|
||||||
@ -311,15 +311,15 @@ namespace QtAndroid
|
|||||||
|
|
||||||
QString deviceName()
|
QString deviceName()
|
||||||
{
|
{
|
||||||
QString manufacturer = QJNIObjectPrivate::getStaticObjectField("android/os/Build", "MANUFACTURER", "Ljava/lang/String;").toString();
|
QString manufacturer = QJniObject::getStaticObjectField("android/os/Build", "MANUFACTURER", "Ljava/lang/String;").toString();
|
||||||
QString model = QJNIObjectPrivate::getStaticObjectField("android/os/Build", "MODEL", "Ljava/lang/String;").toString();
|
QString model = QJniObject::getStaticObjectField("android/os/Build", "MODEL", "Ljava/lang/String;").toString();
|
||||||
|
|
||||||
return manufacturer + QLatin1Char(' ') + model;
|
return manufacturer + QLatin1Char(' ') + model;
|
||||||
}
|
}
|
||||||
|
|
||||||
int createSurface(AndroidSurfaceClient *client, const QRect &geometry, bool onTop, int imageDepth)
|
int createSurface(AndroidSurfaceClient *client, const QRect &geometry, bool onTop, int imageDepth)
|
||||||
{
|
{
|
||||||
QJNIEnvironmentPrivate env;
|
QJniEnvironment env;
|
||||||
if (!env)
|
if (!env)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -355,7 +355,7 @@ namespace QtAndroid
|
|||||||
if (!geometry.isNull())
|
if (!geometry.isNull())
|
||||||
geometry.getRect(&x, &y, &w, &h);
|
geometry.getRect(&x, &y, &w, &h);
|
||||||
|
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass,
|
QJniObject::callStaticMethod<void>(m_applicationClass,
|
||||||
"insertNativeView",
|
"insertNativeView",
|
||||||
"(ILandroid/view/View;IIII)V",
|
"(ILandroid/view/View;IIII)V",
|
||||||
surfaceId,
|
surfaceId,
|
||||||
@ -370,7 +370,7 @@ namespace QtAndroid
|
|||||||
|
|
||||||
void setViewVisibility(jobject view, bool visible)
|
void setViewVisibility(jobject view, bool visible)
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass,
|
QJniObject::callStaticMethod<void>(m_applicationClass,
|
||||||
"setViewVisibility",
|
"setViewVisibility",
|
||||||
"(Landroid/view/View;Z)V",
|
"(Landroid/view/View;Z)V",
|
||||||
view,
|
view,
|
||||||
@ -382,7 +382,7 @@ namespace QtAndroid
|
|||||||
if (surfaceId == -1)
|
if (surfaceId == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QJNIEnvironmentPrivate env;
|
QJniEnvironment env;
|
||||||
if (!env)
|
if (!env)
|
||||||
return;
|
return;
|
||||||
jint x = 0, y = 0, w = -1, h = -1;
|
jint x = 0, y = 0, w = -1, h = -1;
|
||||||
@ -411,7 +411,7 @@ namespace QtAndroid
|
|||||||
m_surfaces.erase(it);
|
m_surfaces.erase(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJNIEnvironmentPrivate env;
|
QJniEnvironment env;
|
||||||
if (env)
|
if (env)
|
||||||
env->CallStaticVoidMethod(m_applicationClass,
|
env->CallStaticVoidMethod(m_applicationClass,
|
||||||
m_destroySurfaceMethodID,
|
m_destroySurfaceMethodID,
|
||||||
@ -423,7 +423,7 @@ namespace QtAndroid
|
|||||||
if (surfaceId == -1)
|
if (surfaceId == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass,
|
QJniObject::callStaticMethod<void>(m_applicationClass,
|
||||||
"bringChildToFront",
|
"bringChildToFront",
|
||||||
"(I)V",
|
"(I)V",
|
||||||
surfaceId);
|
surfaceId);
|
||||||
@ -434,7 +434,7 @@ namespace QtAndroid
|
|||||||
if (surfaceId == -1)
|
if (surfaceId == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass,
|
QJniObject::callStaticMethod<void>(m_applicationClass,
|
||||||
"bringChildToBack",
|
"bringChildToBack",
|
||||||
"(I)V",
|
"(I)V",
|
||||||
surfaceId);
|
surfaceId);
|
||||||
@ -550,7 +550,7 @@ static jboolean startQtApplication(JNIEnv */*env*/, jclass /*clazz*/)
|
|||||||
|
|
||||||
if (m_applicationClass) {
|
if (m_applicationClass) {
|
||||||
qWarning("exit app 0");
|
qWarning("exit app 0");
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(m_applicationClass, "quitApp", "()V");
|
QJniObject::callStaticMethod<void>(m_applicationClass, "quitApp", "()V");
|
||||||
}
|
}
|
||||||
|
|
||||||
sem_post(&m_terminateSemaphore);
|
sem_post(&m_terminateSemaphore);
|
||||||
|
@ -37,10 +37,10 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "androidjnimenu.h"
|
|
||||||
#include "androidjnimain.h"
|
#include "androidjnimain.h"
|
||||||
#include "qandroidplatformmenubar.h"
|
#include "androidjnimenu.h"
|
||||||
#include "qandroidplatformmenu.h"
|
#include "qandroidplatformmenu.h"
|
||||||
|
#include "qandroidplatformmenubar.h"
|
||||||
#include "qandroidplatformmenuitem.h"
|
#include "qandroidplatformmenuitem.h"
|
||||||
|
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
@ -50,7 +50,7 @@
|
|||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QWindow>
|
#include <QWindow>
|
||||||
#include <QtCore/private/qjnihelpers_p.h>
|
#include <QtCore/private/qjnihelpers_p.h>
|
||||||
#include <QtCore/private/qjni_p.h>
|
#include <QtCore/QJniObject>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -82,12 +82,12 @@ namespace QtAndroidMenu
|
|||||||
|
|
||||||
void resetMenuBar()
|
void resetMenuBar()
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "resetOptionsMenu");
|
QJniObject::callStaticMethod<void>(applicationClass(), "resetOptionsMenu");
|
||||||
}
|
}
|
||||||
|
|
||||||
void openOptionsMenu()
|
void openOptionsMenu()
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "openOptionsMenu");
|
QJniObject::callStaticMethod<void>(applicationClass(), "openOptionsMenu");
|
||||||
}
|
}
|
||||||
|
|
||||||
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env)
|
void showContextMenu(QAndroidPlatformMenu *menu, const QRect &anchorRect, JNIEnv *env)
|
||||||
@ -104,13 +104,14 @@ namespace QtAndroidMenu
|
|||||||
{
|
{
|
||||||
QMutexLocker lock(&visibleMenuMutex);
|
QMutexLocker lock(&visibleMenuMutex);
|
||||||
if (visibleMenu == menu) {
|
if (visibleMenu == menu) {
|
||||||
QJNIObjectPrivate::callStaticMethod<void>(applicationClass(), "closeContextMenu");
|
QJniObject::callStaticMethod<void>(applicationClass(), "closeContextMenu");
|
||||||
pendingContextMenus.clear();
|
pendingContextMenus.clear();
|
||||||
} else {
|
} else {
|
||||||
pendingContextMenus.removeOne(menu);
|
pendingContextMenus.removeOne(menu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
void syncMenu(QAndroidPlatformMenu */*menu*/)
|
void syncMenu(QAndroidPlatformMenu */*menu*/)
|
||||||
{
|
{
|
||||||
// QMutexLocker lock(&visibleMenuMutex);
|
// QMutexLocker lock(&visibleMenuMutex);
|
||||||
|
@ -39,10 +39,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <jni.h>
|
#include <QtCore/QJniEnvironment>
|
||||||
|
|
||||||
|
#include <alloca.h>
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
#include <extract.h>
|
#include <extract.h>
|
||||||
#include <alloca.h>
|
#include <jni.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define LOG_TAG "extractSyleInfo"
|
#define LOG_TAG "extractSyleInfo"
|
||||||
@ -133,12 +135,15 @@ Java_org_qtproject_qt_android_ExtractStyle_extractChunkInfo20(JNIEnv *env, jobje
|
|||||||
env->GetByteArrayRegion(chunkObj, 0, chunkSize,
|
env->GetByteArrayRegion(chunkObj, 0, chunkSize,
|
||||||
reinterpret_cast<jbyte*>(storage));
|
reinterpret_cast<jbyte*>(storage));
|
||||||
|
|
||||||
if (!env->ExceptionCheck())
|
if (QJniEnvironment::exceptionCheckAndClear(env))
|
||||||
return Java_org_qtproject_qt_android_ExtractStyle_extractNativeChunkInfo20(env, obj,
|
|
||||||
long(storage));
|
|
||||||
else
|
|
||||||
env->ExceptionClear();
|
|
||||||
return 0;
|
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) {
|
static inline void fill9patchOffsets(Res_png_9patch20* patch) {
|
||||||
|
@ -37,13 +37,15 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qandroidassetsfileenginehandler.h"
|
|
||||||
#include "androidjnimain.h"
|
#include "androidjnimain.h"
|
||||||
|
#include "qandroidassetsfileenginehandler.h"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QtCore/private/qjni_p.h>
|
#include <QtCore/QJniEnvironment>
|
||||||
|
#include <QtCore/QJniObject>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -139,16 +141,16 @@ public:
|
|||||||
FolderIterator(const QString &path)
|
FolderIterator(const QString &path)
|
||||||
: m_path(path)
|
: m_path(path)
|
||||||
{
|
{
|
||||||
QJNIObjectPrivate files = QJNIObjectPrivate::callStaticObjectMethod(QtAndroid::applicationClass(),
|
QJniObject files = QJniObject::callStaticObjectMethod(QtAndroid::applicationClass(),
|
||||||
"listAssetContent",
|
"listAssetContent",
|
||||||
"(Landroid/content/res/AssetManager;Ljava/lang/String;)[Ljava/lang/String;",
|
"(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()) {
|
if (files.isValid()) {
|
||||||
QJNIEnvironmentPrivate env;
|
QJniEnvironment env;
|
||||||
jobjectArray jFiles = static_cast<jobjectArray>(files.object());
|
jobjectArray jFiles = static_cast<jobjectArray>(files.object());
|
||||||
const jint nFiles = env->GetArrayLength(jFiles);
|
const jint nFiles = env->GetArrayLength(jFiles);
|
||||||
for (int i = 0; i < nFiles; ++i) {
|
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){
|
insert(std::upper_bound(begin(), end(), item, [](const auto &a, const auto &b){
|
||||||
return a.name < b.name;
|
return a.name < b.name;
|
||||||
}), item);
|
}), item);
|
||||||
|
@ -41,26 +41,24 @@
|
|||||||
|
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
|
|
||||||
#include "qandroidinputcontext.h"
|
|
||||||
#include "androidjnimain.h"
|
|
||||||
#include "androidjniinput.h"
|
|
||||||
#include "qandroideventdispatcher.h"
|
|
||||||
#include "androiddeadlockprotector.h"
|
#include "androiddeadlockprotector.h"
|
||||||
|
#include "androidjniinput.h"
|
||||||
|
#include "androidjnimain.h"
|
||||||
|
#include "qandroideventdispatcher.h"
|
||||||
|
#include "qandroidinputcontext.h"
|
||||||
#include "qandroidplatformintegration.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 <qevent.h>
|
||||||
#include <qguiapplication.h>
|
#include <qguiapplication.h>
|
||||||
|
#include <qinputmethod.h>
|
||||||
#include <qsharedpointer.h>
|
#include <qsharedpointer.h>
|
||||||
#include <qthread.h>
|
#include <qthread.h>
|
||||||
#include <qinputmethod.h>
|
|
||||||
#include <qwindow.h>
|
#include <qwindow.h>
|
||||||
#include <QtCore/private/qjni_p.h>
|
|
||||||
#include <private/qhighdpiscaling_p.h>
|
|
||||||
|
|
||||||
#include <QTextCharFormat>
|
|
||||||
#include <QTextBoundaryFinder>
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -434,7 +432,8 @@ QAndroidInputContext::QAndroidInputContext()
|
|||||||
, m_batchEditNestingLevel(0)
|
, m_batchEditNestingLevel(0)
|
||||||
, m_focusObject(0)
|
, m_focusObject(0)
|
||||||
{
|
{
|
||||||
jclass clazz = QJNIEnvironmentPrivate::findClass(QtNativeInputConnectionClassName);
|
QJniEnvironment env;
|
||||||
|
jclass clazz = env.findClass(QtNativeInputConnectionClassName);
|
||||||
if (Q_UNLIKELY(!clazz)) {
|
if (Q_UNLIKELY(!clazz)) {
|
||||||
qCritical() << "Native registration unable to find class '"
|
qCritical() << "Native registration unable to find class '"
|
||||||
<< QtNativeInputConnectionClassName
|
<< QtNativeInputConnectionClassName
|
||||||
@ -442,7 +441,6 @@ QAndroidInputContext::QAndroidInputContext()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QJNIEnvironmentPrivate env;
|
|
||||||
if (Q_UNLIKELY(env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0)) {
|
if (Q_UNLIKELY(env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0)) {
|
||||||
qCritical() << "RegisterNatives failed for '"
|
qCritical() << "RegisterNatives failed for '"
|
||||||
<< QtNativeInputConnectionClassName
|
<< QtNativeInputConnectionClassName
|
||||||
@ -450,7 +448,7 @@ QAndroidInputContext::QAndroidInputContext()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
clazz = QJNIEnvironmentPrivate::findClass(QtExtractedTextClassName);
|
clazz = env.findClass(QtExtractedTextClassName);
|
||||||
if (Q_UNLIKELY(!clazz)) {
|
if (Q_UNLIKELY(!clazz)) {
|
||||||
qCritical() << "Native registration unable to find class '"
|
qCritical() << "Native registration unable to find class '"
|
||||||
<< QtExtractedTextClassName
|
<< QtExtractedTextClassName
|
||||||
|
@ -90,19 +90,19 @@ bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
|
|||||||
|
|
||||||
QString str = htmlText(opt->windowTitle());
|
QString str = htmlText(opt->windowTitle());
|
||||||
if (!str.isEmpty())
|
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());
|
str = htmlText(opt->text());
|
||||||
if (!str.isEmpty())
|
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());
|
str = htmlText(opt->informativeText());
|
||||||
if (!str.isEmpty())
|
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());
|
str = htmlText(opt->detailedText());
|
||||||
if (!str.isEmpty())
|
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);
|
const int * currentLayout = buttonLayout(Qt::Horizontal, AndroidLayout);
|
||||||
while (*currentLayout != QPlatformDialogHelper::EOL) {
|
while (*currentLayout != QPlatformDialogHelper::EOL) {
|
||||||
@ -123,7 +123,7 @@ void QAndroidPlatformMessageDialogHelper::addButtons(QSharedPointer<QMessageDial
|
|||||||
QString label = b.label;
|
QString label = b.label;
|
||||||
label.remove(QChar('&'));
|
label.remove(QChar('&'));
|
||||||
m_javaMessageDialog.callMethod<void>("addButton", "(ILjava/lang/String;)V", b.id,
|
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);
|
StandardButton b = static_cast<StandardButton>(i);
|
||||||
if (buttonRole(b) == role && (opt->standardButtons() & i)) {
|
if (buttonRole(b) == role && (opt->standardButtons() & i)) {
|
||||||
const QString text = QGuiApplicationPrivate::platformTheme()->standardButtonText(b);
|
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)
|
bool registerNatives(JNIEnv *env)
|
||||||
{
|
{
|
||||||
jclass clazz = QJNIEnvironmentPrivate::findClass(QtMessageHandlerHelperClassName, env);
|
QJniEnvironment qenv;
|
||||||
|
jclass clazz = qenv.findClass(QtMessageHandlerHelperClassName);
|
||||||
if (!clazz) {
|
if (!clazz) {
|
||||||
__android_log_print(ANDROID_LOG_FATAL, QtAndroid::qtTagText(), QtAndroid::classErrorMsgFmt()
|
__android_log_print(ANDROID_LOG_FATAL, QtAndroid::qtTagText(), QtAndroid::classErrorMsgFmt()
|
||||||
, QtMessageHandlerHelperClassName);
|
, QtMessageHandlerHelperClassName);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2013 BogDan Vatra <bogdan@kde.org>
|
** Copyright (C) 2013 BogDan Vatra <bogdan@kde.org>
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the plugins of the Qt Toolkit.
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
@ -39,10 +40,13 @@
|
|||||||
|
|
||||||
#ifndef QANDROIDPLATFORMDIALOGHELPERS_H
|
#ifndef QANDROIDPLATFORMDIALOGHELPERS_H
|
||||||
#define QANDROIDPLATFORMDIALOGHELPERS_H
|
#define QANDROIDPLATFORMDIALOGHELPERS_H
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <qpa/qplatformdialoghelper.h>
|
|
||||||
#include <QEventLoop>
|
#include <QEventLoop>
|
||||||
#include <private/qjni_p.h>
|
#include <QtCore/QJniEnvironment>
|
||||||
|
#include <QtCore/QJniObject>
|
||||||
|
#include <qpa/qplatformdialoghelper.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -68,7 +72,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
int m_buttonId;
|
int m_buttonId;
|
||||||
QEventLoop m_loop;
|
QEventLoop m_loop;
|
||||||
QJNIObjectPrivate m_javaMessageDialog;
|
QJniObject m_javaMessageDialog;
|
||||||
bool m_shown;
|
bool m_shown;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB)
|
** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB)
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the plugins of the Qt Toolkit.
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
@ -40,10 +41,10 @@
|
|||||||
#include "qandroidplatformfiledialoghelper.h"
|
#include "qandroidplatformfiledialoghelper.h"
|
||||||
|
|
||||||
#include <androidjnimain.h>
|
#include <androidjnimain.h>
|
||||||
#include <jni.h>
|
#include <QtCore/QJniObject>
|
||||||
|
|
||||||
#include <QMimeType>
|
|
||||||
#include <QMimeDatabase>
|
#include <QMimeDatabase>
|
||||||
|
#include <QMimeType>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -71,9 +72,9 @@ bool QAndroidPlatformFileDialogHelper::handleActivityResult(jint requestCode, ji
|
|||||||
return true;
|
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()) {
|
if (uri.isValid()) {
|
||||||
takePersistableUriPermission(uri);
|
takePersistableUriPermission(uri);
|
||||||
m_selectedFile.append(QUrl(uri.toString()));
|
m_selectedFile.append(QUrl(uri.toString()));
|
||||||
@ -83,15 +84,15 @@ bool QAndroidPlatformFileDialogHelper::handleActivityResult(jint requestCode, ji
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QJNIObjectPrivate uriClipData =
|
const QJniObject uriClipData =
|
||||||
intent.callObjectMethod("getClipData", "()Landroid/content/ClipData;");
|
intent.callObjectMethod("getClipData", "()Landroid/content/ClipData;");
|
||||||
if (uriClipData.isValid()) {
|
if (uriClipData.isValid()) {
|
||||||
const int size = uriClipData.callMethod<jint>("getItemCount");
|
const int size = uriClipData.callMethod<jint>("getItemCount");
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
QJNIObjectPrivate item = uriClipData.callObjectMethod(
|
QJniObject item = uriClipData.callObjectMethod(
|
||||||
"getItemAt", "(I)Landroid/content/ClipData$Item;", i);
|
"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);
|
takePersistableUriPermission(itemUri);
|
||||||
m_selectedFile.append(itemUri.toString());
|
m_selectedFile.append(itemUri.toString());
|
||||||
}
|
}
|
||||||
@ -102,17 +103,17 @@ bool QAndroidPlatformFileDialogHelper::handleActivityResult(jint requestCode, ji
|
|||||||
return true;
|
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");
|
JniIntentClass, "FLAG_GRANT_READ_URI_PERMISSION");
|
||||||
|
|
||||||
if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
|
if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
|
||||||
modeFlags |= QJNIObjectPrivate::getStaticField<jint>(
|
modeFlags |= QJniObject::getStaticField<jint>(
|
||||||
JniIntentClass, "FLAG_GRANT_WRITE_URI_PERMISSION");
|
JniIntentClass, "FLAG_GRANT_WRITE_URI_PERMISSION");
|
||||||
}
|
}
|
||||||
|
|
||||||
QJNIObjectPrivate contentResolver = m_activity.callObjectMethod(
|
QJniObject contentResolver = m_activity.callObjectMethod(
|
||||||
"getContentResolver", "()Landroid/content/ContentResolver;");
|
"getContentResolver", "()Landroid/content/ContentResolver;");
|
||||||
contentResolver.callMethod<void>("takePersistableUriPermission", "(Landroid/net/Uri;I)V",
|
contentResolver.callMethod<void>("takePersistableUriPermission", "(Landroid/net/Uri;I)V",
|
||||||
uri.object(), modeFlags);
|
uri.object(), modeFlags);
|
||||||
@ -120,16 +121,16 @@ void QAndroidPlatformFileDialogHelper::takePersistableUriPermission(const QJNIOb
|
|||||||
|
|
||||||
void QAndroidPlatformFileDialogHelper::setIntentTitle(const QString &title)
|
void QAndroidPlatformFileDialogHelper::setIntentTitle(const QString &title)
|
||||||
{
|
{
|
||||||
const QJNIObjectPrivate extraTitle = QJNIObjectPrivate::getStaticObjectField(
|
const QJniObject extraTitle = QJniObject::getStaticObjectField(
|
||||||
JniIntentClass, "EXTRA_TITLE", "Ljava/lang/String;");
|
JniIntentClass, "EXTRA_TITLE", "Ljava/lang/String;");
|
||||||
m_intent.callObjectMethod("putExtra",
|
m_intent.callObjectMethod("putExtra",
|
||||||
"(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
|
"(Ljava/lang/String;Ljava/lang/String;)Landroid/content/Intent;",
|
||||||
extraTitle.object(), QJNIObjectPrivate::fromString(title).object());
|
extraTitle.object(), QJniObject::fromString(title).object());
|
||||||
}
|
}
|
||||||
|
|
||||||
void QAndroidPlatformFileDialogHelper::setOpenableCategory()
|
void QAndroidPlatformFileDialogHelper::setOpenableCategory()
|
||||||
{
|
{
|
||||||
const QJNIObjectPrivate CATEGORY_OPENABLE = QJNIObjectPrivate::getStaticObjectField(
|
const QJniObject CATEGORY_OPENABLE = QJniObject::getStaticObjectField(
|
||||||
JniIntentClass, "CATEGORY_OPENABLE", "Ljava/lang/String;");
|
JniIntentClass, "CATEGORY_OPENABLE", "Ljava/lang/String;");
|
||||||
m_intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;",
|
m_intent.callObjectMethod("addCategory", "(Ljava/lang/String;)Landroid/content/Intent;",
|
||||||
CATEGORY_OPENABLE.object());
|
CATEGORY_OPENABLE.object());
|
||||||
@ -137,7 +138,7 @@ void QAndroidPlatformFileDialogHelper::setOpenableCategory()
|
|||||||
|
|
||||||
void QAndroidPlatformFileDialogHelper::setAllowMultipleSelections(bool allowMultiple)
|
void QAndroidPlatformFileDialogHelper::setAllowMultipleSelections(bool allowMultiple)
|
||||||
{
|
{
|
||||||
const QJNIObjectPrivate allowMultipleSelections = QJNIObjectPrivate::getStaticObjectField(
|
const QJniObject allowMultipleSelections = QJniObject::getStaticObjectField(
|
||||||
JniIntentClass, "EXTRA_ALLOW_MULTIPLE", "Ljava/lang/String;");
|
JniIntentClass, "EXTRA_ALLOW_MULTIPLE", "Ljava/lang/String;");
|
||||||
m_intent.callObjectMethod("putExtra", "(Ljava/lang/String;Z)Landroid/content/Intent;",
|
m_intent.callObjectMethod("putExtra", "(Ljava/lang/String;Z)Landroid/content/Intent;",
|
||||||
allowMultipleSelections.object(), allowMultiple);
|
allowMultipleSelections.object(), allowMultiple);
|
||||||
@ -169,17 +170,17 @@ void QAndroidPlatformFileDialogHelper::setMimeTypes()
|
|||||||
|
|
||||||
QString type = !mimeTypes.isEmpty() ? mimeTypes.at(0) : QLatin1String("*/*");
|
QString type = !mimeTypes.isEmpty() ? mimeTypes.at(0) : QLatin1String("*/*");
|
||||||
m_intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;",
|
m_intent.callObjectMethod("setType", "(Ljava/lang/String;)Landroid/content/Intent;",
|
||||||
QJNIObjectPrivate::fromString(type).object());
|
QJniObject::fromString(type).object());
|
||||||
|
|
||||||
if (!mimeTypes.isEmpty()) {
|
if (!mimeTypes.isEmpty()) {
|
||||||
const QJNIObjectPrivate extraMimeType = QJNIObjectPrivate::getStaticObjectField(
|
const QJniObject extraMimeType = QJniObject::getStaticObjectField(
|
||||||
JniIntentClass, "EXTRA_MIME_TYPES", "Ljava/lang/String;");
|
JniIntentClass, "EXTRA_MIME_TYPES", "Ljava/lang/String;");
|
||||||
|
|
||||||
QJNIObjectPrivate mimeTypesArray = QJNIObjectPrivate::callStaticObjectMethod(
|
QJniObject mimeTypesArray = QJniObject::callStaticObjectMethod(
|
||||||
"org/qtproject/qt/android/QtNative",
|
"org/qtproject/qt/android/QtNative",
|
||||||
"getStringArray",
|
"getStringArray",
|
||||||
"(Ljava/lang/String;)[Ljava/lang/String;",
|
"(Ljava/lang/String;)[Ljava/lang/String;",
|
||||||
QJNIObjectPrivate::fromString(mimeTypes.join(",")).object());
|
QJniObject::fromString(mimeTypes.join(",")).object());
|
||||||
|
|
||||||
m_intent.callObjectMethod(
|
m_intent.callObjectMethod(
|
||||||
"putExtra", "(Ljava/lang/String;[Ljava/lang/String;)Landroid/content/Intent;",
|
"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;");
|
JniIntentClass, intentType.toLatin1(), "Ljava/lang/String;");
|
||||||
return QJNIObjectPrivate(JniIntentClass, "(Ljava/lang/String;)V",
|
return QJniObject(JniIntentClass, "(Ljava/lang/String;)V",
|
||||||
ACTION_OPEN_DOCUMENT.object());
|
ACTION_OPEN_DOCUMENT.object());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB)
|
** Copyright (C) 2019 Klaralvdalens Datakonsult AB (KDAB)
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the plugins of the Qt Toolkit.
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
@ -41,11 +42,11 @@
|
|||||||
#define QANDROIDPLATFORMFILEDIALOGHELPER_H
|
#define QANDROIDPLATFORMFILEDIALOGHELPER_H
|
||||||
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
|
||||||
#include <QEventLoop>
|
#include <QEventLoop>
|
||||||
#include <qpa/qplatformdialoghelper.h>
|
#include <QtCore/QJniObject>
|
||||||
#include <QtCore/private/qjnihelpers_p.h>
|
#include <QtCore/private/qjnihelpers_p.h>
|
||||||
#include <private/qjni_p.h>
|
#include <qpa/qplatformdialoghelper.h>
|
||||||
#include <QEventLoop>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -73,8 +74,8 @@ public:
|
|||||||
bool handleActivityResult(jint requestCode, jint resultCode, jobject data) override;
|
bool handleActivityResult(jint requestCode, jint resultCode, jobject data) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QJNIObjectPrivate getFileDialogIntent(const QString &intentType);
|
QJniObject getFileDialogIntent(const QString &intentType);
|
||||||
void takePersistableUriPermission(const QJNIObjectPrivate &uri);
|
void takePersistableUriPermission(const QJniObject &uri);
|
||||||
void setIntentTitle(const QString &title);
|
void setIntentTitle(const QString &title);
|
||||||
void setOpenableCategory();
|
void setOpenableCategory();
|
||||||
void setAllowMultipleSelections(bool allowMultiple);
|
void setAllowMultipleSelections(bool allowMultiple);
|
||||||
@ -82,8 +83,8 @@ private:
|
|||||||
|
|
||||||
QEventLoop m_eventLoop;
|
QEventLoop m_eventLoop;
|
||||||
QList<QUrl> m_selectedFile;
|
QList<QUrl> m_selectedFile;
|
||||||
QJNIObjectPrivate m_intent;
|
QJniObject m_intent;
|
||||||
const QJNIObjectPrivate m_activity;
|
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/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the plugins of the Qt Toolkit.
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
@ -42,7 +42,8 @@
|
|||||||
|
|
||||||
#include "androidsurfaceclient.h"
|
#include "androidsurfaceclient.h"
|
||||||
#include "qandroidplatformwindow.h"
|
#include "qandroidplatformwindow.h"
|
||||||
#include <QtCore/private/qjni_p.h>
|
|
||||||
|
#include <QtCore/QJniObject>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int m_surfaceId;
|
int m_surfaceId;
|
||||||
QJNIObjectPrivate m_view;
|
QJniObject m_view;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
|
** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the plugins of the Qt Toolkit.
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
@ -39,35 +40,34 @@
|
|||||||
|
|
||||||
#include "qandroidplatformintegration.h"
|
#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 "androidjniaccessibility.h"
|
||||||
|
#include "androidjnimain.h"
|
||||||
#include "qabstracteventdispatcher.h"
|
#include "qabstracteventdispatcher.h"
|
||||||
#include "qandroideventdispatcher.h"
|
#include "qandroideventdispatcher.h"
|
||||||
#include "qandroidplatformbackingstore.h"
|
|
||||||
#include "qandroidplatformaccessibility.h"
|
#include "qandroidplatformaccessibility.h"
|
||||||
|
#include "qandroidplatformbackingstore.h"
|
||||||
#include "qandroidplatformclipboard.h"
|
#include "qandroidplatformclipboard.h"
|
||||||
#include "qandroidplatformforeignwindow.h"
|
|
||||||
#include "qandroidplatformfontdatabase.h"
|
#include "qandroidplatformfontdatabase.h"
|
||||||
|
#include "qandroidplatformforeignwindow.h"
|
||||||
|
#include "qandroidplatformoffscreensurface.h"
|
||||||
#include "qandroidplatformopenglcontext.h"
|
#include "qandroidplatformopenglcontext.h"
|
||||||
#include "qandroidplatformopenglwindow.h"
|
#include "qandroidplatformopenglwindow.h"
|
||||||
#include "qandroidplatformscreen.h"
|
#include "qandroidplatformscreen.h"
|
||||||
#include "qandroidplatformservices.h"
|
#include "qandroidplatformservices.h"
|
||||||
#include "qandroidplatformtheme.h"
|
#include "qandroidplatformtheme.h"
|
||||||
#include "qandroidsystemlocale.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>
|
#include <jni.h>
|
||||||
|
|
||||||
@ -200,17 +200,17 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶
|
|||||||
m_accessibility = new QAndroidPlatformAccessibility();
|
m_accessibility = new QAndroidPlatformAccessibility();
|
||||||
#endif // QT_NO_ACCESSIBILITY
|
#endif // QT_NO_ACCESSIBILITY
|
||||||
|
|
||||||
QJNIObjectPrivate javaActivity(QtAndroid::activity());
|
QJniObject javaActivity(QtAndroid::activity());
|
||||||
if (!javaActivity.isValid())
|
if (!javaActivity.isValid())
|
||||||
javaActivity = QtAndroid::service();
|
javaActivity = QtAndroid::service();
|
||||||
|
|
||||||
if (javaActivity.isValid()) {
|
if (javaActivity.isValid()) {
|
||||||
QJNIObjectPrivate resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
|
QJniObject resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
|
||||||
QJNIObjectPrivate configuration = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;");
|
QJniObject configuration = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;");
|
||||||
|
|
||||||
int touchScreen = configuration.getField<jint>("touchscreen");
|
int touchScreen = configuration.getField<jint>("touchscreen");
|
||||||
if (touchScreen == QJNIObjectPrivate::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_FINGER")
|
if (touchScreen == QJniObject::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_FINGER")
|
||||||
|| touchScreen == QJNIObjectPrivate::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_STYLUS"))
|
|| touchScreen == QJniObject::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_STYLUS"))
|
||||||
{
|
{
|
||||||
m_touchDevice = new QPointingDevice;
|
m_touchDevice = new QPointingDevice;
|
||||||
m_touchDevice->setType(QInputDevice::DeviceType::TouchScreen);
|
m_touchDevice->setType(QInputDevice::DeviceType::TouchScreen);
|
||||||
@ -219,16 +219,16 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶
|
|||||||
| QPointingDevice::Capability::Pressure
|
| QPointingDevice::Capability::Pressure
|
||||||
| QPointingDevice::Capability::NormalizedPosition);
|
| 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());
|
Q_ASSERT(pm.isValid());
|
||||||
if (pm.callMethod<jboolean>("hasSystemFeature","(Ljava/lang/String;)Z",
|
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);
|
m_touchDevice->setMaximumTouchPoints(10);
|
||||||
} else if (pm.callMethod<jboolean>("hasSystemFeature","(Ljava/lang/String;)Z",
|
} 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);
|
m_touchDevice->setMaximumTouchPoints(4);
|
||||||
} else if (pm.callMethod<jboolean>("hasSystemFeature","(Ljava/lang/String;)Z",
|
} 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);
|
m_touchDevice->setMaximumTouchPoints(2);
|
||||||
}
|
}
|
||||||
QWindowSystemInterface::registerInputDevice(m_touchDevice);
|
QWindowSystemInterface::registerInputDevice(m_touchDevice);
|
||||||
@ -236,11 +236,14 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶
|
|||||||
|
|
||||||
auto contentResolver = javaActivity.callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;");
|
auto contentResolver = javaActivity.callObjectMethod("getContentResolver", "()Landroid/content/ContentResolver;");
|
||||||
Q_ASSERT(contentResolver.isValid());
|
Q_ASSERT(contentResolver.isValid());
|
||||||
QJNIObjectPrivate txtShowPassValue = QJNIObjectPrivate::callStaticObjectMethod("android/provider/Settings$System",
|
QJniObject txtShowPassValue = QJniObject::callStaticObjectMethod(
|
||||||
|
"android/provider/Settings$System",
|
||||||
"getString",
|
"getString",
|
||||||
"(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;",
|
"(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;",
|
||||||
contentResolver.object(),
|
contentResolver.object(),
|
||||||
QJNIObjectPrivate::getStaticObjectField("android/provider/Settings$System", "TEXT_SHOW_PASSWORD", "Ljava/lang/String;").object());
|
QJniObject::getStaticObjectField("android/provider/Settings$System",
|
||||||
|
"TEXT_SHOW_PASSWORD",
|
||||||
|
"Ljava/lang/String;").object());
|
||||||
if (txtShowPassValue.isValid()) {
|
if (txtShowPassValue.isValid()) {
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
const int txtShowPass = txtShowPassValue.toString().toInt(&ok);
|
const int txtShowPass = txtShowPassValue.toString().toInt(&ok);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
|
** Copyright (C) 2012 BogDan Vatra <bogdan@kde.org>
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the plugins of the Qt Toolkit.
|
** This file is part of the plugins of the Qt Toolkit.
|
||||||
@ -37,10 +38,12 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include "androidjnimenu.h"
|
||||||
#include "qandroidplatformmenu.h"
|
#include "qandroidplatformmenu.h"
|
||||||
#include "qandroidplatformmenuitem.h"
|
#include "qandroidplatformmenuitem.h"
|
||||||
#include "androidjnimenu.h"
|
|
||||||
#include <QtCore/private/qjni_p.h>
|
#include <QtCore/qjnienvironment.h>
|
||||||
|
#include <QtCore/qjniobject.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -152,7 +155,7 @@ void QAndroidPlatformMenu::showPopup(const QWindow *parentWindow, const QRect &t
|
|||||||
Q_UNUSED(parentWindow);
|
Q_UNUSED(parentWindow);
|
||||||
Q_UNUSED(item);
|
Q_UNUSED(item);
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
QtAndroidMenu::showContextMenu(this, targetRect, QJNIEnvironmentPrivate());
|
QtAndroidMenu::showContextMenu(this, targetRect, QJniEnvironment());
|
||||||
}
|
}
|
||||||
|
|
||||||
QPlatformMenuItem *QAndroidPlatformMenu::menuItemForTag(quintptr tag) const
|
QPlatformMenuItem *QAndroidPlatformMenu::menuItemForTag(quintptr tag) const
|
||||||
|
@ -40,20 +40,20 @@
|
|||||||
|
|
||||||
#include "qandroidplatformopenglwindow.h"
|
#include "qandroidplatformopenglwindow.h"
|
||||||
|
|
||||||
#include "qandroidplatformscreen.h"
|
#include "androiddeadlockprotector.h"
|
||||||
#include "androidjnimain.h"
|
#include "androidjnimain.h"
|
||||||
#include "qandroideventdispatcher.h"
|
#include "qandroideventdispatcher.h"
|
||||||
#include "androiddeadlockprotector.h"
|
#include "qandroidplatformscreen.h"
|
||||||
|
|
||||||
#include <QSurfaceFormat>
|
#include <QSurfaceFormat>
|
||||||
#include <QtGui/private/qwindow_p.h>
|
#include <QtGui/private/qwindow_p.h>
|
||||||
#include <QtGui/qguiapplication.h>
|
#include <QtGui/qguiapplication.h>
|
||||||
|
|
||||||
#include <qpa/qwindowsysteminterface.h>
|
|
||||||
#include <qpa/qplatformscreen.h>
|
|
||||||
#include <QtGui/private/qeglconvenience_p.h>
|
#include <QtGui/private/qeglconvenience_p.h>
|
||||||
#include <android/native_window.h>
|
#include <android/native_window.h>
|
||||||
#include <android/native_window_jni.h>
|
#include <android/native_window_jni.h>
|
||||||
|
#include <qpa/qplatformscreen.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -175,9 +175,9 @@ void QAndroidPlatformOpenGLWindow::applicationStateChanged(Qt::ApplicationState
|
|||||||
void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
|
void QAndroidPlatformOpenGLWindow::createEgl(EGLConfig config)
|
||||||
{
|
{
|
||||||
clearEgl();
|
clearEgl();
|
||||||
QJNIEnvironmentPrivate env;
|
QJniEnvironment env;
|
||||||
m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object());
|
m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object());
|
||||||
m_androidSurfaceObject = QJNIObjectPrivate();
|
m_androidSurfaceObject = QJniObject();
|
||||||
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_nativeWindow, NULL);
|
m_eglSurface = eglCreateWindowSurface(m_eglDisplay, config, m_nativeWindow, NULL);
|
||||||
m_format = q_glFormatFromConfig(m_eglDisplay, config, window()->requestedFormat());
|
m_format = q_glFormatFromConfig(m_eglDisplay, config, window()->requestedFormat());
|
||||||
if (Q_UNLIKELY(m_eglSurface == EGL_NO_SURFACE)) {
|
if (Q_UNLIKELY(m_eglSurface == EGL_NO_SURFACE)) {
|
||||||
|
@ -41,13 +41,15 @@
|
|||||||
#ifndef QANDROIDPLATFORMOPENGLWINDOW_H
|
#ifndef QANDROIDPLATFORMOPENGLWINDOW_H
|
||||||
#define QANDROIDPLATFORMOPENGLWINDOW_H
|
#define QANDROIDPLATFORMOPENGLWINDOW_H
|
||||||
|
|
||||||
#include <EGL/egl.h>
|
|
||||||
#include <QWaitCondition>
|
|
||||||
#include <QtCore/private/qjni_p.h>
|
|
||||||
|
|
||||||
#include "androidsurfaceclient.h"
|
#include "androidsurfaceclient.h"
|
||||||
#include "qandroidplatformwindow.h"
|
#include "qandroidplatformwindow.h"
|
||||||
|
|
||||||
|
#include <QWaitCondition>
|
||||||
|
#include <QtCore/qjnienvironment.h>
|
||||||
|
#include <QtCore/qjniobject.h>
|
||||||
|
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class QAndroidPlatformOpenGLWindow : public QAndroidPlatformWindow, public AndroidSurfaceClient
|
class QAndroidPlatformOpenGLWindow : public QAndroidPlatformWindow, public AndroidSurfaceClient
|
||||||
@ -77,7 +79,7 @@ private:
|
|||||||
EGLNativeWindowType m_nativeWindow = nullptr;
|
EGLNativeWindowType m_nativeWindow = nullptr;
|
||||||
|
|
||||||
int m_nativeSurfaceId = -1;
|
int m_nativeSurfaceId = -1;
|
||||||
QJNIObjectPrivate m_androidSurfaceObject;
|
QJniObject m_androidSurfaceObject;
|
||||||
QWaitCondition m_surfaceWaitCondition;
|
QWaitCondition m_surfaceWaitCondition;
|
||||||
QSurfaceFormat m_format;
|
QSurfaceFormat m_format;
|
||||||
QRect m_oldGeometry;
|
QRect m_oldGeometry;
|
||||||
|
@ -41,14 +41,14 @@
|
|||||||
#ifndef QANDROIDPLATFORMSCREEN_H
|
#ifndef QANDROIDPLATFORMSCREEN_H
|
||||||
#define QANDROIDPLATFORMSCREEN_H
|
#define QANDROIDPLATFORMSCREEN_H
|
||||||
|
|
||||||
#include <qpa/qplatformscreen.h>
|
#include "androidsurfaceclient.h"
|
||||||
|
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include <QWaitCondition>
|
#include <QWaitCondition>
|
||||||
#include <QtCore/private/qjni_p.h>
|
#include <QtCore/QJniObject>
|
||||||
|
#include <qpa/qplatformscreen.h>
|
||||||
#include "androidsurfaceclient.h"
|
|
||||||
|
|
||||||
#include <android/native_window.h>
|
#include <android/native_window.h>
|
||||||
|
|
||||||
|
@ -38,11 +38,12 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qandroidplatformservices.h"
|
#include "qandroidplatformservices.h"
|
||||||
#include <QUrl>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
#include <QMimeDatabase>
|
#include <QMimeDatabase>
|
||||||
#include <QtCore/private/qjni_p.h>
|
#include <QUrl>
|
||||||
|
#include <QtCore/QJniObject>
|
||||||
#include <private/qjnihelpers_p.h>
|
#include <private/qjnihelpers_p.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@ -66,9 +67,9 @@ bool QAndroidPlatformServices::openUrl(const QUrl &theUrl)
|
|||||||
mime = mimeDb.mimeTypeForUrl(url).name();
|
mime = mimeDb.mimeTypeForUrl(url).name();
|
||||||
}
|
}
|
||||||
|
|
||||||
QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString());
|
QJniObject urlString = QJniObject::fromString(url.toString());
|
||||||
QJNIObjectPrivate mimeString = QJNIObjectPrivate::fromString(mime);
|
QJniObject mimeString = QJniObject::fromString(mime);
|
||||||
return QJNIObjectPrivate::callStaticMethod<jboolean>(
|
return QJniObject::callStaticMethod<jboolean>(
|
||||||
QtAndroid::applicationClass(), "openURL",
|
QtAndroid::applicationClass(), "openURL",
|
||||||
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Z",
|
"(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Z",
|
||||||
QtAndroidPrivate::context(), urlString.object(), mimeString.object());
|
QtAndroidPrivate::context(), urlString.object(), mimeString.object());
|
||||||
|
@ -37,15 +37,15 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qandroidplatformvulkanwindow.h"
|
#include "androiddeadlockprotector.h"
|
||||||
#include "qandroidplatformscreen.h"
|
|
||||||
#include "androidjnimain.h"
|
#include "androidjnimain.h"
|
||||||
#include "qandroideventdispatcher.h"
|
#include "qandroideventdispatcher.h"
|
||||||
#include "androiddeadlockprotector.h"
|
#include "qandroidplatformscreen.h"
|
||||||
|
#include "qandroidplatformvulkanwindow.h"
|
||||||
|
|
||||||
#include <QSurfaceFormat>
|
#include <QSurfaceFormat>
|
||||||
#include <qpa/qwindowsysteminterface.h>
|
|
||||||
#include <qpa/qplatformscreen.h>
|
#include <qpa/qplatformscreen.h>
|
||||||
|
#include <qpa/qwindowsysteminterface.h>
|
||||||
|
|
||||||
#include <android/native_window.h>
|
#include <android/native_window.h>
|
||||||
#include <android/native_window_jni.h>
|
#include <android/native_window_jni.h>
|
||||||
@ -172,7 +172,7 @@ VkSurfaceKHR *QAndroidPlatformVulkanWindow::vkSurface()
|
|||||||
if (m_nativeSurfaceId == -1 || !m_androidSurfaceObject.isValid())
|
if (m_nativeSurfaceId == -1 || !m_androidSurfaceObject.isValid())
|
||||||
return &m_vkSurface;
|
return &m_vkSurface;
|
||||||
|
|
||||||
QJNIEnvironmentPrivate env;
|
QJniEnvironment env;
|
||||||
m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object());
|
m_nativeWindow = ANativeWindow_fromSurface(env, m_androidSurfaceObject.object());
|
||||||
|
|
||||||
VkAndroidSurfaceCreateInfoKHR surfaceInfo;
|
VkAndroidSurfaceCreateInfoKHR surfaceInfo;
|
||||||
|
@ -46,13 +46,13 @@
|
|||||||
|
|
||||||
#define VK_USE_PLATFORM_ANDROID_KHR
|
#define VK_USE_PLATFORM_ANDROID_KHR
|
||||||
|
|
||||||
#include <QWaitCondition>
|
|
||||||
#include <QtCore/private/qjni_p.h>
|
|
||||||
|
|
||||||
#include "androidsurfaceclient.h"
|
#include "androidsurfaceclient.h"
|
||||||
|
#include "qandroidplatformvulkaninstance.h"
|
||||||
#include "qandroidplatformwindow.h"
|
#include "qandroidplatformwindow.h"
|
||||||
|
|
||||||
#include "qandroidplatformvulkaninstance.h"
|
#include <QWaitCondition>
|
||||||
|
#include <QtCore/QJniEnvironment>
|
||||||
|
#include <QtCore/QJniObject>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ private:
|
|||||||
|
|
||||||
int m_nativeSurfaceId;
|
int m_nativeSurfaceId;
|
||||||
ANativeWindow *m_nativeWindow;
|
ANativeWindow *m_nativeWindow;
|
||||||
QJNIObjectPrivate m_androidSurfaceObject;
|
QJniObject m_androidSurfaceObject;
|
||||||
QWaitCondition m_surfaceWaitCondition;
|
QWaitCondition m_surfaceWaitCondition;
|
||||||
QSurfaceFormat m_format;
|
QSurfaceFormat m_format;
|
||||||
QRect m_oldGeometry;
|
QRect m_oldGeometry;
|
||||||
|
@ -37,14 +37,15 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "qandroidsystemlocale.h"
|
|
||||||
#include "androidjnimain.h"
|
#include "androidjnimain.h"
|
||||||
#include <QtCore/private/qjni_p.h>
|
#include "qandroidsystemlocale.h"
|
||||||
#include <QtCore/private/qjnihelpers_p.h>
|
|
||||||
#include "qdatetime.h"
|
#include "qdatetime.h"
|
||||||
#include "qstringlist.h"
|
#include "qstringlist.h"
|
||||||
#include "qvariant.h"
|
#include "qvariant.h"
|
||||||
|
|
||||||
|
#include <QtCore/private/qjnihelpers_p.h>
|
||||||
|
#include <QtCore/QJniObject>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
QAndroidSystemLocale::QAndroidSystemLocale() : m_locale(QLocale::C)
|
QAndroidSystemLocale::QAndroidSystemLocale() : m_locale(QLocale::C)
|
||||||
@ -55,17 +56,17 @@ void QAndroidSystemLocale::getLocaleFromJava() const
|
|||||||
{
|
{
|
||||||
QWriteLocker locker(&m_lock);
|
QWriteLocker locker(&m_lock);
|
||||||
|
|
||||||
QJNIObjectPrivate javaLocaleObject;
|
QJniObject javaLocaleObject;
|
||||||
QJNIObjectPrivate javaActivity(QtAndroid::activity());
|
QJniObject javaActivity(QtAndroid::activity());
|
||||||
if (!javaActivity.isValid())
|
if (!javaActivity.isValid())
|
||||||
javaActivity = QtAndroid::service();
|
javaActivity = QtAndroid::service();
|
||||||
if (javaActivity.isValid()) {
|
if (javaActivity.isValid()) {
|
||||||
QJNIObjectPrivate resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
|
QJniObject resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
|
||||||
QJNIObjectPrivate configuration = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;");
|
QJniObject configuration = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;");
|
||||||
|
|
||||||
javaLocaleObject = configuration.getObjectField("locale", "Ljava/util/Locale;");
|
javaLocaleObject = configuration.getObjectField("locale", "Ljava/util/Locale;");
|
||||||
} else {
|
} 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();
|
QString languageCode = javaLocaleObject.callObjectMethod("getLanguage", "()Ljava/lang/String;").toString();
|
||||||
@ -165,8 +166,8 @@ QVariant QAndroidSystemLocale::query(QueryType type, QVariant in) const
|
|||||||
Q_ASSERT_X(false, Q_FUNC_INFO, "This can't happen.");
|
Q_ASSERT_X(false, Q_FUNC_INFO, "This can't happen.");
|
||||||
case UILanguages: {
|
case UILanguages: {
|
||||||
if (QtAndroidPrivate::androidSdkVersion() >= 24) {
|
if (QtAndroidPrivate::androidSdkVersion() >= 24) {
|
||||||
QJNIObjectPrivate localeListObject =
|
QJniObject localeListObject =
|
||||||
QJNIObjectPrivate::callStaticObjectMethod("android/os/LocaleList", "getDefault",
|
QJniObject::callStaticObjectMethod("android/os/LocaleList", "getDefault",
|
||||||
"()Landroid/os/LocaleList;");
|
"()Landroid/os/LocaleList;");
|
||||||
if (localeListObject.isValid()) {
|
if (localeListObject.isValid()) {
|
||||||
QString lang = localeListObject.callObjectMethod("toLanguageTags",
|
QString lang = localeListObject.callObjectMethod("toLanguageTags",
|
||||||
|
@ -45,3 +45,7 @@ endif()
|
|||||||
if(QT_FEATURE_private_tests)
|
if(QT_FEATURE_private_tests)
|
||||||
add_subdirectory(qproperty)
|
add_subdirectory(qproperty)
|
||||||
endif()
|
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