JNI: move signature/className template functions into a template class
Template functions don't permit partial specialization, e.g. we cannot specialize typeSignature() to return an array signature for any std::vector or QList type. We need to do that for better array support, so move those functions as static members into a template class, which then can be specialized. Since submodules are both calling and specializing typeSignature and className as template functions, keep and use those until the porting is complete. Change-Id: I74ec957fc41f78046cd9d0f803d8cc9d1e56672b Reviewed-by: Petri Virkkunen <petri.virkkunen@qt.io> Reviewed-by: Zoltan Gera <zoltan.gera@qt.io> Reviewed-by: Tinja Paavoseppä <tinja.paavoseppa@qt.io>
This commit is contained in:
parent
0022b05a9a
commit
e1a349983c
@ -25,7 +25,7 @@ public:
|
||||
JNIEnv *jniEnv() const;
|
||||
jclass findClass(const char *className);
|
||||
template<typename Class>
|
||||
jclass findClass() { return findClass(QtJniTypes::className<Class>().data()); }
|
||||
jclass findClass() { return findClass(QtJniTypes::Traits<Class>::className().data()); }
|
||||
jmethodID findMethod(jclass clazz, const char *methodName, const char *signature);
|
||||
template<typename ...Args>
|
||||
jmethodID findMethod(jclass clazz, const char *methodName) {
|
||||
|
@ -39,31 +39,35 @@ struct Type : Object \
|
||||
#define Q_DECLARE_JNI_TYPE(Type, Signature) \
|
||||
Q_DECLARE_JNI_TYPE_HELPER(Type) \
|
||||
template<> \
|
||||
constexpr auto QtJniTypes::typeSignature<QtJniTypes::Type>() \
|
||||
{ \
|
||||
static_assert((Signature[0] == 'L' || Signature[0] == '[') \
|
||||
&& Signature[sizeof(Signature) - 2] == ';', \
|
||||
"Type signature needs to start with 'L' or '['" \
|
||||
" and end with ';'"); \
|
||||
return QtJniTypes::CTString(Signature); \
|
||||
} \
|
||||
struct QtJniTypes::Traits<QtJniTypes::Type> { \
|
||||
static constexpr auto signature() \
|
||||
{ \
|
||||
static_assert((Signature[0] == 'L' \
|
||||
|| Signature[0] == '[') \
|
||||
&& Signature[sizeof(Signature) - 2] == ';', \
|
||||
"Type signature needs to start with 'L' or" \
|
||||
" '[' and end with ';'"); \
|
||||
return QtJniTypes::CTString(Signature); \
|
||||
} \
|
||||
}; \
|
||||
|
||||
#define Q_DECLARE_JNI_CLASS(Type, Signature) \
|
||||
Q_DECLARE_JNI_TYPE_HELPER(Type) \
|
||||
template<> \
|
||||
constexpr auto QtJniTypes::className<QtJniTypes::Type>() \
|
||||
{ \
|
||||
return QtJniTypes::CTString(Signature); \
|
||||
} \
|
||||
template<> \
|
||||
constexpr auto QtJniTypes::typeSignature<QtJniTypes::Type>() \
|
||||
{ \
|
||||
return QtJniTypes::CTString("L") \
|
||||
+ QtJniTypes::CTString(Signature) \
|
||||
+ QtJniTypes::CTString(";"); \
|
||||
} \
|
||||
struct QtJniTypes::Traits<QtJniTypes::Type> { \
|
||||
static constexpr auto className() \
|
||||
{ \
|
||||
return QtJniTypes::CTString(Signature); \
|
||||
} \
|
||||
static constexpr auto signature() \
|
||||
{ \
|
||||
return QtJniTypes::CTString("L") \
|
||||
+ className() \
|
||||
+ QtJniTypes::CTString(";"); \
|
||||
} \
|
||||
}; \
|
||||
|
||||
#define Q_DECLARE_JNI_NATIVE_METHOD(...) \
|
||||
#define Q_DECLARE_JNI_NATIVE_METHOD(...) \
|
||||
QT_OVERLOADED_MACRO(QT_DECLARE_JNI_NATIVE_METHOD, __VA_ARGS__) \
|
||||
|
||||
#define QT_DECLARE_JNI_NATIVE_METHOD_2(Method, Name) \
|
||||
|
@ -149,97 +149,113 @@ static void staticAssertTypeMismatch()
|
||||
"Use a JNI based type instead.");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr auto typeSignature()
|
||||
{
|
||||
if constexpr (std::is_array_v<T>) {
|
||||
using UnderlyingType = typename std::remove_extent_t<T>;
|
||||
static_assert(!std::is_array_v<UnderlyingType>,
|
||||
"typeSignature() does not handle multi-dimensional arrays");
|
||||
return CTString("[") + typeSignature<UnderlyingType>();
|
||||
} else if constexpr (std::is_same_v<T, jobject>) {
|
||||
return CTString("Ljava/lang/Object;");
|
||||
} else if constexpr (std::is_same_v<T, jclass>) {
|
||||
return CTString("Ljava/lang/Class;");
|
||||
} else if constexpr (std::is_same_v<T, jstring>) {
|
||||
return CTString("Ljava/lang/String;");
|
||||
} else if constexpr (std::is_same_v<T, jobjectArray>) {
|
||||
return CTString("[Ljava/lang/Object;");
|
||||
} else if constexpr (std::is_same_v<T, jthrowable>) {
|
||||
return CTString("Ljava/lang/Throwable;");
|
||||
} else if constexpr (std::is_same_v<T, jbooleanArray>) {
|
||||
return CTString("[Z");
|
||||
} else if constexpr (std::is_same_v<T, jbyteArray>) {
|
||||
return CTString("[B");
|
||||
} else if constexpr (std::is_same_v<T, jshortArray>) {
|
||||
return CTString("[S");
|
||||
} else if constexpr (std::is_same_v<T, jintArray>) {
|
||||
return CTString("[I");
|
||||
} else if constexpr (std::is_same_v<T, jlongArray>) {
|
||||
return CTString("[J");
|
||||
} else if constexpr (std::is_same_v<T, jfloatArray>) {
|
||||
return CTString("[F");
|
||||
} else if constexpr (std::is_same_v<T, jdoubleArray>) {
|
||||
return CTString("[D");
|
||||
} else if constexpr (std::is_same_v<T, jcharArray>) {
|
||||
return CTString("[C");
|
||||
} else if constexpr (std::is_same_v<T, jboolean>) {
|
||||
return CTString("Z");
|
||||
} else if constexpr (std::is_same_v<T, bool>) {
|
||||
return CTString("Z");
|
||||
} else if constexpr (std::is_same_v<T, jbyte>) {
|
||||
return CTString("B");
|
||||
} else if constexpr (std::is_same_v<T, jchar>) {
|
||||
return CTString("C");
|
||||
} else if constexpr (std::is_same_v<T, char>) {
|
||||
return CTString("C");
|
||||
} else if constexpr (std::is_same_v<T, jshort>) {
|
||||
return CTString("S");
|
||||
} else if constexpr (std::is_same_v<T, short>) {
|
||||
return CTString("S");
|
||||
} else if constexpr (std::is_same_v<T, jint>) {
|
||||
return CTString("I");
|
||||
} else if constexpr (std::is_same_v<T, int>) {
|
||||
return CTString("I");
|
||||
} else if constexpr (std::is_same_v<T, uint>) {
|
||||
return CTString("I");
|
||||
} else if constexpr (std::is_same_v<T, jlong>) {
|
||||
return CTString("J");
|
||||
} else if constexpr (std::is_same_v<T, long>) {
|
||||
return CTString("J");
|
||||
} else if constexpr (std::is_same_v<T, jfloat>) {
|
||||
return CTString("F");
|
||||
} else if constexpr (std::is_same_v<T, float>) {
|
||||
return CTString("F");
|
||||
} else if constexpr (std::is_same_v<T, jdouble>) {
|
||||
return CTString("D");
|
||||
} else if constexpr (std::is_same_v<T, double>) {
|
||||
return CTString("D");
|
||||
} else if constexpr (std::is_same_v<T, void>) {
|
||||
return CTString("V");
|
||||
}
|
||||
|
||||
// else: The return type becomes void, indicating that the typeSignature
|
||||
// template is not implemented for the respective type. We use this to
|
||||
// detect invalid types in the ValidSignatureTypes and ValidFieldType
|
||||
// predicates below.
|
||||
}
|
||||
|
||||
template<bool flag = false>
|
||||
static void staticAssertClassNotRegistered()
|
||||
{
|
||||
static_assert(flag, "Class not registered, use Q_DECLARE_JNI_CLASS");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr auto className()
|
||||
template <typename T>
|
||||
struct Traits {
|
||||
// The return type of className/signature becomes void for any type
|
||||
// not handled here. This indicates that the Traits type is not specialized
|
||||
// for the respective type, which we use to detect invalid types in the
|
||||
// ValidSignatureTypes and ValidFieldType predicates below.
|
||||
|
||||
static constexpr auto className()
|
||||
{
|
||||
if constexpr (std::is_same_v<T, jstring>)
|
||||
return CTString("java/lang/String");
|
||||
else if constexpr (std::is_same_v<T, jobject>)
|
||||
return CTString("java/lang/Object");
|
||||
else if constexpr (std::is_same_v<T, jclass>)
|
||||
return CTString("java/lang/Class");
|
||||
else if constexpr (std::is_same_v<T, jthrowable>)
|
||||
return CTString("java/lang/Throwable");
|
||||
// else: return void -> not implemented
|
||||
}
|
||||
|
||||
static constexpr auto signature()
|
||||
{
|
||||
if constexpr (!std::is_same_v<decltype(className()), void>) {
|
||||
// the type signature of any object class is L<className>;
|
||||
return CTString("L") + className() + CTString(";");
|
||||
} else if constexpr (std::is_array_v<T>) {
|
||||
using UnderlyingType = typename std::remove_extent_t<T>;
|
||||
static_assert(!std::is_array_v<UnderlyingType>,
|
||||
"Traits::signature() does not handle multi-dimensional arrays");
|
||||
return CTString("[") + Traits<UnderlyingType>::signature();
|
||||
} else if constexpr (std::is_same_v<T, jobjectArray>) {
|
||||
return CTString("[Ljava/lang/Object;");
|
||||
} else if constexpr (std::is_same_v<T, jbooleanArray>) {
|
||||
return CTString("[Z");
|
||||
} else if constexpr (std::is_same_v<T, jbyteArray>) {
|
||||
return CTString("[B");
|
||||
} else if constexpr (std::is_same_v<T, jshortArray>) {
|
||||
return CTString("[S");
|
||||
} else if constexpr (std::is_same_v<T, jintArray>) {
|
||||
return CTString("[I");
|
||||
} else if constexpr (std::is_same_v<T, jlongArray>) {
|
||||
return CTString("[J");
|
||||
} else if constexpr (std::is_same_v<T, jfloatArray>) {
|
||||
return CTString("[F");
|
||||
} else if constexpr (std::is_same_v<T, jdoubleArray>) {
|
||||
return CTString("[D");
|
||||
} else if constexpr (std::is_same_v<T, jcharArray>) {
|
||||
return CTString("[C");
|
||||
} else if constexpr (std::is_same_v<T, jboolean>) {
|
||||
return CTString("Z");
|
||||
} else if constexpr (std::is_same_v<T, bool>) {
|
||||
return CTString("Z");
|
||||
} else if constexpr (std::is_same_v<T, jbyte>) {
|
||||
return CTString("B");
|
||||
} else if constexpr (std::is_same_v<T, jchar>) {
|
||||
return CTString("C");
|
||||
} else if constexpr (std::is_same_v<T, char>) {
|
||||
return CTString("C");
|
||||
} else if constexpr (std::is_same_v<T, jshort>) {
|
||||
return CTString("S");
|
||||
} else if constexpr (std::is_same_v<T, short>) {
|
||||
return CTString("S");
|
||||
} else if constexpr (std::is_same_v<T, jint>) {
|
||||
return CTString("I");
|
||||
} else if constexpr (std::is_same_v<T, int>) {
|
||||
return CTString("I");
|
||||
} else if constexpr (std::is_same_v<T, uint>) {
|
||||
return CTString("I");
|
||||
} else if constexpr (std::is_same_v<T, jlong>) {
|
||||
return CTString("J");
|
||||
} else if constexpr (std::is_same_v<T, long>) {
|
||||
return CTString("J");
|
||||
} else if constexpr (std::is_same_v<T, jfloat>) {
|
||||
return CTString("F");
|
||||
} else if constexpr (std::is_same_v<T, float>) {
|
||||
return CTString("F");
|
||||
} else if constexpr (std::is_same_v<T, jdouble>) {
|
||||
return CTString("D");
|
||||
} else if constexpr (std::is_same_v<T, double>) {
|
||||
return CTString("D");
|
||||
} else if constexpr (std::is_same_v<T, void>) {
|
||||
return CTString("V");
|
||||
}
|
||||
// else: return void -> not implemented
|
||||
}
|
||||
};
|
||||
|
||||
// compatibility until submodules are ported
|
||||
template <typename T>
|
||||
constexpr auto typeSignature()
|
||||
{
|
||||
if constexpr (std::is_same_v<T, jstring>)
|
||||
return CTString("java/lang/String");
|
||||
else
|
||||
staticAssertClassNotRegistered();
|
||||
return Traits<T>::signature();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr auto className()
|
||||
{
|
||||
return Traits<T>::className();
|
||||
}
|
||||
|
||||
// have to use the compatibility functions here until porting is complete
|
||||
template<typename T>
|
||||
static constexpr bool isPrimitiveType()
|
||||
{
|
||||
|
@ -31,7 +31,7 @@ QAndroidTimeZonePrivate::QAndroidTimeZonePrivate()
|
||||
{
|
||||
// Keep in sync with systemTimeZoneId():
|
||||
androidTimeZone = QJniObject::callStaticMethod<QtJniTypes::TimeZone>(
|
||||
QtJniTypes::className<QtJniTypes::TimeZone>(), "getDefault");
|
||||
QtJniTypes::Traits<QtJniTypes::TimeZone>::className(), "getDefault");
|
||||
const QJniObject id = androidTimeZone.callMethod<jstring>("getID");
|
||||
m_id = id.toString().toUtf8();
|
||||
}
|
||||
@ -59,7 +59,7 @@ static QString getDisplayName(QJniObject zone, jint style, jboolean dst,
|
||||
{
|
||||
QJniObject jbcpTag = QJniObject::fromString(locale.bcp47Name());
|
||||
QJniObject jlocale = QJniObject::callStaticMethod<QtJniTypes::Locale>(
|
||||
QtJniTypes::className<QtJniTypes::Locale>(), "forLanguageTag",
|
||||
QtJniTypes::Traits<QtJniTypes::Locale>::className(), "forLanguageTag",
|
||||
jbcpTag.object<jstring>());
|
||||
|
||||
return zone.callMethod<jstring>("getDisplayName", dst, style,
|
||||
@ -70,7 +70,7 @@ void QAndroidTimeZonePrivate::init(const QByteArray &ianaId)
|
||||
{
|
||||
const QString iana = QString::fromUtf8(ianaId);
|
||||
androidTimeZone = QJniObject::callStaticMethod<QtJniTypes::TimeZone>(
|
||||
QtJniTypes::className<QtJniTypes::TimeZone>(), "getTimeZone",
|
||||
QtJniTypes::Traits<QtJniTypes::TimeZone>::className(), "getTimeZone",
|
||||
QJniObject::fromString(iana).object<jstring>());
|
||||
|
||||
// The ID or display name of the zone we've got, if it looks like what we asked for:
|
||||
@ -200,7 +200,7 @@ QByteArray QAndroidTimeZonePrivate::systemTimeZoneId() const
|
||||
{
|
||||
// Keep in sync with default constructor:
|
||||
QJniObject androidSystemTimeZone = QJniObject::callStaticMethod<QtJniTypes::TimeZone>(
|
||||
QtJniTypes::className<QtJniTypes::TimeZone>(), "getDefault");
|
||||
QtJniTypes::Traits<QtJniTypes::TimeZone>::className(), "getDefault");
|
||||
const QJniObject id = androidSystemTimeZone.callMethod<jstring>("getID");
|
||||
return id.toString().toUtf8();
|
||||
}
|
||||
@ -209,7 +209,7 @@ QList<QByteArray> QAndroidTimeZonePrivate::availableTimeZoneIds() const
|
||||
{
|
||||
QList<QByteArray> availableTimeZoneIdList;
|
||||
QJniObject androidAvailableIdList = QJniObject::callStaticMethod<QtJniTypes::StringArray>(
|
||||
QtJniTypes::className<QtJniTypes::TimeZone>(), "getAvailableIDs");
|
||||
QtJniTypes::Traits<QtJniTypes::TimeZone>::className(), "getAvailableIDs");
|
||||
|
||||
QJniEnvironment jniEnv;
|
||||
int androidTZcount = jniEnv->GetArrayLength(androidAvailableIdList.object<jarray>());
|
||||
|
@ -465,7 +465,7 @@ const QLatin1String MIME_TYPE_DIR("vnd.android.document/directory");
|
||||
QString documentId(const QJniObject &uri)
|
||||
{
|
||||
return QJniObject::callStaticMethod<jstring, QtJniTypes::UriType>(
|
||||
QtJniTypes::className<QtJniTypes::DocumentsContract>(),
|
||||
QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
|
||||
"getDocumentId",
|
||||
uri.object()).toString();
|
||||
}
|
||||
@ -473,7 +473,7 @@ QString documentId(const QJniObject &uri)
|
||||
QString treeDocumentId(const QJniObject &uri)
|
||||
{
|
||||
return QJniObject::callStaticMethod<jstring, QtJniTypes::UriType>(
|
||||
QtJniTypes::className<QtJniTypes::DocumentsContract>(),
|
||||
QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
|
||||
"getTreeDocumentId",
|
||||
uri.object()).toString();
|
||||
}
|
||||
@ -481,7 +481,7 @@ QString treeDocumentId(const QJniObject &uri)
|
||||
QJniObject buildChildDocumentsUriUsingTree(const QJniObject &uri, const QString &parentDocumentId)
|
||||
{
|
||||
return QJniObject::callStaticMethod<QtJniTypes::UriType>(
|
||||
QtJniTypes::className<QtJniTypes::DocumentsContract>(),
|
||||
QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
|
||||
"buildChildDocumentsUriUsingTree",
|
||||
uri.object<QtJniTypes::UriType>(),
|
||||
QJniObject::fromString(parentDocumentId).object<jstring>());
|
||||
@ -491,7 +491,7 @@ QJniObject buildChildDocumentsUriUsingTree(const QJniObject &uri, const QString
|
||||
QJniObject buildDocumentUriUsingTree(const QJniObject &treeUri, const QString &documentId)
|
||||
{
|
||||
return QJniObject::callStaticMethod<QtJniTypes::UriType>(
|
||||
QtJniTypes::className<QtJniTypes::DocumentsContract>(),
|
||||
QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
|
||||
"buildDocumentUriUsingTree",
|
||||
treeUri.object<QtJniTypes::UriType>(),
|
||||
QJniObject::fromString(documentId).object<jstring>());
|
||||
@ -500,7 +500,7 @@ QJniObject buildDocumentUriUsingTree(const QJniObject &treeUri, const QString &d
|
||||
bool isDocumentUri(const QJniObject &uri)
|
||||
{
|
||||
return QJniObject::callStaticMethod<jboolean>(
|
||||
QtJniTypes::className<QtJniTypes::DocumentsContract>(),
|
||||
QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
|
||||
"isDocumentUri",
|
||||
QNativeInterface::QAndroidApplication::context(),
|
||||
uri.object<QtJniTypes::UriType>());
|
||||
@ -509,7 +509,7 @@ bool isDocumentUri(const QJniObject &uri)
|
||||
bool isTreeUri(const QJniObject &uri)
|
||||
{
|
||||
return QJniObject::callStaticMethod<jboolean>(
|
||||
QtJniTypes::className<QtJniTypes::DocumentsContract>(),
|
||||
QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
|
||||
"isTreeUri",
|
||||
uri.object<QtJniTypes::UriType>());
|
||||
}
|
||||
@ -518,7 +518,7 @@ QJniObject createDocument(const QJniObject &parentDocumentUri, const QString &mi
|
||||
const QString &displayName)
|
||||
{
|
||||
return QJniObject::callStaticMethod<QtJniTypes::UriType>(
|
||||
QtJniTypes::className<QtJniTypes::DocumentsContract>(),
|
||||
QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
|
||||
"createDocument",
|
||||
contentResolverInstance().object<QtJniTypes::ContentResolverType>(),
|
||||
parentDocumentUri.object<QtJniTypes::UriType>(),
|
||||
@ -533,7 +533,7 @@ bool deleteDocument(const QJniObject &documentUri)
|
||||
return {};
|
||||
|
||||
return QJniObject::callStaticMethod<jboolean>(
|
||||
QtJniTypes::className<QtJniTypes::DocumentsContract>(),
|
||||
QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
|
||||
"deleteDocument",
|
||||
contentResolverInstance().object<QtJniTypes::ContentResolverType>(),
|
||||
documentUri.object<QtJniTypes::UriType>());
|
||||
@ -548,7 +548,7 @@ QJniObject moveDocument(const QJniObject &sourceDocumentUri,
|
||||
return {};
|
||||
|
||||
return QJniObject::callStaticMethod<QtJniTypes::UriType>(
|
||||
QtJniTypes::className<QtJniTypes::DocumentsContract>(),
|
||||
QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
|
||||
"moveDocument",
|
||||
contentResolverInstance().object<QtJniTypes::ContentResolverType>(),
|
||||
sourceDocumentUri.object<QtJniTypes::UriType>(),
|
||||
@ -563,7 +563,7 @@ QJniObject renameDocument(const QJniObject &documentUri, const QString &displayN
|
||||
return {};
|
||||
|
||||
return QJniObject::callStaticMethod<QtJniTypes::UriType>(
|
||||
QtJniTypes::className<QtJniTypes::DocumentsContract>(),
|
||||
QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
|
||||
"renameDocument",
|
||||
contentResolverInstance().object<QtJniTypes::ContentResolverType>(),
|
||||
documentUri.object<QtJniTypes::UriType>(),
|
||||
@ -598,7 +598,7 @@ QJniObject parseUri(const QString &uri)
|
||||
uriToParse.replace(' ', QUrl::toPercentEncoding(" "));
|
||||
|
||||
return QJniObject::callStaticMethod<QtJniTypes::UriType>(
|
||||
QtJniTypes::className<QtJniTypes::Uri>(),
|
||||
QtJniTypes::Traits<QtJniTypes::Uri>::className(),
|
||||
"parse",
|
||||
QJniObject::fromString(uriToParse).object<jstring>());
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ namespace {
|
||||
QAndroidPlatformScreen* createScreenForDisplayId(int displayId)
|
||||
{
|
||||
const QJniObject display = QJniObject::callStaticObjectMethod<QtJniTypes::Display>(
|
||||
QtJniTypes::className<QtJniTypes::QtNative>(),
|
||||
QtJniTypes::Traits<QtJniTypes::QtNative>::className(),
|
||||
"getDisplay",
|
||||
displayId);
|
||||
if (!display.isValid())
|
||||
@ -184,10 +184,10 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList ¶
|
||||
qFatal("Could not bind GL_ES API");
|
||||
|
||||
m_primaryDisplayId = QJniObject::getStaticField<jint>(
|
||||
QtJniTypes::className<QtJniTypes::Display>(), "DEFAULT_DISPLAY");
|
||||
QtJniTypes::Traits<QtJniTypes::Display>::className(), "DEFAULT_DISPLAY");
|
||||
|
||||
const QJniObject nativeDisplaysList = QJniObject::callStaticObjectMethod<QtJniTypes::List>(
|
||||
QtJniTypes::className<QtJniTypes::QtNative>(),
|
||||
QtJniTypes::Traits<QtJniTypes::QtNative>::className(),
|
||||
"getAvailableDisplays");
|
||||
|
||||
const int numberOfAvailableDisplays = nativeDisplaysList.callMethod<jint>("size");
|
||||
|
@ -92,7 +92,7 @@ QAndroidPlatformScreen::QAndroidPlatformScreen(const QJniObject &displayObject)
|
||||
displayObject.object<QtJniTypes::Display>());
|
||||
|
||||
const auto sizeObj = QJniObject::callStaticMethod<QtJniTypes::Size>(
|
||||
QtJniTypes::className<QtJniTypes::QtNative>(),
|
||||
QtJniTypes::Traits<QtJniTypes::QtNative>::className(),
|
||||
"getDisplaySize",
|
||||
displayContext.object<QtJniTypes::Context>(),
|
||||
displayObject.object<QtJniTypes::Display>());
|
||||
|
@ -78,11 +78,11 @@ bool QAndroidPlatformServices::openUrl(const QUrl &theUrl)
|
||||
const auto providerName = QJniObject::fromString(appId + ".qtprovider"_L1);
|
||||
|
||||
const auto urlPath = QJniObject::fromString(url.path());
|
||||
const auto urlFile = QJniObject(QtJniTypes::className<QtJniTypes::File>(),
|
||||
const auto urlFile = QJniObject(QtJniTypes::Traits<QtJniTypes::File>::className(),
|
||||
urlPath.object<jstring>());
|
||||
|
||||
const auto fileProviderUri = QJniObject::callStaticMethod<QtJniTypes::UriType>(
|
||||
QtJniTypes::className<QtJniTypes::FileProvider>(), "getUriForFile",
|
||||
QtJniTypes::Traits<QtJniTypes::FileProvider>::className(), "getUriForFile",
|
||||
QAndroidApplication::context(), providerName.object<jstring>(),
|
||||
urlFile.object<QtJniTypes::FileType>());
|
||||
|
||||
|
@ -19,35 +19,45 @@ private slots:
|
||||
|
||||
struct QtJavaWrapper {};
|
||||
template<>
|
||||
constexpr auto QtJniTypes::typeSignature<QtJavaWrapper>()
|
||||
struct QtJniTypes::Traits<QtJavaWrapper>
|
||||
{
|
||||
return QtJniTypes::CTString("Lorg/qtproject/qt/android/QtJavaWrapper;");
|
||||
}
|
||||
static constexpr auto signature()
|
||||
{
|
||||
return QtJniTypes::CTString("Lorg/qtproject/qt/android/QtJavaWrapper;");
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
constexpr auto QtJniTypes::typeSignature<QJniObject>()
|
||||
struct QtJniTypes::Traits<QJniObject>
|
||||
{
|
||||
return QtJniTypes::CTString("Ljava/lang/Object;");
|
||||
}
|
||||
static constexpr auto signature()
|
||||
{
|
||||
return QtJniTypes::CTString("Ljava/lang/Object;");
|
||||
}
|
||||
};
|
||||
|
||||
struct QtCustomJniObject : QJniObject {};
|
||||
template<>
|
||||
constexpr auto QtJniTypes::typeSignature<QtCustomJniObject>()
|
||||
{
|
||||
return QtJniTypes::CTString("Lorg/qtproject/qt/android/QtCustomJniObject;");
|
||||
}
|
||||
|
||||
static_assert(QtJniTypes::typeSignature<QtJavaWrapper>() == "Lorg/qtproject/qt/android/QtJavaWrapper;");
|
||||
static_assert(QtJniTypes::typeSignature<QtJavaWrapper>() != "Ljava/lang/Object;");
|
||||
static_assert(!(QtJniTypes::typeSignature<QtJavaWrapper>() == "X"));
|
||||
template<>
|
||||
struct QtJniTypes::Traits<QtCustomJniObject>
|
||||
{
|
||||
static constexpr auto signature()
|
||||
{
|
||||
return QtJniTypes::CTString("Lorg/qtproject/qt/android/QtCustomJniObject;");
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(QtJniTypes::Traits<QtJavaWrapper>::signature() == "Lorg/qtproject/qt/android/QtJavaWrapper;");
|
||||
static_assert(QtJniTypes::Traits<QtJavaWrapper>::signature() != "Ljava/lang/Object;");
|
||||
static_assert(!(QtJniTypes::Traits<QtJavaWrapper>::signature() == "X"));
|
||||
|
||||
Q_DECLARE_JNI_CLASS(JavaType, "org/qtproject/qt/JavaType");
|
||||
static_assert(QtJniTypes::typeSignature<QtJniTypes::JavaType>() == "Lorg/qtproject/qt/JavaType;");
|
||||
static_assert(QtJniTypes::Traits<QtJniTypes::JavaType>::signature() == "Lorg/qtproject/qt/JavaType;");
|
||||
Q_DECLARE_JNI_TYPE(ArrayType, "[Lorg/qtproject/qt/ArrayType;")
|
||||
static_assert(QtJniTypes::typeSignature<QtJniTypes::ArrayType>() == "[Lorg/qtproject/qt/ArrayType;");
|
||||
static_assert(QtJniTypes::Traits<QtJniTypes::ArrayType>::signature() == "[Lorg/qtproject/qt/ArrayType;");
|
||||
|
||||
Q_DECLARE_JNI_CLASS(QtTextToSpeech, "org/qtproject/qt/android/speech/QtTextToSpeech")
|
||||
static_assert(QtJniTypes::className<QtJniTypes::QtTextToSpeech>() == "org/qtproject/qt/android/speech/QtTextToSpeech");
|
||||
static_assert(QtJniTypes::Traits<QtJniTypes::QtTextToSpeech>::className() == "org/qtproject/qt/android/speech/QtTextToSpeech");
|
||||
|
||||
static_assert(QtJniTypes::fieldSignature<jint>() == "I");
|
||||
static_assert(QtJniTypes::fieldSignature<jint[]>() == "[I");
|
||||
|
Loading…
x
Reference in New Issue
Block a user