diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e869318b6..235c81668 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -194,8 +194,6 @@ add_library(neochat STATIC neochatroommember.h models/threadmodel.cpp models/threadmodel.h - permissionmanager.cpp - permissionmanager.h ) set_source_files_properties(qml/OsmLocationPlugin.qml PROPERTIES @@ -306,10 +304,6 @@ add_subdirectory(devtools) add_subdirectory(login) add_subdirectory(chatbar) -if (ANDROID) - add_subdirectory(kandroidextras) -endif() - if(NOT ANDROID AND NOT WIN32) qt_target_qml_sources(neochat QML_FILES qml/ShareAction.qml @@ -442,7 +436,7 @@ endif() if(ANDROID) target_sources(neochat PRIVATE notifyrc.qrc) - target_link_libraries(neochat PUBLIC KAndroidExtras PRIVATE Qt::Svg OpenSSL::SSL) + target_link_libraries(neochat PRIVATE Qt::Svg OpenSSL::SSL) if(SQLite3_FOUND) target_link_libraries(neochat-app PRIVATE SQLite::SQLite3) endif() diff --git a/src/kandroidextras/CMakeLists.txt b/src/kandroidextras/CMakeLists.txt deleted file mode 100644 index ebdd08df4..000000000 --- a/src/kandroidextras/CMakeLists.txt +++ /dev/null @@ -1,78 +0,0 @@ -# SPDX-FileCopyrightText: 2019 Volker Krause -# SPDX-License-Identifier: BSD-3-Clause - -add_library(KAndroidExtras STATIC) - -target_sources(KAndroidExtras PRIVATE - android/activity.cpp - android/android_headers.cpp - android/contentresolver.cpp - android/context.cpp - android/intent.cpp - android/uri.cpp - - java/java_headers.cpp - java/javalocale.cpp - - jni/jni_headers.cpp -) - -if (NOT ANDROID) - target_sources(KAndroidExtras PRIVATE - fake/mock_impl.cpp - fake/mock_jniobject.cpp - ) -endif() - -generate_export_header(KAndroidExtras BASE_NAME KAndroidExtras) -target_compile_features(KAndroidExtras PUBLIC cxx_std_20) # for __VA_OPT__ -target_link_libraries(KAndroidExtras PUBLIC Qt::Core) - -if (ANDROID) - target_link_libraries(KAndroidExtras PRIVATE Qt::CorePrivate) -else() - target_include_directories(KAndroidExtras PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/fake ${CMAKE_CURRENT_SOURCE_DIR}/fake/qt6) -endif() - -ecm_generate_headers(KAndroidExtras_android_FORWARDING_HEADERS - HEADER_NAMES - Activity - AndroidTypes - CalendarContract - ContentResolver - Context - Intent - ManifestPermission - OpenableColumns - Settings - Uri - PREFIX KAndroidExtras - REQUIRED_HEADERS KAndroidExtras_android_HEADERS - RELATIVE android -) - -ecm_generate_headers(KAndroidExtras_java_FORWARDING_HEADERS - HEADER_NAMES - JavaLocale - JavaTypes - PREFIX KAndroidExtras - REQUIRED_HEADERS KAndroidExtras_java_HEADERS - RELATIVE java -) - -ecm_generate_headers(KAndroidExtras_jni_FORWARDING_HEADERS - HEADER_NAMES - JniArgument - JniArray - JniObject - JniMethod - JniReturnValue - JniPp - JniProperty - JniSignature - JniTypes - JniTypeTraits - PREFIX KAndroidExtras - REQUIRED_HEADERS KAndroidExtras_jni_HEADERS - RELATIVE jni -) diff --git a/src/kandroidextras/README.md b/src/kandroidextras/README.md deleted file mode 100644 index 2f9c3ebbe..000000000 --- a/src/kandroidextras/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# KAndroidExtras - -Utilities for using Java Native Interface (JNI) to interface with Android platform API. - -## Java Native Interface (JNI) wrapper - -C++ header-only code for defining compile-time checked JNI wrappers. - -Supported: -- typed `jobject` wrappers (`Jni::Object`) -- wrappers for Java arrays holding primitive or non-primitive content (`Jni::Array`) -- reading static final properties (`JNI_CONSTANT`) -- reading and writing non-static properties (`JNI_PROPERTY`) -- static and non-static method calls, constructors (`JNI_METHOD`, `JNI_STATIC_METHOD`, `JNI_CONSTRUCTOR`) - -Not yet supported: -- registering native methods for Java -> C++ calls - -## JNI mock implementation - -This is useful for automated testing of JNI code on other platforms than Android. - -## Wrappers for Java and Android types - -Predefined wrappers for common platform types needed in multiple places. diff --git a/src/kandroidextras/README.md.license b/src/kandroidextras/README.md.license deleted file mode 100644 index 323fa40d6..000000000 --- a/src/kandroidextras/README.md.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: 2022 Volker Krause -SPDX-License-Identifier: CC0-1.0 diff --git a/src/kandroidextras/android/activity.cpp b/src/kandroidextras/android/activity.cpp deleted file mode 100644 index 90c8bdd88..000000000 --- a/src/kandroidextras/android/activity.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#include "activity.h" - -#include -#include -#include - -#include "private/qandroidextras_p.h" -#include -#include - -using namespace KAndroidExtras; - -Intent Activity::getIntent() -{ - const QJniObject activity = QNativeInterface::QAndroidApplication::context(); - if (!activity.isValid()) - return {}; - - const auto intent = activity.callObjectMethod("getIntent", Jni::signature()); - return Intent(Jni::fromHandle(intent)); -} - -bool Activity::startActivity(const Intent &intent, int receiverRequestCode) -{ - QJniEnvironment jniEnv; - QtAndroidPrivate::startActivity(intent, receiverRequestCode); - if (jniEnv->ExceptionCheck()) { - jniEnv->ExceptionClear(); - return false; - } - return true; -} diff --git a/src/kandroidextras/android/activity.h b/src/kandroidextras/android/activity.h deleted file mode 100644 index 3cfbbccff..000000000 --- a/src/kandroidextras/android/activity.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_ACTIVITY_H -#define KANDROIDEXTRAS_ACTIVITY_H - -#include "kandroidextras_export.h" - -namespace KAndroidExtras -{ - -class Intent; - -/** Methods around android.app.Activity. */ -namespace Activity -{ -/** Returns the Intent that started the activity. */ -KANDROIDEXTRAS_EXPORT Intent getIntent(); - -/** Same as QtAndroid::startActivity(), but with exception handling. */ -KANDROIDEXTRAS_EXPORT bool startActivity(const Intent &intent, int receiverRequestCode); // TODO add callback arg -} - -} - -#endif // KANDROIDEXTRAS_ACTIVITY_H diff --git a/src/kandroidextras/android/android_headers.cpp b/src/kandroidextras/android/android_headers.cpp deleted file mode 100644 index e4ae0368c..000000000 --- a/src/kandroidextras/android/android_headers.cpp +++ /dev/null @@ -1,13 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -// list all headers here that have no .cpp file -// this only serves as a guarantee that these headers actually compile -#include "androidtypes.h" -#include "calendarcontract.h" -#include "manifestpermission.h" -#include "openablecolumns.h" -#include "settings.h" diff --git a/src/kandroidextras/android/androidtypes.h b/src/kandroidextras/android/androidtypes.h deleted file mode 100644 index 7be54986e..000000000 --- a/src/kandroidextras/android/androidtypes.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_ANDROIDTYPES_H -#define KANDROIDEXTRAS_ANDROIDTYPES_H - -#include - -namespace KAndroidExtras -{ - -JNI_TYPE(android, content, ContentResolver) -JNI_TYPE(android, content, Context) -JNI_TYPE(android, content, Intent) -JNI_TYPE(android, database, Cursor) -JNI_NESTED_TYPE(android, Manifest, permission) -JNI_TYPE(android, net, Uri) -JNI_NESTED_TYPE(android, provider, CalendarContract, AttendeesColumns) -JNI_NESTED_TYPE(android, provider, CalendarContract, CalendarColumns) -JNI_NESTED_TYPE(android, provider, CalendarContract, EventsColumns) -JNI_NESTED_TYPE(android, provider, CalendarContract, RemindersColumns) -JNI_TYPE(android, provider, OpenableColumns) -JNI_TYPE(android, provider, Settings) - -} - -#endif // KANDROIDEXTRAS_ANDROIDTYPES_H diff --git a/src/kandroidextras/android/calendarcontract.h b/src/kandroidextras/android/calendarcontract.h deleted file mode 100644 index 54298fbaf..000000000 --- a/src/kandroidextras/android/calendarcontract.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - SPDX-FileCopyrightText: 2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_CALENDARCONTRACT_H -#define KANDROIDEXTRAS_CALENDARCONTRACT_H - -#include -#include -#include -#include - -namespace KAndroidExtras -{ - -/** CalendarContracts.EventColumns wrapper. */ -class CalendarColumns -{ - JNI_UNMANAGED_OBJECT(CalendarColumns, android::provider::CalendarContract_CalendarColumns) - - JNI_CONSTANT(jint, CAL_ACCESS_CONTRIBUTOR) - JNI_CONSTANT(jint, CAL_ACCESS_EDITOR) - JNI_CONSTANT(jint, CAL_ACCESS_FREEBUSY) - JNI_CONSTANT(jint, CAL_ACCESS_NONE) - JNI_CONSTANT(jint, CAL_ACCESS_OVERRIDE) - JNI_CONSTANT(jint, CAL_ACCESS_OWNER) - JNI_CONSTANT(jint, CAL_ACCESS_READ) - JNI_CONSTANT(jint, CAL_ACCESS_RESPOND) - JNI_CONSTANT(jint, CAL_ACCESS_ROOT) -}; - -/** CalendarContracts.EventColumns wrapper. */ -class EventsColumns -{ - JNI_UNMANAGED_OBJECT(EventsColumns, android::provider::CalendarContract_EventsColumns) - - JNI_CONSTANT(jint, ACCESS_CONFIDENTIAL) - JNI_CONSTANT(jint, ACCESS_DEFAULT) - JNI_CONSTANT(jint, ACCESS_PRIVATE) - JNI_CONSTANT(jint, ACCESS_PUBLIC) - - JNI_CONSTANT(jint, AVAILABILITY_BUSY) - JNI_CONSTANT(jint, AVAILABILITY_FREE) - JNI_CONSTANT(jint, AVAILABILITY_TENTATIVE) -}; - -/** CalendarContracts.AttendeesColumns wrapper. */ -class AttendeesColumns -{ - JNI_UNMANAGED_OBJECT(AttendeesColumns, android::provider::CalendarContract_AttendeesColumns) - - JNI_CONSTANT(jint, ATTENDEE_STATUS_ACCEPTED) - JNI_CONSTANT(jint, ATTENDEE_STATUS_DECLINED) - JNI_CONSTANT(jint, ATTENDEE_STATUS_INVITED) - JNI_CONSTANT(jint, ATTENDEE_STATUS_NONE) - JNI_CONSTANT(jint, ATTENDEE_STATUS_TENTATIVE) - - JNI_CONSTANT(jint, RELATIONSHIP_ATTENDEE) - JNI_CONSTANT(jint, RELATIONSHIP_NONE) - JNI_CONSTANT(jint, RELATIONSHIP_ORGANIZER) - JNI_CONSTANT(jint, RELATIONSHIP_PERFORMER) - JNI_CONSTANT(jint, RELATIONSHIP_SPEAKER) - - JNI_CONSTANT(jint, TYPE_NONE) - JNI_CONSTANT(jint, TYPE_OPTIONAL) - JNI_CONSTANT(jint, TYPE_REQUIRED) - JNI_CONSTANT(jint, TYPE_RESOURCE) -}; - -/** CalendarContract.RemindersColumns wrapper. */ -class RemindersColumns -{ - JNI_UNMANAGED_OBJECT(RemindersColumns, android::provider::CalendarContract_RemindersColumns) - - JNI_CONSTANT(jint, METHOD_ALARM) - JNI_CONSTANT(jint, METHOD_ALERT) - JNI_CONSTANT(jint, METHOD_DEFAULT) - JNI_CONSTANT(jint, METHOD_EMAIL) - JNI_CONSTANT(jint, METHOD_SMS) -}; - -} - -#endif // KANDROIDEXTRAS_OPENABLECOLUMNS_H diff --git a/src/kandroidextras/android/contentresolver.cpp b/src/kandroidextras/android/contentresolver.cpp deleted file mode 100644 index fc5569a82..000000000 --- a/src/kandroidextras/android/contentresolver.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#include "contentresolver.h" -#include "openablecolumns.h" -#include "uri.h" - -#include -#include - -#include -#include -#include - -using namespace KAndroidExtras; - -QJniObject ContentResolver::get() -{ - const QJniObject context = QNativeInterface::QAndroidApplication::context(); - return context.callObjectMethod("getContentResolver", Jni::signature()); -} - -QString ContentResolver::mimeType(const QUrl &url) -{ - auto cs = ContentResolver::get(); - const auto uri = Uri::fromUrl(url); - auto mt = cs.callObjectMethod("getType", Jni::signature(), uri.object()); - return mt.toString(); -} - -QString ContentResolver::fileName(const QUrl &url) -{ - auto cs = ContentResolver::get(); - const auto uri = Uri::fromUrl(url); - - // query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) - auto cursor = cs.callObjectMethod( - "query", - Jni::signature(), - uri.object(), - 0, - 0, - 0, - 0); - - const QJniObject DISPLAY_NAME = OpenableColumns::DISPLAY_NAME; - const auto nameIndex = cursor.callMethod("getColumnIndex", (const char *)Jni::signature(), DISPLAY_NAME.object()); - cursor.callMethod("moveToFirst", (const char *)Jni::signature()); - return cursor.callObjectMethod("getString", Jni::signature(), nameIndex).toString(); -} diff --git a/src/kandroidextras/android/contentresolver.h b/src/kandroidextras/android/contentresolver.h deleted file mode 100644 index c54bdceb0..000000000 --- a/src/kandroidextras/android/contentresolver.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_CONTENTRESOLVER_H -#define KANDROIDEXTRAS_CONTENTRESOLVER_H - -#include "kandroidextras_export.h" - -#include -class QJniObject; -class QString; -class QUrl; - -namespace KAndroidExtras -{ - -/** Methods for working with Android's ContentResolver. */ -namespace ContentResolver -{ -/** Get the JNI content resolver. */ -KANDROIDEXTRAS_EXPORT QJniObject get(); - -/** Returns the mime type of the given content: URL. - * @see Android ContentResolver.getType - */ -KANDROIDEXTRAS_EXPORT QString mimeType(const QUrl &url); - -/** File name of a file provided by a content: URL. */ -KANDROIDEXTRAS_EXPORT QString fileName(const QUrl &url); -} - -} - -#endif // KANDROIDEXTRAS_CONTENTRESOLVER_H diff --git a/src/kandroidextras/android/context.cpp b/src/kandroidextras/android/context.cpp deleted file mode 100644 index c7d1db911..000000000 --- a/src/kandroidextras/android/context.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#include "context.h" - -#include -#include - -#include - -using namespace KAndroidExtras; - -QJniObject Context::getPackageName() -{ - const QJniObject context = QNativeInterface::QAndroidApplication::context(); - return context.callObjectMethod("getPackageName", Jni::signature()); -} diff --git a/src/kandroidextras/android/context.h b/src/kandroidextras/android/context.h deleted file mode 100644 index 194f87885..000000000 --- a/src/kandroidextras/android/context.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_CONTEXT_H -#define KANDROIDEXTRAS_CONTEXT_H - -#include "kandroidextras_export.h" - -class QJniObject; - -namespace KAndroidExtras -{ - -/** Methods around android.content.Context. */ -namespace Context -{ -KANDROIDEXTRAS_EXPORT QJniObject getPackageName(); -} - -} - -#endif // KANDROIDEXTRAS_CONTEXT_H diff --git a/src/kandroidextras/android/intent.cpp b/src/kandroidextras/android/intent.cpp deleted file mode 100644 index 89652b6e1..000000000 --- a/src/kandroidextras/android/intent.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#include "intent.h" -#include "uri.h" - -#include -#include - -#include - -using namespace KAndroidExtras; - -Intent::~Intent() = default; - -Intent::operator QJniObject() const -{ - return jniHandle(); -} - -template -QJniObject Intent::getObjectExtra(const char *methodName, const QJniObject &name) const -{ - return jniHandle().callObjectMethod(methodName, Jni::signature(), name.object()); -} - -QString Intent::getStringExtra(const QJniObject &name) const -{ - return getObjectExtra("getStringExtra", name).toString(); -} - -QStringList Intent::getStringArrayExtra(const QJniObject &name) const -{ - const auto extra = getObjectExtra>("getStringArrayExtra", name); - return Jni::fromArray(extra); -} diff --git a/src/kandroidextras/android/intent.h b/src/kandroidextras/android/intent.h deleted file mode 100644 index fc87d0e3f..000000000 --- a/src/kandroidextras/android/intent.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_INTENT_H -#define KANDROIDEXTRAS_INTENT_H - -#include "kandroidextras_export.h" - -#include -#include -#include -#include -#include - -class QUrl; - -namespace KAndroidExtras -{ - -/** Methods to interact with android.content.Intent objects. - * This does not only offer features beyond what QAndroidIntent, it also provides - * a putExtra() implementation that actually interoperates with system services. - */ -class KANDROIDEXTRAS_EXPORT Intent -{ - JNI_OBJECT(Intent, android::content::Intent) -public: - /** Creates a new empty intent. */ - JNI_CONSTRUCTOR(Intent) - ~Intent(); - - /** Add a category to the intent. */ - JNI_METHOD(android::content::Intent, addCategory, java::lang::String) - /** Add flags to this intent. */ - JNI_METHOD(android::content::Intent, addFlags, jint) - /** Returns the data of this intent. */ - JNI_METHOD(android::net::Uri, getData) - /** Get the intent action. */ - JNI_METHOD(java::lang::String, getAction) - /** Sets the action of the intent. */ - JNI_METHOD(android::content::Intent, setAction, java::lang::String) - /** Set the data URL of this intent. */ - JNI_METHOD(android::content::Intent, setData, android::net::Uri) - - /** Returns the mimetype of this intent. */ - JNI_METHOD(java::lang::String, getType) - /** Set the mime type for this intent. */ - JNI_METHOD(android::content::Intent, setType, java::lang::String) - - /** Read extra intent data. */ - QString getStringExtra(const QJniObject &name) const; - QStringList getStringArrayExtra(const QJniObject &name) const; - /** Add extra intent data of type @tparam T. */ - template - inline void putExtra(const QJniObject &name, const QJniObject &value) - { - jniHandle().callObjectMethod("putExtra", Jni::signature(), name.object(), value.object()); - } - - /** Implicit conversion to an QJniObject. */ - operator QJniObject() const; - - /** Action constant for create document intents. */ - JNI_CONSTANT(java::lang::String, ACTION_CREATE_DOCUMENT) - /** Main activity entry point. */ - JNI_CONSTANT(java::lang::String, ACTION_MAIN) - /** Action constant for open document intents. */ - JNI_CONSTANT(java::lang::String, ACTION_OPEN_DOCUMENT) - /** Action constant for viewing intents. */ - JNI_CONSTANT(java::lang::String, ACTION_VIEW) - /** Share data. */ - JNI_CONSTANT(java::lang::String, ACTION_SEND) - /** Share multiple data items. */ - JNI_CONSTANT(java::lang::String, ACTION_SEND_MULTIPLE) - - /** Category constant for openable content. */ - JNI_CONSTANT(java::lang::String, CATEGORY_OPENABLE) - - JNI_CONSTANT(java::lang::String, EXTRA_EMAIL) - JNI_CONSTANT(java::lang::String, EXTRA_STREAM) - JNI_CONSTANT(java::lang::String, EXTRA_SUBJECT) - JNI_CONSTANT(java::lang::String, EXTRA_TEXT) - - /** Flag for granting read URI permissions on content providers. */ - JNI_CONSTANT(jint, FLAG_GRANT_READ_URI_PERMISSION) - /** Flag for granting write URI permissions on content providers. */ - JNI_CONSTANT(jint, FLAG_GRANT_WRITE_URI_PERMISSION) - -private: - template - QJniObject getObjectExtra(const char *methodName, const QJniObject &name) const; -}; - -} - -#endif // KANDROIDEXTRAS_INTENT_H diff --git a/src/kandroidextras/android/manifestpermission.h b/src/kandroidextras/android/manifestpermission.h deleted file mode 100644 index a24f6f9bb..000000000 --- a/src/kandroidextras/android/manifestpermission.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_MANIFESTPERMISSIONM_H -#define KANDROIDEXTRAS_MANIFESTPERMISSIONM_H - -#include -#include -#include -#include - -namespace KAndroidExtras -{ - -/** - * Access to manifest permissions. - * @see https://developer.android.com/reference/android/Manifest.permission - */ -class ManifestPermission -{ - JNI_UNMANAGED_OBJECT(ManifestPermission, android::Manifest_permission) -public: - JNI_CONSTANT(java::lang::String, READ_CALENDAR) - JNI_CONSTANT(java::lang::String, WRITE_CALENDAR) - JNI_CONSTANT(java::lang::String, READ_EXTERNAL_STORAGE) - JNI_CONSTANT(java::lang::String, WRITE_EXTERNAL_STORAGE) - JNI_CONSTANT(java::lang::String, POST_NOTIFICATIONS) - JNI_CONSTANT(java::lang::String, CAMERA) -}; - -} - -#endif // KANDROIDEXTRAS_MANIFESTPERMISSIONM_H diff --git a/src/kandroidextras/android/openablecolumns.h b/src/kandroidextras/android/openablecolumns.h deleted file mode 100644 index 27e853ab5..000000000 --- a/src/kandroidextras/android/openablecolumns.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_OPENABLECOLUMNS_H -#define KANDROIDEXTRAS_OPENABLECOLUMNS_H - -#include -#include -#include -#include - -namespace KAndroidExtras -{ - -/** - * Constants for ContentResolver queries. - * @see https://developer.android.com/reference/android/provider/OpenableColumns - */ -class OpenableColumns -{ - JNI_UNMANAGED_OBJECT(OpenableColumns, android::provider::OpenableColumns) -public: - JNI_CONSTANT(java::lang::String, DISPLAY_NAME) - JNI_CONSTANT(java::lang::String, SIZE) -}; - -} - -#endif // KANDROIDEXTRAS_OPENABLECOLUMNS_H diff --git a/src/kandroidextras/android/settings.h b/src/kandroidextras/android/settings.h deleted file mode 100644 index 8319bcc05..000000000 --- a/src/kandroidextras/android/settings.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_SETTINGS_H -#define KANDROIDEXTRAS_SETTINGS_H - -#include -#include - -namespace KAndroidExtras -{ - -/** Methods around android.provider.Settings. */ -class Settings -{ - JNI_UNMANAGED_OBJECT(Settings, android::provider::Settings) - JNI_CONSTANT(java::lang::String, ACTION_APP_NOTIFICATION_SETTINGS) - JNI_CONSTANT(java::lang::String, ACTION_CHANNEL_NOTIFICATION_SETTINGS) - JNI_CONSTANT(java::lang::String, EXTRA_APP_PACKAGE) - JNI_CONSTANT(java::lang::String, EXTRA_CHANNEL_ID) -}; - -} - -#endif // KANDROIDEXTRAS_SETTINGS_H diff --git a/src/kandroidextras/android/uri.cpp b/src/kandroidextras/android/uri.cpp deleted file mode 100644 index b689b1a5b..000000000 --- a/src/kandroidextras/android/uri.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#include "uri.h" - -#include -#include - -using namespace KAndroidExtras; - -QJniObject Uri::fromUrl(const QUrl &url) -{ - return QJniObject::callStaticObjectMethod(Jni::typeName(), - "parse", - Jni::signature(), - QJniObject::fromString(url.toString(QUrl::FullyEncoded)).object()); -} - -QUrl Uri::toUrl(const QJniObject &uri) -{ - if (!uri.isValid()) { - return QUrl(); - } - return QUrl(uri.callObjectMethod("toString", Jni::signature()).toString()); -} diff --git a/src/kandroidextras/android/uri.h b/src/kandroidextras/android/uri.h deleted file mode 100644 index 9cd9a5874..000000000 --- a/src/kandroidextras/android/uri.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_URI_H -#define KANDROIDEXTRAS_URI_H - -#include "kandroidextras_export.h" - -#include -#include - -#include - -namespace KAndroidExtras -{ - -/** Conversion methods for android.net.Uri. */ -namespace Uri -{ -/** Create an android.net.Uri from a QUrl. */ -KANDROIDEXTRAS_EXPORT QJniObject fromUrl(const QUrl &url); - -/** Convert a android.net.Uri to a QUrl. */ -KANDROIDEXTRAS_EXPORT QUrl toUrl(const QJniObject &uri); -} - -JNI_DECLARE_CONVERTER(android::net::Uri, QUrl, (Uri::toUrl(value)), (Uri::fromUrl(value))) - -} - -#endif // KANDROIDEXTRAS_URI_H diff --git a/src/kandroidextras/fake/jni.h b/src/kandroidextras/fake/jni.h deleted file mode 100644 index 6bbd1ab4d..000000000 --- a/src/kandroidextras/fake/jni.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef FAKE_JNI_H -#define FAKE_JNI_H - -#include -#include - -#ifdef Q_OS_ANDROID -#error This is a mock object for use on non-Android! -#endif - -typedef uint8_t jboolean; -typedef int8_t jbyte; -typedef uint16_t jchar; -typedef int16_t jshort; -typedef int32_t jint; -typedef int64_t jlong; -typedef float jfloat; -typedef double jdouble; - -typedef jint jsize; - -typedef void *jobject; -typedef jobject jclass; -typedef jobject jstring; -typedef jobject jarray; -typedef jarray jobjectArray; -typedef jarray jbooleanArray; -typedef jarray jbyteArray; -typedef jarray jcharArray; -typedef jarray jshortArray; -typedef jarray jintArray; -typedef jarray jlongArray; -typedef jarray jfloatArray; -typedef jarray jdoubleArray; - -namespace detail -{ -template -inline T *getArrayElements(jsize size) -{ - T *array = new T[size]; - std::iota(array, array + size, T{}); - return array; -} -} - -struct JNIEnv { - inline bool ExceptionCheck() - { - return false; - } - inline void ExceptionClear() - { - } - - inline int GetArrayLength(jobjectArray) - { - return m_arrayLength; - } - inline jobjectArray NewObjectArray(jsize, jclass, jobject) - { - return nullptr; - } - inline jobject GetObjectArrayElement(jobjectArray, int index) - { - return reinterpret_cast(index); - } - inline void SetObjectArrayElement(jobjectArray, jsize, jobject) - { - } - - inline jbooleanArray NewBooleanArray(jsize) - { - return nullptr; - } - inline jbyteArray NewByteArray(jsize) - { - return nullptr; - } - inline jcharArray NewCharArray(jsize) - { - return nullptr; - } - inline jshortArray NewShortArray(jsize) - { - return nullptr; - } - inline jintArray NewIntArray(jsize) - { - return nullptr; - } - inline jlongArray NewLongArray(jsize) - { - return nullptr; - } - inline jfloatArray NewFloatArray(jsize) - { - return nullptr; - } - inline jdoubleArray NewDoubleArray(jsize) - { - return nullptr; - } - - inline jboolean *GetBooleanArrayElements(jbooleanArray, jboolean *) - { - return detail::getArrayElements(m_arrayLength); - } - inline jbyte *GetByteArrayElements(jbyteArray, jboolean *) - { - return detail::getArrayElements(m_arrayLength); - } - inline jchar *GetCharArrayElements(jcharArray, jboolean *) - { - return detail::getArrayElements(m_arrayLength); - } - inline jshort *GetShortArrayElements(jshortArray, jboolean *) - { - return detail::getArrayElements(m_arrayLength); - } - inline jint *GetIntArrayElements(jintArray, jboolean *) - { - return detail::getArrayElements(m_arrayLength); - } - inline jlong *GetLongArrayElements(jlongArray, jboolean *) - { - return detail::getArrayElements(m_arrayLength); - } - inline jfloat *GetFloatArrayElements(jfloatArray, jboolean *) - { - return detail::getArrayElements(m_arrayLength); - } - inline jdouble *GetDoubleArrayElements(jdoubleArray, jboolean *) - { - return detail::getArrayElements(m_arrayLength); - } - - inline void ReleaseBooleanArrayElements(jbooleanArray, jboolean *data, jint) - { - delete[] data; - } - inline void ReleaseByteArrayElements(jbyteArray, jbyte *data, jint) - { - delete[] data; - } - inline void ReleaseCharArrayElements(jcharArray, jchar *data, jint) - { - delete[] data; - } - inline void ReleaseShortArrayElements(jshortArray, jshort *data, jint) - { - delete[] data; - } - inline void ReleaseIntArrayElements(jintArray, jint *data, jint) - { - delete[] data; - } - inline void ReleaseLongArrayElements(jlongArray, jlong *data, jint) - { - delete[] data; - } - inline void ReleaseFloatArrayElements(jfloatArray, jfloat *data, jint) - { - delete[] data; - } - inline void ReleaseDoubleArrayElements(jdoubleArray, jdouble *data, jint) - { - delete[] data; - } - - inline void SetBooleanArrayRegion(jbooleanArray, jsize, jsize, const jboolean *) - { - } - inline void SetByteArrayRegion(jbyteArray, jsize, jsize, const jbyte *) - { - } - inline void SetCharArrayRegion(jcharArray, jsize, jsize, const jchar *) - { - } - inline void SetShortArrayRegion(jshortArray, jsize, jsize, const jshort *) - { - } - inline void SetIntArrayRegion(jintArray, jsize, jsize, const jint *) - { - } - inline void SetLongArrayRegion(jlongArray, jsize, jsize, const jlong *) - { - } - inline void SetFloatArrayRegion(jfloatArray, jsize, jsize, const jfloat *) - { - } - inline void SetDoubleArrayRegion(jdoubleArray, jsize, jsize, const jdouble *) - { - } - - static jsize m_arrayLength; -}; - -#define JNI_COMMIT 1 -#define JNI_ABORT 2 - -#endif diff --git a/src/kandroidextras/fake/mock_impl.cpp b/src/kandroidextras/fake/mock_impl.cpp deleted file mode 100644 index 834404d07..000000000 --- a/src/kandroidextras/fake/mock_impl.cpp +++ /dev/null @@ -1,9 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#include "jni.h" - -int JNIEnv::m_arrayLength = 0; diff --git a/src/kandroidextras/fake/mock_jnienvironment.h b/src/kandroidextras/fake/mock_jnienvironment.h deleted file mode 100644 index b5ae85923..000000000 --- a/src/kandroidextras/fake/mock_jnienvironment.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020-2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_MOCK_JNIENVIRONMENT_H -#define KANDROIDEXTRAS_MOCK_JNIENVIRONMENT_H - -#include "jni.h" - -namespace KAndroidExtras -{ -class MockJniEnvironment -{ -public: - inline jclass findClass(const char *) - { - return nullptr; - } - inline JNIEnv *operator->() - { - return &m_env; - } - -protected: - mutable JNIEnv m_env; -}; -} - -#endif diff --git a/src/kandroidextras/fake/mock_jniobject.cpp b/src/kandroidextras/fake/mock_jniobject.cpp deleted file mode 100644 index cf14e5749..000000000 --- a/src/kandroidextras/fake/mock_jniobject.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020-2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#include "mock_jniobject.h" - -using namespace KAndroidExtras::Internal; - -QStringList MockJniObjectBase::m_staticProtocol; - -class MockJniObjectBasePrivate : public QSharedData -{ -public: - QStringList protocol; - QHash properties; - QVariant value; -}; - -MockJniObjectBase::MockJniObjectBase() - : d(new MockJniObjectBasePrivate) -{ -} - -MockJniObjectBase::MockJniObjectBase(const char *className) - : d(new MockJniObjectBasePrivate) -{ - addToProtocol(QLatin1StringView("ctor: ") + QLatin1StringView(className)); -} - -MockJniObjectBase::MockJniObjectBase(jobject object) - : d(new MockJniObjectBasePrivate) -{ - Q_UNUSED(object); - addToProtocol(QLatin1StringView("ctor: o")); -} - -MockJniObjectBase::MockJniObjectBase(const MockJniObjectBase &) = default; -MockJniObjectBase &MockJniObjectBase::operator=(const MockJniObjectBase &) = default; -MockJniObjectBase::~MockJniObjectBase() = default; - -QStringList MockJniObjectBase::protocol() const -{ - return d->protocol; -} - -void MockJniObjectBase::addToProtocol(const QString &line) const -{ - d->protocol.push_back(line); -} - -void MockJniObjectBase::setProtocol(const QStringList &protocol) -{ - d->protocol = protocol; -} - -QVariant MockJniObjectBase::property(const QByteArray &name) const -{ - return d->properties.value(name); -} - -void MockJniObjectBase::setProperty(const QByteArray &name, const QVariant &value) -{ - d->properties.insert(name, value); -} - -QVariant MockJniObjectBase::value() const -{ - return d->value; -} - -void MockJniObjectBase::setValue(const QVariant &value) -{ - d->value = value; -} - -void MockJniObjectBase::setData(jobject object) -{ - d = reinterpret_cast(object); -} diff --git a/src/kandroidextras/fake/mock_jniobject.h b/src/kandroidextras/fake/mock_jniobject.h deleted file mode 100644 index 3c808c332..000000000 --- a/src/kandroidextras/fake/mock_jniobject.h +++ /dev/null @@ -1,262 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020-2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_MOCK_JNIOBJECT_H -#define KANDROIDEXTRAS_MOCK_JNIOBJECT_H - -#include "jni.h" -#include "kandroidextras_export.h" - -#include "kandroidextras/jnisignature.h" -#include "kandroidextras/jnitypes.h" - -#include -#include -#include - -class MockJniObjectBasePrivate; - -namespace KAndroidExtras -{ -namespace Internal -{ -template -constexpr inline const char *argTypeToString() -{ - return KAndroidExtras::Jni::signature(); -} -template<> -constexpr inline const char *argTypeToString() -{ - return "o"; -} - -class KANDROIDEXTRAS_EXPORT MockJniObjectBase -{ -public: - MockJniObjectBase(); - MockJniObjectBase(const MockJniObjectBase &); - ~MockJniObjectBase(); - MockJniObjectBase &operator=(const MockJniObjectBase &); - - MockJniObjectBase(const char *className); - - inline MockJniObjectBase(const char *className, const char *signature) - : MockJniObjectBase() - { - addToProtocol(QLatin1StringView("ctor: ") + QLatin1StringView(className) + QLatin1Char(' ') + QLatin1StringView(signature)); - } - template - inline MockJniObjectBase(const char *className, const char *signature, Args...) - : MockJniObjectBase() - { - addToProtocol(QLatin1StringView("ctor: ") + QLatin1StringView(className) + QLatin1Char(' ') + QLatin1StringView(signature) + QLatin1StringView(" (") - + (... + QLatin1StringView(KAndroidExtras::Internal::argTypeToString())) + QLatin1Char(')')); - } - - MockJniObjectBase(jobject object); - - bool isValid() const - { - return true; - } - - static QStringList m_staticProtocol; - - QStringList protocol() const; - void addToProtocol(const QString &line) const; - -protected: - QVariant property(const QByteArray &name) const; - void setProperty(const QByteArray &name, const QVariant &value); - QVariant value() const; - void setValue(const QVariant &value); - void setData(jobject object); - - void setProtocol(const QStringList &protocol); - QExplicitlySharedDataPointer d; -}; - -template -class MockJniObject : public MockJniObjectBase -{ -public: - using MockJniObjectBase::MockJniObjectBase; - static inline JniObjectT fromString(const QString &s) - { - JniObjectT o; - o.setValue(s); - return o; - } - static inline JniObjectT fromLocalRef(jobject o) - { - JniObjectT obj; - obj.addToProtocol(QLatin1StringView("ctor: ") + QString::number((qulonglong)o)); - return obj; - } - inline QString toString() const - { - return value().userType() == QMetaType::QString ? value().toString() : protocol().join(QLatin1Char('\n')); - } - - inline jobject object() const - { - return d.data(); - } - template - inline T object() const - { - return {}; - } - - template - inline T callMethod(const char *methodName, const char *signature, Args...) const - { - const QString s = QLatin1StringView("callMethod: ") + QLatin1StringView(methodName) + QLatin1Char(' ') + QLatin1StringView(signature) - + QLatin1StringView(" (") + (... + QLatin1StringView(KAndroidExtras::Internal::argTypeToString())) + QLatin1Char(')'); - addToProtocol(s); - if constexpr (!std::is_same_v) { - return {}; - } - } - template - inline T callMethod(const char *methodName, const char *signature) const - { - const QString s = - QLatin1StringView("callMethod: ") + QLatin1StringView(methodName) + QLatin1Char(' ') + QLatin1StringView(signature) + QLatin1StringView(" ()"); - addToProtocol(s); - if constexpr (!std::is_same_v) { - return {}; - } - } - - template - inline JniObjectT callObjectMethod(const char *methodName, const char *signature, Args...) const - { - const QString s = QLatin1StringView("callObjectMethod: ") + QLatin1StringView(methodName) + QLatin1Char(' ') + QLatin1StringView(signature) - + QLatin1StringView(" (") + (... + QLatin1StringView(KAndroidExtras::Internal::argTypeToString())) + QLatin1Char(')'); - addToProtocol(s); - - JniObjectT obj; - obj.setProtocol(protocol()); - return obj; - } - inline JniObjectT callObjectMethod(const char *methodName, const char *signature) const - { - addToProtocol(QLatin1StringView("callObjectMethod: ") + QLatin1StringView(methodName) + QLatin1Char(' ') + QLatin1StringView(signature) - + QLatin1StringView(" ()")); - - JniObjectT obj; - obj.setProtocol(protocol()); - return obj; - } - - template - inline T getField(const char *fieldName) const - { - addToProtocol(QLatin1StringView("getField: ") + QLatin1StringView(fieldName) + QLatin1Char(' ') - + QLatin1StringView(KAndroidExtras::Jni::signature())); - return property(fieldName).template value(); - } - - inline JniObjectT getObjectField(const char *fieldName, const char *signature) const - { - addToProtocol(QLatin1StringView("getObjectField: ") + QLatin1StringView(fieldName) + QLatin1Char(' ') + QLatin1StringView(signature)); - return property(fieldName).template value(); - } - - template - inline void setField(const char *fieldName, const char *signature, T value) - { - Q_UNUSED(value); - addToProtocol(QLatin1StringView("setField: ") + QLatin1StringView(fieldName) + QLatin1Char(' ') + QLatin1StringView(signature)); - if constexpr (std::is_same_v) { - setObjectProperty(fieldName, value); - } else { - setProperty(fieldName, QVariant::fromValue(value)); - } - } - template - inline void setField(const char *fieldName, T value) - { - setField(fieldName, KAndroidExtras::Jni::signature(), value); - } - - template - static inline T callStaticMethod(const char *className, const char *methodName, const char *signature, Args...) - { - const QString s = QLatin1StringView("callStaticMethod: ") + QLatin1StringView(className) + QLatin1Char(' ') + QLatin1StringView(methodName) - + QLatin1Char(' ') + QLatin1StringView(signature) + QLatin1StringView(" (") - + (... + QLatin1StringView(KAndroidExtras::Internal::argTypeToString())) + QLatin1Char(')'); - m_staticProtocol.push_back(s); - if constexpr (!std::is_same_v) { - return {}; - } - } - template - static inline T callStaticMethod(const char *className, const char *methodName, const char *signature) - { - const QString s = QLatin1StringView("callStaticMethod: ") + QLatin1StringView(className) + QLatin1Char(' ') + QLatin1StringView(methodName) - + QLatin1Char(' ') + QLatin1StringView(signature) + QLatin1StringView(" ()"); - m_staticProtocol.push_back(s); - if constexpr (!std::is_same_v) { - return {}; - } - } - - template - static inline JniObjectT callStaticObjectMethod(const char *className, const char *methodName, const char *signature, Args...) - { - const QString s = QLatin1StringView("callStaticObjectMethod: ") + QLatin1StringView(className) + QLatin1Char(' ') + QLatin1StringView(methodName) - + QLatin1Char(' ') + QLatin1StringView(signature) + QLatin1StringView(" (") - + (... + QLatin1StringView(KAndroidExtras::Internal::argTypeToString())) + QLatin1Char(')'); - JniObjectT obj; - obj.addToProtocol(s); - return obj; - } - - static inline JniObjectT callStaticObjectMethod(const char *className, const char *methodName, const char *signature) - { - JniObjectT obj; - obj.addToProtocol(QLatin1StringView("callStaticObjectMethod: ") + QLatin1StringView(className) + QLatin1Char(' ') + QLatin1StringView(methodName) - + QLatin1Char(' ') + QLatin1StringView(signature) + QLatin1StringView(" ()")); - return obj; - } - - static inline JniObjectT getStaticObjectField(const char *className, const char *fieldName, const char *signature) - { - m_staticProtocol.push_back(QLatin1StringView("getStaticObjectField: ") + QLatin1StringView(className) + QLatin1Char(' ') + QLatin1StringView(fieldName) - + QLatin1Char(' ') + QLatin1StringView(signature)); - return {}; - } - - template - static inline JniObjectT getStaticObjectField(const char *className, const char *fieldName) - { - m_staticProtocol.push_back(QLatin1StringView("getStaticObjectField<>: ") + QLatin1StringView(className) + QLatin1Char(' ') - + QLatin1StringView(fieldName)); - return {}; - } - - template - static inline T getStaticField(const char *className, const char *fieldName) - { - m_staticProtocol.push_back(QLatin1StringView("getStaticField<>: ") + QLatin1StringView(className) + QLatin1Char(' ') + QLatin1StringView(fieldName) - + QLatin1Char(' ') + QLatin1StringView(KAndroidExtras::Jni::signature())); - return {}; - } - - inline void setObjectProperty(const QByteArray &name, jobject value) - { - JniObjectT o; - o.setData(value); - setProperty(name, QVariant::fromValue(o)); - } -}; - -} -} - -#endif diff --git a/src/kandroidextras/fake/qt6/QCoreApplication b/src/kandroidextras/fake/qt6/QCoreApplication deleted file mode 100644 index 511de7168..000000000 --- a/src/kandroidextras/fake/qt6/QCoreApplication +++ /dev/null @@ -1,24 +0,0 @@ -/* - SPDX-FileCopyrightText: 2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_MOCK_QCOREAPPLICATION_H -#define KANDROIDEXTRAS_MOCK_QCOREAPPLICATION_H - -#include_next - -#include - -namespace QNativeInterface { -namespace QAndroidApplication { - inline QJniObject context() - { - QJniObject obj; - obj.addToProtocol(QStringLiteral("global androidContext()")); - return obj; - } -} -} - -#endif diff --git a/src/kandroidextras/fake/qt6/QJniEnvironment b/src/kandroidextras/fake/qt6/QJniEnvironment deleted file mode 100644 index d171a76be..000000000 --- a/src/kandroidextras/fake/qt6/QJniEnvironment +++ /dev/null @@ -1,17 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020-2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_MOCK_QJNIENVIRONMENT_H -#define KANDROIDEXTRAS_MOCK_QJNIENVIRONMENT_H - -#include "mock_jnienvironment.h" - -class QJniEnvironment : public KAndroidExtras::MockJniEnvironment -{ -public: - inline JNIEnv* jniEnv() const { return &m_env; } -}; - -#endif diff --git a/src/kandroidextras/fake/qt6/QJniObject b/src/kandroidextras/fake/qt6/QJniObject deleted file mode 100644 index 614dca598..000000000 --- a/src/kandroidextras/fake/qt6/QJniObject +++ /dev/null @@ -1,6 +0,0 @@ -/* - SPDX-FileCopyrightText: 2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#include "qjniobject.h" diff --git a/src/kandroidextras/fake/qt6/private/qandroidextras_p.h b/src/kandroidextras/fake/qt6/private/qandroidextras_p.h deleted file mode 100644 index 43f02f499..000000000 --- a/src/kandroidextras/fake/qt6/private/qandroidextras_p.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020-2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_MAKE_QTANDROIDEXTRAS_P_H -#define KANDROIDEXTRAS_MAKE_QTANDROIDEXTRAS_P_H - -#include - -/** Mock object for QtAndroid namespace. */ -namespace QtAndroidPrivate -{ -inline void startActivity(const QJniObject &, int) -{ -} -} - -#endif diff --git a/src/kandroidextras/fake/qt6/qjniobject.h b/src/kandroidextras/fake/qt6/qjniobject.h deleted file mode 100644 index 9ae171d1a..000000000 --- a/src/kandroidextras/fake/qt6/qjniobject.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020-2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_MOCK_QJNIOBJECT_H -#define KANDROIDEXTRAS_MOCK_QJNIOBJECT_H - -#include "mock_jniobject.h" - -/** Mock object for QJniObject outside of Android, for automated testing. */ -class KANDROIDEXTRAS_EXPORT QJniObject : public KAndroidExtras::Internal::MockJniObject -{ -public: - using MockJniObject::MockJniObject; -}; - -Q_DECLARE_METATYPE(QJniObject) - -#endif diff --git a/src/kandroidextras/java/java_headers.cpp b/src/kandroidextras/java/java_headers.cpp deleted file mode 100644 index f84ae1540..000000000 --- a/src/kandroidextras/java/java_headers.cpp +++ /dev/null @@ -1,9 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -// list all headers here that have no .cpp file -// this only serves as a guarantee that these headers actually compile -#include "javatypes.h" diff --git a/src/kandroidextras/java/javalocale.cpp b/src/kandroidextras/java/javalocale.cpp deleted file mode 100644 index 484bb2f6c..000000000 --- a/src/kandroidextras/java/javalocale.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#include "javalocale.h" - -#include -#include - -#include - -using namespace KAndroidExtras; - -QJniObject Locale::fromLocale(const QLocale &locale) -{ - auto lang = QJniObject::fromString(QLocale::languageToString(locale.language())); - auto country = QJniObject::fromString(QLocale::countryToString(locale.country())); - auto script = QJniObject::fromString(QLocale::scriptToString(locale.script())); - - return QJniObject(Jni::typeName(), - (const char *)Jni::signature(), - lang.object(), - country.object(), - script.object()); -} - -QJniObject Locale::current() -{ - return fromLocale(QLocale()); -} diff --git a/src/kandroidextras/java/javalocale.h b/src/kandroidextras/java/javalocale.h deleted file mode 100644 index ad8427635..000000000 --- a/src/kandroidextras/java/javalocale.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_LOCALE_H -#define KANDROIDEXTRAS_LOCALE_H - -#include "kandroidextras_export.h" - -class QJniObject; -class QLocale; - -namespace KAndroidExtras -{ - -/** Conversion methods between java.util.Locale and QLocale. - * @note Do not rename this file to locale.h, that clashes with POSIX locale.h when your - * include paths are unfortunately set up causing bizarre compilation issues. - */ -namespace Locale -{ -/** Create an java.util.Locale object from a QLocale. */ -KANDROIDEXTRAS_EXPORT QJniObject fromLocale(const QLocale &locale); - -/** Create an java.util.Locale object for the current QLocale. */ -KANDROIDEXTRAS_EXPORT QJniObject current(); -} - -} - -#endif // KANDROIDEXTRAS_LOCALE_H diff --git a/src/kandroidextras/java/javatypes.h b/src/kandroidextras/java/javatypes.h deleted file mode 100644 index fa216dfe1..000000000 --- a/src/kandroidextras/java/javatypes.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_JAVATYPES_H -#define KANDROIDEXTRAS_JAVATYPES_H - -#include -#include - -namespace KAndroidExtras -{ - -JNI_TYPE(java, io, File) -JNI_TYPE(java, lang, String) -JNI_TYPE(java, util, Locale) - -JNI_DECLARE_CONVERTER(java::lang::String, QString, (value.toString()), (QJniObject::fromString(value))) - -} - -#endif // KANDROIDEXTRAS_JAVATYPES_H diff --git a/src/kandroidextras/jni/jni_headers.cpp b/src/kandroidextras/jni/jni_headers.cpp deleted file mode 100644 index 5a1ece371..000000000 --- a/src/kandroidextras/jni/jni_headers.cpp +++ /dev/null @@ -1,19 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -// list all headers here that have no .cpp file -// this only serves as a guarantee that these headers actually compile -#include "jniargument.h" -#include "jniarray.h" -#include "jnimethod.h" -#include "jniobject.h" -#include "jnipp.h" -#include "jniprimitivetypes.h" -#include "jniproperty.h" -#include "jnireturnvalue.h" -#include "jnisignature.h" -#include "jnitypes.h" -#include "jnitypetraits.h" diff --git a/src/kandroidextras/jni/jniargument.h b/src/kandroidextras/jni/jniargument.h deleted file mode 100644 index 9d99d1300..000000000 --- a/src/kandroidextras/jni/jniargument.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - SPDX-FileCopyrightText: 2021-2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_JNIARGUMENTVALUE_H -#define KANDROIDEXTRAS_JNIARGUMENTVALUE_H - -#include "jniobject.h" -#include "jnitypetraits.h" - -namespace KAndroidExtras -{ -namespace Jni -{ -template -class Array; -} - -///@cond internal -namespace Internal -{ -/** Call argument wrapper. */ -template> -struct argument { - static_assert(!is_invalid_primitive_type::value, "Using an incompatible primitive type!"); - typedef std::conditional_t::value, T, const Jni::Object &> type; - static inline constexpr auto toCallArgument(type value) - { - if constexpr (Jni::is_primitive_type::value) { - return primitive_value::toJni(value); - } else { - return value.jniHandle().object(); - } - } -}; -template -struct argument> { - typedef const T &type; - static inline auto toCallArgument(const T &value) - { - return Jni::handle(value).object(); - } -}; -template -struct argument> { - typedef const Jni::Array &type; - static inline auto toCallArgument(const Jni::Array &value) - { - return value.jniHandle().object(); - } -}; -} -///@endcond -} - -#endif diff --git a/src/kandroidextras/jni/jniarray.h b/src/kandroidextras/jni/jniarray.h deleted file mode 100644 index 4a6afe06b..000000000 --- a/src/kandroidextras/jni/jniarray.h +++ /dev/null @@ -1,395 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_JNIARRAY_H -#define KANDROIDEXTRAS_JNIARRAY_H - -#include "jniargument.h" -#include "jnireturnvalue.h" -#include "jnitypetraits.h" - -#include - -namespace KAndroidExtras -{ - -///@cond internal -namespace Internal -{ - -/** Primitive type array type traits. */ -template -struct array_trait { - typedef jobjectArray type; -}; - -#define MAKE_ARRAY_TRAIT(base_type, type_name) \ - template<> \ - struct array_trait { \ - typedef base_type##Array type; \ - static inline type newArray(QJniEnvironment &env, jsize size) \ - { \ - return env->New##type_name##Array(size); \ - } \ - static inline base_type *getArrayElements(QJniEnvironment &env, type array, jboolean *isCopy) \ - { \ - return env->Get##type_name##ArrayElements(array, isCopy); \ - } \ - static inline void releaseArrayElements(QJniEnvironment &env, type array, base_type *data, jint mode) \ - { \ - return env->Release##type_name##ArrayElements(array, data, mode); \ - } \ - static inline void setArrayRegion(QJniEnvironment &env, type array, jsize start, jsize length, const base_type *data) \ - { \ - env->Set##type_name##ArrayRegion(array, start, length, data); \ - } \ - }; - -MAKE_ARRAY_TRAIT(jboolean, Boolean) -MAKE_ARRAY_TRAIT(jbyte, Byte) -MAKE_ARRAY_TRAIT(jchar, Char) -MAKE_ARRAY_TRAIT(jshort, Short) -MAKE_ARRAY_TRAIT(jint, Int) -MAKE_ARRAY_TRAIT(jlong, Long) -MAKE_ARRAY_TRAIT(jfloat, Float) -MAKE_ARRAY_TRAIT(jdouble, Double) - -#undef MAKE_ARRAY_TRAIT - -/** Meta function for retrieving a JNI array .*/ -template -struct FromArray { -}; - -template -struct FromArray { - inline auto operator()(const QJniObject &array) const - { - if (!array.isValid()) { - return Container{}; - } - const auto a = static_cast(array.object()); - QJniEnvironment env; - const auto size = env->GetArrayLength(a); - Container r; - r.reserve(size); - for (auto i = 0; i < size; ++i) { - r.push_back(QJniObject::fromLocalRef(env->GetObjectArrayElement(a, i))); - } - return r; - } -}; - -template -struct FromArray { - inline auto operator()(const QJniObject &array) const - { - if (!array.isValid()) { - return Container{}; - } - const auto a = static_cast(array.object()); - QJniEnvironment env; - const auto size = env->GetArrayLength(a); - Container r; - r.reserve(size); - for (auto i = 0; i < size; ++i) { - r.push_back(Jni::reverse_converter::type::convert(QJniObject::fromLocalRef(env->GetObjectArrayElement(a, i)))); - } - return r; - } -}; - -// specializations for primitive types -template -struct FromArray { - typedef array_trait _t; - inline auto operator()(const QJniObject &array) const - { - if (!array.isValid()) { - return Container{}; - } - - const auto a = static_cast(array.object()); - QJniEnvironment env; - const auto size = env->GetArrayLength(a); - Container r; - r.reserve(size); - - auto data = _t::getArrayElements(env, a, nullptr); - std::copy(data, data + size, std::back_inserter(r)); - _t::releaseArrayElements(env, a, data, JNI_ABORT); - - return r; - } -}; - -// array wrapper, common base for primitive and non-primitive types -template -class ArrayImplBase -{ -public: - typedef T value_type; - typedef jsize size_type; - typedef jsize difference_type; - - ArrayImplBase() = default; - inline ArrayImplBase(const QJniObject &array) - : m_array(array) - { - } - ArrayImplBase(const ArrayImplBase &) = default; - ArrayImplBase(ArrayImplBase &&) = default; - - inline size_type size() const - { - if (!m_array.isValid()) { - return 0; - } - const auto a = static_cast(m_array.object()); - QJniEnvironment env; - return env->GetArrayLength(a); - } - - inline operator QJniObject() const - { - return m_array; - } - inline QJniObject jniHandle() const - { - return m_array; - } - -protected: - typedef array_trait _t; - - typename _t::type handle() const - { - return static_cast(m_array.object()); - } - - QJniObject m_array; -}; - -template -class ArrayImpl -{ -}; - -// array wrapper for primitive types -template -class ArrayImpl : public ArrayImplBase -{ - static_assert(!Internal::is_invalid_primitive_type::value, "Using an incompatible primitive type!"); - -public: - inline ArrayImpl(const QJniObject &array) - : ArrayImplBase(array) - { - // ### do this on demand? - getArrayElements(); - } - - /** Create a new array with @p size elements. */ - inline explicit ArrayImpl(jsize size) - { - QJniEnvironment env; - ArrayImplBase::m_array = QJniObject::fromLocalRef(ArrayImplBase::_t::newArray(env, size)); - getArrayElements(); - } - - ArrayImpl() = default; - ArrayImpl(const ArrayImpl &) = delete; // ### ref count m_data and allow copying? - ArrayImpl(ArrayImpl &&) = default; - ~ArrayImpl() - { - QJniEnvironment env; - ArrayImplBase::_t::releaseArrayElements(env, this->handle(), m_data, JNI_ABORT); - } - - T operator[](jsize index) const - { - return m_data[index]; - } - - T *begin() const - { - return m_data; - } - T *end() const - { - return m_data + ArrayImplBase::size(); - } - -private: - inline void getArrayElements() - { - if (!ArrayImplBase::m_array.isValid()) { - return; - } - QJniEnvironment env; - m_data = ArrayImplBase::_t::getArrayElements(env, this->handle(), nullptr); - } - - T *m_data = nullptr; -}; - -// array wrapper for non-primitive types -template -class ArrayImpl : public ArrayImplBase -{ -public: - using ArrayImplBase::ArrayImplBase; - - /** Create a new array with @p size elements initialized with @p value. */ - explicit inline ArrayImpl(jsize size, typename Internal::argument::type value) - { - QJniEnvironment env; - auto clazz = env.findClass(Jni::typeName()); - ArrayImplBase::m_array = QJniObject::fromLocalRef(env->NewObjectArray(size, clazz, Internal::argument::toCallArgument(value))); - } - - /** Create a new array with @p size null elements. */ - explicit inline ArrayImpl(jsize size, std::nullptr_t = nullptr) - { - QJniEnvironment env; - auto clazz = env.findClass(Jni::typeName()); - ArrayImplBase::m_array = QJniObject::fromLocalRef(env->NewObjectArray(size, clazz, nullptr)); - } - - ArrayImpl() = default; - ArrayImpl(const ArrayImpl &) = default; - ArrayImpl(ArrayImpl &&) = default; - - auto operator[](jsize index) const - { - QJniEnvironment env; - return Internal::return_wrapper::toReturnValue(QJniObject::fromLocalRef(env->GetObjectArrayElement(this->handle(), index))); - } - - class ref - { - public: - inline operator auto() - { - QJniEnvironment env; - return Internal::return_wrapper::toReturnValue(QJniObject::fromLocalRef(env->GetObjectArrayElement(c.handle(), index))); - } - inline ref &operator=(typename Internal::argument::type v) - { - QJniEnvironment env; - env->SetObjectArrayElement(c.handle(), index, Internal::argument::toCallArgument(v)); - return *this; - } - - private: - ArrayImpl &c; - jsize index; - - friend class ArrayImpl; - inline ref(jsize _i, ArrayImpl &_c) - : c(_c) - , index(_i) - { - } - }; - ref operator[](jsize index) - { - return ref(index, *this); - } - - class const_iterator - { - const ArrayImpl &c; - jsize i = 0; - - public: - typedef jsize difference_type; - typedef T value_type; - typedef T &reference; - typedef std::random_access_iterator_tag iterator_category; - typedef T *pointer; - - const_iterator(const ArrayImpl &_c, jsize _i) - : c(_c) - , i(_i) - { - } - - difference_type operator-(const_iterator other) const - { - return i - other.i; - } - - const_iterator &operator++() - { - ++i; - return *this; - } - const_iterator operator++(int) - { - return const_iterator(c, i++); - } - - bool operator==(const_iterator other) const - { - return i == other.i; - } - bool operator!=(const_iterator other) const - { - return i != other.i; - } - - auto operator*() const - { - return c[i]; - } - }; - - const_iterator begin() const - { - return const_iterator(*this, 0); - } - const_iterator end() const - { - return const_iterator(*this, ArrayImplBase::size()); - } -}; - -} -///@endcond - -namespace Jni -{ - -/** Convert a JNI array to a C++ container. - * Container value types can be any of - * - QJniObject - * - a primitive JNI type - * - a type with a conversion defined with @c JNI_DECLARE_CONVERTER - */ -template -constexpr - __attribute__((__unused__)) Internal::FromArray::value> - fromArray = {}; - -/** Container-like wrapper for JNI arrays. */ -template -class Array : public Internal::ArrayImpl::value> -{ -public: - using Internal::ArrayImpl::value>::ArrayImpl; - template - inline operator Container() const - { - // ### should this be re-implemented in terms of Jni::Array API rather than direct JNI access? - return Jni::fromArray(this->m_array); - } -}; -} - -} - -#endif diff --git a/src/kandroidextras/jni/jnimethod.h b/src/kandroidextras/jni/jnimethod.h deleted file mode 100644 index 04c6b2b23..000000000 --- a/src/kandroidextras/jni/jnimethod.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - SPDX-FileCopyrightText: 2021 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_JNIMETHOD_H -#define KANDROIDEXTRAS_JNIMETHOD_H - -#include "jniargument.h" -#include "jniarray.h" -#include "jniobject.h" -#include "jnipp.h" -#include "jnireturnvalue.h" -#include "jnitypetraits.h" - -namespace KAndroidExtras -{ -///@cond internal - -// method parameter generation -#define JNI_PARAM(Type, Name) typename KAndroidExtras::Internal::argument::type Name - -#define JNI_PARAMS_0(accu, arg) -#define JNI_PARAMS_1(accu, arg, ...) JNI_PARAM(arg, a1) -#define JNI_PARAMS_2(accu, arg, ...) JNI_PARAM(arg, a2), JNI_PARAMS_1(accu, __VA_ARGS__) -#define JNI_PARAMS_3(accu, arg, ...) JNI_PARAM(arg, a3), JNI_PARAMS_2(accu, __VA_ARGS__) - -#define JNI_PARAMS_(N, accu, ...) JNI_PP_CONCAT(JNI_PARAMS_, N)(accu, __VA_ARGS__) -#define JNI_PARAMS(...) JNI_PARAMS_(JNI_PP_NARG(__VA_ARGS__), "", __VA_ARGS__) - -// method argument forwarding generation -#define JNI_ARG(Type, Name) KAndroidExtras::Internal::argument::toCallArgument(Name) -#define JNI_ARGS_0(accu, arg) -#define JNI_ARGS_1(accu, arg, ...) JNI_ARG(arg, a1) -#define JNI_ARGS_2(accu, arg, ...) JNI_ARG(arg, a2), JNI_ARGS_1(accu, __VA_ARGS__) -#define JNI_ARGS_3(accu, arg, ...) JNI_ARG(arg, a3), JNI_ARGS_2(accu, __VA_ARGS__) - -#define JNI_ARGS_(N, accu, ...) JNI_PP_CONCAT(JNI_ARGS_, N)(accu, __VA_ARGS__) -#define JNI_ARGS(...) JNI_ARGS_(JNI_PP_NARG(__VA_ARGS__), "", __VA_ARGS__) - -namespace Internal -{ -// method call wrapper -template -struct caller { - static_assert(!is_invalid_primitive_type::value, "Using an incompatible primitive type!"); - template - static auto call(const QJniObject &handle, const char *name, const char *signature, Args &&...args) - { - if constexpr (std::is_same_v) { - handle.callMethod(name, signature, std::forward(args)...); - } else if constexpr (Jni::is_primitive_type::value) { - return Internal::return_wrapper::toReturnValue( - handle.callMethod::JniType>(name, signature, std::forward(args)...)); - } else { - return Internal::return_wrapper::toReturnValue(handle.callObjectMethod(name, signature, std::forward(args)...)); - } - } - - static auto call(const QJniObject &handle, const char *name, const char *signature) - { - if constexpr (std::is_same_v) { - return handle.callMethod(name, signature); - } else if constexpr (Jni::is_primitive_type::value) { - return Internal::return_wrapper::toReturnValue(handle.callMethod::JniType>(name, signature)); - } else { - return Internal::return_wrapper::toReturnValue(handle.callObjectMethod(name, signature)); - } - } -}; - -// static method call wrapper -template -struct static_caller { - static_assert(!is_invalid_primitive_type::value, "Using an incompatible primitive type!"); - template - static auto call(const char *className, const char *name, const char *signature, Args &&...args) - { - if constexpr (std::is_same_v) { - return QJniObject::callStaticMethod(className, name, signature, std::forward(args)...); - } else if constexpr (Jni::is_primitive_type::value) { - return Internal::return_wrapper::toReturnValue( - QJniObject::callStaticMethod::JniType>(className, name, signature, std::forward(args)...)); - } else { - return Internal::return_wrapper::toReturnValue(QJniObject::callStaticObjectMethod(className, name, signature, std::forward(args)...)); - } - } - static auto call(const char *className, const char *name, const char *signature) - { - if constexpr (std::is_same_v) { - return QJniObject::callStaticMethod(className, name, signature); - } else if constexpr (Jni::is_primitive_type::value) { - return Internal::return_wrapper::toReturnValue( - QJniObject::callStaticMethod::JniType>(className, name, signature)); - } else { - return Internal::return_wrapper::toReturnValue(QJniObject::callStaticObjectMethod(className, name, signature)); - } - } -}; -} -///@endcond - -/** - * Wrap a JNI method call. - * This will add a method named @p Name to the current class. Argument types are checked at compile time, - * with the following inputs being accepted: - * - primitive types have to match exactly - * - non-primitive types can be either passed as @c QJniObject instance or with a type that has an - * conversion registered with @c JNI_DECLARE_CONVERTER. - * - * The return type of the method is determined as follows: - * - primitive types are returned directly - * - non-primitive types without a registered type conversion are returned as @c QJniObject. - * - non-primitive types with a registered type conversion are returned in a wrapper class that can - * be implicitly converted either to the destination type of the conversion, or a @c QJniObject. - * This allows to avoid type conversion when chaining calls for example, it however needs additional - * care when used in combination with automatic type deduction. - * - array return types also result in a wrapper class that can be implicitly converted to a sequential - * container or a @p QJniObject representing the JNI array. - * - * Thie macro can only be placed in classes having the @c JNI_OBJECT macro. - * - * @param RetT The return type. Must either be a primitive type or a type declared with @c JNI_TYPE - * @param Name The name of the method. Must match the JNI method to be called exactly. - * @param Args A list or argument types (can be empty). Must either be primitive types or types declared - * with @c JNI_TYPE. - */ -#define JNI_METHOD(RetT, Name, ...) \ - inline auto Name(JNI_PARAMS(__VA_ARGS__)) const \ - { \ - using namespace KAndroidExtras; \ - return Internal::caller::call(jniHandle(), "" #Name, Jni::signature() __VA_OPT__(, ) JNI_ARGS(__VA_ARGS__)); \ - } - -/** - * Wrap a JNI static method call. - * This will add a static method named @p Name to the current class. Argument types are checked at compile time, - * with the following inputs being accepted: - * - primitive types have to match exactly - * - non-primitive types can be either passed as @c QJniObject instance or with a type that has an - * conversion registered with @c JNI_DECLARE_CONVERTER. - * - * The return type of the method is determined as follows: - * - primitive types are returned directly - * - non-primitive types without a registered type conversion are returned as @c QJniObject. - * - non-primitive types with a registered type conversion are returned in a wrapper class that can - * be implicitly converted either to the destination type of the conversion, or a @c QJniObject. - * This allows to avoid type conversion when chaining calls for example, it however needs additional - * care when used in combination with automatic type deduction. - * - array return types also result in a wrapper class that can be implicitly converted to a sequential - * container or a @p QJniObject representing the JNI array. - * - * Thie macro can only be placed in classes having the @c JNI_UNMANAGED_OBJECT or @c JNI_OBJECT macro. - * - * @param RetT The return type. Must either be a primitive type or a type declared with @c JNI_TYPE - * @param Name The name of the method. Must match the JNI method to be called exactly. - * @param Args A list or argument types (can be empty). Must either be primitive types or types declared - * with @c JNI_TYPE. - */ -#define JNI_STATIC_METHOD(RetT, Name, ...) \ - static inline auto Name(JNI_PARAMS(__VA_ARGS__)) \ - { \ - using namespace KAndroidExtras; \ - return Internal::static_caller::call(Jni::typeName<_jni_ThisType>(), \ - "" #Name, \ - Jni::signature() __VA_OPT__(, ) JNI_ARGS(__VA_ARGS__)); \ - } - -/** - * Wrap a JNI constructor call. - * This will add a constructor named @p Name to the current class. Argument types are checked at compile time, - * with the following inputs being accepted: - * - primitive types have to match exactly - * - non-primitive types can be either passed as @c QJniObject instance or with a type that has an - * conversion registered with @c JNI_DECLARE_CONVERTER. - * - * Thie macro can only be placed in classes having @c JNI_OBJECT macro. - * - * @param Name The name of the method. Must match the JNI method to be called exactly. - * @param Args A list or argument types (can be empty). Must either be primitive types or types declared - * with @c JNI_TYPE. - */ -#define JNI_CONSTRUCTOR(Name, ...) \ - inline Name(JNI_PARAMS(__VA_ARGS__)) \ - { \ - using namespace KAndroidExtras; \ - setJniHandle(QJniObject(Jni::typeName<_jni_ThisType>(), (const char *)Jni::signature() __VA_OPT__(, ) JNI_ARGS(__VA_ARGS__))); \ - } - -} - -#endif diff --git a/src/kandroidextras/jni/jniobject.h b/src/kandroidextras/jni/jniobject.h deleted file mode 100644 index 606cdd090..000000000 --- a/src/kandroidextras/jni/jniobject.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019-2021 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_JNIOBJECT_H -#define KANDROIDEXTRAS_JNIOBJECT_H - -#include "jnitypetraits.h" - -namespace KAndroidExtras -{ - -namespace java -{ -namespace lang -{ -struct String; -} -} - -namespace Internal -{ -struct FromHandleTag { -}; -} - -namespace Jni -{ - -template -class Object; - -template -inline QJniObject handle(const T &wrapper) -{ - return wrapper.jniHandle(); -} - -/** Convert an untyped JNI object handle to a typed wrapper. - * This is essentially the JNI equivalent to a reinterpret_cast from a void*. - * Only use this if you are sure @p handle has the correct type, otherwise - * things will horribly go wrong. - */ -template -inline auto fromHandle(const QJniObject &handle) -{ - if constexpr (Jni::is_object_wrapper::value) { - return T(handle, Internal::FromHandleTag()); - } else { - return Jni::Object(handle); - } -} - -template -inline auto fromHandle(jobject handle) -{ - return fromHandle(QJniObject(handle)); -} - -/** Wrapper for JNI objects with a convertible C++ type. - * This provides implicit on-demand conversion to the C++ type, for types - * that don't have a manually defined wrapper. - */ -template -class Object -{ -private: - template - class _dummy_t - { - }; - -public: - inline explicit Object(const QJniObject &v) - : m_handle(v) - { - } - - // implicit conversion from a compatible C++ type - inline Object(const std::conditional_t::type, void>, _dummy_t, typename Jni::converter::type> &v) - : m_handle(Jni::reverse_converter::type::convert(v)) - { - } - - // implicit conversion from a custom wrapper for the same type - template, WrapperT>> - inline Object(const WrapperT &w) - : m_handle(Jni::handle(w)) - { - } - - // special-case QString, as that often comes out of implicitly converted types, - // and thus can't be consumed by another implicit conversion step - template, StrT>> - inline Object(const QString &s) - : m_handle(QJniObject::fromString(s)) - { - } - - // special case for null values - inline Object(std::nullptr_t) - : m_handle((jobject) nullptr) - { - } - - inline operator QJniObject() const - { - return m_handle; - } - inline operator typename Jni::converter::type() const - { - return Jni::converter::convert(m_handle); - } - - inline QJniObject jniHandle() const - { - return m_handle; - } - - // forward basic QJniObject API - inline bool isValid() const - { - return m_handle.isValid(); - } - template, StrT>> - inline QString toString() const - { - return m_handle.toString(); - } - -private: - QJniObject m_handle; -}; - -/** Annotates a class for holding JNI method or property wrappers. - * - * Use this if the class only has static methods or constants. For methods - * and properties, you either need to use @c JNI_OBJECT instead, or make - * sure there is a @p jniHandle() method returning a @c QJniObject - * representing the current instance. - * - * @param Class the name of the class this is added to. - * @param BaseType the Java type this class represents, defined by the - * @c JNI_TYPE or @c JNI_NESTED_TYPE macros. - */ -#define JNI_UNMANAGED_OBJECT(Class, BaseType) \ -public: \ - typedef Class _jni_ThisType; \ - typedef BaseType _jni_BaseType; \ - \ -private: \ - static inline constexpr const char *jniName() \ - { \ - return KAndroidExtras::Jni::typeName(); \ - } \ - friend constexpr const char *KAndroidExtras::Jni::typeName(); - -/** Annotates a class for holding JNI method or property wrappers. - * - * @param Class the name of the class this is added to. - * @param BaseType the Java type this class represents, defined by the - * @c JNI_TYPE or @c JNI_NESTED_TYPE macros. - */ -#define JNI_OBJECT(Class, BaseType) \ - JNI_UNMANAGED_OBJECT(Class, BaseType) \ -private: \ - QJniObject _m_jni_handle; \ - inline QJniObject jniHandle() const \ - { \ - return _m_jni_handle; \ - } \ - inline void setJniHandle(const QJniObject &h) \ - { \ - _m_jni_handle = h; \ - } \ - friend QJniObject KAndroidExtras::Jni::handle(const Class &); \ - friend auto KAndroidExtras::Jni::fromHandle(const QJniObject &); \ - explicit inline Class(const QJniObject &handle, KAndroidExtras::Internal::FromHandleTag) \ - : _m_jni_handle(handle) \ - { \ - } - -} -} - -#endif diff --git a/src/kandroidextras/jni/jnipp.h b/src/kandroidextras/jni/jnipp.h deleted file mode 100644 index 91776124d..000000000 --- a/src/kandroidextras/jni/jnipp.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019-2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_JNIPP_H -#define KANDROIDEXTRAS_JNIPP_H - -/** @file jnipp.h - * Preprocessor macro implementation details. - */ - -///@cond internal - -// determine how many elements are in __VA_ARGS__ -#define JNI_PP_NARG(...) JNI_PP_NARG_(__VA_ARGS__ __VA_OPT__(, ) JNI_PP_RSEQ_N()) -#define JNI_PP_NARG_(...) JNI_PP_ARG_N(__VA_ARGS__) -#define JNI_PP_ARG_N(_1, _2, _3, _4, _5, _6, _7, N, ...) N -#define JNI_PP_RSEQ_N() 7, 6, 5, 4, 3, 2, 1, 0 - -// preprocessor-level token concat -#define JNI_PP_CONCAT(arg1, arg2) JNI_PP_CONCAT1(arg1, arg2) -#define JNI_PP_CONCAT1(arg1, arg2) JNI_PP_CONCAT2(arg1, arg2) -#define JNI_PP_CONCAT2(arg1, arg2) arg1##arg2 - -///@endcond - -#endif // KANDROIDEXTRAS_JNIPP_H diff --git a/src/kandroidextras/jni/jniprimitivetypes.h b/src/kandroidextras/jni/jniprimitivetypes.h deleted file mode 100644 index 5d49c48e5..000000000 --- a/src/kandroidextras/jni/jniprimitivetypes.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020-2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_JNIPRIMITIVETYPES_H -#define KANDROIDEXTRAS_JNIPRIMITIVETYPES_H - -#include "jni.h" - -#include - -namespace KAndroidExtras -{ - -namespace Jni -{ - -/** Type trait to check whether @tparam T is a primitive JNI type or an object type. */ -template -struct is_primitive_type : std::false_type { -}; -template<> -struct is_primitive_type : std::true_type { -}; -template<> -struct is_primitive_type : std::true_type { -}; -template<> -struct is_primitive_type : std::true_type { -}; -template<> -struct is_primitive_type : std::true_type { -}; -template<> -struct is_primitive_type : std::true_type { -}; -template<> -struct is_primitive_type : std::true_type { -}; -template<> -struct is_primitive_type : std::true_type { -}; -template<> -struct is_primitive_type : std::true_type { -}; -template<> -struct is_primitive_type : std::true_type { -}; -// special case for bool <-> jboolean conversion -template<> -struct is_primitive_type : std::true_type { -}; - -} - -namespace Internal -{ - -/** Utility trait to check for basic C++ types that are not JNI primitive types. */ -template -struct is_invalid_primitive_type : std::false_type { -}; -template<> -struct is_invalid_primitive_type : std::true_type { -}; -template<> -struct is_invalid_primitive_type : std::true_type { -}; -template<> -struct is_invalid_primitive_type : std::true_type { -}; -template<> -struct is_invalid_primitive_type : std::true_type { -}; - -// C++ primitive to JNI primitive conversion -template -struct primitive_value { - static_assert(!is_invalid_primitive_type::value, "Using an incompatible primitive type!"); - typedef T JniType; - typedef T NativeType; - static constexpr inline T toJni(T value) - { - return value; - } - static constexpr inline T fromJni(T value) - { - return value; - } -}; -template<> -struct primitive_value { -}; -template<> -struct primitive_value { - typedef jboolean JniType; - typedef bool NativeType; - static constexpr inline jboolean toJni(bool value) - { - return value ? 1 : 0; - } - static constexpr inline bool fromJni(jboolean value) - { - return value != 0; - } -}; -template<> -struct primitive_value { - typedef jboolean JniType; - typedef bool NativeType; - static constexpr inline jboolean toJni(bool value) - { - return value ? 1 : 0; - } - static constexpr inline bool fromJni(jboolean value) - { - return value != 0; - } -}; - -} -} - -#endif diff --git a/src/kandroidextras/jni/jniproperty.h b/src/kandroidextras/jni/jniproperty.h deleted file mode 100644 index fb29a2e0b..000000000 --- a/src/kandroidextras/jni/jniproperty.h +++ /dev/null @@ -1,227 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_JNIPROPERTIES_H -#define KANDROIDEXTRAS_JNIPROPERTIES_H - -#include "jniargument.h" -#include "jniobject.h" -#include "jnisignature.h" -#include "jnitypes.h" -#include "jnitypetraits.h" - -#include - -namespace KAndroidExtras -{ - -namespace Jni -{ -template -class Array; -} - -/** @cond internal */ -namespace Internal -{ - -/** Wrapper for static properties. */ -template -struct StaticProperty { -}; -template -struct StaticProperty { - static_assert(!is_invalid_primitive_type::value, "Using an incompatible primitive type!"); - inline QJniObject get() const - { - return QJniObject::getStaticObjectField(Jni::typeName(), Jni::typeName(), Jni::signature()); - } - inline operator QJniObject() const - { - return get(); - } - inline operator typename Jni::converter::type() const - { - return Jni::converter::convert(get()); - } - template::value, RetT>> - inline operator Jni::Object() const - { - return Jni::Object(get()); - } -}; - -template -struct StaticProperty { - inline operator auto() const - { - return primitive_value::fromJni( - QJniObject::getStaticField::JniType>(Jni::typeName(), Jni::typeName())); - } -}; - -/** Shared code for non-static property wrappers. */ -template -class PropertyBase -{ -protected: - inline QJniObject handle() const - { - const auto owner = reinterpret_cast(reinterpret_cast(this) - OffsetHolder::offset()); - return owner->jniHandle(); - } -}; - -/** Wrapper for non-static properties. */ -template -struct Property { -}; -template -class Property : public PropertyBase -{ -private: - struct _jni_NoType { - }; - static_assert(!is_invalid_primitive_type::value, "Using an incompatible primitive type!"); - -public: - inline QJniObject get() const - { - return this->handle().getObjectField(Jni::typeName(), Jni::signature()); - } - inline operator QJniObject() const - { - return get(); - } - inline operator typename Jni::converter::type() const - { - return Jni::converter::convert(get()); - } - template::value, RetT>> - inline operator PropType() const - { - return PropType(get()); - } - template::value, RetT>> - inline operator Jni::Object() const - { - return Jni::Object(get()); - } - - inline Property &operator=(typename Internal::argument::type value) - { - this->handle().setField(Jni::typeName(), Jni::signature(), Internal::argument::toCallArgument(value)); - return *this; - } - inline Property &operator=(const QJniObject &value) - { - this->handle().setField(Jni::typeName(), Jni::signature(), value.object()); - return *this; - } - inline Property &operator=(const typename std::conditional::type, void>, - _jni_NoType, - typename Jni::converter::type>::type &value) - { - this->handle().setField(Jni::typeName(), Jni::signature(), Jni::reverse_converter::type::convert(value).object()); - return *this; - } - - // special case for string comparison, which is often done against different types and thus the implicit conversion operator - // isn't going to be enough - template, CmpT>> - inline bool operator==(const CmpT &other) const - { - return QString(*this) == other; - } -}; - -template -class Property : public PropertyBase -{ -public: - inline operator auto() const - { - return primitive_value::fromJni(this->handle().template getField::JniType>(Jni::typeName())); - } - inline Property &operator=(PropType value) - { - this->handle().setField(Jni::typeName(), primitive_value::toJni(value)); - return *this; - } -}; - -// TODO KF6: can be replaced by QT_WARNING_DISABLE_INVALID_OFFSETOF -#if defined(Q_CC_CLANG) -#define JNI_WARNING_DISABLE_INVALID_OFFSETOF QT_WARNING_DISABLE_CLANG("-Winvalid-offsetof") -#elif defined(Q_CC_GNU) -#define JNI_WARNING_DISABLE_INVALID_OFFSETOF QT_WARNING_DISABLE_GCC("-Winvalid-offsetof") -#else -#define JNI_WARNING_DISABLE_INVALID_OFFSETOF -#endif - -/** @endcond */ -} - -/** - * Wrap a static final property. - * This will add a public static member named @p name to the current class. This member defines an - * implicit conversion operator which will trigger the corresponding a JNI read operation. - * Can only be placed in classes with a @c JNI_OBJECT. - * - * @note Make sure to access this member with a specific type, assigning to an @c auto variable will - * copy the wrapper type, not read the property value. - * - * @param type The data type of the property. - * @param name The name of the property. - */ -#define JNI_CONSTANT(type, name) \ -private: \ - struct _jni_##name##__NameHolder { \ - static constexpr const char *jniName() \ - { \ - return "" #name; \ - } \ - }; \ - \ -public: \ - static inline const KAndroidExtras::Internal::StaticProperty::value> name; - -/** - * Wrap a member property. - * This will add a public zero-size member named @p name to the current class. This member defines an - * implicit conversion operator which will trigger the corresponding a JNI read operation, as well - * as an overloaded assignment operator for the corresponding write operation. - * Can only be placed in classes with a @c JNI_OBJECT. - * - * @note Make sure to access this member with a specific type, assigning to an @c auto variable will - * copy the wrapper type, not read the property value. - * - * @param type The data type of the property. - * @param name The name of the property. - */ -#define JNI_PROPERTY(type, name) \ -private: \ - struct _jni_##name##__NameHolder { \ - static constexpr const char *jniName() \ - { \ - return "" #name; \ - } \ - }; \ - struct _jni_##name##__OffsetHolder { \ - static constexpr std::size_t offset() \ - { \ - QT_WARNING_PUSH JNI_WARNING_DISABLE_INVALID_OFFSETOF return offsetof(_jni_ThisType, name); \ - QT_WARNING_POP \ - } \ - }; \ - friend class KAndroidExtras::Internal::PropertyBase<_jni_ThisType, _jni_##name##__OffsetHolder>; \ - \ -public: \ - [[no_unique_address]] KAndroidExtras::Internal:: \ - Property::value> name; -} - -#endif // KANDROIDEXTRAS_JNIPROPERTIES_H diff --git a/src/kandroidextras/jni/jnireturnvalue.h b/src/kandroidextras/jni/jnireturnvalue.h deleted file mode 100644 index 0d6e43ceb..000000000 --- a/src/kandroidextras/jni/jnireturnvalue.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - SPDX-FileCopyrightText: 2021-2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_JNIRETURNVALUE_H -#define KANDROIDEXTRAS_JNIRETURNVALUE_H - -#include "jniobject.h" -#include "jnitypetraits.h" - -namespace KAndroidExtras -{ -namespace Jni -{ -template -class Array; -} - -///@cond internal -namespace Internal -{ -/** Return value wrapping helper. */ -template> -class return_wrapper -{ - static_assert(!is_invalid_primitive_type::value, "Using an incompatible primitive type!"); - static inline constexpr bool is_primitive = Jni::is_primitive_type::value; - static inline constexpr bool is_convertible = !std::is_same_v::type, void>; - - typedef std::conditional_t JniReturnT; - -public: - static inline constexpr auto toReturnValue(JniReturnT value) - { - if constexpr (is_convertible) { - return Jni::Object(value); - } else if constexpr (is_primitive) { - return primitive_value::fromJni(value); - } else { - return value; - } - } -}; -template -class return_wrapper> -{ -public: - static inline auto toReturnValue(const QJniObject &value) - { - return Jni::fromHandle(value); - } -}; -template -class return_wrapper> -{ -public: - static inline auto toReturnValue(const QJniObject &value) - { - return Jni::Array(value); - } -}; -template<> -struct return_wrapper { -}; -} -///@endcond -} - -#endif diff --git a/src/kandroidextras/jni/jnisignature.h b/src/kandroidextras/jni/jnisignature.h deleted file mode 100644 index beaa57713..000000000 --- a/src/kandroidextras/jni/jnisignature.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_JNISIGNATURE_H -#define KANDROIDEXTRAS_JNISIGNATURE_H - -#include "jnitypes.h" - -#include "jni.h" -#include -#include - -namespace KAndroidExtras -{ - -namespace Jni -{ -template -class Array; -} - -/** @cond internal */ -namespace Internal -{ - -/** Compile-time concat-able string. */ -template -struct StaticString { - inline operator const char *() const - { - static const char data[] = {String..., 0}; - return data; - } -}; - -/** Compile-time strlen. */ -constexpr inline int static_strlen(const char *str) -{ - return str[0] == '\0' ? 0 : static_strlen(str + 1) + 1; -} - -/** Compile-time concat for two StaticString. */ -template -constexpr inline auto static_concat(const StaticString &, const StaticString &) -{ - return StaticString(); -} - -/** Compile-time concept for N StaticString. */ -template -constexpr inline auto static_concat(const String1 &str1, const String2 &str2, const Strings &...strs) -{ - return static_concat(static_concat(str1, str2), strs...); -} - -/** Conversion from const char* literals to StaticString. */ -template -struct staticStringFromJniType; -template -struct staticStringFromJniType> { - typedef StaticString()[Indexes]...> value; -}; - -/** Meta function for assembling JNI signatures. */ -template -struct JniSignature { - constexpr inline auto operator()() const - { - using namespace Internal; - return static_concat(StaticString<'L'>(), - typename staticStringFromJniType())>>::value(), - StaticString<';'>()); - } -}; - -template<> -struct JniSignature { - constexpr inline auto operator()() const - { - return StaticString<'Z'>(); - } -}; -template<> -struct JniSignature { - constexpr inline auto operator()() const - { - return StaticString<'B'>(); - } -}; -template<> -struct JniSignature { - constexpr inline auto operator()() const - { - return StaticString<'C'>(); - } -}; -template<> -struct JniSignature { - constexpr inline auto operator()() const - { - return StaticString<'S'>(); - } -}; -template<> -struct JniSignature { - constexpr inline auto operator()() const - { - return StaticString<'I'>(); - } -}; -template<> -struct JniSignature { - constexpr inline auto operator()() const - { - return StaticString<'J'>(); - } -}; -template<> -struct JniSignature { - constexpr inline auto operator()() const - { - return StaticString<'F'>(); - } -}; -template<> -struct JniSignature { - constexpr inline auto operator()() const - { - return StaticString<'D'>(); - } -}; -template<> -struct JniSignature { - constexpr inline auto operator()() const - { - return StaticString<'V'>(); - } -}; -// special case due to jboolean != bool -template<> -struct JniSignature { - constexpr inline auto operator()() const - { - return StaticString<'Z'>(); - } -}; - -template -struct JniSignature { - constexpr inline auto operator()() const - { - using namespace Internal; - return static_concat(StaticString<'['>(), JniSignature()()); - } -}; - -template -struct JniSignature> { - constexpr inline auto operator()() const - { - using namespace Internal; - return static_concat(StaticString<'['>(), JniSignature()()); - } -}; - -template -struct JniSignature { - constexpr inline auto operator()() const - { - using namespace Internal; - return static_concat(StaticString<'('>(), JniSignature()()..., StaticString<')'>(), JniSignature()()); - } -}; -} -/** @endcond */ - -/** Helper methods to deal with JNI. */ -namespace Jni -{ -/** Returns the JNI signature string for the template argument types. */ -template -constexpr __attribute__((__unused__)) Internal::JniSignature signature = {}; -} - -} - -#endif // KANDROIDEXTRAS_JNISIGNATURE_H diff --git a/src/kandroidextras/jni/jnitypes.h b/src/kandroidextras/jni/jnitypes.h deleted file mode 100644 index 95f0e67c0..000000000 --- a/src/kandroidextras/jni/jnitypes.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - SPDX-FileCopyrightText: 2019 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_JNITYPES_H -#define KANDROIDEXTRAS_JNITYPES_H - -#include "jnipp.h" - -/** C++/Android integration utilities built on top of @c QJniObject. */ -namespace KAndroidExtras -{ - -///@cond internal - -// preprocessor "iteration" for regular classes -#define JNI_TYPE_1(name, type, ...) \ - struct type { \ - static constexpr const char *jniName() \ - { \ - return name #type; \ - } \ - }; -#define JNI_TYPE_2(name, type, ...) \ - namespace type \ - { \ - JNI_TYPE_1(name #type "/", __VA_ARGS__) \ - } -#define JNI_TYPE_3(name, type, ...) \ - namespace type \ - { \ - JNI_TYPE_2(name #type "/", __VA_ARGS__) \ - } -#define JNI_TYPE_4(name, type, ...) \ - namespace type \ - { \ - JNI_TYPE_3(name #type "/", __VA_ARGS__) \ - } -#define JNI_TYPE_5(name, type, ...) \ - namespace type \ - { \ - JNI_TYPE_4(name #type "/", __VA_ARGS__) \ - } -#define JNI_TYPE_6(name, type, ...) \ - namespace type \ - { \ - JNI_TYPE_5(name #type "/", __VA_ARGS__) \ - } -#define JNI_TYPE_7(name, type, ...) \ - namespace type \ - { \ - JNI_TYPE_6(#type "/", __VA_ARGS__) \ - } -#define JNI_TYPE_(N, name, ...) JNI_PP_CONCAT(JNI_TYPE_, N)(name, __VA_ARGS__) - -// preprocessor "iteration" for nested classes -#define JNI_NESTED_TYPE_2(name, type, nested_type, ...) \ - struct type##_##nested_type { \ - static constexpr const char *jniName() \ - { \ - return name #type "$" #nested_type; \ - } \ - }; -#define JNI_NESTED_TYPE_3(name, type, ...) \ - namespace type \ - { \ - JNI_NESTED_TYPE_2(name #type "/", __VA_ARGS__) \ - } -#define JNI_NESTED_TYPE_4(name, type, ...) \ - namespace type \ - { \ - JNI_NESTED_TYPE_3(name #type "/", __VA_ARGS__) \ - } -#define JNI_NESTED_TYPE_5(name, type, ...) \ - namespace type \ - { \ - JNI_NESTED_TYPE_4(name #type "/", __VA_ARGS__) \ - } -#define JNI_NESTED_TYPE_6(name, type, ...) \ - namespace type \ - { \ - JNI_NESTED_TYPE_5(name #type "/", __VA_ARGS__) \ - } -#define JNI_NESTED_TYPE_7(name, type, ...) \ - namespace type \ - { \ - JNI_NESTED_TYPE_6(#type "/", __VA_ARGS__) \ - } -#define JNI_NESTED_TYPE_(N, name, ...) JNI_PP_CONCAT(JNI_NESTED_TYPE_, N)(name, __VA_ARGS__) - -///@endcond - -/** Macro to define Java types with their corresponding JNI signature strings. */ -#define JNI_TYPE(...) JNI_TYPE_(JNI_PP_NARG(__VA_ARGS__), "", __VA_ARGS__) - -/** Macro to define a nested Java class with its corresponding JNI signature string. */ -#define JNI_NESTED_TYPE(...) JNI_NESTED_TYPE_(JNI_PP_NARG(__VA_ARGS__), "", __VA_ARGS__) - -/** Functions for interfacing with the Java Native Interface (JNI). */ -namespace Jni -{ -/** Returns the JNI type name of the given template argument. */ -template -inline constexpr const char *typeName() -{ - return T::jniName(); -} -} - -} - -#endif // KANDROIDEXTRAS_JNITYPES_H diff --git a/src/kandroidextras/jni/jnitypetraits.h b/src/kandroidextras/jni/jnitypetraits.h deleted file mode 100644 index bccce289b..000000000 --- a/src/kandroidextras/jni/jnitypetraits.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - SPDX-FileCopyrightText: 2020 Volker Krause - - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#ifndef KANDROIDEXTRAS_JNITYPETRAITS_H -#define KANDROIDEXTRAS_JNITYPETRAITS_H - -#include "jniprimitivetypes.h" -#include "jnitypes.h" - -#include - -namespace KAndroidExtras -{ - -namespace Jni -{ - -template -class Array; - -/** Type conversion trait, see @c JNI_DECLARE_CONVERTER. */ -template -struct converter { - typedef void type; -}; - -template -struct reverse_converter { - typedef converter::type> type; -}; - -/** Type trait for checking whether @tparam T is a JNI array type. */ -template -struct is_array : std::false_type { -}; -template -struct is_array> : std::true_type { -}; - -/** Type trais for checking whether @tparam T is a JNI object wrapper type. */ -template> -struct is_object_wrapper : std::false_type { -}; -template -struct is_object_wrapper> : std::true_type { -}; - -/** Type trais for checking whether @tparam T is needs the generic JNI object wrapper (Jni::Object). */ -template -struct is_generic_wrapper - : std::conditional_t::value && !is_array::value && !is_object_wrapper::value, std::true_type, std::false_type> { -}; - -} - -/** - * Declare a JNI type to be convertible to a native type. - * @param JniType A type declared with @p JNI_TYPE. - * @param NativeType A C++ type @p JniType can be converted to/from. - * @param FromJniFn Code converting a @c QJniObject @c value to @p NativeType. - * @param ToJniCode converting a @p NativeType @c value to a QJniObject. - */ -#define JNI_DECLARE_CONVERTER(JniType, NativeType, FromJniFn, ToJniFn) \ - namespace Jni \ - { \ - template<> \ - struct converter { \ - typedef JniType type; \ - static inline QJniObject convert(const NativeType &value) \ - { \ - return (ToJniFn); \ - } \ - }; \ - template<> \ - struct converter { \ - typedef NativeType type; \ - static inline NativeType convert(const QJniObject &value) \ - { \ - return (FromJniFn); \ - } \ - }; \ - } - -} - -#endif diff --git a/src/notificationsmanager.cpp b/src/notificationsmanager.cpp index 4940df43a..c82e05cc5 100644 --- a/src/notificationsmanager.cpp +++ b/src/notificationsmanager.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -23,7 +24,6 @@ #include "controller.h" #include "neochatconnection.h" #include "neochatroom.h" -#include "permissionmanager.h" #include "roommanager.h" #include "texthandler.h" #include "windowcontroller.h" @@ -43,7 +43,7 @@ NotificationsManager::NotificationsManager(QObject *parent) void NotificationsManager::handleNotifications(QPointer connection) { - if (!PermissionManager::instance().checkPermission(Permission::PostNotification)) { + if (KNotificationPermission::checkPermission() != Qt::PermissionStatus::Granted) { return; } diff --git a/src/permissionmanager.cpp b/src/permissionmanager.cpp deleted file mode 100644 index c1e97c0a5..000000000 --- a/src/permissionmanager.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - SPDX-FileCopyrightText: 2022 Volker Krause - SPDX-License-Identifier: LGPL-2.0-or-later -*/ - -#include "permissionmanager.h" - -#include - -#ifdef Q_OS_ANDROID -#include "private/qandroidextras_p.h" -#include -#endif - -#ifdef Q_OS_ANDROID -static QString permissionName(Permission::Permission p) -{ - using namespace KAndroidExtras; - switch (p) { - case Permission::InvalidPermission: - Q_UNREACHABLE(); - case Permission::ReadCalendar: - return ManifestPermission::READ_CALENDAR; - case Permission::WriteCalendar: - return ManifestPermission::WRITE_CALENDAR; - case Permission::PostNotification: // only for SDK >= 33 - return ManifestPermission::POST_NOTIFICATIONS; - case Permission::Camera: - return ManifestPermission::CAMERA; - } -} -#endif - -PermissionManager &PermissionManager::instance() -{ - static PermissionManager _instance; - return _instance; -} - -PermissionManager::PermissionManager(QObject *parent) - : QObject(parent) -{ -} - -bool PermissionManager::checkPermission(Permission::Permission permission) -{ - if (permission == Permission::InvalidPermission) { - qWarning() << "check for invalid permission - check your QML code!"; - return false; - } -#ifdef Q_OS_ANDROID - if (permission == Permission::PostNotification && QtAndroidPrivate::androidSdkVersion() < 33) { - return true; - } - - return QtAndroidPrivate::checkPermission(permissionName(permission)).result() == QtAndroidPrivate::PermissionResult::Authorized; -#else // non-Android - Q_UNUSED(permission); - return true; -#endif -} - -void PermissionManager::requestPermission(Permission::Permission permission, QJSValue callback) -{ - if (permission == Permission::InvalidPermission) { - qWarning() << "request for invalid permission - check your QML code!"; - return; - } - - qDebug() << permission; - // already got the permission - if (PermissionManager::checkPermission(permission)) { - callback.call(); - return; - } - -#ifdef Q_OS_ANDROID - // TODO make this properly async - if (QtAndroidPrivate::checkPermission(permissionName(permission)).result() != QtAndroidPrivate::PermissionResult::Authorized) { - if (QtAndroidPrivate::requestPermission(permissionName(permission)).result() != QtAndroidPrivate::PermissionResult::Authorized) { - return; - } - } - callback.call(); -#endif -} - -#include "moc_permissionmanager.cpp" diff --git a/src/permissionmanager.h b/src/permissionmanager.h deleted file mode 100644 index caaf39506..000000000 --- a/src/permissionmanager.h +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-FileCopyrightText: 2022 Volker Krause -// SPDX-FileCopyrightText: 2024 James Graham -// SPDX-License-Identifier: LGPL-2.0-or-later - -#pragma once - -#include -#include -#include - -/** Permission enum for use in QML. */ -namespace Permission -{ -Q_NAMESPACE -enum Permission { - InvalidPermission, // captures QML errors resulting in "0" enum values - ReadCalendar, - WriteCalendar, - PostNotification, - Camera, -}; -Q_ENUM_NS(Permission) -} - -/** Check and request platform permissions for access to controlled resources (calendar, location, etc). */ -class PermissionManager : public QObject -{ - Q_OBJECT - QML_ELEMENT - QML_SINGLETON -public: - static PermissionManager &instance(); - static PermissionManager *create(QQmlEngine *engine, QJSEngine *) - { - engine->setObjectOwnership(&instance(), QQmlEngine::CppOwnership); - return &instance(); - } - - Q_INVOKABLE static bool checkPermission(Permission::Permission permission); - Q_INVOKABLE static void requestPermission(Permission::Permission permission, QJSValue callback); - -private: - explicit PermissionManager(QObject *parent = nullptr); -};