File indexing completed on 2024-11-17 04:18:46
0001 /* 0002 SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org> 0003 SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 0006 #include "connector_p.h" 0007 #include "logging.h" 0008 0009 #include <QCoreApplication> 0010 using QAndroidJniObject = QJniObject; 0011 0012 using namespace KUnifiedPush; 0013 0014 static QString fromJniString(JNIEnv *env, jstring s) 0015 { 0016 if (!s) { 0017 return {}; 0018 } 0019 0020 const char *str = env->GetStringUTFChars(s, nullptr); 0021 const auto qs = QString::fromUtf8(str); 0022 env->ReleaseStringUTFChars(s, str); 0023 return qs; 0024 } 0025 0026 static void newEndpoint(JNIEnv *env, jobject that, jstring token, jstring endpoint) 0027 { 0028 Q_UNUSED(that); 0029 for (auto c : ConnectorPrivate::s_instances) { 0030 c->NewEndpoint(fromJniString(env, token), fromJniString(env, endpoint)); 0031 } 0032 } 0033 0034 static void registrationFailed(JNIEnv *env, jobject that, jstring token, jstring reason) 0035 { 0036 Q_UNUSED(that); 0037 // TODO 0038 qDebug() << "TODO" << fromJniString(env, token) << fromJniString(env, reason); 0039 } 0040 0041 static void unregistered(JNIEnv *env, jobject that, jstring token) 0042 { 0043 Q_UNUSED(that); 0044 for (auto c : ConnectorPrivate::s_instances) { 0045 c->Unregistered(fromJniString(env, token)); 0046 } 0047 } 0048 0049 static void message(JNIEnv *env, jobject that, jstring token, jbyteArray message, jstring messageId) 0050 { 0051 Q_UNUSED(that); 0052 const auto messageSize = env->GetArrayLength(message); 0053 const auto messageData = env->GetByteArrayElements(message, nullptr); 0054 const auto messageQBA = QByteArray::fromRawData(reinterpret_cast<const char*>(messageData), messageSize); 0055 for (auto c : ConnectorPrivate::s_instances) { 0056 c->Message(fromJniString(env, token), messageQBA, fromJniString(env, messageId)); 0057 } 0058 env->ReleaseByteArrayElements(message, messageData, JNI_ABORT); 0059 } 0060 0061 static const JNINativeMethod methods[] = { 0062 {"newEndpoint", "(Ljava/lang/String;Ljava/lang/String;)V", (void*)newEndpoint}, 0063 {"registrationFailed", "(Ljava/lang/String;Ljava/lang/String;)V", (void*)registrationFailed}, 0064 {"unregistered", "(Ljava/lang/String;)V", (void*)unregistered}, 0065 {"message", "(Ljava/lang/String;[BLjava/lang/String;)V", (void*)message}, 0066 }; 0067 0068 Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void*) 0069 { 0070 static bool initialized = false; 0071 if (initialized) { 0072 return JNI_VERSION_1_4; 0073 } 0074 initialized = true; 0075 0076 JNIEnv *env = nullptr; 0077 if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) { 0078 qCWarning(Log) << "Failed to get JNI environment."; 0079 return -1; 0080 } 0081 jclass cls = env->FindClass("org/kde/kunifiedpush/MessageReceiver"); 0082 if (env->RegisterNatives(cls, methods, sizeof(methods) / sizeof(JNINativeMethod)) < 0) { 0083 qCWarning(Log) << "Failed to register native functions."; 0084 return -1; 0085 } 0086 0087 return JNI_VERSION_1_4; 0088 } 0089 0090 std::vector<ConnectorPrivate*> ConnectorPrivate::s_instances; 0091 0092 void ConnectorPrivate::init() 0093 { 0094 s_instances.push_back(this); 0095 } 0096 0097 void ConnectorPrivate::deinit() 0098 { 0099 s_instances.erase(std::remove(s_instances.begin(), s_instances.end(), this), s_instances.end()); 0100 } 0101 0102 void ConnectorPrivate::doSetDistributor(const QString &distServiceName) 0103 { 0104 QJniObject context = QNativeInterface::QAndroidApplication::context(); 0105 m_distributor = QAndroidJniObject("org.kde.kunifiedpush.Distributor", "(Ljava/lang/String;Landroid/content/Context;)V", QAndroidJniObject::fromString(distServiceName).object(), context.object()); 0106 } 0107 0108 bool ConnectorPrivate::hasDistributor() const 0109 { 0110 return m_distributor.isValid(); 0111 } 0112 0113 void ConnectorPrivate::doRegister() 0114 { 0115 m_distributor.callMethod<void>("register", "(Ljava/lang/String;Ljava/lang/String;)V", QAndroidJniObject::fromString(m_token).object(), QAndroidJniObject::fromString(m_description).object()); 0116 } 0117 0118 void ConnectorPrivate::doUnregister() 0119 { 0120 m_distributor.callMethod<void>("unregister", "(Ljava/lang/String;)V", QAndroidJniObject::fromString(m_token).object()); 0121 }