From 9cb2200d4fe2c99edb39e5a78f1a7ca37fdbe54c Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 11 Jun 2024 16:50:40 +0200 Subject: [PATCH] JNI: pre-declare JNI classes for standard Java types This avoids that we or users have to declare e.g. String or Uri in several places in Qt. This also prevents problems where multiple declarations (possibly from different headers) cause build errors. As a drive-by, remove some unnecessary type declarations (e.g. UriType, which had the same class string as Uri). To ease the submodule update process, define a preprocessor symbol that submodules can use to conditionally declare the type locally. Once the dependency update is through, the symbol can be removed and submodules can use the declaration from qjnitypes.h. Change-Id: I7d96edf644a54246302b5c5cb478e66fa615e73e Reviewed-by: Assam Boudjelthia (cherry picked from commit 457a1c973d68e705f9cf72ac72b19fc26cdb2917) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/io/qstandardpaths_android.cpp | 1 - .../kernel/qcoreapplication_platform.h | 4 -- src/corelib/kernel/qjnihelpers_p.h | 3 - src/corelib/kernel/qjnitypes.h | 27 +++++++++ src/corelib/time/qtimezoneprivate_android.cpp | 1 - src/network/kernel/qnetworkproxy_android.cpp | 1 - .../android/androidcontentfileengine.cpp | 57 +++++++++---------- .../android/qandroidplatformiconengine.cpp | 3 - .../android/qandroidplatformservices.cpp | 7 +-- .../kernel/qjnitypes/tst_qjnitypes.cpp | 1 - 10 files changed, 56 insertions(+), 49 deletions(-) diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp index f39b6855b66..3dbbfc1e1cf 100644 --- a/src/corelib/io/qstandardpaths_android.cpp +++ b/src/corelib/io/qstandardpaths_android.cpp @@ -13,7 +13,6 @@ QT_BEGIN_NAMESPACE Q_DECLARE_JNI_CLASS(Environment, "android/os/Environment"); -Q_DECLARE_JNI_CLASS(File, "java/io/File"); using namespace QNativeInterface; using namespace Qt::StringLiterals; diff --git a/src/corelib/kernel/qcoreapplication_platform.h b/src/corelib/kernel/qcoreapplication_platform.h index d5f266179ec..4bca99493a7 100644 --- a/src/corelib/kernel/qcoreapplication_platform.h +++ b/src/corelib/kernel/qcoreapplication_platform.h @@ -32,10 +32,6 @@ typedef _jobject* jobject; QT_BEGIN_NAMESPACE -#if defined(Q_OS_ANDROID) -Q_DECLARE_JNI_CLASS(Context, "android/content/Context") -#endif - namespace QNativeInterface { #if defined(Q_OS_ANDROID) || defined(Q_QDOC) diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h index a7b879d9e12..f0c0a416831 100644 --- a/src/corelib/kernel/qjnihelpers_p.h +++ b/src/corelib/kernel/qjnihelpers_p.h @@ -22,9 +22,6 @@ QT_BEGIN_NAMESPACE -Q_DECLARE_JNI_CLASS(Activity, "android/app/Activity") -Q_DECLARE_JNI_CLASS(Service, "android/app/Service") - namespace QtAndroidPrivate { class Q_CORE_EXPORT ActivityResultListener diff --git a/src/corelib/kernel/qjnitypes.h b/src/corelib/kernel/qjnitypes.h index f6b486dc93d..682a91534cc 100644 --- a/src/corelib/kernel/qjnitypes.h +++ b/src/corelib/kernel/qjnitypes.h @@ -275,6 +275,33 @@ static const JNINativeMethod Method##_method = { \ #define Q_JNI_NATIVE_SCOPED_METHOD(Method, Scope) Scope::Method##_method +// Classes for value types +Q_DECLARE_JNI_CLASS(String, "java/lang/String") +Q_DECLARE_JNI_CLASS(Integer, "java/lang/Integer"); +Q_DECLARE_JNI_CLASS(Long, "java/lang/Long"); +Q_DECLARE_JNI_CLASS(Double, "java/lang/Double"); +Q_DECLARE_JNI_CLASS(Float, "java/lang/Float"); +Q_DECLARE_JNI_CLASS(Boolean, "java/lang/Boolean"); +Q_DECLARE_JNI_CLASS(Void, "java/lang/Void"); + +// Utility and I/O +Q_DECLARE_JNI_CLASS(UUID, "java/util/UUID") +Q_DECLARE_JNI_CLASS(ArrayList, "java/util/ArrayList") +Q_DECLARE_JNI_CLASS(HashMap, "java/util/HashMap") +Q_DECLARE_JNI_CLASS(Set, "java/util/Set") +Q_DECLARE_JNI_CLASS(File, "java/io/File"); + +// Android specific types +Q_DECLARE_JNI_CLASS(Uri, "android/net/Uri"); +Q_DECLARE_JNI_CLASS(Parcelable, "android/os/Parcelable"); +Q_DECLARE_JNI_CLASS(Context, "android/content/Context"); +Q_DECLARE_JNI_CLASS(Intent, "android/content/Intent"); +Q_DECLARE_JNI_CLASS(ContentResolver, "android/content/ContentResolver"); +Q_DECLARE_JNI_CLASS(Activity, "android/app/Activity"); +Q_DECLARE_JNI_CLASS(Service, "android/app/Service"); + +#define QT_DECLARE_JNI_CLASS_STANDARD_TYPES + QT_END_NAMESPACE #endif // defined(Q_QDOC) || defined(Q_OS_ANDROID) diff --git a/src/corelib/time/qtimezoneprivate_android.cpp b/src/corelib/time/qtimezoneprivate_android.cpp index e80d15fab1b..862b48477b4 100644 --- a/src/corelib/time/qtimezoneprivate_android.cpp +++ b/src/corelib/time/qtimezoneprivate_android.cpp @@ -14,7 +14,6 @@ QT_BEGIN_NAMESPACE Q_DECLARE_JNI_CLASS(TimeZone, "java/util/TimeZone"); Q_DECLARE_JNI_CLASS(Locale, "java/util/Locale"); Q_DECLARE_JNI_CLASS(Date, "java/util/Date"); -Q_DECLARE_JNI_CLASS(String, "java/lang/String") /* Private diff --git a/src/network/kernel/qnetworkproxy_android.cpp b/src/network/kernel/qnetworkproxy_android.cpp index bc1894db5ab..d5b56bba865 100644 --- a/src/network/kernel/qnetworkproxy_android.cpp +++ b/src/network/kernel/qnetworkproxy_android.cpp @@ -25,7 +25,6 @@ Q_GLOBAL_STATIC(ProxyInfoObject, proxyInfoInstance) Q_DECLARE_JNI_CLASS(QtNetwork, "org/qtproject/qt/android/network/QtNetwork") Q_DECLARE_JNI_CLASS(ProxyInfo, "android/net/ProxyInfo") -Q_DECLARE_JNI_CLASS(String, "java/lang/String") ProxyInfoObject::ProxyInfoObject() { diff --git a/src/plugins/platforms/android/androidcontentfileengine.cpp b/src/plugins/platforms/android/androidcontentfileengine.cpp index 5757f5d8cc0..f4afb3789a0 100644 --- a/src/plugins/platforms/android/androidcontentfileengine.cpp +++ b/src/plugins/platforms/android/androidcontentfileengine.cpp @@ -16,9 +16,6 @@ QT_BEGIN_NAMESPACE using namespace QNativeInterface; using namespace Qt::StringLiterals; -Q_DECLARE_JNI_CLASS(ContentResolverType, "android/content/ContentResolver"); -Q_DECLARE_JNI_CLASS(UriType, "android/net/Uri"); -Q_DECLARE_JNI_CLASS(Uri, "android/net/Uri"); Q_DECLARE_JNI_CLASS(ParcelFileDescriptorType, "android/os/ParcelFileDescriptor"); Q_DECLARE_JNI_CLASS(CursorType, "android/database/Cursor"); @@ -27,7 +24,7 @@ static QJniObject &contentResolverInstance() static QJniObject contentResolver; if (!contentResolver.isValid()) { contentResolver = QJniObject(QNativeInterface::QAndroidApplication::context()) - .callMethod("getContentResolver"); + .callMethod("getContentResolver"); } return contentResolver; @@ -79,7 +76,7 @@ bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode, } m_pfd = contentResolverInstance().callMethod< - QtJniTypes::ParcelFileDescriptorType, QtJniTypes::UriType, jstring>( + QtJniTypes::ParcelFileDescriptorType, QtJniTypes::Uri, jstring>( "openFileDescriptor", m_documentFile->uri().object(), QJniObject::fromString(openModeStr).object()); @@ -373,7 +370,7 @@ public: { auto cursor = contentResolverInstance().callMethod( "query", - uri.object(), + uri.object(), QJniArray(projection), selection.isEmpty() ? nullptr : QJniObject::fromString(selection).object(), QJniArray(selectionArgs), @@ -451,7 +448,7 @@ const QLatin1String MIME_TYPE_DIR("vnd.android.document/directory"); QString documentId(const QJniObject &uri) { - return QJniObject::callStaticMethod( + return QJniObject::callStaticMethod( QtJniTypes::Traits::className(), "getDocumentId", uri.object()).toString(); @@ -459,7 +456,7 @@ QString documentId(const QJniObject &uri) QString treeDocumentId(const QJniObject &uri) { - return QJniObject::callStaticMethod( + return QJniObject::callStaticMethod( QtJniTypes::Traits::className(), "getTreeDocumentId", uri.object()).toString(); @@ -467,20 +464,20 @@ QString treeDocumentId(const QJniObject &uri) QJniObject buildChildDocumentsUriUsingTree(const QJniObject &uri, const QString &parentDocumentId) { - return QJniObject::callStaticMethod( + return QJniObject::callStaticMethod( QtJniTypes::Traits::className(), "buildChildDocumentsUriUsingTree", - uri.object(), + uri.object(), QJniObject::fromString(parentDocumentId).object()); } QJniObject buildDocumentUriUsingTree(const QJniObject &treeUri, const QString &documentId) { - return QJniObject::callStaticMethod( + return QJniObject::callStaticMethod( QtJniTypes::Traits::className(), "buildDocumentUriUsingTree", - treeUri.object(), + treeUri.object(), QJniObject::fromString(documentId).object()); } @@ -490,7 +487,7 @@ bool isDocumentUri(const QJniObject &uri) QtJniTypes::Traits::className(), "isDocumentUri", QNativeInterface::QAndroidApplication::context(), - uri.object()); + uri.object()); } bool isTreeUri(const QJniObject &uri) @@ -498,17 +495,17 @@ bool isTreeUri(const QJniObject &uri) return QJniObject::callStaticMethod( QtJniTypes::Traits::className(), "isTreeUri", - uri.object()); + uri.object()); } QJniObject createDocument(const QJniObject &parentDocumentUri, const QString &mimeType, const QString &displayName) { - return QJniObject::callStaticMethod( + return QJniObject::callStaticMethod( QtJniTypes::Traits::className(), "createDocument", - contentResolverInstance().object(), - parentDocumentUri.object(), + contentResolverInstance().object(), + parentDocumentUri.object(), QJniObject::fromString(mimeType).object(), QJniObject::fromString(displayName).object()); } @@ -522,8 +519,8 @@ bool deleteDocument(const QJniObject &documentUri) return QJniObject::callStaticMethod( QtJniTypes::Traits::className(), "deleteDocument", - contentResolverInstance().object(), - documentUri.object()); + contentResolverInstance().object(), + documentUri.object()); } QJniObject moveDocument(const QJniObject &sourceDocumentUri, @@ -534,13 +531,13 @@ QJniObject moveDocument(const QJniObject &sourceDocumentUri, if (!(flags & Document::FLAG_SUPPORTS_MOVE)) return {}; - return QJniObject::callStaticMethod( + return QJniObject::callStaticMethod( QtJniTypes::Traits::className(), "moveDocument", - contentResolverInstance().object(), - sourceDocumentUri.object(), - sourceParentDocumentUri.object(), - targetParentDocumentUri.object()); + contentResolverInstance().object(), + sourceDocumentUri.object(), + sourceParentDocumentUri.object(), + targetParentDocumentUri.object()); } QJniObject renameDocument(const QJniObject &documentUri, const QString &displayName) @@ -549,11 +546,11 @@ QJniObject renameDocument(const QJniObject &documentUri, const QString &displayN if (!(flags & Document::FLAG_SUPPORTS_RENAME)) return {}; - return QJniObject::callStaticMethod( + return QJniObject::callStaticMethod( QtJniTypes::Traits::className(), "renameDocument", - contentResolverInstance().object(), - documentUri.object(), + contentResolverInstance().object(), + documentUri.object(), QJniObject::fromString(displayName).object()); } } // End DocumentsContract namespace @@ -584,7 +581,7 @@ QJniObject parseUri(const QString &uri) if (uriToParse.contains(' ')) uriToParse.replace(' ', QUrl::toPercentEncoding(" ")); - return QJniObject::callStaticMethod( + return QJniObject::callStaticMethod( QtJniTypes::Traits::className(), "parse", QJniObject::fromString(uriToParse).object()); @@ -721,7 +718,7 @@ bool DocumentFile::canRead() const { const auto context = QJniObject(QNativeInterface::QAndroidApplication::context()); const bool selfUriPermission = context.callMethod("checkCallingOrSelfUriPermission", - m_uri.object(), + m_uri.object(), FLAG_GRANT_READ_URI_PERMISSION); if (selfUriPermission != 0) return false; @@ -733,7 +730,7 @@ bool DocumentFile::canWrite() const { const auto context = QJniObject(QNativeInterface::QAndroidApplication::context()); const bool selfUriPermission = context.callMethod("checkCallingOrSelfUriPermission", - m_uri.object(), + m_uri.object(), FLAG_GRANT_WRITE_URI_PERMISSION); if (selfUriPermission != 0) return false; diff --git a/src/plugins/platforms/android/qandroidplatformiconengine.cpp b/src/plugins/platforms/android/qandroidplatformiconengine.cpp index faa63dcca13..a88696886dd 100644 --- a/src/plugins/platforms/android/qandroidplatformiconengine.cpp +++ b/src/plugins/platforms/android/qandroidplatformiconengine.cpp @@ -28,12 +28,9 @@ Q_DECLARE_JNI_CLASS(FontInfo, "androidx/core/provider/FontsContractCompat$FontIn // various utility types Q_DECLARE_JNI_CLASS(List, "java/util/List"); // List is just an Interface -Q_DECLARE_JNI_CLASS(ArrayList, "java/util/ArrayList"); Q_DECLARE_JNI_CLASS(HashSet, "java/util/HashSet"); -Q_DECLARE_JNI_CLASS(Uri, "android/net/Uri") Q_DECLARE_JNI_CLASS(CancellationSignal, "android/os/CancellationSignal") Q_DECLARE_JNI_CLASS(ParcelFileDescriptor, "android/os/ParcelFileDescriptor") -Q_DECLARE_JNI_CLASS(ContentResolver, "android/content/ContentResolver") Q_DECLARE_JNI_CLASS(PackageManager, "android/content/pm/PackageManager") Q_DECLARE_JNI_CLASS(ProviderInfo, "android/content/pm/ProviderInfo") Q_DECLARE_JNI_CLASS(PackageInfo, "android/content/pm/PackageInfo") diff --git a/src/plugins/platforms/android/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp index 39287aa9058..34edc64751b 100644 --- a/src/plugins/platforms/android/qandroidplatformservices.cpp +++ b/src/plugins/platforms/android/qandroidplatformservices.cpp @@ -38,9 +38,6 @@ QAndroidPlatformServices::QAndroidPlatformServices() } } -Q_DECLARE_JNI_CLASS(UriType, "android/net/Uri") -Q_DECLARE_JNI_CLASS(FileType, "java/io/File") -Q_DECLARE_JNI_CLASS(File, "java/io/File") Q_DECLARE_JNI_CLASS(FileProvider, "androidx/core/content/FileProvider"); bool QAndroidPlatformServices::openUrl(const QUrl &theUrl) @@ -84,10 +81,10 @@ bool QAndroidPlatformServices::openUrl(const QUrl &theUrl) const auto urlFile = QJniObject(QtJniTypes::Traits::className(), urlPath.object()); - const auto fileProviderUri = QJniObject::callStaticMethod( + const auto fileProviderUri = QJniObject::callStaticMethod( QtJniTypes::Traits::className(), "getUriForFile", QAndroidApplication::context(), providerName.object(), - urlFile.object()); + urlFile.object()); if (fileProviderUri.isValid()) return openUrl(fileProviderUri.callMethod("toString")); diff --git a/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp b/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp index 38a06bbd311..cb9c7022b1d 100644 --- a/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp +++ b/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp @@ -63,7 +63,6 @@ Q_DECLARE_JNI_CLASS(JavaType, "org/qtproject/qt/JavaType"); static_assert(QtJniTypes::Traits::signature() == "Lorg/qtproject/qt/JavaType;"); static_assert(QtJniTypes::Traits::signature() == "[Lorg/qtproject/qt/JavaType;"); -Q_DECLARE_JNI_CLASS(String, "java/lang/String"); static_assert(QtJniTypes::Traits::className() == "java/lang/String"); static_assert(QtJniTypes::Traits::className() == "java/lang/String"); static_assert(QtJniTypes::Traits::signature() == "Ljava/lang/String;");